Browse Source

Build 2.1

PascalCoin 8 years ago
parent
commit
d1cb0a6c14

+ 2 - 1
PascalCoinWallet.dpr

@@ -37,7 +37,8 @@ uses
   UFRMAccountInfo in 'Units\Forms\UFRMAccountInfo.pas' {FRMAccountInfo},
   UFRMAccountInfo in 'Units\Forms\UFRMAccountInfo.pas' {FRMAccountInfo},
   UFRMMemoText in 'Units\Forms\UFRMMemoText.pas' {FRMMemoText},
   UFRMMemoText in 'Units\Forms\UFRMMemoText.pas' {FRMMemoText},
   UChunk in 'Units\PascalCoin\UChunk.pas',
   UChunk in 'Units\PascalCoin\UChunk.pas',
-  UBaseTypes in 'Units\PascalCoin\UBaseTypes.pas';
+  UBaseTypes in 'Units\PascalCoin\UBaseTypes.pas',
+  UCommon in 'Units\Utils\UCommon.pas';
 
 
 {$R *.res}
 {$R *.res}
 
 

+ 52 - 48
README.md

@@ -34,32 +34,32 @@ Also, consider a donation at PascalCoin development account: "0-10"
 
 
 ## History:  
 ## History:  
 
 
+### Build 2.1.0.0 - 2017-07-14
+- Fixed bug of slow mass transactions from a single account due to incorrect sending order
+- Fixed memory leak on GetSafeBox request call
+- Added new GUI improvements on Operations form
+
 ### Build 2.0.0.0 - 2017-06-23
 ### Build 2.0.0.0 - 2017-06-23
-- **MANDATORY UPGRADE - HARD FORK ACTIVATION WILL OCCUR ON BLOCK 115000**
-- **IMPORTANT FOR EXCHANGES** Version 2 has changed the way operation hashes (OPHASH) are calculated **for existing operations**. This means a prior v1  operation with ophash "X" will now appear with ophash "Y" when querying via the JSON-RPC API. This is relevant when scanning for user deposits. Make sure you do not confuse an old deposit as being new since it now has a new ophash. **Ensure** that your system is aware of this OPHASH calculation change before installing V2, since this change occurs on installation even before the hard-fork. Please note, OPHASH was not designed as an ID however we recognize many are using it this manner. Also note, you can still search for operations using old ophash value via JSON-RPC API.
-- **Introducing Protocol v2.**
+- MANDATORY UPGRADE - HARD FORK ACTIVATION WILL OCCUR ON BLOCK 115000
+- Introducing Protocol v2.
   - https://github.com/PascalCoin/PascalCoin/blob/master/PascalCoinWhitePaperV2.pdf
   - https://github.com/PascalCoin/PascalCoin/blob/master/PascalCoinWhitePaperV2.pdf
-  - **Core Changes:**
+  - Core Changes:
     - New safebox hash calculation algorithm to allow safebox checkpointing
     - New safebox hash calculation algorithm to allow safebox checkpointing
-    - Updated OPHASH algorithm for calculation operation hashes, now includes all operation data
     - Improved difficulty target calculation to obtain a more stable average blocktime of 5 minutes, given abrupt hashpower fluctuations
     - Improved difficulty target calculation to obtain a more stable average blocktime of 5 minutes, given abrupt hashpower fluctuations
     - Bug-fix for China region users
     - Bug-fix for China region users
     - Anti-spam measures
     - Anti-spam measures
       - New Consensus Rule: A block can only contain 1 zero fee operation per sender account. If a sender account issues 2 or more zero-fee operations, that block is invalid.
       - New Consensus Rule: A block can only contain 1 zero fee operation per sender account. If a sender account issues 2 or more zero-fee operations, that block is invalid.
     - SafeBox now stored in chunks to facilitate checkpoint distribution
     - SafeBox now stored in chunks to facilitate checkpoint distribution
-	- Reintroduce block operations into pending pool when it is orphaned
-  
-  - **Added Checkpointing:**
+	- Reintroduce orphan blocks operations on main blockchain
+  - Added Checkpointing:
     - Checkpoint created on every 100'th block
     - Checkpoint created on every 100'th block
     - Added network operations to transfer Checkpoint chunks (compressed)
     - Added network operations to transfer Checkpoint chunks (compressed)
-
-  - **Added In-Protocol PASA Exchanging:**
+  - Addded In-Protocol PASA Exchanging:
     - New Operation: List Account, used to list an account for public or private sale 
     - New Operation: List Account, used to list an account for public or private sale 
     - New Operation: Delist Account, used to delist an account from sale 
     - New Operation: Delist Account, used to delist an account from sale 
     - New Operation: Buy Account, used to purchase an account lised for sale
     - New Operation: Buy Account, used to purchase an account lised for sale
     - Updated Operation: Transaction, can be used in place of Buy Account operation in private account sales
     - Updated Operation: Transaction, can be used in place of Buy Account operation in private account sales
-      
-  - **RPC API Changes:**
+  - RPC API Changes:
     - All changes are backwards-compatible for current 3rd-party infrastructure providers (exchanges, wallets).
     - All changes are backwards-compatible for current 3rd-party infrastructure providers (exchanges, wallets).
     - However, use of param "ophash" has been changed in V2, see "Operation Object changes" section to know how to use "old_ophash" param value    
     - However, use of param "ophash" has been changed in V2, see "Operation Object changes" section to know how to use "old_ophash" param value    
     - JSON changes:
     - JSON changes:
@@ -69,12 +69,11 @@ Also, consider a donation at PascalCoin development account: "0-10"
           - "locked_until_block", "price", "seller_account" 
           - "locked_until_block", "price", "seller_account" 
           - "private_sale" : Boolean value 
           - "private_sale" : Boolean value 
           - "new_enc_pubkey" : (Only on "private_sale" = true) - HEXASTRING with private sale encoded public key
           - "new_enc_pubkey" : (Only on "private_sale" = true) - HEXASTRING with private sale encoded public key
-		- Added param "name": String
-		  - Name available chars: abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-+{}[]\_:"|<>,.?/~
-		  - Name first char: (cannot start with number): abcdefghijklmnopqrstuvwxyz!@#$%^&*()-+{}[]\_:"|<>,.?/~
-		  - Name lenght: Empty or 3..64 chars length
-		- Added param "type": Integer (Valid values from 0..65535)
-        
+        - Added param "name": String
+          - Name available chars: abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-+{}[]\_:"|<>,.?/~
+          - Name first char: (cannot start with number): abcdefghijklmnopqrstuvwxyz!@#$%^&*()-+{}[]\_:"|<>,.?/~
+          - Name lenght: Empty or 3..64 chars length
+        - Added param "type": Integer (Valid values from 0..65535)
       - Operation Object changes:
       - Operation Object changes:
         - Changed param "ophash": Current returned value of "ophash" is not the same than previous builds (changed calculation method)
         - Changed param "ophash": Current returned value of "ophash" is not the same than previous builds (changed calculation method)
         - New param "old_ophash": Will return previous "ophash" value only for old blocks (prior to v2 protocol activation)
         - New param "old_ophash": Will return previous "ophash" value only for old blocks (prior to v2 protocol activation)
@@ -98,8 +97,7 @@ Also, consider a donation at PascalCoin development account: "0-10"
           - Params: Same "listaccountforsale" params, and also:
           - Params: Same "listaccountforsale" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
-            - "last_n_operation" : The current n_operation of signer account
-        
+            - "last_n_operation" : The current n_operation of signer account        
         - "delistaccountforsale" : Delist an account for sale
         - "delistaccountforsale" : Delist an account for sale
           - Params:
           - Params:
             - "account_target" : Account to be delisted
             - "account_target" : Account to be delisted
@@ -109,8 +107,7 @@ Also, consider a donation at PascalCoin development account: "0-10"
 		  - Params: Same "delistaccountforsale" params, and also:
 		  - Params: Same "delistaccountforsale" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
-            - "last_n_operation" : The current n_operation of signer account            
-          
+            - "last_n_operation" : The current n_operation of signer account                      
         - "buyaccount" : Buy an account previously listed for sale (public or private)
         - "buyaccount" : Buy an account previously listed for sale (public or private)
           - Params: 
           - Params: 
             - "buyer_account","account_to_purchase",
             - "buyer_account","account_to_purchase",
@@ -121,50 +118,57 @@ Also, consider a donation at PascalCoin development account: "0-10"
           - Params: Same "buyaccount" params, and also:
           - Params: Same "buyaccount" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "buyer_account"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "buyer_account"
-            - "last_n_operation" : The current n_operation of buyer account
-			
-	    - "changeaccountinfo" : Changes an account Public key, or name, or type value (at least 1 on 3)
-		  - Params:
-			- "account_target" : Account to be delisted
-		    - "account_signer" : Account that signs and pays the fee (must have same public key that target account, or be the same)
-			- "new_b58_pubkey"/"new_enc_pubkey": If used, then will change the target account public key
-			- "new_name": If used, then will change the target account name
-			- "new_type": If used, then will change the target account type
-			- "fee","payload","payload_method","pwd"
-		- "signchangeaccountinfo" : Signs a change account info for cold cold wallets
+            - "last_n_operation" : The current n_operation of buyer account	
+        - "changeaccountinfo" : Changes an account Public key, or name, or type value (at least 1 on 3)
+            - Params:
+            - "account_target" : Account to be delisted
+            - "account_signer" : Account that signs and pays the fee (must have same public key that target account, or be the same)
+            - "new_b58_pubkey"/"new_enc_pubkey": If used, then will change the target account public key
+            - "new_name": If used, then will change the target account name
+            - "new_type": If used, then will change the target account type
+            - "fee","payload","payload_method","pwd"
+        - "signchangeaccountinfo" : Signs a change account info for cold cold wallets
           - Params: Same "changeaccountinfo" params, and also:
           - Params: Same "changeaccountinfo" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "last_n_operation" : The current n_operation of signer account
             - "last_n_operation" : The current n_operation of signer account
-
         - "findaccounts" : Find accounts by name/type and returns them as an array of Account objects
         - "findaccounts" : Find accounts by name/type and returns them as an array of Account objects
-		  - Returned array will be sorted by account number
-		  - Params:
-		    - "name" : (String) If has value, will return the account that match name
-			- "type" : (Integer) If has value, will return accounts with same type
-			- "start" : (Integer) Start account (by default, 0)
-			- "max" : (Integer) Max of accounts returned in array (by default, 100)
-		    
-			
+          - Returned array will be sorted by account number
+          - Params:
+            - "name" : (String) If has value, will return the account that match name
+            - "type" : (Integer) If has value, will return accounts with same type
+            - "start" : (Integer) Start account (by default, 0)
+            - "max" : (Integer) Max of accounts returned in array (by default, 100)
       - Updated methods:
       - Updated methods:
         - "changekey" : Added param "account_signer" that allow to pay fee using another account with same public key than target "account" param. This allows to change keys on empty accounts (balance = 0) and pay fee
         - "changekey" : Added param "account_signer" that allow to pay fee using another account with same public key than target "account" param. This allows to change keys on empty accounts (balance = 0) and pay fee
         - "signchangekey" : Added param "account_signer", same use that in "changekey" method
         - "signchangekey" : Added param "account_signer", same use that in "changekey" method
-
   - GUI changes:  (not available on daemon)
   - GUI changes:  (not available on daemon)
     - New columns "name" and "type" on accounts
     - New columns "name" and "type" on accounts
-	- Information about Accounts/Operation using F1
+    - Information about Accounts/Operation using F1
     - Operations form now accepts:  (Will be active after V2 protocol activation)
     - Operations form now accepts:  (Will be active after V2 protocol activation)
       - List account for sale (public or private)
       - List account for sale (public or private)
       - Delist account
       - Delist account
       - Buy account
       - Buy account
-	  - Change account name/type
+      - Change account name/type
     - Operations form allows to search for accounts using F2 over an account edit box
     - Operations form allows to search for accounts using F2 over an account edit box
-    - Changes in text showing operations information
-      
-- **Other changes:**  
+    - Changes in text showing operations information     
+- Other changes:
   - Bug for china users fixed  
   - Bug for china users fixed  
   - Bugs fixed
   - Bugs fixed
 
 
+### Build 1.5.6.0 - 2017-05-03
+- Allow multiselect accounts (GUI wallet)
+- Priority for operations with fee:
+  - Allow miner server (pools) to select what to mine using pascalcoin_daemon.ini file (daemon only)
+    - RPC_SERVERMINER_MAX_OPERATIONS_PER_BLOCK: Max of operations that can be included in a block (Default 5000, min value 1000)
+    - RPC_SERVERMINER_MAX_ZERO_FEE_OPERATIONS: Max of operations with 0 fee that can be included in a block (Default 2000, min value 400)
+  - Operations with fee have always preference over 0 fee operations (will be mined first)
+  - If operations with fee fills all the buffer, then no zero fee operation will be included
+- Fixed bug on receiving big blocks and slow net connection to prevent never synchronize
+- Fixed bug on miner server that produces "invalid operations hash" error on valid solutions with 0 operations
+- Fixed bug on file storage
+- Fixed minor bugs
+
 ### Build 1.5.5.0 - 2017-04-11
 ### Build 1.5.5.0 - 2017-04-11
 - Corrected fee result on RPC calls as a negative number on "Change key" operations
 - Corrected fee result on RPC calls as a negative number on "Change key" operations
 - Corrected PASCURRENCY value to be limited as a 4 decimal digits on RPC calls
 - Corrected PASCURRENCY value to be limited as a 4 decimal digits on RPC calls

+ 44 - 38
README.txt

@@ -34,6 +34,11 @@ Also, consider a donation at PascalCoin development account: "0-10"
 
 
 ## History:  
 ## History:  
 
 
+### Build 2.1.0.0 - 2017-07-14
+- Fixed bug of slow mass transactions from a single account due to incorrect sending order
+- Fixed memory leak on GetSafeBox request call
+- Added new GUI improvements on Operations form
+
 ### Build 2.0.0.0 - 2017-06-23
 ### Build 2.0.0.0 - 2017-06-23
 - MANDATORY UPGRADE - HARD FORK ACTIVATION WILL OCCUR ON BLOCK 115000
 - MANDATORY UPGRADE - HARD FORK ACTIVATION WILL OCCUR ON BLOCK 115000
 - Introducing Protocol v2.
 - Introducing Protocol v2.
@@ -46,17 +51,14 @@ Also, consider a donation at PascalCoin development account: "0-10"
       - New Consensus Rule: A block can only contain 1 zero fee operation per sender account. If a sender account issues 2 or more zero-fee operations, that block is invalid.
       - New Consensus Rule: A block can only contain 1 zero fee operation per sender account. If a sender account issues 2 or more zero-fee operations, that block is invalid.
     - SafeBox now stored in chunks to facilitate checkpoint distribution
     - SafeBox now stored in chunks to facilitate checkpoint distribution
 	- Reintroduce orphan blocks operations on main blockchain
 	- Reintroduce orphan blocks operations on main blockchain
-  
   - Added Checkpointing:
   - Added Checkpointing:
     - Checkpoint created on every 100'th block
     - Checkpoint created on every 100'th block
     - Added network operations to transfer Checkpoint chunks (compressed)
     - Added network operations to transfer Checkpoint chunks (compressed)
-
   - Addded In-Protocol PASA Exchanging:
   - Addded In-Protocol PASA Exchanging:
     - New Operation: List Account, used to list an account for public or private sale 
     - New Operation: List Account, used to list an account for public or private sale 
     - New Operation: Delist Account, used to delist an account from sale 
     - New Operation: Delist Account, used to delist an account from sale 
     - New Operation: Buy Account, used to purchase an account lised for sale
     - New Operation: Buy Account, used to purchase an account lised for sale
     - Updated Operation: Transaction, can be used in place of Buy Account operation in private account sales
     - Updated Operation: Transaction, can be used in place of Buy Account operation in private account sales
-      
   - RPC API Changes:
   - RPC API Changes:
     - All changes are backwards-compatible for current 3rd-party infrastructure providers (exchanges, wallets).
     - All changes are backwards-compatible for current 3rd-party infrastructure providers (exchanges, wallets).
     - However, use of param "ophash" has been changed in V2, see "Operation Object changes" section to know how to use "old_ophash" param value    
     - However, use of param "ophash" has been changed in V2, see "Operation Object changes" section to know how to use "old_ophash" param value    
@@ -67,12 +69,11 @@ Also, consider a donation at PascalCoin development account: "0-10"
           - "locked_until_block", "price", "seller_account" 
           - "locked_until_block", "price", "seller_account" 
           - "private_sale" : Boolean value 
           - "private_sale" : Boolean value 
           - "new_enc_pubkey" : (Only on "private_sale" = true) - HEXASTRING with private sale encoded public key
           - "new_enc_pubkey" : (Only on "private_sale" = true) - HEXASTRING with private sale encoded public key
-		- Added param "name": String
-		  - Name available chars: abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-+{}[]\_:"|<>,.?/~
-		  - Name first char: (cannot start with number): abcdefghijklmnopqrstuvwxyz!@#$%^&*()-+{}[]\_:"|<>,.?/~
-		  - Name lenght: Empty or 3..64 chars length
-		- Added param "type": Integer (Valid values from 0..65535)
-        
+        - Added param "name": String
+          - Name available chars: abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-+{}[]\_:"|<>,.?/~
+          - Name first char: (cannot start with number): abcdefghijklmnopqrstuvwxyz!@#$%^&*()-+{}[]\_:"|<>,.?/~
+          - Name lenght: Empty or 3..64 chars length
+        - Added param "type": Integer (Valid values from 0..65535)
       - Operation Object changes:
       - Operation Object changes:
         - Changed param "ophash": Current returned value of "ophash" is not the same than previous builds (changed calculation method)
         - Changed param "ophash": Current returned value of "ophash" is not the same than previous builds (changed calculation method)
         - New param "old_ophash": Will return previous "ophash" value only for old blocks (prior to v2 protocol activation)
         - New param "old_ophash": Will return previous "ophash" value only for old blocks (prior to v2 protocol activation)
@@ -96,8 +97,7 @@ Also, consider a donation at PascalCoin development account: "0-10"
           - Params: Same "listaccountforsale" params, and also:
           - Params: Same "listaccountforsale" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
-            - "last_n_operation" : The current n_operation of signer account
-        
+            - "last_n_operation" : The current n_operation of signer account        
         - "delistaccountforsale" : Delist an account for sale
         - "delistaccountforsale" : Delist an account for sale
           - Params:
           - Params:
             - "account_target" : Account to be delisted
             - "account_target" : Account to be delisted
@@ -107,8 +107,7 @@ Also, consider a donation at PascalCoin development account: "0-10"
 		  - Params: Same "delistaccountforsale" params, and also:
 		  - Params: Same "delistaccountforsale" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
-            - "last_n_operation" : The current n_operation of signer account            
-          
+            - "last_n_operation" : The current n_operation of signer account                      
         - "buyaccount" : Buy an account previously listed for sale (public or private)
         - "buyaccount" : Buy an account previously listed for sale (public or private)
           - Params: 
           - Params: 
             - "buyer_account","account_to_purchase",
             - "buyer_account","account_to_purchase",
@@ -119,50 +118,57 @@ Also, consider a donation at PascalCoin development account: "0-10"
           - Params: Same "buyaccount" params, and also:
           - Params: Same "buyaccount" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "buyer_account"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "buyer_account"
-            - "last_n_operation" : The current n_operation of buyer account
-			
-	    - "changeaccountinfo" : Changes an account Public key, or name, or type value (at least 1 on 3)
-		  - Params:
-			- "account_target" : Account to be delisted
-		    - "account_signer" : Account that signs and pays the fee (must have same public key that target account, or be the same)
-			- "new_b58_pubkey"/"new_enc_pubkey": If used, then will change the target account public key
-			- "new_name": If used, then will change the target account name
-			- "new_type": If used, then will change the target account type
-			- "fee","payload","payload_method","pwd"
-		- "signchangeaccountinfo" : Signs a change account info for cold cold wallets
+            - "last_n_operation" : The current n_operation of buyer account	
+        - "changeaccountinfo" : Changes an account Public key, or name, or type value (at least 1 on 3)
+            - Params:
+            - "account_target" : Account to be delisted
+            - "account_signer" : Account that signs and pays the fee (must have same public key that target account, or be the same)
+            - "new_b58_pubkey"/"new_enc_pubkey": If used, then will change the target account public key
+            - "new_name": If used, then will change the target account name
+            - "new_type": If used, then will change the target account type
+            - "fee","payload","payload_method","pwd"
+        - "signchangeaccountinfo" : Signs a change account info for cold cold wallets
           - Params: Same "changeaccountinfo" params, and also:
           - Params: Same "changeaccountinfo" params, and also:
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "rawoperations" : HEXASTRING with previous signed operations (optional)
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "signer_b58_pubkey"/"signer_enc_pubkey" : The current public key of "account_signer"
             - "last_n_operation" : The current n_operation of signer account
             - "last_n_operation" : The current n_operation of signer account
-
         - "findaccounts" : Find accounts by name/type and returns them as an array of Account objects
         - "findaccounts" : Find accounts by name/type and returns them as an array of Account objects
-		  - Returned array will be sorted by account number
-		  - Params:
-		    - "name" : (String) If has value, will return the account that match name
-			- "type" : (Integer) If has value, will return accounts with same type
-			- "start" : (Integer) Start account (by default, 0)
-			- "max" : (Integer) Max of accounts returned in array (by default, 100)
-		    
-			
+          - Returned array will be sorted by account number
+          - Params:
+            - "name" : (String) If has value, will return the account that match name
+            - "type" : (Integer) If has value, will return accounts with same type
+            - "start" : (Integer) Start account (by default, 0)
+            - "max" : (Integer) Max of accounts returned in array (by default, 100)
       - Updated methods:
       - Updated methods:
         - "changekey" : Added param "account_signer" that allow to pay fee using another account with same public key than target "account" param. This allows to change keys on empty accounts (balance = 0) and pay fee
         - "changekey" : Added param "account_signer" that allow to pay fee using another account with same public key than target "account" param. This allows to change keys on empty accounts (balance = 0) and pay fee
         - "signchangekey" : Added param "account_signer", same use that in "changekey" method
         - "signchangekey" : Added param "account_signer", same use that in "changekey" method
-
   - GUI changes:  (not available on daemon)
   - GUI changes:  (not available on daemon)
     - New columns "name" and "type" on accounts
     - New columns "name" and "type" on accounts
-	- Information about Accounts/Operation using F1
+    - Information about Accounts/Operation using F1
     - Operations form now accepts:  (Will be active after V2 protocol activation)
     - Operations form now accepts:  (Will be active after V2 protocol activation)
       - List account for sale (public or private)
       - List account for sale (public or private)
       - Delist account
       - Delist account
       - Buy account
       - Buy account
-	  - Change account name/type
+      - Change account name/type
     - Operations form allows to search for accounts using F2 over an account edit box
     - Operations form allows to search for accounts using F2 over an account edit box
-    - Changes in text showing operations information
-      
+    - Changes in text showing operations information     
 - Other changes:
 - Other changes:
   - Bug for china users fixed  
   - Bug for china users fixed  
   - Bugs fixed
   - Bugs fixed
 
 
+### Build 1.5.6.0 - 2017-05-03
+- Allow multiselect accounts (GUI wallet)
+- Priority for operations with fee:
+  - Allow miner server (pools) to select what to mine using pascalcoin_daemon.ini file (daemon only)
+    - RPC_SERVERMINER_MAX_OPERATIONS_PER_BLOCK: Max of operations that can be included in a block (Default 5000, min value 1000)
+    - RPC_SERVERMINER_MAX_ZERO_FEE_OPERATIONS: Max of operations with 0 fee that can be included in a block (Default 2000, min value 400)
+  - Operations with fee have always preference over 0 fee operations (will be mined first)
+  - If operations with fee fills all the buffer, then no zero fee operation will be included
+- Fixed bug on receiving big blocks and slow net connection to prevent never synchronize
+- Fixed bug on miner server that produces "invalid operations hash" error on valid solutions with 0 operations
+- Fixed bug on file storage
+- Fixed minor bugs
+
 ### Build 1.5.5.0 - 2017-04-11
 ### Build 1.5.5.0 - 2017-04-11
 - Corrected fee result on RPC calls as a negative number on "Change key" operations
 - Corrected fee result on RPC calls as a negative number on "Change key" operations
 - Corrected PASCURRENCY value to be limited as a 4 decimal digits on RPC calls
 - Corrected PASCURRENCY value to be limited as a 4 decimal digits on RPC calls

+ 1 - 1
Units/PascalCoin/UConst.pas

@@ -135,7 +135,7 @@ Const
   CT_OpSubtype_ChangeKeySigned            = 71;
   CT_OpSubtype_ChangeKeySigned            = 71;
   CT_OpSubtype_ChangeAccountInfo          = 81;
   CT_OpSubtype_ChangeAccountInfo          = 81;
 
 
-  CT_ClientAppVersion : AnsiString = {$IFDEF PRODUCTION}'2.0.0'{$ELSE}{$IFDEF TESTNET}'TESTNET 2.0.0'{$ELSE}{$ENDIF}{$ENDIF};
+  CT_ClientAppVersion : AnsiString = {$IFDEF PRODUCTION}'2.1.0'{$ELSE}{$IFDEF TESTNET}'TESTNET 2.1.0'{$ELSE}{$ENDIF}{$ENDIF};
 
 
   CT_Discover_IPs =  'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin2.ddns.net;pascalcoin1.dynamic-dns.net;pascalcoin1.dns1.us';
   CT_Discover_IPs =  'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin2.ddns.net;pascalcoin1.dynamic-dns.net;pascalcoin1.dns1.us';
 
 

+ 62 - 38
Units/PascalCoin/UNetProtocol.pas

@@ -294,6 +294,7 @@ Type
     FHasReceivedData : Boolean;
     FHasReceivedData : Boolean;
     FIsDownloadingBlocks : Boolean;
     FIsDownloadingBlocks : Boolean;
     FRandomWaitSecondsSendHello : Cardinal;
     FRandomWaitSecondsSendHello : Cardinal;
+    FBufferLock : TPCCriticalSection;
     FBufferReceivedOperationsHash : TOrderedRawList;
     FBufferReceivedOperationsHash : TOrderedRawList;
     FBufferToSendOperations : TOperationsHashTree;
     FBufferToSendOperations : TOperationsHashTree;
     FClientTimestampIp : AnsiString;
     FClientTimestampIp : AnsiString;
@@ -1696,19 +1697,26 @@ function TNetConnection.AddOperationsToBufferForSend(Operations: TOperationsHash
 Var i : Integer;
 Var i : Integer;
 begin
 begin
   Result := 0;
   Result := 0;
-  FNetLock.Acquire;
   try
   try
-    for i := 0 to Operations.OperationsCount - 1 do begin
-      if FBufferReceivedOperationsHash.IndexOf(Operations.GetOperation(i).Sha256)<0 then begin
-        FBufferReceivedOperationsHash.Add(Operations.GetOperation(i).Sha256);
-        If FBufferToSendOperations.IndexOfOperation(Operations.GetOperation(i))<0 then begin
-          FBufferToSendOperations.AddOperationToHashTree(Operations.GetOperation(i));
-          Inc(Result);
+    FBufferLock.Acquire;
+    Try
+      for i := 0 to Operations.OperationsCount - 1 do begin
+        if FBufferReceivedOperationsHash.IndexOf(Operations.GetOperation(i).Sha256)<0 then begin
+          FBufferReceivedOperationsHash.Add(Operations.GetOperation(i).Sha256);
+          If FBufferToSendOperations.IndexOfOperation(Operations.GetOperation(i))<0 then begin
+            FBufferToSendOperations.AddOperationToHashTree(Operations.GetOperation(i));
+            Inc(Result);
+          end;
         end;
         end;
       end;
       end;
+    finally
+      FBufferLock.Release;
+    end;
+  Except
+    On E:Exception do begin
+      TLog.NewLog(ltError,ClassName,'Error at AddOperationsToBufferForSend ('+E.ClassName+'): '+E.Message);
+      Result := 0;
     end;
     end;
-  finally
-    FNetLock.Release;
   end;
   end;
 end;
 end;
 
 
@@ -1787,6 +1795,7 @@ begin
   SetClient( TBufferedNetTcpIpClient.Create(Self) );
   SetClient( TBufferedNetTcpIpClient.Create(Self) );
   TNetData.NetData.FNetConnections.Add(Self);
   TNetData.NetData.FNetConnections.Add(Self);
   TNetData.NetData.NotifyNetConnectionUpdated;
   TNetData.NetData.NotifyNetConnectionUpdated;
+  FBufferLock := TPCCriticalSection.Create('TNetConnection_BufferLock');
   FBufferReceivedOperationsHash := TOrderedRawList.Create;
   FBufferReceivedOperationsHash := TOrderedRawList.Create;
   FBufferToSendOperations := TOperationsHashTree.Create;
   FBufferToSendOperations := TOperationsHashTree.Create;
   FClientTimestampIp := '';
   FClientTimestampIp := '';
@@ -1823,6 +1832,7 @@ begin
     FreeAndNil(FNetLock);
     FreeAndNil(FNetLock);
     FreeAndNil(FClientBufferRead);
     FreeAndNil(FClientBufferRead);
     FreeAndNil(FTcpIpClient);
     FreeAndNil(FTcpIpClient);
+    FreeAndNil(FBufferLock);
     FreeAndNil(FBufferReceivedOperationsHash);
     FreeAndNil(FBufferReceivedOperationsHash);
     FreeAndNil(FBufferToSendOperations);
     FreeAndNil(FBufferToSendOperations);
     inherited;
     inherited;
@@ -1956,7 +1966,7 @@ begin
         DisconnectInvalidClient(false,errors+' > '+TNetData.HeaderDataToText(HeaderData)+' BuffSize: '+inttostr(DataBuffer.Size));
         DisconnectInvalidClient(false,errors+' > '+TNetData.HeaderDataToText(HeaderData)+' BuffSize: '+inttostr(DataBuffer.Size));
       end else begin
       end else begin
         // Add to received buffer
         // Add to received buffer
-        FNetLock.Acquire;
+        FBufferLock.Acquire;
         Try
         Try
           for i := 0 to operations.OperationsCount - 1 do begin
           for i := 0 to operations.OperationsCount - 1 do begin
             op := operations.GetOperation(i);
             op := operations.GetOperation(i);
@@ -1965,7 +1975,7 @@ begin
             if (c>=0) then FBufferToSendOperations.Delete(c);
             if (c>=0) then FBufferToSendOperations.Delete(c);
           end;
           end;
         Finally
         Finally
-          FNetLock.Release;
+          FBufferLock.Release;
         End;
         End;
         TNode.Node.AddOperations(Self,operations,Nil,errors);
         TNode.Node.AddOperations(Self,operations,Nil,errors);
       end;
       end;
@@ -2807,40 +2817,49 @@ end;
 
 
 function TNetConnection.Send_AddOperations(Operations : TOperationsHashTree) : Boolean;
 function TNetConnection.Send_AddOperations(Operations : TOperationsHashTree) : Boolean;
 Var data : TMemoryStream;
 Var data : TMemoryStream;
-  c1,c2,request_id : Cardinal;
-  i : Integer;
+  c1, request_id : Cardinal;
+  i, nOpsToSend : Integer;
   optype : Byte;
   optype : Byte;
 begin
 begin
   Result := false;
   Result := false;
   if Not Connected then exit;
   if Not Connected then exit;
   FNetLock.Acquire;
   FNetLock.Acquire;
   try
   try
-    for i := 0 to Operations.OperationsCount - 1 do begin
-      if FBufferReceivedOperationsHash.IndexOf(Operations.GetOperation(i).Sha256)<0 then begin
-        FBufferReceivedOperationsHash.Add(Operations.GetOperation(i).Sha256);
-        If FBufferToSendOperations.IndexOfOperation(Operations.GetOperation(i))<0 then begin
-          FBufferToSendOperations.AddOperationToHashTree(Operations.GetOperation(i));
+    nOpsToSend := 0;
+    FBufferLock.Acquire;
+    Try
+      If Assigned(Operations) then begin
+        for i := 0 to Operations.OperationsCount - 1 do begin
+          if FBufferReceivedOperationsHash.IndexOf(Operations.GetOperation(i).Sha256)<0 then begin
+            FBufferReceivedOperationsHash.Add(Operations.GetOperation(i).Sha256);
+            If FBufferToSendOperations.IndexOfOperation(Operations.GetOperation(i))<0 then begin
+              FBufferToSendOperations.AddOperationToHashTree(Operations.GetOperation(i));
+            end;
+          end;
         end;
         end;
+        nOpsToSend := Operations.OperationsCount;
       end;
       end;
-    end;
-    if FBufferToSendOperations.OperationsCount>0 then begin
-      TLog.NewLog(ltdebug,ClassName,'Sending '+inttostr(FBufferToSendOperations.OperationsCount)+' Operations to '+ClientRemoteAddr);
-      data := TMemoryStream.Create;
-      try
-        request_id := TNetData.NetData.NewRequestId;
-        c1 := FBufferToSendOperations.OperationsCount;
-        data.Write(c1,4);
-        for i := 0 to FBufferToSendOperations.OperationsCount-1 do begin
-          optype := FBufferToSendOperations.GetOperation(i).OpType;
-          data.Write(optype,1);
-          FBufferToSendOperations.GetOperation(i).SaveToNettransfer(data);
+      if FBufferToSendOperations.OperationsCount>0 then begin
+        TLog.NewLog(ltdebug,ClassName,Format('Sending %d Operations to %s (inProc:%d, Received:%d)',[FBufferToSendOperations.OperationsCount,ClientRemoteAddr,nOpsToSend,FBufferReceivedOperationsHash.Count]));
+        data := TMemoryStream.Create;
+        try
+          request_id := TNetData.NetData.NewRequestId;
+          c1 := FBufferToSendOperations.OperationsCount;
+          data.Write(c1,4);
+          for i := 0 to FBufferToSendOperations.OperationsCount-1 do begin
+            optype := FBufferToSendOperations.GetOperation(i).OpType;
+            data.Write(optype,1);
+            FBufferToSendOperations.GetOperation(i).SaveToNettransfer(data);
+          end;
+          Send(ntp_autosend,CT_NetOp_AddOperations,0,request_id,data);
+          FBufferToSendOperations.ClearHastThree;
+        finally
+          data.Free;
         end;
         end;
-        Send(ntp_autosend,CT_NetOp_AddOperations,0,request_id,data);
-        FBufferToSendOperations.ClearHastThree;
-      finally
-        data.Free;
-      end;
-    end else TLog.NewLog(ltdebug,ClassName,'Not sending any operations to '+ClientRemoteAddr+' ('+IntToStr(Operations.OperationsCount)+')');
+      end else TLog.NewLog(ltdebug,ClassName,Format('Not sending any operations to %s (inProc:%d, Received:%d, Sent:%d)',[ClientRemoteAddr,nOpsToSend,FBufferReceivedOperationsHash.Count,FBufferToSendOperations.OperationsCount]));
+    finally
+      FBufferLock.Release;
+    end;
   finally
   finally
     FNetLock.Release;
     FNetLock.Release;
   end;
   end;
@@ -2973,8 +2992,13 @@ begin
   FNetLock.Acquire;
   FNetLock.Acquire;
   Try
   Try
     // Clear buffers
     // Clear buffers
-    FBufferReceivedOperationsHash.Clear;
-    FBufferToSendOperations.ClearHastThree;
+    FBufferLock.Acquire;
+    Try
+      FBufferReceivedOperationsHash.Clear;
+      FBufferToSendOperations.ClearHastThree;
+    finally
+      FBufferLock.Release;
+    end;
     // Checking if operationblock is the same to prevent double messaging...
     // Checking if operationblock is the same to prevent double messaging...
     If (TPCOperationsComp.EqualsOperationBlock(FRemoteOperationBlock,NewBlock.OperationBlock)) then begin
     If (TPCOperationsComp.EqualsOperationBlock(FRemoteOperationBlock,NewBlock.OperationBlock)) then begin
       TLog.NewLog(ltDebug,ClassName,'This connection has the same block, does not need to send');
       TLog.NewLog(ltDebug,ClassName,'This connection has the same block, does not need to send');

+ 65 - 30
Units/PascalCoin/UNode.pas

@@ -50,6 +50,9 @@ Type
     FPeerCache : AnsiString;
     FPeerCache : AnsiString;
     FDisabledsNewBlocksCount : Integer;
     FDisabledsNewBlocksCount : Integer;
     FSentOperations : TOrderedRawList;
     FSentOperations : TOrderedRawList;
+    {$IFDEF BufferOfFutureOperations}
+    FBufferAuxWaitingOperations : TOperationsHashTree;
+    {$ENDIF}
     Procedure OnBankNewBlock(Sender : TObject);
     Procedure OnBankNewBlock(Sender : TObject);
     procedure SetNodeLogFilename(const Value: AnsiString);
     procedure SetNodeLogFilename(const Value: AnsiString);
     function GetNodeLogFilename: AnsiString;
     function GetNodeLogFilename: AnsiString;
@@ -134,7 +137,6 @@ Type
 
 
   TThreadNodeNotifyOperations = Class(TPCThread)
   TThreadNodeNotifyOperations = Class(TPCThread)
     FNetConnection : TNetConnection;
     FNetConnection : TNetConnection;
-    FOperationsHashTree : TOperationsHashTree;
   protected
   protected
     procedure BCExecute; override;
     procedure BCExecute; override;
     Constructor Create(NetConnection : TNetConnection; MakeACopyOfOperationsHashTree : TOperationsHashTree);
     Constructor Create(NetConnection : TNetConnection; MakeACopyOfOperationsHashTree : TOperationsHashTree);
@@ -219,20 +221,12 @@ begin
     end;
     end;
     FOperations.SanitizeOperations;
     FOperations.SanitizeOperations;
     if Result then begin
     if Result then begin
-      // 1.5.4 - Prevent continuous sending non included operations
-      // Using a Sent operations buffer (FSentOperations) will allow to only "resend" operations once
       opsht := TOperationsHashTree.Create;
       opsht := TOperationsHashTree.Create;
       Try
       Try
         for i := 0 to FOperations.Count - 1 do begin
         for i := 0 to FOperations.Count - 1 do begin
-          j := FSentOperations.GetTag(FOperations.Operation[i].Sha256);
-          if (j=0) Or (j=Bank.LastBlockFound.OperationBlock.block) then begin
-            // Only will "re-send" operations that where received on last block and not included in this one
-            opsht.AddOperationToHashTree(FOperations.Operation[i]);
-            // Add to sent operations
-            FSentOperations.Add(FOperations.Operation[i].Sha256,Bank.LastBlockFound.OperationBlock.block);
-          end else begin
-            TLog.NewLog(ltError,ClassName,'Sanitized operation not included (j='+IntToStr(j)+') ('+inttostr(i+1)+'/'+inttostr(FOperations.Count)+'): '+FOperations.Operation[i].ToString);
-          end;
+          opsht.AddOperationToHashTree(FOperations.Operation[i]);
+          // Add to sent operations
+          FSentOperations.Add(FOperations.Operation[i].Sha256,Bank.LastBlockFound.OperationBlock.block);
         end;
         end;
         if opsht.OperationsCount>0 then begin
         if opsht.OperationsCount>0 then begin
           TLog.NewLog(ltinfo,classname,'Resending '+IntToStr(opsht.OperationsCount)+' operations for new block');
           TLog.NewLog(ltinfo,classname,'Resending '+IntToStr(opsht.OperationsCount)+' operations for new block');
@@ -243,7 +237,7 @@ begin
         // Clean sent operations buffer
         // Clean sent operations buffer
         j := 0;
         j := 0;
         for i := FSentOperations.Count-1 downto 0 do begin
         for i := FSentOperations.Count-1 downto 0 do begin
-          If (FSentOperations.GetTag(i)<Bank.LastBlockFound.OperationBlock.block-Random(5)+1) then begin
+          If (FSentOperations.GetTag(i)<Bank.LastBlockFound.OperationBlock.block-2) then begin
             FSentOperations.Delete(i);
             FSentOperations.Delete(i);
             inc(j);
             inc(j);
           end;
           end;
@@ -289,6 +283,39 @@ begin
 end;
 end;
 
 
 function TNode.AddOperations(SenderConnection : TNetConnection; Operations : TOperationsHashTree; OperationsResult : TOperationsResumeList; var errors: AnsiString): Integer;
 function TNode.AddOperations(SenderConnection : TNetConnection; Operations : TOperationsHashTree; OperationsResult : TOperationsResumeList; var errors: AnsiString): Integer;
+  {$IFDEF BufferOfFutureOperations}
+  Procedure Process_BufferOfFutureOperations(valids_operations : TOperationsHashTree);
+  Var i,j, nAdded, nDeleted : Integer;
+    sAcc : TAccount;
+    ActOp : TPCOperation;
+    e : AnsiString;
+  Begin
+    // Prior to add new operations, will try to add waiting ones
+    nAdded := 0; nDeleted := 0;
+    For j:=0 to 3 do begin
+      i := 0;
+      While (i<FBufferAuxWaitingOperations.OperationsCount) do begin
+        ActOp := FBufferAuxWaitingOperations.GetOperation(i);
+        If FOperations.AddOperation(true,ActOp,e) then begin
+          TLog.NewLog(ltInfo,Classname,Format('AddOperation FromBufferWaitingOperations %d/%d: %s',[i+1,FBufferAuxWaitingOperations.OperationsCount,ActOp.ToString]));
+          inc(nAdded);
+          valids_operations.AddOperationToHashTree(ActOp);
+          FBufferAuxWaitingOperations.Delete(i);
+        end else begin
+          sAcc := FOperations.SafeBoxTransaction.Account(ActOp.SignerAccount);
+          If (sAcc.n_operation>ActOp.N_Operation) Or
+             ((sAcc.n_operation=ActOp.N_Operation) AND (sAcc.balance>0)) then begin
+             FBufferAuxWaitingOperations.Delete(i);
+             inc(nDeleted);
+          end else inc(i);
+        end;
+      end;
+    end;
+    If (nAdded>0) or (nDeleted>0) or (FBufferAuxWaitingOperations.OperationsCount>0) then begin
+      TLog.NewLog(ltInfo,Classname,Format('FromBufferWaitingOperations status - Added:%d Deleted:%d Buffer:%d',[nAdded,nDeleted,FBufferAuxWaitingOperations.OperationsCount]));
+    end;
+  end;
+  {$ENDIF}
 Var
 Var
   i,j : Integer;
   i,j : Integer;
   operationscomp : TPCOperationsComp;
   operationscomp : TPCOperationsComp;
@@ -299,6 +326,7 @@ Var
   s : String;
   s : String;
   OPR : TOperationResume;
   OPR : TOperationResume;
   ActOp : TPCOperation;
   ActOp : TPCOperation;
+  sAcc : TAccount;
 begin
 begin
   Result := -1;
   Result := -1;
   if Assigned(OperationsResult) then OperationsResult.Clear;
   if Assigned(OperationsResult) then OperationsResult.Clear;
@@ -319,6 +347,9 @@ begin
       if TThread.CurrentThread.ThreadID=MainThreadID then raise Exception.Create(s) else exit;
       if TThread.CurrentThread.ThreadID=MainThreadID then raise Exception.Create(s) else exit;
     end;
     end;
     try
     try
+      {$IFDEF BufferOfFutureOperations}
+      Process_BufferOfFutureOperations(valids_operations);
+      {$ENDIF}
       for j := 0 to Operations.OperationsCount-1 do begin
       for j := 0 to Operations.OperationsCount-1 do begin
         ActOp := Operations.GetOperation(j);
         ActOp := Operations.GetOperation(j);
         If (FOperations.OperationsHashTree.IndexOfOperation(ActOp)<0) And (FSentOperations.GetTag(ActOp.Sha256)=0) then begin
         If (FOperations.OperationsHashTree.IndexOfOperation(ActOp)<0) And (FSentOperations.GetTag(ActOp.Sha256)=0) then begin
@@ -364,6 +395,19 @@ begin
                 OPR.errors := e;
                 OPR.errors := e;
                 OperationsResult.Add(OPR);
                 OperationsResult.Add(OPR);
               end;
               end;
+              {$IFDEF BufferOfFutureOperations}
+              // Used to solve 2.0.0 "invalid order of operations" bug
+              If (Assigned(SenderConnection)) Then begin
+                sAcc := FOperations.SafeBoxTransaction.Account(ActOp.SignerAccount);
+                If (sAcc.n_operation<ActOp.N_Operation) Or
+                   ((sAcc.n_operation=ActOp.N_Operation) AND (sAcc.balance=0) And (ActOp.OperationFee>0) And (ActOp.OpType = CT_Op_Changekey)) then begin
+                  If FBufferAuxWaitingOperations.IndexOfOperation(ActOp)<0 then begin
+                    FBufferAuxWaitingOperations.AddOperationToHashTree(ActOp);
+                    TLog.NewLog(ltInfo,Classname,Format('New FromBufferWaitingOperations %d/%d (new buffer size:%d): %s',[j+1,Operations.OperationsCount,FBufferAuxWaitingOperations.OperationsCount,ActOp.ToString]));
+                  end;
+                end;
+              end;
+              {$ENDIF}
             end;
             end;
           end;
           end;
         end else begin
         end else begin
@@ -426,6 +470,9 @@ begin
   FOperations := TPCOperationsComp.Create(Self);
   FOperations := TPCOperationsComp.Create(Self);
   FOperations.bank := FBank;
   FOperations.bank := FBank;
   FNotifyList := TList.Create;
   FNotifyList := TList.Create;
+  {$IFDEF BufferOfFutureOperations}
+  FBufferAuxWaitingOperations := TOperationsHashTree.Create;
+  {$ENDIF}
   if Not Assigned(_Node) then _Node := Self;
   if Not Assigned(_Node) then _Node := Self;
 end;
 end;
 
 
@@ -502,7 +549,9 @@ begin
     step := 'Destroying Bank';
     step := 'Destroying Bank';
     FreeAndNil(FBCBankNotify);
     FreeAndNil(FBCBankNotify);
     FreeAndNil(FBank);
     FreeAndNil(FBank);
-
+    {$IFDEF BufferOfFutureOperations}
+    FreeAndNil(FBufferAuxWaitingOperations);
+    {$ENDIF}
     step := 'inherited';
     step := 'inherited';
     FreeAndNil(FNodeLog);
     FreeAndNil(FNodeLog);
     inherited;
     inherited;
@@ -992,24 +1041,12 @@ end;
 { TThreadNodeNotifyOperations }
 { TThreadNodeNotifyOperations }
 
 
 procedure TThreadNodeNotifyOperations.BCExecute;
 procedure TThreadNodeNotifyOperations.BCExecute;
-Var nOpsCount : Integer;
 begin
 begin
-  nOpsCount := FOperationsHashTree.OperationsCount;
-  if nOpsCount<=0 then exit;
-  if TNetData.NetData.ConnectionLock(Self, FNetConnection, 500) then begin
-    try
-      if Not FNetconnection.Connected then exit;
-      nOpsCount := FNetConnection.AddOperationsToBufferForSend(FOperationsHashTree);
-    finally
-      TNetData.NetData.ConnectionUnlock(FNetConnection);
-    end;
-  end;
-  if nOpsCount<=0 then exit;
   Sleep(Random(5000)); // Delay 0..5 seconds to allow receive data and don't send if not necessary
   Sleep(Random(5000)); // Delay 0..5 seconds to allow receive data and don't send if not necessary
   if TNetData.NetData.ConnectionLock(Self, FNetConnection, 500) then begin
   if TNetData.NetData.ConnectionLock(Self, FNetConnection, 500) then begin
     try
     try
       if Not FNetconnection.Connected then exit;
       if Not FNetconnection.Connected then exit;
-      FNetConnection.Send_AddOperations(FOperationsHashTree);
+      FNetConnection.Send_AddOperations(Nil);
     finally
     finally
       TNetData.NetData.ConnectionUnlock(FNetConnection);
       TNetData.NetData.ConnectionUnlock(FNetConnection);
     end;
     end;
@@ -1018,16 +1055,14 @@ end;
 
 
 constructor TThreadNodeNotifyOperations.Create(NetConnection: TNetConnection; MakeACopyOfOperationsHashTree: TOperationsHashTree);
 constructor TThreadNodeNotifyOperations.Create(NetConnection: TNetConnection; MakeACopyOfOperationsHashTree: TOperationsHashTree);
 begin
 begin
-  FOperationsHashTree := TOperationsHashTree.Create;
-  FOperationsHashTree.CopyFromHashTree(MakeACopyOfOperationsHashTree);
   FNetConnection := NetConnection;
   FNetConnection := NetConnection;
+  FNetConnection.AddOperationsToBufferForSend(MakeACopyOfOperationsHashTree);
   Inherited Create(false);
   Inherited Create(false);
   FreeOnTerminate := true;
   FreeOnTerminate := true;
 end;
 end;
 
 
 destructor TThreadNodeNotifyOperations.Destroy;
 destructor TThreadNodeNotifyOperations.Destroy;
 begin
 begin
-  FreeAndNil(FOperationsHashTree);
   inherited;
   inherited;
 end;
 end;
 
 

+ 8 - 1
Units/PascalCoin/UThread.pas

@@ -238,18 +238,24 @@ end;
 
 
 class function TPCThread.TryProtectEnterCriticalSection(const Sender: TObject;
 class function TPCThread.TryProtectEnterCriticalSection(const Sender: TObject;
   MaxWaitMilliseconds: Cardinal; var Lock: TPCCriticalSection): Boolean;
   MaxWaitMilliseconds: Cardinal; var Lock: TPCCriticalSection): Boolean;
-Var tc,tc2,tc3,lockCurrThread,lockWatingForCounter,lockStartedTimestamp : Cardinal;
+Var tc : Cardinal;
+  {$IFDEF HIGHLOG}
+  tc2,tc3,lockCurrThread,lockWatingForCounter,lockStartedTimestamp : Cardinal;
   s : String;
   s : String;
+  {$ENDIF}
 begin
 begin
   tc := GetTickCount;
   tc := GetTickCount;
   if MaxWaitMilliseconds>60000 then MaxWaitMilliseconds := 60000;
   if MaxWaitMilliseconds>60000 then MaxWaitMilliseconds := 60000;
+  {$IFDEF HIGHLOG}
   lockWatingForCounter := Lock.WaitingForCounter;
   lockWatingForCounter := Lock.WaitingForCounter;
   lockStartedTimestamp := Lock.StartedTimestamp;
   lockStartedTimestamp := Lock.StartedTimestamp;
   lockCurrThread := Lock.CurrentThread;
   lockCurrThread := Lock.CurrentThread;
+  {$ENDIF}
   Repeat
   Repeat
     Result := Lock.TryEnter;
     Result := Lock.TryEnter;
     if Not Result then sleep(1);
     if Not Result then sleep(1);
   Until (Result) Or (GetTickCount > (tc + MaxWaitMilliseconds));
   Until (Result) Or (GetTickCount > (tc + MaxWaitMilliseconds));
+  {$IFDEF HIGHLOG}
   if Not Result then begin
   if Not Result then begin
     tc2 := GetTickCount;
     tc2 := GetTickCount;
     if lockStartedTimestamp=0 then lockStartedTimestamp := Lock.StartedTimestamp;
     if lockStartedTimestamp=0 then lockStartedTimestamp := Lock.StartedTimestamp;
@@ -264,6 +270,7 @@ begin
       ]);
       ]);
     TLog.NewLog(ltdebug,Classname,s);
     TLog.NewLog(ltdebug,Classname,s);
   end;
   end;
+  {$ENDIF}
 end;
 end;
 
 
 { TPCThreadList }
 { TPCThreadList }

+ 4 - 0
Units/PascalCoin/config.inc

@@ -32,7 +32,11 @@
   {$DEFINE PRODUCTION}
   {$DEFINE PRODUCTION}
   {.$DEFINE TESTNET}
   {.$DEFINE TESTNET}
 
 
+  // For GUI: Allows to show average time on blockchain explorer
   {.$DEFINE SHOW_AVERAGE_TIME_STATS}
   {.$DEFINE SHOW_AVERAGE_TIME_STATS}
+
+  // For special use: Allows to store in a buffer, operations not proceded due to n_operation value invalid
+  {.$DEFINE BufferOfFutureOperations}
   
   
   // HighLog will result in a higher log generation
   // HighLog will result in a higher log generation
   {.$DEFINE HIGHLOG}
   {.$DEFINE HIGHLOG}