Browse Source

Merge pull request #10 from PascalCoinDev/master

TESTNET 5 Beta 4
Pascal Coin 5 years ago
parent
commit
6d88281a7c

+ 10 - 2
CHANGELOG.md

@@ -12,8 +12,12 @@
 - Implementation of PIP-0027 (E-PASA Inifine Address-Space) -> https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0027.md
 - Implementation of PIP-0027 (E-PASA Inifine Address-Space) -> https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0027.md
   - Third party apps/implementations of hard coded operations need to pay attention of an extra byte added on each operation using Payload
   - Third party apps/implementations of hard coded operations need to pay attention of an extra byte added on each operation using Payload
   - TODO: Explain "in core" changes
   - TODO: Explain "in core" changes
+- Implementation of PIP-0037 (Distinguish account updates between active/passive mode)
+  - Added fields "updated_b_active_mode" and "updated_b_passive_mode" at each account to indicate in which block this account has been updated
+  - "active" means that private key has been used, so, is the initiator of the operation (can be as a sender or as a signer)
+  - "passive" means that this account is a receiver or a passive target (receiver or seller, for example)
 - Partial implementation of PIP-0012 (Recover Accounts option after 4 years) -> https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0012.md
 - Partial implementation of PIP-0012 (Recover Accounts option after 4 years) -> https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0012.md
-  - Accounts updated counter will only update when executing operations in active mode (sender or signer)
+  - Accounts updated counter will only update when executing operations in active mode (See PIP-0037)
   - If account is a receiver (passive mode) then n_operation_update_block will not update value and can be recovered after 4 years (as defined on original PascalCoin v1 WhitePaper)
   - If account is a receiver (passive mode) then n_operation_update_block will not update value and can be recovered after 4 years (as defined on original PascalCoin v1 WhitePaper)
 - Fixed important security issue related to PIP-0003 caused by possible "parallelization" of the Proof-of-work
 - Fixed important security issue related to PIP-0003 caused by possible "parallelization" of the Proof-of-work
   - Discovered by Herman Schoenfeld <[email protected]>
   - Discovered by Herman Schoenfeld <[email protected]>
@@ -53,6 +57,8 @@
     - "receiver_swap_account": (Integer) Counterpaty account that will receive "amount_to_swap" on ATOMIC COIN SWAP
     - "receiver_swap_account": (Integer) Counterpaty account that will receive "amount_to_swap" on ATOMIC COIN SWAP
     - "data" : (HEXASTRING) will return the Account Data stored with PIP-0024
     - "data" : (HEXASTRING) will return the Account Data stored with PIP-0024
     - "seal" : (HEXASTRING) will return the Account Seal stored with PIP-0029
     - "seal" : (HEXASTRING) will return the Account Seal stored with PIP-0029
+    - "updated_b_active_mode" : (Integer) Block number of last account change on active mode (private key usage for signature)
+    - "updated_b_passive_mode" : (Integer) Block number of last account change on passive mode (as a receiver of a transaction or similar)
   - Updated "Operation Object" return values:
   - Updated "Operation Object" return values:
     - "senders" : ARRAY
     - "senders" : ARRAY
       - "payload_type" : (Byte) as described on PIP-0027
       - "payload_type" : (Byte) as described on PIP-0027
@@ -68,7 +74,9 @@
   - Updated "Multi Operation Object" values:
   - Updated "Multi Operation Object" values:
     - "changers" : ARRAY
     - "changers" : ARRAY
       - "new_data" : (HEXASTRING) : If "data" is changed on "account"
       - "new_data" : (HEXASTRING) : If "data" is changed on "account"
-
+  - Allowed to use all input params related to an account number as a String and including checksum
+    - Example: Call "sendto" using param "sender"="1234-44" or "target"="12345-54"
+    - If value is not a valid format, call will return error
 TODO  
 TODO  
 - TODO: RPC calls for PIP-0029
 - TODO: RPC calls for PIP-0029
 - TODO: RPC calls for PIP-0030
 - TODO: RPC calls for PIP-0030

+ 47 - 0
PIP/PIP-0037.md

@@ -0,0 +1,47 @@
+<pre>
+  PIP: PIP-0037
+  Title: Distinguish account updates between active/passive mode
+  Type: Protocol
+  Impact: Hard-Fork
+  Author: Albert Molina based on @bentley idea at Discord Channel and others
+  Comments-URI: https://discord.gg/sJqcgtD
+  Status: Proposed
+  Created: 2019-10-20
+</pre>
+
+## Summary
+
+Update the previous `Account.updated_block` field to distinguish between **active** updates versus **passive** updates
+
+## Motivation
+
+Motivated by the activation of the PIP-0012 and some improvements made that distinguish between an active usage of the account versus a passive modification
+
+## Background 
+
+Currently the OP_RECOVER operation is based on a single `updated_block` field that is updated each time an account changes.
+
+The change can be caused by any operation that affects this account, even if the private key of this account has not been used (for example, receiving a transaction)
+
+In order to distinguish when the update has been made in active or passive mode, the proposal is to separate the single `update_block` field in 2 fields:
+- `updated_on_block_active_mode`
+- `updated_on_block_passive_mode`
+
+Adding this distinction, will allow a fair use of the OP_RECOVER operation as was originally designed in initial PascalCoin WhitePaper
+
+## Specification
+
+Add 2 new fields on `Account` object:
+- `updated_on_block_active_mode`
+- `updated_on_block_passive_mode`
+
+Delete the previous `updated_block` field because can be calculated with `=MAX( updated_on_block_active_mode, updated_on_block_passive_mode)`
+
+Definition of **active mode**
+
+When an account is the originator of the operation and the private key of this account has been used.
+
+For example: A `Sender` of any transaction, or when an account has been changed it's state including when is not the signer of the operation
+
+By definition, every time `n_operation` field is updated, `updated_on_block_active_mode` is updated too
+

+ 0 - 0
src/PascalCoinMiner.pp


+ 110 - 123
src/core/UAccounts.pas

@@ -87,18 +87,20 @@ Type
     class Function AllowUseHardcodedRandomHashTable(const AHardcodedFileName : String; const AHardcodedSha256Value : TRawBytes) : Boolean;
     class Function AllowUseHardcodedRandomHashTable(const AHardcodedFileName : String; const AHardcodedSha256Value : TRawBytes) : Boolean;
   end;
   end;
 
 
+  { TAccount }
+
   TAccount = Record
   TAccount = Record
     account: Cardinal;        // FIXED value. Account number
     account: Cardinal;        // FIXED value. Account number
     accountInfo : TAccountInfo;
     accountInfo : TAccountInfo;
     balance: UInt64;          // Balance, always >= 0
     balance: UInt64;          // Balance, always >= 0
-    updated_on_block: Cardinal;   // Number of block where was updated (active or passive mode)
+    updated_on_block_passive_mode: Cardinal; // Number of block where was updated (active or passive mode)
     updated_on_block_active_mode: Cardinal; // Number of block where was used (active mode only)
     updated_on_block_active_mode: Cardinal; // Number of block where was used (active mode only)
     n_operation: Cardinal;    // count number of owner operations (when receive, this is not updated)
     n_operation: Cardinal;    // count number of owner operations (when receive, this is not updated)
     name : TRawBytes;         // Protocol 2. Unique name
     name : TRawBytes;         // Protocol 2. Unique name
     account_type : Word;      // Protocol 2. Layer 2 use case
     account_type : Word;      // Protocol 2. Layer 2 use case
     account_data : TRawBytes; // Protocol 5. PIP-0024 RAW data information
     account_data : TRawBytes; // Protocol 5. PIP-0024 RAW data information
     account_seal : TRawBytes;  // Protocol 5. PIP-0029 seal of data changes
     account_seal : TRawBytes;  // Protocol 5. PIP-0029 seal of data changes
-    previous_updated_block : Cardinal; // New Build 1.0.8 -> Only used to store this info to storage. It helps App to search when an account was updated. NOT USED FOR HASH CALCULATIONS!
+    function GetLastUpdatedBlock : Cardinal;
   End;
   End;
   PAccount = ^TAccount;
   PAccount = ^TAccount;
 
 
@@ -310,8 +312,8 @@ Type
     Procedure UpdateAccount(account_number : Cardinal; const newAccountInfo: TAccountInfo; const newName : TRawBytes; newType : Word;
     Procedure UpdateAccount(account_number : Cardinal; const newAccountInfo: TAccountInfo; const newName : TRawBytes; newType : Word;
          newBalance: UInt64; newN_operation: Cardinal;
          newBalance: UInt64; newN_operation: Cardinal;
          const newAccountData, newAccountSeal : TRawBytes;
          const newAccountData, newAccountSeal : TRawBytes;
-         accountUpdateStyle : TAccountUpdateStyle; newUpdated_block, newUpdated_block_active_mode, newPrevious_Updated_block : Cardinal;
-         AHasBenUpdatedOnActiveMode : Boolean);
+         accountUpdateStyle : TAccountUpdateStyle; newUpdated_block_pasive_mode, newUpdated_block_active_mode : Cardinal;
+         AHasBenUpdatedOnActiveMode, AHasBenUpdatedOnPasiveMode : Boolean);
     Function AddNew(Const blockChain : TOperationBlock) : TBlockAccount;
     Function AddNew(Const blockChain : TOperationBlock) : TBlockAccount;
     function DoUpgradeToProtocol2 : Boolean;
     function DoUpgradeToProtocol2 : Boolean;
     function DoUpgradeToProtocol3 : Boolean;
     function DoUpgradeToProtocol3 : Boolean;
@@ -439,6 +441,7 @@ Type
       LatestOpIDUsedForSeal : TRawBytes;
       LatestOpIDUsedForSeal : TRawBytes;
       AccountSealed : PAccount;
       AccountSealed : PAccount;
       SealChangesCounter : Integer;
       SealChangesCounter : Integer;
+      UsedAsPasiveMode : Boolean;
       UsedAsActiveMode : Boolean;
       UsedAsActiveMode : Boolean;
     End;
     End;
     PSealedAccount = ^TSealedAccount;
     PSealedAccount = ^TSealedAccount;
@@ -515,16 +518,16 @@ Const
   CT_OperationBlock_NUL : TOperationBlock = (block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
   CT_OperationBlock_NUL : TOperationBlock = (block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
     protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;initial_safe_box_hash:Nil;operations_hash:Nil;proof_of_work:Nil;previous_proof_of_work:Nil);
     protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;initial_safe_box_hash:Nil;operations_hash:Nil;proof_of_work:Nil;previous_proof_of_work:Nil);
   CT_AccountInfo_NUL : TAccountInfo = (state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);hashed_secret:Nil);
   CT_AccountInfo_NUL : TAccountInfo = (state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);hashed_secret:Nil);
-  CT_Account_NUL : TAccount = (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil;previous_updated_block:0);
+  CT_Account_NUL : TAccount = (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block_passive_mode:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil);
   CT_BlockAccount_NUL : TBlockAccount = (
   CT_BlockAccount_NUL : TBlockAccount = (
     blockchainInfo:(block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
     blockchainInfo:(block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
     protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;initial_safe_box_hash:Nil;operations_hash:Nil;proof_of_work:Nil;previous_proof_of_work:Nil);
     protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;initial_safe_box_hash:Nil;operations_hash:Nil;proof_of_work:Nil;previous_proof_of_work:Nil);
     accounts:(
     accounts:(
-    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil;previous_updated_block:0),
-    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil;previous_updated_block:0),
-    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil;previous_updated_block:0),
-    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil;previous_updated_block:0),
-    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil;previous_updated_block:0)
+    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block_passive_mode:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil),
+    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block_passive_mode:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil),
+    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block_passive_mode:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil),
+    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block_passive_mode:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil),
+    (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_on_block_passive_mode:0;updated_on_block_active_mode:0;n_operation:0;name:Nil;account_type:0;account_data:Nil;account_seal:Nil)
     );
     );
     block_hash:Nil;
     block_hash:Nil;
     accumulatedWork:0);
     accumulatedWork:0);
@@ -605,8 +608,8 @@ Begin
     for i:=0 to sb.BlocksCount-1 do begin
     for i:=0 to sb.BlocksCount-1 do begin
       bl_my := sb.Block(i);
       bl_my := sb.Block(i);
       for j:=Low(bl_my.accounts) to High(bl_my.accounts) do begin
       for j:=Low(bl_my.accounts) to High(bl_my.accounts) do begin
-        If (maxBlock < (bl_my.accounts[j].updated_on_block)) or (maxBlock < (bl_my.accounts[j].updated_on_block_active_mode)) or (bl_my.accounts[j].updated_on_block<bl_my.accounts[j].updated_on_block_active_mode) then begin
-          Raise Exception.Create(Format('%s Integrity on (i)=%d for block account:%d updated on %d , active updated on %d ,maxBlock %d',[title, i,bl_my.accounts[j].account,bl_my.accounts[j].updated_on_block,bl_my.accounts[j].updated_on_block_active_mode,maxBlock]));
+        If (maxBlock < (bl_my.accounts[j].updated_on_block_passive_mode)) or (maxBlock < (bl_my.accounts[j].updated_on_block_active_mode)) then begin
+          Raise Exception.Create(Format('%s Integrity on (i)=%d for block account:%d pasive updated on %d , active updated on %d ,maxBlock %d',[title, i,bl_my.accounts[j].account,bl_my.accounts[j].updated_on_block_passive_mode,bl_my.accounts[j].updated_on_block_active_mode,maxBlock]));
         end;
         end;
       end;
       end;
       auxH.Replace(i*32,bl_my.block_hash[Low(bl_my.block_hash)],Length(bl_my.block_hash));
       auxH.Replace(i*32,bl_my.block_hash[Low(bl_my.block_hash)],Length(bl_my.block_hash));
@@ -624,6 +627,14 @@ end;
 
 
 var _INTERNAL_PascalCoinProtocol : TPascalCoinProtocol = Nil;
 var _INTERNAL_PascalCoinProtocol : TPascalCoinProtocol = Nil;
 
 
+{ TAccount }
+
+function TAccount.GetLastUpdatedBlock: Cardinal;
+begin
+  if (Self.updated_on_block_passive_mode>Self.updated_on_block_active_mode) then Result := Self.updated_on_block_passive_mode
+  else Result := Self.updated_on_block_active_mode;
+end;
+
 class function TPascalCoinProtocol.GetNewTarget(vteorical, vreal: Cardinal; protocol_version : Integer; isSlowMovement : Boolean; const actualTarget: TRawBytes): TRawBytes;
 class function TPascalCoinProtocol.GetNewTarget(vteorical, vreal: Cardinal; protocol_version : Integer; isSlowMovement : Boolean; const actualTarget: TRawBytes): TRawBytes;
 Var
 Var
   bnact, bnaux: TBigNum;
   bnact, bnaux: TBigNum;
@@ -1259,6 +1270,7 @@ class procedure TAccountComp.SaveAccountToAStream(Stream: TStream; const Account
 var w : Word;
 var w : Word;
   LTmpSeal : T20Bytes;
   LTmpSeal : T20Bytes;
   LTmpRaw : TRawBytes;
   LTmpRaw : TRawBytes;
+  LCardinal : Cardinal;
 begin
 begin
   if current_protocol<CT_PROTOCOL_5 then
   if current_protocol<CT_PROTOCOL_5 then
     w := CT_PROTOCOL_4
     w := CT_PROTOCOL_4
@@ -1267,9 +1279,12 @@ begin
   Stream.Write(Account.account,Sizeof(Account.account));
   Stream.Write(Account.account,Sizeof(Account.account));
   TStreamOp.WriteAnsiString(Stream,AccountInfo2RawString(Account.accountInfo));
   TStreamOp.WriteAnsiString(Stream,AccountInfo2RawString(Account.accountInfo));
   Stream.Write(Account.balance,Sizeof(Account.balance));
   Stream.Write(Account.balance,Sizeof(Account.balance));
-  Stream.Write(Account.updated_on_block,Sizeof(Account.updated_on_block));
   if current_protocol>=CT_PROTOCOL_5 then begin
   if current_protocol>=CT_PROTOCOL_5 then begin
+    Stream.Write(Account.updated_on_block_passive_mode,Sizeof(Account.updated_on_block_passive_mode));
     Stream.Write(Account.updated_on_block_active_mode,Sizeof(Account.updated_on_block_active_mode));
     Stream.Write(Account.updated_on_block_active_mode,Sizeof(Account.updated_on_block_active_mode));
+  end else begin
+    LCardinal := Account.GetLastUpdatedBlock;
+    Stream.Write(LCardinal,Sizeof(LCardinal));
   end;
   end;
   Stream.Write(Account.n_operation,Sizeof(Account.n_operation));
   Stream.Write(Account.n_operation,Sizeof(Account.n_operation));
   TStreamOp.WriteAnsiString(Stream,Account.name);
   TStreamOp.WriteAnsiString(Stream,Account.name);
@@ -1297,10 +1312,10 @@ begin
   TAccountComp.RawString2AccountInfo(raw,Account.accountInfo);
   TAccountComp.RawString2AccountInfo(raw,Account.accountInfo);
   if (Stream.Size - Stream.Position<20) then Exit;
   if (Stream.Size - Stream.Position<20) then Exit;
   Stream.Read(Account.balance,Sizeof(Account.balance));
   Stream.Read(Account.balance,Sizeof(Account.balance));
-  Stream.Read(Account.updated_on_block,Sizeof(Account.updated_on_block));
+  Stream.Read(Account.updated_on_block_passive_mode,Sizeof(Account.updated_on_block_passive_mode));
   if LSaved_protocol>=CT_PROTOCOL_5 then begin
   if LSaved_protocol>=CT_PROTOCOL_5 then begin
     Stream.Read(Account.updated_on_block_active_mode,Sizeof(Account.updated_on_block_active_mode));
     Stream.Read(Account.updated_on_block_active_mode,Sizeof(Account.updated_on_block_active_mode));
-  end;
+  end else Account.updated_on_block_active_mode := Account.updated_on_block_passive_mode;
   Stream.Read(Account.n_operation,Sizeof(Account.n_operation));
   Stream.Read(Account.n_operation,Sizeof(Account.n_operation));
   if TStreamOp.ReadAnsiString(Stream,Account.name)<0 then Exit;
   if TStreamOp.ReadAnsiString(Stream,Account.name)<0 then Exit;
   if Stream.Read(Account.account_type,SizeOf(Account.account_type)) <> 2 then Exit;
   if Stream.Read(Account.account_type,SizeOf(Account.account_type)) <> 2 then Exit;
@@ -1478,14 +1493,13 @@ begin
   Result := (account1.account = account2.account)
   Result := (account1.account = account2.account)
           And (EqualAccountInfos(account1.accountInfo,account2.accountInfo))
           And (EqualAccountInfos(account1.accountInfo,account2.accountInfo))
           And (account1.balance = account2.balance)
           And (account1.balance = account2.balance)
-          And (account1.updated_on_block = account2.updated_on_block)
+          And (account1.updated_on_block_passive_mode = account2.updated_on_block_passive_mode)
           And (account1.updated_on_block_active_mode = account2.updated_on_block_active_mode)
           And (account1.updated_on_block_active_mode = account2.updated_on_block_active_mode)
           And (account1.n_operation = account2.n_operation)
           And (account1.n_operation = account2.n_operation)
           And (TBaseType.Equals(account1.name,account2.name))
           And (TBaseType.Equals(account1.name,account2.name))
           And (account1.account_type = account2.account_type)
           And (account1.account_type = account2.account_type)
           And (TBaseType.Equals(account1.account_data,account2.account_data))
           And (TBaseType.Equals(account1.account_data,account2.account_data))
-          And (TBaseType.Equals(account1.account_seal,account2.account_seal))
-          And (account1.previous_updated_block = account2.previous_updated_block);
+          And (TBaseType.Equals(account1.account_seal,account2.account_seal));
 end;
 end;
 
 
 class function TAccountComp.EqualOperationBlocks(const opBlock1, opBlock2: TOperationBlock): Boolean;
 class function TAccountComp.EqualOperationBlocks(const opBlock1, opBlock2: TOperationBlock): Boolean;
@@ -1726,7 +1740,7 @@ end;
 class function TAccountComp.AccountToTxt(const Account: TAccount): String;
 class function TAccountComp.AccountToTxt(const Account: TAccount): String;
 begin
 begin
   Result := Format('%s Balance:%s N_Op:%d UpdB:%d UpdBA:%d Type:%d Name:%s PK:%s Data:%s Seal:%s',[AccountNumberToAccountTxtNumber(Account.account),
   Result := Format('%s Balance:%s N_Op:%d UpdB:%d UpdBA:%d Type:%d Name:%s PK:%s Data:%s Seal:%s',[AccountNumberToAccountTxtNumber(Account.account),
-    FormatMoney(Account.balance),Account.n_operation,Account.updated_on_block,Account.updated_on_block_active_mode,Account.account_type,
+    FormatMoney(Account.balance),Account.n_operation,Account.updated_on_block_passive_mode,Account.updated_on_block_active_mode,Account.account_type,
       Account.name.ToPrintable,TCrypto.ToHexaString(TAccountComp.AccountInfo2RawString(Account.accountInfo)),
       Account.name.ToPrintable,TCrypto.ToHexaString(TAccountComp.AccountInfo2RawString(Account.accountInfo)),
       Account.account_data.ToHexaString,Account.account_seal.ToHexaString ]);
       Account.account_data.ToHexaString,Account.account_seal.ToHexaString ]);
 end;
 end;
@@ -1988,14 +2002,13 @@ Type
     accountInfo : TDynRawBytes;
     accountInfo : TDynRawBytes;
     {$ENDIF}
     {$ENDIF}
     balance: UInt64;
     balance: UInt64;
-    updated_on_block: Cardinal;
+    updated_on_block_passive_mode: Cardinal;
     updated_on_block_active_mode: Cardinal;
     updated_on_block_active_mode: Cardinal;
     n_operation: Cardinal;
     n_operation: Cardinal;
     name : TRawBytes;
     name : TRawBytes;
     account_type : Word;
     account_type : Word;
     account_data : TDynRawBytes;
     account_data : TDynRawBytes;
     account_seal : T20Bytes;
     account_seal : T20Bytes;
-    previous_updated_block : Cardinal;
   End;
   End;
 
 
   TMemOperationBlock = Record // TOperationBlock with less memory usage
   TMemOperationBlock = Record // TOperationBlock with less memory usage
@@ -2053,14 +2066,13 @@ begin
   TBaseType.To256RawBytes(raw,dest.accountInfo);
   TBaseType.To256RawBytes(raw,dest.accountInfo);
   {$ENDIF}
   {$ENDIF}
   dest.balance := source.balance;
   dest.balance := source.balance;
-  dest.updated_on_block:=source.updated_on_block;
+  dest.updated_on_block_passive_mode:=source.updated_on_block_passive_mode;
   dest.updated_on_block_active_mode:=source.updated_on_block_active_mode;
   dest.updated_on_block_active_mode:=source.updated_on_block_active_mode;
   dest.n_operation:=source.n_operation;
   dest.n_operation:=source.n_operation;
   dest.name:=source.name;
   dest.name:=source.name;
   dest.account_type:=source.account_type;
   dest.account_type:=source.account_type;
   dest.account_data:=Copy(source.account_data);
   dest.account_data:=Copy(source.account_data);
   dest.account_seal:=TBaseType.To20Bytes(source.account_seal);
   dest.account_seal:=TBaseType.To20Bytes(source.account_seal);
-  dest.previous_updated_block:=source.previous_updated_block;
   {$ELSE}
   {$ELSE}
   dest := source;
   dest := source;
   {$ENDIF}
   {$ENDIF}
@@ -2086,14 +2098,13 @@ begin
   TAccountComp.RawString2AccountInfo(raw,dest.accountInfo);
   TAccountComp.RawString2AccountInfo(raw,dest.accountInfo);
   {$ENDIF}
   {$ENDIF}
   dest.balance := source.balance;
   dest.balance := source.balance;
-  dest.updated_on_block:=source.updated_on_block;
+  dest.updated_on_block_passive_mode:=source.updated_on_block_passive_mode;
   dest.updated_on_block_active_mode:=source.updated_on_block_active_mode;
   dest.updated_on_block_active_mode:=source.updated_on_block_active_mode;
   dest.n_operation:=source.n_operation;
   dest.n_operation:=source.n_operation;
   dest.name:=source.name;
   dest.name:=source.name;
   dest.account_type:=source.account_type;
   dest.account_type:=source.account_type;
   dest.account_data:=Copy(source.account_data);
   dest.account_data:=Copy(source.account_data);
   dest.account_seal:=TBaseType.T20BytesToRawBytes(source.account_seal);
   dest.account_seal:=TBaseType.T20BytesToRawBytes(source.account_seal);
-  dest.previous_updated_block:=source.previous_updated_block;
   {$ELSE}
   {$ELSE}
   dest := source;
   dest := source;
   {$ENDIF}
   {$ENDIF}
@@ -2245,6 +2256,7 @@ var i, base_addr : Integer;
   //
   //
   account_dev,
   account_dev,
   account_0 : TAccount;
   account_0 : TAccount;
+  LAccountKey: TAccountKey;
   //
   //
   acc_0_miner_reward,acc_4_dev_reward : Int64;
   acc_0_miner_reward,acc_4_dev_reward : Int64;
   acc_4_for_dev : Boolean;
   acc_4_for_dev : Boolean;
@@ -2261,6 +2273,11 @@ begin
     If (AccountsCount>account_0.account_type) then begin
     If (AccountsCount>account_0.account_type) then begin
       account_dev := Account(account_0.account_type);
       account_dev := Account(account_0.account_type);
     end else account_dev := account_0;
     end else account_dev := account_0;
+    if (account_dev.account=0) then begin
+      LAccountKey := blockChain.account_key;
+    end else begin
+      LAccountKey := account_dev.accountInfo.accountKey;
+    end;
   end;
   end;
 
 
   base_addr := BlocksCount * CT_AccountsPerBlock;
   base_addr := BlocksCount * CT_AccountsPerBlock;
@@ -2270,11 +2287,11 @@ begin
     Result.accounts[i] := CT_Account_NUL;
     Result.accounts[i] := CT_Account_NUL;
     Result.accounts[i].account := base_addr + i;
     Result.accounts[i].account := base_addr + i;
     Result.accounts[i].accountInfo.state := as_Normal;
     Result.accounts[i].accountInfo.state := as_Normal;
-    Result.accounts[i].updated_on_block := BlocksCount;
+    Result.accounts[i].updated_on_block_passive_mode := BlocksCount;
     Result.accounts[i].updated_on_block_active_mode := BlocksCount;
     Result.accounts[i].updated_on_block_active_mode := BlocksCount;
     Result.accounts[i].n_operation := 0;
     Result.accounts[i].n_operation := 0;
     if (acc_4_for_dev) And (i=CT_AccountsPerBlock-1) then begin
     if (acc_4_for_dev) And (i=CT_AccountsPerBlock-1) then begin
-      Result.accounts[i].accountInfo.accountKey := account_dev.accountInfo.accountKey;
+      Result.accounts[i].accountInfo.accountKey := LAccountKey;
       SetLength(accs_dev,length(accs_dev)+1);
       SetLength(accs_dev,length(accs_dev)+1);
       accs_dev[High(accs_dev)] := base_addr + i;
       accs_dev[High(accs_dev)] := base_addr + i;
       Result.accounts[i].balance := acc_4_dev_reward;
       Result.accounts[i].balance := acc_4_dev_reward;
@@ -2307,7 +2324,7 @@ begin
     AccountKeyListAddAccounts(blockChain.account_key,accs_miner);
     AccountKeyListAddAccounts(blockChain.account_key,accs_miner);
   end;
   end;
   If (length(accs_dev)>0) then begin
   If (length(accs_dev)>0) then begin
-    AccountKeyListAddAccounts(account_dev.accountInfo.accountKey,accs_dev);
+    AccountKeyListAddAccounts(LAccountKey,accs_dev);
   end;
   end;
   // Calculating new value of safebox
   // Calculating new value of safebox
   FSafeBoxHash := CalcSafeBoxHash;
   FSafeBoxHash := CalcSafeBoxHash;
@@ -2834,10 +2851,10 @@ procedure TPCSafeBox.CommitToPrevious;
           blockAccount.accounts[j].account_data,
           blockAccount.accounts[j].account_data,
           blockAccount.accounts[j].account_seal,
           blockAccount.accounts[j].account_seal,
           aus_commiting_from_otherchain,
           aus_commiting_from_otherchain,
-          blockAccount.accounts[j].updated_on_block,
+          blockAccount.accounts[j].updated_on_block_passive_mode,
           blockAccount.accounts[j].updated_on_block_active_mode,
           blockAccount.accounts[j].updated_on_block_active_mode,
-          blockAccount.accounts[j].previous_updated_block,
-          False // Not used when aus_commiting_from_otherchain
+          False, // Not used when aus_commiting_from_otherchain
+          False  // Not used when aus_commiting_from_otherchain
           );
           );
       end;
       end;
     end;
     end;
@@ -2970,9 +2987,9 @@ procedure TPCSafeBox.RollBackToSnapshot(snapshotBlock: Cardinal);
            blockAccount.accounts[j].account_data,
            blockAccount.accounts[j].account_data,
            blockAccount.accounts[j].account_seal,
            blockAccount.accounts[j].account_seal,
            aus_rollback,
            aus_rollback,
-           blockAccount.accounts[j].updated_on_block,
+           blockAccount.accounts[j].updated_on_block_passive_mode,
            blockAccount.accounts[j].updated_on_block_active_mode,
            blockAccount.accounts[j].updated_on_block_active_mode,
-           blockAccount.accounts[j].previous_updated_block,
+           False,  // Not used when aus_rollback
            False); // Not used when aus_rollback
            False); // Not used when aus_rollback
        end;
        end;
      end;
      end;
@@ -3145,8 +3162,8 @@ begin
   for LBlockNumber := 0 to BlocksCount - 1 do begin
   for LBlockNumber := 0 to BlocksCount - 1 do begin
     LPtrBlockAccount := PBlockAccount(FBlockAccountsList.Items[LBlockNumber]);
     LPtrBlockAccount := PBlockAccount(FBlockAccountsList.Items[LBlockNumber]);
     for i := Low(LPtrBlockAccount^.accounts) to High(LPtrBlockAccount^.accounts) do begin
     for i := Low(LPtrBlockAccount^.accounts) to High(LPtrBlockAccount^.accounts) do begin
-      // Set the initial "updated_on_block_active_mode" value at least like "updated_on_block"
-      LPtrBlockAccount^.accounts[i].updated_on_block_active_mode := LPtrBlockAccount^.accounts[i].updated_on_block;
+      // Set the initial "updated_on_block_active_mode" value at same "updated_on_block_passive_mode"
+      LPtrBlockAccount^.accounts[i].updated_on_block_active_mode := LPtrBlockAccount^.accounts[i].updated_on_block_passive_mode;
     end;
     end;
     {$IFDEF uselowmem}
     {$IFDEF uselowmem}
     TBaseType.To32Bytes(CalcBlockHash( Block(LBlockNumber), CT_PROTOCOL_5),PBlockAccount(FBlockAccountsList.Items[LBlockNumber])^.block_hash);
     TBaseType.To32Bytes(CalcBlockHash( Block(LBlockNumber), CT_PROTOCOL_5),PBlockAccount(FBlockAccountsList.Items[LBlockNumber])^.block_hash);
@@ -3167,7 +3184,7 @@ end;
 
 
 function TPCSafeBox.LoadSafeBoxFromStream(Stream : TStream; checkAll : Boolean; checkSafeboxHash : TRawBytes; progressNotify : TProgressNotify; previousCheckedSafebox : TPCSafebox; var LastReadBlock : TBlockAccount; var errors : String) : Boolean;
 function TPCSafeBox.LoadSafeBoxFromStream(Stream : TStream; checkAll : Boolean; checkSafeboxHash : TRawBytes; progressNotify : TProgressNotify; previousCheckedSafebox : TPCSafebox; var LastReadBlock : TBlockAccount; var errors : String) : Boolean;
 Var
 Var
-  iblock,iacc : Cardinal;
+  iblock,iacc, LTempCardinal : Cardinal;
   raw, LPreviousProofOfWork : TRawBytes;
   raw, LPreviousProofOfWork : TRawBytes;
   block : TBlockAccount;
   block : TBlockAccount;
   P : PBlockAccount;
   P : PBlockAccount;
@@ -3262,10 +3279,10 @@ begin
           if TStreamOp.ReadAnsiString(Stream,raw)<0 then exit;
           if TStreamOp.ReadAnsiString(Stream,raw)<0 then exit;
           block.accounts[iacc].accountInfo := TAccountComp.RawString2AccountInfo(raw);
           block.accounts[iacc].accountInfo := TAccountComp.RawString2AccountInfo(raw);
           if Stream.Read(block.accounts[iacc].balance,SizeOf(UInt64))<SizeOf(UInt64) then exit;
           if Stream.Read(block.accounts[iacc].balance,SizeOf(UInt64))<SizeOf(UInt64) then exit;
-          if Stream.Read(block.accounts[iacc].updated_on_block,4)<4 then exit;
+          if Stream.Read(block.accounts[iacc].updated_on_block_passive_mode,4)<4 then exit;
           if FCurrentProtocol>=CT_PROTOCOL_5 then begin
           if FCurrentProtocol>=CT_PROTOCOL_5 then begin
             if Stream.Read(block.accounts[iacc].updated_on_block_active_mode,4)<4 then exit;
             if Stream.Read(block.accounts[iacc].updated_on_block_active_mode,4)<4 then exit;
-          end;
+          end else block.accounts[iacc].updated_on_block_active_mode := block.accounts[iacc].updated_on_block_passive_mode;
           if Stream.Read(block.accounts[iacc].n_operation,4)<4 then exit;
           if Stream.Read(block.accounts[iacc].n_operation,4)<4 then exit;
           If FCurrentProtocol>=CT_PROTOCOL_2 then begin
           If FCurrentProtocol>=CT_PROTOCOL_2 then begin
             if TStreamOp.ReadAnsiString(Stream,block.accounts[iacc].name)<0 then exit;
             if TStreamOp.ReadAnsiString(Stream,block.accounts[iacc].name)<0 then exit;
@@ -3275,9 +3292,10 @@ begin
             if TStreamOp.ReadAnsiString(Stream,block.accounts[iacc].account_data)<0 then Exit;
             if TStreamOp.ReadAnsiString(Stream,block.accounts[iacc].account_data)<0 then Exit;
             if (Length(block.accounts[iacc].account_data)>CT_MaxAccountDataSize) then Exit;
             if (Length(block.accounts[iacc].account_data)>CT_MaxAccountDataSize) then Exit;
             if TStreamOp.ReadAnsiString(Stream,block.accounts[iacc].account_seal)<0 then Exit;
             if TStreamOp.ReadAnsiString(Stream,block.accounts[iacc].account_seal)<0 then Exit;
+          end else begin
+            if Stream.Read(LTempCardinal,4)<4 then exit;
           end;
           end;
           //
           //
-          if Stream.Read(block.accounts[iacc].previous_updated_block,4)<4 then exit;
           // check valid
           // check valid
           If (Length(block.accounts[iacc].name)>0) then begin
           If (Length(block.accounts[iacc].name)>0) then begin
             if FOrderedByName.IndexOf(block.accounts[iacc].name)>=0 then begin
             if FOrderedByName.IndexOf(block.accounts[iacc].name)>=0 then begin
@@ -3525,6 +3543,7 @@ procedure TPCSafeBox.SaveSafeBoxBlockToAStream(DestStream: TStream; nBlock: Card
 var b : TBlockAccount;
 var b : TBlockAccount;
   iacc : integer;
   iacc : integer;
   Stream : TStream;
   Stream : TStream;
+  LCardinal : Cardinal;
 begin
 begin
   b := Block(nblock);
   b := Block(nblock);
   if DestStream is TMemoryStream then Stream := DestStream
   if DestStream is TMemoryStream then Stream := DestStream
@@ -3537,9 +3556,12 @@ begin
       Stream.Write(b.accounts[iacc].account,Sizeof(b.accounts[iacc].account));
       Stream.Write(b.accounts[iacc].account,Sizeof(b.accounts[iacc].account));
       TStreamOp.WriteAnsiString(Stream,TAccountComp.AccountInfo2RawString(b.accounts[iacc].accountInfo));
       TStreamOp.WriteAnsiString(Stream,TAccountComp.AccountInfo2RawString(b.accounts[iacc].accountInfo));
       Stream.Write(b.accounts[iacc].balance,Sizeof(b.accounts[iacc].balance));
       Stream.Write(b.accounts[iacc].balance,Sizeof(b.accounts[iacc].balance));
-      Stream.Write(b.accounts[iacc].updated_on_block,Sizeof(b.accounts[iacc].updated_on_block));
       if FCurrentProtocol>=CT_PROTOCOL_5 then begin
       if FCurrentProtocol>=CT_PROTOCOL_5 then begin
+        Stream.Write(b.accounts[iacc].updated_on_block_passive_mode,Sizeof(b.accounts[iacc].updated_on_block_passive_mode));
         Stream.Write(b.accounts[iacc].updated_on_block_active_mode,Sizeof(b.accounts[iacc].updated_on_block_active_mode));
         Stream.Write(b.accounts[iacc].updated_on_block_active_mode,Sizeof(b.accounts[iacc].updated_on_block_active_mode));
+      end else begin
+        LCardinal := b.accounts[iacc].GetLastUpdatedBlock;
+        Stream.Write(LCardinal,SizeOf(LCardinal));
       end;
       end;
       Stream.Write(b.accounts[iacc].n_operation,Sizeof(b.accounts[iacc].n_operation));
       Stream.Write(b.accounts[iacc].n_operation,Sizeof(b.accounts[iacc].n_operation));
       If FCurrentProtocol>=CT_PROTOCOL_2 then begin
       If FCurrentProtocol>=CT_PROTOCOL_2 then begin
@@ -3549,8 +3571,10 @@ begin
       if FCurrentProtocol>=CT_PROTOCOL_5 then begin
       if FCurrentProtocol>=CT_PROTOCOL_5 then begin
         TStreamOp.WriteAnsiString(Stream,b.accounts[iacc].account_data);
         TStreamOp.WriteAnsiString(Stream,b.accounts[iacc].account_data);
         TStreamOp.WriteAnsiString(Stream,b.accounts[iacc].account_seal);
         TStreamOp.WriteAnsiString(Stream,b.accounts[iacc].account_seal);
+      end else begin
+        LCardinal := 0;
+        Stream.Write(LCardinal,Sizeof(LCardinal));
       end;
       end;
-      Stream.Write(b.accounts[iacc].previous_updated_block,Sizeof(b.accounts[iacc].previous_updated_block));
     end;
     end;
     TStreamOp.WriteAnsiString(Stream,b.block_hash);
     TStreamOp.WriteAnsiString(Stream,b.block_hash);
     Stream.Write(b.accumulatedWork,Sizeof(b.accumulatedWork));
     Stream.Write(b.accumulatedWork,Sizeof(b.accumulatedWork));
@@ -4178,7 +4202,7 @@ procedure TPCSafeBox.SearchBlockWhenOnSeparatedChain(blockNumber: Cardinal; out
     // Is valid?
     // Is valid?
     maxUB := 0;
     maxUB := 0;
     for j:=Low(blockAccount.accounts) to High(blockAccount.accounts) do begin
     for j:=Low(blockAccount.accounts) to High(blockAccount.accounts) do begin
-      If blockAccount.accounts[j].updated_on_block>maxUB then maxUB := blockAccount.accounts[j].updated_on_block;
+      If blockAccount.accounts[j].GetLastUpdatedBlock>maxUB then maxUB := blockAccount.accounts[j].GetLastUpdatedBlock;
     end;
     end;
     Result := (maxUB <= FPreviousSafeboxOriginBlock);
     Result := (maxUB <= FPreviousSafeboxOriginBlock);
   end;
   end;
@@ -4219,8 +4243,8 @@ end;
 procedure TPCSafeBox.UpdateAccount(account_number : Cardinal; const newAccountInfo: TAccountInfo;
 procedure TPCSafeBox.UpdateAccount(account_number : Cardinal; const newAccountInfo: TAccountInfo;
   const newName : TRawBytes; newType : Word; newBalance: UInt64; newN_operation: Cardinal;
   const newName : TRawBytes; newType : Word; newBalance: UInt64; newN_operation: Cardinal;
   const newAccountData, newAccountSeal : TRawBytes;
   const newAccountData, newAccountSeal : TRawBytes;
-  accountUpdateStyle : TAccountUpdateStyle; newUpdated_block, newUpdated_block_active_mode, newPrevious_Updated_block : Cardinal;
-  AHasBenUpdatedOnActiveMode : Boolean);
+  accountUpdateStyle : TAccountUpdateStyle; newUpdated_block_pasive_mode, newUpdated_block_active_mode : Cardinal;
+  AHasBenUpdatedOnActiveMode, AHasBenUpdatedOnPasiveMode : Boolean);
 Var iBlock : Cardinal;
 Var iBlock : Cardinal;
   i,j,iAccount, iDeleted, iAdded : Integer;
   i,j,iAccount, iDeleted, iAdded : Integer;
   lastbalance : UInt64;
   lastbalance : UInt64;
@@ -4258,9 +4282,8 @@ begin
   If (accountUpdateStyle In [aus_rollback,aus_commiting_from_otherchain]) then begin
   If (accountUpdateStyle In [aus_rollback,aus_commiting_from_otherchain]) then begin
     // Directly update name and updated values
     // Directly update name and updated values
     blockAccount.accounts[iAccount].name:=newName;
     blockAccount.accounts[iAccount].name:=newName;
-    blockAccount.accounts[iAccount].updated_on_block:=newUpdated_block;
+    blockAccount.accounts[iAccount].updated_on_block_passive_mode:=newUpdated_block_pasive_mode;
     blockAccount.accounts[iAccount].updated_on_block_active_mode:=newUpdated_block_active_mode;
     blockAccount.accounts[iAccount].updated_on_block_active_mode:=newUpdated_block_active_mode;
-    blockAccount.accounts[iAccount].previous_updated_block:=newPrevious_Updated_block;
   end else begin
   end else begin
     // Name:
     // Name:
     If Not TBaseType.Equals(blockAccount.accounts[iAccount].name,newName) then begin
     If Not TBaseType.Equals(blockAccount.accounts[iAccount].name,newName) then begin
@@ -4325,15 +4348,19 @@ begin
         end;
         end;
       end;
       end;
     end;
     end;
-    // Will update previous_updated_block only on first time/block
-    If blockAccount.accounts[iAccount].updated_on_block<>BlocksCount then begin
-      blockAccount.accounts[iAccount].previous_updated_block := blockAccount.accounts[iAccount].updated_on_block;
-      blockAccount.accounts[iAccount].updated_on_block := BlocksCount;
+    if CurrentProtocol < CT_PROTOCOL_5 then begin
+      // On protocol 1..4 the "updated_on_block" was a single value without active/pasive distinction
+      // so it will be stored at "updated_on_block_passive_mode" always
+      blockAccount.accounts[iAccount].updated_on_block_active_mode := BlocksCount;
+      blockAccount.accounts[iAccount].updated_on_block_passive_mode := BlocksCount;
     end;
     end;
     if (AHasBenUpdatedOnActiveMode) then begin
     if (AHasBenUpdatedOnActiveMode) then begin
       // This flag will indicate that this account has been used as ACTIVE MODE so needs to update on which block was updated
       // This flag will indicate that this account has been used as ACTIVE MODE so needs to update on which block was updated
       blockAccount.accounts[iAccount].updated_on_block_active_mode := BlocksCount;
       blockAccount.accounts[iAccount].updated_on_block_active_mode := BlocksCount;
     end;
     end;
+    if (AHasBenUpdatedOnPasiveMode) then begin
+      blockAccount.accounts[iAccount].updated_on_block_passive_mode := BlocksCount;
+    end;
   end;
   end;
 
 
   // New Protocol 5 fields
   // New Protocol 5 fields
@@ -4477,29 +4504,14 @@ begin
   // NOTE:
   // NOTE:
   // At this point, we have checked integrity, cannot check later!
   // At this point, we have checked integrity, cannot check later!
 
 
+  APrevious.UpdateIfLower(LPBuyerAccount^.account,LPBuyerAccount^.GetLastUpdatedBlock);
+  APrevious.UpdateIfLower(LPAccountToBuy^.account,LPAccountToBuy^.GetLastUpdatedBlock);
+  APrevious.UpdateIfLower(LPSellerAccount^.account,LPSellerAccount^.GetLastUpdatedBlock);
+
   UpdateSealAndActiveModeFlag(LPBuyerAccount_Sealed,AOpID,True);  // Only the buyer account is the Active account
   UpdateSealAndActiveModeFlag(LPBuyerAccount_Sealed,AOpID,True);  // Only the buyer account is the Active account
   UpdateSealAndActiveModeFlag(LPAccountToBuy_Sealed,AOpID,False);
   UpdateSealAndActiveModeFlag(LPAccountToBuy_Sealed,AOpID,False);
   UpdateSealAndActiveModeFlag(LPSellerAccount_Sealed,AOpID,False);
   UpdateSealAndActiveModeFlag(LPSellerAccount_Sealed,AOpID,False);
 
 
-  APrevious.UpdateIfLower(LPBuyerAccount^.account,LPBuyerAccount^.updated_on_block);
-  APrevious.UpdateIfLower(LPAccountToBuy^.account,LPAccountToBuy^.updated_on_block);
-  APrevious.UpdateIfLower(LPSellerAccount^.account,LPSellerAccount^.updated_on_block);
-
-  If LPBuyerAccount^.updated_on_block<>Origin_BlocksCount then begin
-    LPBuyerAccount^.previous_updated_block := LPBuyerAccount^.updated_on_block;
-    LPBuyerAccount^.updated_on_block := Origin_BlocksCount;
-  end;
-
-  If LPAccountToBuy^.updated_on_block<>Origin_BlocksCount then begin
-    LPAccountToBuy^.previous_updated_block := LPAccountToBuy^.updated_on_block;
-    LPAccountToBuy^.updated_on_block := Origin_BlocksCount;
-  end;
-
-  If LPSellerAccount^.updated_on_block<>Origin_BlocksCount then begin
-    LPSellerAccount^.previous_updated_block := LPSellerAccount^.updated_on_block;
-    LPSellerAccount^.updated_on_block := Origin_BlocksCount;
-  end;
-
   // Inc buyer n_operation
   // Inc buyer n_operation
   LPBuyerAccount^.n_operation := ANOperation;
   LPBuyerAccount^.n_operation := ANOperation;
   // Set new balance values
   // Set new balance values
@@ -4558,8 +4570,10 @@ begin
             Pa^.account_data,
             Pa^.account_data,
             Pa^.account_seal,
             Pa^.account_seal,
             aus_transaction_commit,
             aus_transaction_commit,
-            0,0,0,
-            PSealed^.UsedAsActiveMode);
+            Pa^.updated_on_block_passive_mode,
+            Pa^.updated_on_block_active_mode,
+            PSealed^.UsedAsActiveMode,
+            PSealed^.UsedAsPasiveMode);
     end;
     end;
     //
     //
     if (Origin_TotalBalance<>FTotalBalance) then begin
     if (Origin_TotalBalance<>FTotalBalance) then begin
@@ -4782,37 +4796,18 @@ begin
     Exit;
     Exit;
   end;
   end;
 
 
+  previous.UpdateIfLower(PaccSender^.account,PaccSender^.GetLastUpdatedBlock);
+  previous.UpdateIfLower(PaccTarget^.account,PaccTarget^.GetLastUpdatedBlock);
+
   UpdateSealAndActiveModeFlag(PaccSender_Sealed,AOpID,True);
   UpdateSealAndActiveModeFlag(PaccSender_Sealed,AOpID,True);
   UpdateSealAndActiveModeFlag(PaccTarget_Sealed,AOpID,False);
   UpdateSealAndActiveModeFlag(PaccTarget_Sealed,AOpID,False);
 
 
-  previous.UpdateIfLower(PaccSender^.account,PaccSender^.updated_on_block);
-  previous.UpdateIfLower(PaccTarget^.account,PaccTarget^.updated_on_block);
-
-  If PaccSender^.updated_on_block<>Origin_BlocksCount then begin
-    PaccSender^.previous_updated_block := PaccSender^.updated_on_block;
-    PaccSender^.updated_on_block := Origin_BlocksCount;
-  end;
-
-  If PaccTarget^.updated_on_block<>Origin_BlocksCount then begin
-    PaccTarget^.previous_updated_block := PaccTarget.updated_on_block;
-    PaccTarget^.updated_on_block := Origin_BlocksCount;
-  end;
-
   if (sender<>signer) then begin
   if (sender<>signer) then begin
+    previous.UpdateIfLower(PaccSigner^.account,PaccSigner^.GetLastUpdatedBlock);
     UpdateSealAndActiveModeFlag(PaccSigner_Sealed,AOpID,True);
     UpdateSealAndActiveModeFlag(PaccSigner_Sealed,AOpID,True);
-    previous.UpdateIfLower(PaccSigner^.account,PaccSigner^.updated_on_block);
-    if (PaccSigner^.updated_on_block<>Origin_BlocksCount) then begin
-      PaccSigner^.previous_updated_block := PaccSigner^.updated_on_block;
-      PaccSigner^.updated_on_block := Origin_BlocksCount;
-    end;
     PaccSigner^.n_operation := n_operation;
     PaccSigner^.n_operation := n_operation;
     PaccSigner^.balance := PaccSender^.balance - (fee);
     PaccSigner^.balance := PaccSender^.balance - (fee);
     PaccSender^.balance := PaccSender^.balance - (amount);
     PaccSender^.balance := PaccSender^.balance - (amount);
-    if FreezedSafeBox.CurrentProtocol>=CT_PROTOCOL_5 then begin
-      // On Protocol 5, n_operation of the sender will be automatically updated
-      PaccSender^.n_operation := PaccSender^.n_operation + 1;
-    end;
-
   end else begin
   end else begin
     PaccSender^.n_operation := n_operation;
     PaccSender^.n_operation := n_operation;
     PaccSender^.balance := PaccSender^.balance - (amount + fee);
     PaccSender^.balance := PaccSender^.balance - (amount + fee);
@@ -4923,26 +4918,20 @@ begin
   for i:=Low(senders) to High(senders) do begin
   for i:=Low(senders) to High(senders) do begin
     PaccSender := GetInternalAccount(senders[i],PaccSender_Sealed);
     PaccSender := GetInternalAccount(senders[i],PaccSender_Sealed);
 
 
+    previous.UpdateIfLower(PaccSender^.account,PaccSender^.GetLastUpdatedBlock);
+
     UpdateSealAndActiveModeFlag(PaccSender_Sealed,AOpID,True);
     UpdateSealAndActiveModeFlag(PaccSender_Sealed,AOpID,True);
 
 
-    previous.UpdateIfLower(PaccSender^.account,PaccSender^.updated_on_block);
-    If PaccSender^.updated_on_block<>Origin_BlocksCount then begin
-      PaccSender^.previous_updated_block := PaccSender^.updated_on_block;
-      PaccSender^.updated_on_block := Origin_BlocksCount;
-    end;
     Inc(PaccSender^.n_operation);
     Inc(PaccSender^.n_operation);
     PaccSender^.balance := PaccSender^.balance - (sender_amounts[i]);
     PaccSender^.balance := PaccSender^.balance - (sender_amounts[i]);
   end;
   end;
   for i:=Low(receivers) to High(receivers) do begin
   for i:=Low(receivers) to High(receivers) do begin
     PaccTarget := GetInternalAccount(receivers[i],PaccTarget_Sealed);
     PaccTarget := GetInternalAccount(receivers[i],PaccTarget_Sealed);
 
 
+    previous.UpdateIfLower(PaccTarget^.account,PaccTarget^.GetLastUpdatedBlock);
+
     UpdateSealAndActiveModeFlag(PaccTarget_Sealed,AOpID,False);
     UpdateSealAndActiveModeFlag(PaccTarget_Sealed,AOpID,False);
 
 
-    previous.UpdateIfLower(PaccTarget^.account,PaccTarget^.updated_on_block);
-    If PaccTarget^.updated_on_block<>Origin_BlocksCount then begin
-      PaccTarget^.previous_updated_block := PaccTarget.updated_on_block;
-      PaccTarget^.updated_on_block := Origin_BlocksCount;
-    end;
     PaccTarget^.balance := PaccTarget^.balance + receivers_amounts[i];
     PaccTarget^.balance := PaccTarget^.balance + receivers_amounts[i];
   end;
   end;
   Dec(FTotalBalance,nTotalFee);
   Dec(FTotalBalance,nTotalFee);
@@ -5034,28 +5023,13 @@ begin
   end;
   end;
   // All Ok, can do changes
   // All Ok, can do changes
 
 
+  previous.UpdateIfLower(P_signer^.account,P_signer^.GetLastUpdatedBlock);
+  previous.UpdateIfLower(P_target^.account,P_target^.GetLastUpdatedBlock);
+
   UpdateSealAndActiveModeFlag(P_signer_Sealed,AOpID,True);
   UpdateSealAndActiveModeFlag(P_signer_Sealed,AOpID,True);
   UpdateSealAndActiveModeFlag(P_target_Sealed,AOpID,True); // BOTH signer and target are ACTIVE
   UpdateSealAndActiveModeFlag(P_target_Sealed,AOpID,True); // BOTH signer and target are ACTIVE
 
 
-  previous.UpdateIfLower(P_signer^.account,P_signer^.updated_on_block);
-  if P_signer^.updated_on_block <> Origin_BlocksCount then begin
-    P_signer^.previous_updated_block := P_signer^.updated_on_block;
-    P_signer^.updated_on_block := Origin_BlocksCount;
-  end;
-  if (signer_account<>target_account) then begin
-    previous.UpdateIfLower(P_target^.account,P_target^.updated_on_block);
-    if P_target^.updated_on_block <> Origin_BlocksCount then begin
-      P_target^.previous_updated_block := P_target^.updated_on_block;
-      P_target^.updated_on_block := Origin_BlocksCount;
-    end;
-  end;
-
   P_signer^.n_operation := signer_n_operation;
   P_signer^.n_operation := signer_n_operation;
-  if (signer_account<>target_account) and
-     (FreezedSafeBox.CurrentProtocol>=CT_PROTOCOL_5) then begin
-      // On Protocol 5, n_operation of the target will be automatically updated
-      P_target^.n_operation := P_target^.n_operation + 1;
-  end;
 
 
   P_target^.accountInfo := accountInfo;
   P_target^.accountInfo := accountInfo;
   P_target^.name := newName;
   P_target^.name := newName;
@@ -5072,6 +5046,15 @@ begin
   FOrderedList.DoUpdateSealIfNeeded(APtrSealedAccount,AOpID);
   FOrderedList.DoUpdateSealIfNeeded(APtrSealedAccount,AOpID);
   if ASetUsedAsActiveMode then begin
   if ASetUsedAsActiveMode then begin
     APtrSealedAccount^.UsedAsActiveMode := True;
     APtrSealedAccount^.UsedAsActiveMode := True;
+    APtrSealedAccount^.AccountSealed^.updated_on_block_active_mode := Origin_BlocksCount;
+  end else begin
+    APtrSealedAccount^.UsedAsPasiveMode := True;
+    APtrSealedAccount^.AccountSealed^.updated_on_block_passive_mode := Origin_BlocksCount;
+  end;
+  if FreezedSafeBox.CurrentProtocol<CT_PROTOCOL_5 then begin
+    // V5 introduced active/pasive mode, but v4 (and previous) does not made distinction
+    APtrSealedAccount^.AccountSealed^.updated_on_block_active_mode := Origin_BlocksCount;
+    APtrSealedAccount^.AccountSealed^.updated_on_block_passive_mode := Origin_BlocksCount;
   end;
   end;
 end;
 end;
 
 
@@ -5104,6 +5087,7 @@ begin
     New(p^.AccountSealed);
     New(p^.AccountSealed);
     p^.AccountSealed^ := PSealedAccount(ASource.FList[i])^.AccountSealed^;
     p^.AccountSealed^ := PSealedAccount(ASource.FList[i])^.AccountSealed^;
     p^.SealChangesCounter := PSealedAccount(ASource.FList[i])^.SealChangesCounter;
     p^.SealChangesCounter := PSealedAccount(ASource.FList[i])^.SealChangesCounter;
+    p^.UsedAsPasiveMode := PSealedAccount(ASource.FList[i])^.UsedAsPasiveMode;
     p^.UsedAsActiveMode := PSealedAccount(ASource.FList[i])^.UsedAsActiveMode;
     p^.UsedAsActiveMode := PSealedAccount(ASource.FList[i])^.UsedAsActiveMode;
     FList.Add(p);
     FList.Add(p);
   end;
   end;
@@ -5185,6 +5169,7 @@ begin
     New( Result^.AccountSealed );
     New( Result^.AccountSealed );
     Result^.AccountSealed^ := FSafeBoxTransaction.FreezedSafeBox.Account(account_number);
     Result^.AccountSealed^ := FSafeBoxTransaction.FreezedSafeBox.Account(account_number);
     Result^.SealChangesCounter := 0;
     Result^.SealChangesCounter := 0;
+    Result^.UsedAsPasiveMode := False;
     Result^.UsedAsActiveMode := False;
     Result^.UsedAsActiveMode := False;
     FList.Insert(i,Result);
     FList.Insert(i,Result);
   end else begin
   end else begin
@@ -5957,6 +5942,7 @@ end;
 
 
 procedure TAccount_Helper.SerializeAccount(AStream: TStream; current_protocol : Word);
 procedure TAccount_Helper.SerializeAccount(AStream: TStream; current_protocol : Word);
 var LRaw : TRawBytes;
 var LRaw : TRawBytes;
+  LCardinal : Cardinal;
 begin
 begin
   if current_protocol>=CT_PROTOCOL_5 then TAccountComp.SaveAccountToAStream(AStream,Self,current_protocol)
   if current_protocol>=CT_PROTOCOL_5 then TAccountComp.SaveAccountToAStream(AStream,Self,current_protocol)
   else begin
   else begin
@@ -5964,7 +5950,8 @@ begin
     LRaw := TAccountComp.AccountInfo2RawString(Self.accountInfo);
     LRaw := TAccountComp.AccountInfo2RawString(Self.accountInfo);
     AStream.WriteBuffer(LRaw[Low(LRaw)],Length(LRaw));
     AStream.WriteBuffer(LRaw[Low(LRaw)],Length(LRaw));
     AStream.Write(Self.balance,8);
     AStream.Write(Self.balance,8);
-    AStream.Write(Self.updated_on_block,4);
+    LCardinal := Self.GetLastUpdatedBlock;
+    AStream.Write(LCardinal,4);
     AStream.Write(Self.n_operation,4);
     AStream.Write(Self.n_operation,4);
     if (current_protocol>=2) then begin
     if (current_protocol>=2) then begin
         // Use new Protocol 2 fields
         // Use new Protocol 2 fields

+ 7 - 18
src/core/UBlockChain.pas

@@ -223,9 +223,6 @@ Type
   TPCOperation = Class
   TPCOperation = Class
   Protected
   Protected
     FProtocolVersion : Word;
     FProtocolVersion : Word;
-    FPrevious_Signer_updated_block: Cardinal;
-    FPrevious_Destination_updated_block : Cardinal;
-    FPrevious_Seller_updated_block : Cardinal;
     FHasValidSignature : Boolean;
     FHasValidSignature : Boolean;
     FUsedPubkeyForSignature : TECDSA_Public;
     FUsedPubkeyForSignature : TECDSA_Public;
     FBufferedSha256 : TRawBytes;
     FBufferedSha256 : TRawBytes;
@@ -234,9 +231,6 @@ Type
     function SaveOpToStream(Stream: TStream; SaveExtendedData : Boolean): Boolean; virtual; abstract;
     function SaveOpToStream(Stream: TStream; SaveExtendedData : Boolean): Boolean; virtual; abstract;
     function LoadOpFromStream(Stream: TStream; LoadExtendedData : Boolean): Boolean; virtual; abstract;
     function LoadOpFromStream(Stream: TStream; LoadExtendedData : Boolean): Boolean; virtual; abstract;
     procedure FillOperationResume(Block : Cardinal; getInfoForAllAccounts : Boolean; Affected_account_number : Cardinal; var OperationResume : TOperationResume); virtual;
     procedure FillOperationResume(Block : Cardinal; getInfoForAllAccounts : Boolean; Affected_account_number : Cardinal; var OperationResume : TOperationResume); virtual;
-    Property Previous_Signer_updated_block : Cardinal read FPrevious_Signer_updated_block; // deprecated
-    Property Previous_Destination_updated_block : Cardinal read FPrevious_Destination_updated_block; // deprecated
-    Property Previous_Seller_updated_block : Cardinal read FPrevious_Seller_updated_block; // deprecated
     function IsValidECDSASignature(const PubKey: TECDSA_Public; const Signature: TECDSA_SIG): Boolean;
     function IsValidECDSASignature(const PubKey: TECDSA_Public; const Signature: TECDSA_SIG): Boolean;
     procedure CopyUsedPubkeySignatureFrom(SourceOperation : TPCOperation); virtual;
     procedure CopyUsedPubkeySignatureFrom(SourceOperation : TPCOperation); virtual;
     function SaveOperationPayloadToStream(const AStream : TStream; const APayload : TOperationPayload) : Boolean;
     function SaveOperationPayloadToStream(const AStream : TStream; const APayload : TOperationPayload) : Boolean;
@@ -2464,9 +2458,6 @@ begin
         op.SaveOpToStream(msCopy,true);
         op.SaveOpToStream(msCopy,true);
         msCopy.Position := 0;
         msCopy.Position := 0;
         P^.Op.LoadOpFromStream(msCopy, true);
         P^.Op.LoadOpFromStream(msCopy, true);
-        P^.Op.FPrevious_Signer_updated_block := op.Previous_Signer_updated_block;
-        P^.Op.FPrevious_Destination_updated_block := op.FPrevious_Destination_updated_block;
-        P^.Op.FPrevious_Seller_updated_block := op.FPrevious_Seller_updated_block;
         P^.Op.FHasValidSignature := op.FHasValidSignature; // Improvement speed v4.0.2 reusing previously signed value
         P^.Op.FHasValidSignature := op.FHasValidSignature; // Improvement speed v4.0.2 reusing previously signed value
         P^.Op.FUsedPubkeyForSignature := op.FUsedPubkeyForSignature;
         P^.Op.FUsedPubkeyForSignature := op.FUsedPubkeyForSignature;
         P^.Op.FBufferedSha256:=op.FBufferedSha256;
         P^.Op.FBufferedSha256:=op.FBufferedSha256;
@@ -3091,9 +3082,6 @@ end;
 procedure TPCOperation.InitializeData(AProtocolVersion : Word);
 procedure TPCOperation.InitializeData(AProtocolVersion : Word);
 begin
 begin
   FProtocolVersion := AProtocolVersion;
   FProtocolVersion := AProtocolVersion;
-  FPrevious_Signer_updated_block := 0;
-  FPrevious_Destination_updated_block := 0;
-  FPrevious_Seller_updated_block := 0;
   FHasValidSignature := false;
   FHasValidSignature := false;
   FUsedPubkeyForSignature:=CT_TECDSA_Public_Nul;
   FUsedPubkeyForSignature:=CT_TECDSA_Public_Nul;
   FBufferedSha256 := Nil;
   FBufferedSha256 := Nil;
@@ -3136,24 +3124,25 @@ begin
 end;
 end;
 
 
 function TPCOperation.LoadFromStorage(Stream: TStream; LoadProtocolVersion:Word; APreviousUpdatedBlocks : TAccountPreviousBlockInfo): Boolean;
 function TPCOperation.LoadFromStorage(Stream: TStream; LoadProtocolVersion:Word; APreviousUpdatedBlocks : TAccountPreviousBlockInfo): Boolean;
+var LPrevious_Signer, LPrevious_Destination, LPrevious_Seller : Cardinal;
 begin
 begin
   Result := false;
   Result := false;
   If LoadOpFromStream(Stream, LoadProtocolVersion>=CT_PROTOCOL_2) then begin
   If LoadOpFromStream(Stream, LoadProtocolVersion>=CT_PROTOCOL_2) then begin
     If LoadProtocolVersion<CT_PROTOCOL_3 then begin
     If LoadProtocolVersion<CT_PROTOCOL_3 then begin
       if Stream.Size - Stream.Position<8 then exit;
       if Stream.Size - Stream.Position<8 then exit;
-      Stream.Read(FPrevious_Signer_updated_block,Sizeof(FPrevious_Signer_updated_block));
-      Stream.Read(FPrevious_Destination_updated_block,Sizeof(FPrevious_Destination_updated_block));
+      Stream.Read(LPrevious_Signer,Sizeof(LPrevious_Signer));
+      Stream.Read(LPrevious_Destination,Sizeof(LPrevious_Destination));
       if (LoadProtocolVersion=CT_PROTOCOL_2) then begin
       if (LoadProtocolVersion=CT_PROTOCOL_2) then begin
-        Stream.Read(FPrevious_Seller_updated_block,Sizeof(FPrevious_Seller_updated_block));
+        Stream.Read(LPrevious_Seller,Sizeof(LPrevious_Seller));
       end;
       end;
       if Assigned(APreviousUpdatedBlocks) then begin
       if Assigned(APreviousUpdatedBlocks) then begin
         // Add to previous list!
         // Add to previous list!
         if SignerAccount>=0 then
         if SignerAccount>=0 then
-          APreviousUpdatedBlocks.UpdateIfLower(SignerAccount,FPrevious_Signer_updated_block);
+          APreviousUpdatedBlocks.UpdateIfLower(SignerAccount,LPrevious_Signer);
         if DestinationAccount>=0 then
         if DestinationAccount>=0 then
-          APreviousUpdatedBlocks.UpdateIfLower(DestinationAccount,FPrevious_Destination_updated_block);
+          APreviousUpdatedBlocks.UpdateIfLower(DestinationAccount,LPrevious_Destination);
         if SellerAccount>=0 then
         if SellerAccount>=0 then
-          APreviousUpdatedBlocks.UpdateIfLower(SellerAccount,FPrevious_Seller_updated_block);
+          APreviousUpdatedBlocks.UpdateIfLower(SellerAccount,LPrevious_Seller);
       end;
       end;
     end;
     end;
     Result := true;
     Result := true;

+ 7 - 7
src/core/UConst.pas

@@ -41,9 +41,9 @@ Const
     {$IFDEF PRODUCTION}'00000003A29C32E84A539ADE24397D41D30116A6FAFEC17B7D9CED68A4238C92'{$ELSE}{$IFDEF TESTNET}''{$ELSE}{$ENDIF}{$ENDIF};
     {$IFDEF PRODUCTION}'00000003A29C32E84A539ADE24397D41D30116A6FAFEC17B7D9CED68A4238C92'{$ELSE}{$IFDEF TESTNET}''{$ELSE}{$ENDIF}{$ENDIF};
 
 
 
 
-  CT_NetServer_Port = {$IFDEF PRODUCTION}4004{$ELSE}{$IFDEF TESTNET}4104{$ELSE}{$ENDIF}{$ENDIF};
-  CT_JSONRPCMinerServer_Port = {$IFDEF PRODUCTION}4009{$ELSE}{$IFDEF TESTNET}4109{$ELSE}{$ENDIF}{$ENDIF};
-  CT_JSONRPC_Port = {$IFDEF PRODUCTION}4003{$ELSE}{$IFDEF TESTNET}4103{$ELSE}{$ENDIF}{$ENDIF};
+  CT_NetServer_Port = {$IFDEF PRODUCTION}4004{$ELSE}{$IFDEF TESTNET}4204{$ELSE}{$ENDIF}{$ENDIF};
+  CT_JSONRPCMinerServer_Port = {$IFDEF PRODUCTION}4009{$ELSE}{$IFDEF TESTNET}4209{$ELSE}{$ENDIF}{$ENDIF};
+  CT_JSONRPC_Port = {$IFDEF PRODUCTION}4003{$ELSE}{$IFDEF TESTNET}4203{$ELSE}{$ENDIF}{$ENDIF};
   CT_AccountsPerBlock = 5;
   CT_AccountsPerBlock = 5;
 
 
   CT_NewLineSecondsAvg: Cardinal = {$IFDEF PRODUCTION}300{$ELSE}{$IFDEF TESTNET}30{$ELSE}{$ENDIF}{$ENDIF};
   CT_NewLineSecondsAvg: Cardinal = {$IFDEF PRODUCTION}300{$ELSE}{$IFDEF TESTNET}30{$ELSE}{$ENDIF}{$ENDIF};
@@ -127,7 +127,7 @@ Const
   CT_Protocol_Upgrade_v5_MinBlock = {$IFDEF PRODUCTION}999999999{$ELSE}500{$ENDIF}; // TODO Need define v5 for production!
   CT_Protocol_Upgrade_v5_MinBlock = {$IFDEF PRODUCTION}999999999{$ELSE}500{$ENDIF}; // TODO Need define v5 for production!
 
 
 
 
-  CT_MagicNetIdentification = {$IFDEF PRODUCTION}$0A043580{$ELSE}$05000003{$ENDIF}; // Unix timestamp 168048000 ... It's Albert birthdate!
+  CT_MagicNetIdentification = {$IFDEF PRODUCTION}$0A043580{$ELSE}$05000004{$ENDIF}; // Unix timestamp 168048000 ... It's Albert birthdate!
 
 
   CT_NetProtocol_Version: Word = $0009; // Version 4.0.2 Will allow only net protocol 9
   CT_NetProtocol_Version: Word = $0009; // Version 4.0.2 Will allow only net protocol 9
   // IMPORTANT NOTE!!!
   // IMPORTANT NOTE!!!
@@ -138,9 +138,9 @@ Const
 
 
   CT_SafeBoxBankVersion : Word = 3; // Protocol 2 upgraded safebox version from 2 to 3
   CT_SafeBoxBankVersion : Word = 3; // Protocol 2 upgraded safebox version from 2 to 3
 
 
-  CT_MagicIdentificator: String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoinTESTNET_5.Beta.3'{$ENDIF}; //
+  CT_MagicIdentificator: String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoinTESTNET_5.Beta.4'{$ENDIF}; //
 
 
-  CT_PascalCoin_Data_Folder : String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoin_TESTNET_5.Beta.3'{$ENDIF}; //
+  CT_PascalCoin_Data_Folder : String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoin_TESTNET_5.Beta.4'{$ENDIF}; //
 
 
   CT_PseudoOp_Reward = $0;
   CT_PseudoOp_Reward = $0;
   // Value of Operations type in Protocol 1
   // Value of Operations type in Protocol 1
@@ -195,7 +195,7 @@ Const
   CT_OpSubtype_Data_Signer                = 103;
   CT_OpSubtype_Data_Signer                = 103;
   CT_OpSubtype_Data_Receiver              = 104;
   CT_OpSubtype_Data_Receiver              = 104;
 
 
-  CT_ClientAppVersion : String = {$IFDEF PRODUCTION}'4.1'{$ELSE}{$IFDEF TESTNET}'TESTNET 5.Beta.3'{$ELSE}{$ENDIF}{$ENDIF};
+  CT_ClientAppVersion : String = {$IFDEF PRODUCTION}'4.1'{$ELSE}{$IFDEF TESTNET}'TESTNET 5.Beta.4'{$ELSE}{$ENDIF}{$ENDIF};
 
 
   CT_Discover_IPs = {$IFDEF PRODUCTION}'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin1.dynamic-dns.net;pascalcoin2.dynamic-dns.net;pascalcoin1.dns1.us;pascalcoin2.dns1.us;pascalcoin1.dns2.us;pascalcoin2.dns2.us'
   CT_Discover_IPs = {$IFDEF PRODUCTION}'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin1.dynamic-dns.net;pascalcoin2.dynamic-dns.net;pascalcoin1.dns1.us;pascalcoin2.dns1.us;pascalcoin1.dns2.us;pascalcoin2.dns2.us'
                     {$ELSE}'pascaltestnet1.dynamic-dns.net;pascaltestnet2.dynamic-dns.net;pascaltestnet1.dns1.us;pascaltestnet2.dns1.us'{$ENDIF};
                     {$ELSE}'pascaltestnet1.dynamic-dns.net;pascaltestnet2.dynamic-dns.net;pascaltestnet1.dns1.us;pascaltestnet2.dns1.us'{$ENDIF};

+ 503 - 0
src/core/UMurMur3Fast.pas

@@ -0,0 +1,503 @@
+unit UMurMur3Fast;
+
+{ Copyright (c) 2019 by Albert Molina
+
+  Distributed under the MIT software license, see the accompanying file LICENSE
+  or visit http://www.opensource.org/licenses/mit-license.php.
+
+  This unit is a part of the PascalCoin Project, an infinitely scalable
+  cryptocurrency. Find us here:
+  Web: https://www.pascalcoin.org
+  Source: https://github.com/PascalCoin/PascalCoin
+
+  If you like it, consider a donation using Bitcoin:
+  16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk
+
+  THIS LICENSE HEADER MUST NOT BE REMOVED.
+}
+
+{$IFDEF FPC}
+  {$MODE delphi}
+  {$OVERFLOWCHECKS OFF}
+  {$RANGECHECKS OFF}
+  {$POINTERMATH ON}
+  {$DEFINE no_assembler} // FPC will not use assembler (error on Linux)
+{$ENDIF}
+
+interface
+
+uses
+SysUtils;
+
+{ This unit contains a fast implementation of MurMur3 hash
+  https://en.wikipedia.org/wiki/MurmurHash
+
+  How to use:
+
+  ### Single call:
+  Call TMurMur3Fast.Hash(  using TBytes or a buffer reference, Optionally add a Initial Seed [0=Default] )
+
+  ### Multiple calls:
+  var M : TMurMur3Fast
+  M.Init(0); // Init buffer and Seed, 0 by default
+  for each bunch:
+    M.Add(  )
+  end for
+  Result := M.ComputeFinal;
+
+  ### Extra
+  You can copy 2 TMurMur3Fast using "Clone"
+
+}
+
+Type
+  TMurMur3Fast = Record
+    MurMurPendingBuffer : TBytes;
+    MurMurNextSeed : Integer;
+    MurMurProcessedCount : Integer;
+    procedure Init(ASeed : UInt32);
+    procedure Add(Const AData : TBytes); overload;
+    procedure Add(Const {$IFNDEF FPC}[ref]{$ENDIF} AData; ADataLen: Integer); overload;
+    function ComputeFinal : UInt32;
+    function Hash(Const AData : TBytes; ASeed : Integer = 0) : UInt32; overload;
+    function Hash(Const {$IFNDEF FPC}[ref]{$ENDIF} AData; ADataLen: Integer; ASeed : Integer = 0) : UInt32; overload;
+    function Clone : TMurMur3Fast;
+  end;
+
+Const
+  CT_TMurMur3Fast_NUL : TMurMur3Fast = (MurMurPendingBuffer:Nil;MurMurNextSeed:0;MurMurProcessedCount:0);
+
+implementation
+
+{$pointermath on}
+
+{
+
+The "MurMurHash3" main assembler function (below) has been obtained from this public source:
+https://stackoverflow.com/questions/30942918/is-there-any-delphi-implementation-of-murmurhash3
+
+Possible author is JBontes (  https://github.com/JBontes/FastCode ) but original file "FastDefaults" does not contain this function. (Checked on 2019-10-01)
+
+}
+
+function MurmurHash3(const {$IFNDEF FPC}[ref]{$ENDIF} HashData; Len: integer; Seed: integer = 0): integer;
+const
+  c1 = $CC9E2D51;
+  c2 = $1B873593;
+  r1 = 15;
+  r2 = 13;
+  m = 5;
+  n = $E6546B64;
+  f1 = $85EBCA6B;
+  f2 = $C2B2AE35;
+{$IFDEF no_assembler}
+var
+  i, Len2: integer;
+  k: cardinal;
+  remaining: cardinal;
+  Data: PCardinal;
+label
+  case1, case2, case3, final;
+begin
+  Result:= Seed;
+  Data:= @HashData;
+  for i:= 0 to (Len shr 2) - 1 do begin
+    k:= Data[i];
+    k:= k * c1;
+    k:= (k shl r1) or (k shr (32 - r1));
+    k:= k * c2;
+    Result:= Result xor k;
+    Result:= (Result shl r2) or (Result shr (32 - r2));
+    Result:= Result * m + n;
+  end; {for i}
+  Len2:= Len;
+  remaining:= 0;
+  case Len and $3 of
+    1: goto case1;
+    2: goto case2;
+    3: goto case3;
+    else goto final;
+  end;
+case3:
+  dec(Len2);
+  inc(remaining, PByte(Data)[Len2] shl 16);
+case2:
+  dec(Len2);
+  inc(remaining, PByte(Data)[Len2] shl 8);
+case1:
+  dec(Len2);
+  inc(remaining, PByte(Data)[Len2]);
+  remaining:= remaining * c1;
+  remaining:= (remaining shl r1) or (remaining shr (32 - r1));
+  remaining:= remaining * c2;
+  Result:= Result xor remaining;
+final:
+  Result:= Result xor Len;
+
+  Result:= Result xor (Result shr 16);
+  Result:= Result * f1;
+  Result:= Result xor (Result shr 13);
+  Result:= Result * f2;
+  Result:= Result xor (Result shr 16);
+end;
+{$ELSE}
+{$REGION 'asm'}
+{$IFDEF CPUx86}
+{$IFDEF FPC}
+  {$asmMode intel}
+{$ENDIF}
+  asm
+    push EBX
+    push EDI
+    push ESI
+    xchg ECX,EDX
+    //EAX = data
+    //ECX = count in bytes
+    //EDX = seed
+    mov  ESI,ECX
+    shr  ECX,2
+    jz @remaining_bytes
+  @loop:
+    mov  EDI,[EAX]
+    imul EDI,EDI,c1
+    rol  EDI,r1
+    imul EDI,EDI,c2
+    xor  EDX,EDI
+    rol  EDX,r2
+    lea  EDX,[EDX*4+EDX+n]
+    lea  EAX,[EAX+4]
+    dec  ECX
+    jnz @loop
+  @remaining_bytes:
+    mov  ECX,ESI
+    and  ECX,$3
+    jz @finalization
+    xor  EBX,EBX
+    dec  ECX
+    mov  BL,byte ptr [EAX+ECX]
+    jz @process_remaining
+    shl  EBX,8
+    dec  ECX
+    mov  BL,byte ptr [EAX+ECX]
+    jz @process_remaining
+    shl  EBX,8
+    mov  BL,byte ptr [EAX]
+  @process_remaining:
+    imul EBX,EBX,c1
+    rol  EBX,r1
+    imul EBX,EBX,c2
+    xor  EDX,EBX
+  @finalization:
+    xor  EDX,ESI
+    mov  EAX,EDX
+    shr  EDX,16
+    xor  EDX,EAX
+    imul EDX,EDX,f1
+    mov  EAX,EDX
+    shr  EDX,13
+    xor  EDX,EAX
+    imul EDX,EDX,f2
+    mov  EAX,EDX
+    shr  EDX,16
+    xor  EAX,EDX
+    pop  ESI
+    pop  EDI
+    pop  EBX
+end;
+{$ENDIF}
+{$IFDEF CPUx64}
+{$IFDEF FPC}
+  {$asmMode intel}
+{$ENDIF}
+asm
+  push RBX
+  push RDI
+  push RSI
+  mov  RAX,RCX
+  mov  RCX,RDX
+  mov  RDX,R8
+  //RAX = data
+  //RCX = count in bytes
+  //RDX = seed
+  mov  ESI,ECX
+  shr  ECX,2
+  jz @remaining_bytes
+@loop:
+  mov  EDI, dword ptr [RAX]
+  imul EDI,EDI,c1
+  rol  EDI,r1
+  imul EDI,EDI,c2
+  xor  EDX,EDI
+  rol  EDX,r2
+  lea  EDX,dword ptr [EDX*4+EDX+n] // *5 + n
+  lea  RAX,qword ptr [RAX+4]
+  dec  ECX
+  jnz @loop
+@remaining_bytes:
+  mov  ECX,ESI
+  and  ECX,$3
+  jz @finalization
+  xor  RBX,RBX
+  dec  ECX
+  mov  BL,byte ptr [RAX+RCX]
+  jz @process_remaining
+  shl  EBX,8
+  dec  ECX
+  mov  BL,byte ptr [RAX+RCX]
+  jz @process_remaining
+  shl  EBX,8
+  mov  BL,byte ptr [RAX]
+@process_remaining:
+  imul EBX,EBX,c1
+  rol  EBX,r1
+  imul EBX,EBX,c2
+  xor  EDX,EBX
+@finalization:
+  xor  EDX,ESI
+  mov  EAX,EDX
+  shr  EDX,16
+  xor  EDX,EAX
+  imul EDX,EDX,f1
+  mov  EAX,EDX
+  shr  EDX,13
+  xor  EDX,EAX
+  imul EDX,EDX,f2
+  mov  EAX,EDX
+  shr  EDX,16
+  xor  EAX,EDX
+  pop  RSI
+  pop  RDI
+  pop  RBX
+end;
+{$ENDIF}
+{$ENDREGION}
+{$ENDIF}
+
+{
+
+  Next MurMurHash3 assembler functions are a modification of previous MurMurHash3 function
+
+}
+
+function MurmurHash3_Compute(const {$IFNDEF FPC}[ref]{$ENDIF} HashData; Len: integer; SeedOrLastCompute: integer = 0): integer;
+const
+  c1 = $CC9E2D51;
+  c2 = $1B873593;
+  r1 = 15;
+  r2 = 13;
+  m = 5;
+  n = $E6546B64;
+  f1 = $85EBCA6B;
+  f2 = $C2B2AE35;
+{$IFDEF no_assembler}
+var
+  i, Len2: integer;
+  k: cardinal;
+  remaining: cardinal;
+  Data: PCardinal;
+label
+  case1, case2, case3, final;
+begin
+  Result:= SeedOrLastCompute;
+  Data:= @HashData;
+  for i:= 0 to (Len shr 2) - 1 do begin
+    k:= Data[i];
+    k:= k * c1;
+    k:= (k shl r1) or (k shr (32 - r1));
+    k:= k * c2;
+    Result:= Result xor k;
+    Result:= (Result shl r2) or (Result shr (32 - r2));
+    Result:= Result * m + n;
+  end; {for i}
+end;
+{$ELSE}
+{$REGION 'asm'}
+{$IFDEF CPUx86}
+  asm
+    push EBX
+    push EDI
+    push ESI
+    xchg ECX,EDX
+    mov  ESI,ECX
+    shr  ECX,2
+    jz @return_seed
+  @loop:
+    mov  EDI,[EAX]
+    imul EDI,EDI,c1
+    rol  EDI,r1
+    imul EDI,EDI,c2
+    xor  EDX,EDI
+    rol  EDX,r2
+    lea  EDX,[EDX*4+EDX+n]
+    lea  EAX,[EAX+4]
+    dec  ECX
+    jnz @loop
+  @return_seed:
+    mov EAX,EDX
+    pop  ESI
+    pop  EDI
+    pop  EBX
+end;
+{$ENDIF}
+{$IFDEF CPUx64}
+asm
+  push RBX
+  push RDI
+  push RSI
+  mov  RAX,RCX
+  mov  RCX,RDX
+  mov  RDX,R8
+  mov  ESI,ECX
+  shr  ECX,2
+  jz @return_seed
+@loop:
+  mov  EDI, dword ptr [RAX]
+  imul EDI,EDI,c1
+  rol  EDI,r1
+  imul EDI,EDI,c2
+  xor  EDX,EDI
+  rol  EDX,r2
+  lea  EDX,dword ptr [EDX*4+EDX+n] // *5 + n
+  lea  RAX,qword ptr [RAX+4]
+  dec  ECX
+  jnz @loop
+@return_seed:
+  mov EAX,EDX
+  pop  RSI
+  pop  RDI
+  pop  RBX
+end;
+{$ENDIF}
+{$ENDREGION}
+{$ENDIF}
+
+
+function MurmurHash3_Final(const {$IFNDEF FPC}[ref]{$ENDIF} HashData; Len: integer; TotalLength : Integer; SeedOrLastCompute: integer = 0): integer;
+const
+  c1 = $CC9E2D51;
+  c2 = $1B873593;
+  r1 = 15;
+  r2 = 13;
+  m = 5;
+  n = $E6546B64;
+  f1 = $85EBCA6B;
+  f2 = $C2B2AE35;
+var
+  i, Len2: integer;
+  k: cardinal;
+  remaining: cardinal;
+  Data: PCardinal;
+label
+  case1, case2, case3, final;
+begin
+  assert( (Len>=0) and (Len<=3) , Format('Invalid Len %d on Final',[Len]));
+  Result:= SeedOrLastCompute;
+  Data:= @HashData;
+
+  Len2:= Len;
+  remaining:= 0;
+  case Len and $3 of
+    1: goto case1;
+    2: goto case2;
+    3: goto case3;
+    else goto final;
+  end;
+case3:
+  dec(Len2);
+  inc(remaining, PByte(Data)[Len2] shl 16);
+case2:
+  dec(Len2);
+  inc(remaining, PByte(Data)[Len2] shl 8);
+case1:
+  dec(Len2);
+  inc(remaining, PByte(Data)[Len2]);
+  remaining:= remaining * c1;
+  remaining:= (remaining shl r1) or (remaining shr (32 - r1));
+  remaining:= remaining * c2;
+  Result:= Result xor remaining;
+final:
+  Result:= Result xor TotalLength;
+
+  Result:= Result xor (Result shr 16);
+  Result:= Result * f1;
+  Result:= Result xor (Result shr 13);
+  Result:= Result * f2;
+  Result:= Result xor (Result shr 16);
+end;
+
+{ TMurMur3Data }
+
+procedure TMurMur3Fast.Add(Const AData: TBytes);
+begin
+  Self.Add( AData[0], Length(AData) );
+end;
+
+procedure TMurMur3Fast.Add(const {$IFNDEF FPC}[ref]{$ENDIF} AData; ADataLen: Integer);
+var LOffset, LPendingBytes : Integer;
+  i : Integer;
+  LDataRef : PByte;
+begin
+  Assert( Length(MurMurPendingBuffer) in [0..3] , Format('Invalid MurMurPendingBuffer length %d',[Length(MurMurPendingBuffer)]) );
+  if ADataLen<=0 then Exit;
+  // Pending from previous Add?
+  if (Length(MurMurPendingBuffer)>0) and
+    ((Length(MurMurPendingBuffer) + ADataLen)>=4) then begin
+    i := Length(MurMurPendingBuffer);
+    SetLength(Self.MurMurPendingBuffer,4);
+
+    LOffset := 4 - i; // Offset will be 1..3
+    Move(AData,Self.MurMurPendingBuffer[i],4-i);
+
+    Self.MurMurNextSeed := MurmurHash3_Compute(Self.MurMurPendingBuffer[0],4,Self.MurMurNextSeed);
+
+    SetLength(Self.MurMurPendingBuffer,0);
+  end else LOffset := 0;
+  // Process
+
+  LDataRef := @AData;
+  inc(LDataRef, LOffset);
+
+  Self.MurMurNextSeed := MurmurHash3_Compute(LDataRef^, ((ADataLen-LOffset) DIV 4)*4, Self.MurMurNextSeed);
+
+  // Save pending bytes
+  LPendingBytes := ((ADataLen-LOffset) MOD 4);
+  if LPendingBytes > 0 then begin
+    SetLength(Self.MurMurPendingBuffer, Length(Self.MurMurPendingBuffer) + LPendingBytes);
+    LDataRef := @AData;
+    inc(LDataRef, ADataLen - LPendingBytes );
+    Move(LDataRef^, Self.MurMurPendingBuffer[ Length(Self.MurMurPendingBuffer) - LPendingBytes ], LPendingBytes);
+  end;
+  Inc(Self.MurMurProcessedCount, ADataLen);
+end;
+
+function TMurMur3Fast.Clone: TMurMur3Fast;
+begin
+  Result := CT_TMurMur3Fast_NUL;
+  Result.MurMurPendingBuffer := System.Copy(Self.MurMurPendingBuffer);
+  Result.MurMurNextSeed := Self.MurMurNextSeed;
+  Result.MurMurProcessedCount := Self.MurMurProcessedCount;
+end;
+
+function TMurMur3Fast.ComputeFinal: UInt32;
+begin
+  Result := MurmurHash3_Final( Self.MurMurPendingBuffer[0], Length(Self.MurMurPendingBuffer), Self.MurMurProcessedCount, Self.MurMurNextSeed );
+end;
+
+function TMurMur3Fast.Hash(const {$IFNDEF FPC}[ref]{$ENDIF} AData; ADataLen, ASeed: Integer): UInt32;
+begin
+  Result := MurmurHash3(AData,ADataLen,ASeed);
+end;
+
+function TMurMur3Fast.Hash(Const AData: TBytes; ASeed: Integer): UInt32;
+begin
+  Result := MurmurHash3(AData[0],Length(AData),ASeed);
+end;
+
+procedure TMurMur3Fast.Init(ASeed: UInt32);
+begin
+  SetLength(Self.MurMurPendingBuffer,0);
+  Self.MurMurNextSeed := ASeed;
+  Self.MurMurProcessedCount := 0;
+end;
+
+end.

+ 6 - 6
src/core/UNode.pas

@@ -1006,15 +1006,15 @@ begin
   if account_number>=Bank.SafeBox.AccountsCount then Exit;
   if account_number>=Bank.SafeBox.AccountsCount then Exit;
   if StartOperation>EndOperation then Exit;
   if StartOperation>EndOperation then Exit;
   acc := Bank.SafeBox.Account(account_number);
   acc := Bank.SafeBox.Account(account_number);
-  if (acc.updated_on_block>0) Or (acc.account=0) then Begin
-    if (SearchBackwardsStartingAtBlock=0) Or (SearchBackwardsStartingAtBlock>=acc.updated_on_block) then begin
-      startBlock := acc.updated_on_block;
+  if (acc.GetLastUpdatedBlock>0) Or (acc.account=0) then Begin
+    if (SearchBackwardsStartingAtBlock=0) Or (SearchBackwardsStartingAtBlock>=acc.GetLastUpdatedBlock) then begin
+      startBlock := acc.GetLastUpdatedBlock;
       lastBalance := acc.balance;
       lastBalance := acc.balance;
     end else begin
     end else begin
       startBlock := SearchBackwardsStartingAtBlock;
       startBlock := SearchBackwardsStartingAtBlock;
       lastBalance := -1;
       lastBalance := -1;
     end;
     end;
-    DoGetFromBlock(startBlock,lastBalance,MaxDepth,0,startBlock<>acc.updated_on_block);
+    DoGetFromBlock(startBlock,lastBalance,MaxDepth,0,startBlock<>acc.GetLastUpdatedBlock);
   end;
   end;
 end;
 end;
 
 
@@ -1093,7 +1093,7 @@ begin
           end;
           end;
         end;
         end;
       end;
       end;
-      block := Bank.SafeBox.Account(account).updated_on_block;
+      block := Bank.SafeBox.Account(account).GetLastUpdatedBlock;
     finally
     finally
       UnlockMempoolRead;
       UnlockMempoolRead;
     end;
     end;
@@ -1208,7 +1208,7 @@ begin
       UnlockMempoolRead;
       UnlockMempoolRead;
     End;
     End;
     // block=0 and not found... start searching at block updated by account updated_block
     // block=0 and not found... start searching at block updated by account updated_block
-    block := Bank.SafeBox.Account(account).updated_on_block;
+    block := Bank.SafeBox.Account(account).GetLastUpdatedBlock;
     if Bank.SafeBox.Account(account).n_operation<n_operation then exit; // n_operation is greater than found in safebox
     if Bank.SafeBox.Account(account).n_operation<n_operation then exit; // n_operation is greater than found in safebox
   end;
   end;
   if (block=0) or (block>=Bank.BlocksCount) then exit;
   if (block=0) or (block>=Bank.BlocksCount) then exit;

+ 0 - 12
src/core/UOpTransaction.pas

@@ -595,8 +595,6 @@ begin
     Exit;
     Exit;
   end;
   end;
 
 
-  FPrevious_Signer_updated_block := account_signer.updated_on_block;
-  FPrevious_Destination_updated_block := account_target.updated_on_block;
   If (public_key in FData.changes_type) then begin
   If (public_key in FData.changes_type) then begin
     account_target.accountInfo.accountKey := FData.new_accountkey;
     account_target.accountInfo.accountKey := FData.new_accountkey;
   end;
   end;
@@ -906,8 +904,6 @@ begin
 
 
   {$endregion}
   {$endregion}
 
 
-  FPrevious_Signer_updated_block := LSender.updated_on_block;
-  FPrevious_Destination_updated_block := LTarget.updated_on_block;
 
 
   // Is buy account ?
   // Is buy account ?
   if (FData.opTransactionStyle = buy_Account ) then begin
   if (FData.opTransactionStyle = buy_Account ) then begin
@@ -979,7 +975,6 @@ begin
     If Not (TAccountComp.IsValidAccountKey(FData.new_accountkey,AErrors)) then exit; // BUG 20171511
     If Not (TAccountComp.IsValidAccountKey(FData.new_accountkey,AErrors)) then exit; // BUG 20171511
     LBuyAccountNewPubkey := FData.new_accountkey;
     LBuyAccountNewPubkey := FData.new_accountkey;
     {$endregion}
     {$endregion}
-    FPrevious_Seller_updated_block := LSeller.updated_on_block;
   end else if // (is auto buy) OR (is transaction that can buy)
   end else if // (is auto buy) OR (is transaction that can buy)
               (
               (
                 (FData.opTransactionStyle in [transaction,transaction_with_auto_buy_account,transaction_with_auto_atomic_swap]) AND
                 (FData.opTransactionStyle in [transaction,transaction_with_auto_buy_account,transaction_with_auto_atomic_swap]) AND
@@ -1030,7 +1025,6 @@ begin
     FData.AccountPrice := LTarget.accountInfo.price;
     FData.AccountPrice := LTarget.accountInfo.price;
     FData.SellerAccount := LTarget.accountInfo.account_to_pay;
     FData.SellerAccount := LTarget.accountInfo.account_to_pay;
     LSeller := ASafeBoxTransaction.Account(LTarget.accountInfo.account_to_pay);
     LSeller := ASafeBoxTransaction.Account(LTarget.accountInfo.account_to_pay);
-    FPrevious_Seller_updated_block := LSeller.updated_on_block;
     if TAccountComp.IsAccountForCoinSwap( LTarget.accountInfo ) then begin
     if TAccountComp.IsAccountForCoinSwap( LTarget.accountInfo ) then begin
       // We will save extra info that account key has not changed
       // We will save extra info that account key has not changed
       FData.new_accountkey := CT_TECDSA_Public_Nul;
       FData.new_accountkey := CT_TECDSA_Public_Nul;
@@ -1508,8 +1502,6 @@ begin
     Exit;
     Exit;
   end;
   end;
 
 
-  FPrevious_Signer_updated_block := account_signer.updated_on_block;
-  FPrevious_Destination_updated_block := account_target.updated_on_block;
   account_target.accountInfo.accountKey := FData.new_accountkey;
   account_target.accountInfo.accountKey := FData.new_accountkey;
   // Set to normal:
   // Set to normal:
   account_target.accountInfo.state := as_Normal;
   account_target.accountInfo.state := as_Normal;
@@ -1781,7 +1773,6 @@ begin
   if Not TAccountComp.IsValidAccountKey(FData.new_accountkey,errors) then begin
   if Not TAccountComp.IsValidAccountKey(FData.new_accountkey,errors) then begin
     Exit;
     Exit;
   end;
   end;
-  FPrevious_Signer_updated_block := acc.updated_on_block;
   Result := AccountTransaction.UpdateAccountInfo(AccountPreviousUpdatedBlock,
   Result := AccountTransaction.UpdateAccountInfo(AccountPreviousUpdatedBlock,
     GetOpID,
     GetOpID,
     FData.account,FData.n_operation, FData.account,
     FData.account,FData.n_operation, FData.account,
@@ -2085,9 +2076,6 @@ begin
     Exit;
     Exit;
   end;
   end;
 
 
-  FPrevious_Signer_updated_block := account_signer.updated_on_block;
-  FPrevious_Destination_updated_block := account_target.updated_on_block;
-
   if LIsDelist then begin
   if LIsDelist then begin
     account_target.accountInfo.state := as_Normal;
     account_target.accountInfo.state := as_Normal;
     account_target.accountInfo.locked_until_block := CT_AccountInfo_NUL.locked_until_block;
     account_target.accountInfo.locked_until_block := CT_AccountInfo_NUL.locked_until_block;

+ 1 - 1
src/core/UPCRPCOpData.pas

@@ -276,7 +276,7 @@ begin
       Exit;
       Exit;
     end;
     end;
     LFirst_Block_Is_Unknown := False;
     LFirst_Block_Is_Unknown := False;
-    LStartBlock := LAccount.updated_on_block;
+    LStartBlock := LAccount.GetLastUpdatedBlock;
     if LStartBlock>=ASender.Node.Bank.BlocksCount then Dec(LStartBlock); // If its updated on mempool, don't look the mempool
     if LStartBlock>=ASender.Node.Bank.BlocksCount then Dec(LStartBlock); // If its updated on mempool, don't look the mempool
   end;
   end;
 
 

+ 42 - 15
src/core/UPoolMinerThreads.pas

@@ -63,14 +63,14 @@ Type
     FTestingMode: Boolean;
     FTestingMode: Boolean;
     Procedure OnPoolMinerClientConnectionChanged(Sender : TObject);
     Procedure OnPoolMinerClientConnectionChanged(Sender : TObject);
     Procedure OnPoolMinerMustChangeValues(Sender : TObject);
     Procedure OnPoolMinerMustChangeValues(Sender : TObject);
-    Procedure OnMinerNewBlockFound(sender : TCustomMinerDeviceThread; const usedMinerValuesForWork : TMinerValuesForWork; Timestamp : Cardinal; NOnce : Cardinal);
+    Procedure OnMinerNewBlockFound(sender : TCustomMinerDeviceThread; const usedMinerValuesForWork : TMinerValuesForWork; Timestamp : Cardinal; NOnce : Cardinal; const AObtainedPoW : TRawBytes);
     Procedure NotifyPoolMinerConnectionChanged;
     Procedure NotifyPoolMinerConnectionChanged;
     procedure SetMinerAddName(AValue: String);
     procedure SetMinerAddName(AValue: String);
     procedure SetTestingPoWLeftBits(AValue: Byte);
     procedure SetTestingPoWLeftBits(AValue: Byte);
   protected
   protected
     procedure BCExecute; override;
     procedure BCExecute; override;
   public
   public
-    Constructor Create(RemoteHost : String; RemotePort : Integer; InitialAccountKey : TAccountKey);
+    Constructor Create(RemoteHost : String; RemotePort : Integer; const AUserName, APassword : String);
     Destructor Destroy; override;
     Destructor Destroy; override;
     Property PoolMinerClient : TPoolMinerClient read FPoolMinerClient;
     Property PoolMinerClient : TPoolMinerClient read FPoolMinerClient;
     Property OnConnectionStateChanged : TNotifyEvent read FOnConnectionStateChanged write FOnConnectionStateChanged;
     Property OnConnectionStateChanged : TNotifyEvent read FOnConnectionStateChanged write FOnConnectionStateChanged;
@@ -185,12 +185,15 @@ Var nID : Cardinal;
   i : Integer;
   i : Integer;
   ResponseMethod : String;
   ResponseMethod : String;
   l : TList<TCustomMinerDeviceThread>;
   l : TList<TCustomMinerDeviceThread>;
+  LParams : TPCJSONArray;
+  LPoolResult : TPCJSONObject;
 begin
 begin
   DebugStep:='Starting';
   DebugStep:='Starting';
   Try
   Try
     while not Terminated do begin
     while not Terminated do begin
       if FTestingMode then begin
       if FTestingMode then begin
       end else if not FPoolMinerClient.Connected then begin
       end else if not FPoolMinerClient.Connected then begin
+        FPoolMinerClient.Stratum_Authorized := False;
         DebugStep:='Not connected';
         DebugStep:='Not connected';
         If Not FPoolMinerClient.Connect then begin
         If Not FPoolMinerClient.Connect then begin
         end else begin
         end else begin
@@ -198,9 +201,12 @@ begin
         end;
         end;
       end else begin
       end else begin
           DebugStep:='Starting process';
           DebugStep:='Starting process';
-          // Start Process
-          nId:=FPoolMinerClient.GetNewId;
-          FPoolMinerClient.SendJSONRPCMethod(CT_PoolMining_Method_MINER_NOTIFY,nil,nId);
+          if FPoolMinerClient.PoolType = ptPoolSubscription then begin
+          end else begin
+            // Start Process Solo mining (direct to PascalCoin node)
+            nId:=FPoolMinerClient.GetNewId;
+            FPoolMinerClient.SendJSONRPCMethod(CT_PoolMining_Method_MINER_NOTIFY,nil,nId);
+          end;
           json := TPCJSONObject.create;
           json := TPCJSONObject.create;
           try
           try
             DebugStep:='Starting repeat';
             DebugStep:='Starting repeat';
@@ -232,7 +238,7 @@ begin
   End;
   End;
 end;
 end;
 
 
-constructor TPoolMinerThread.Create(RemoteHost: String; RemotePort: Integer; InitialAccountKey : TAccountKey);
+constructor TPoolMinerThread.Create(RemoteHost: String; RemotePort: Integer; const AUserName, APassword : String);
 begin
 begin
   FGlobalMinerValuesForWork := CT_TMinerValuesForWork_NULL;
   FGlobalMinerValuesForWork := CT_TMinerValuesForWork_NULL;
   FPoolMinerClient := TPoolMinerClient.Create(Nil);
   FPoolMinerClient := TPoolMinerClient.Create(Nil);
@@ -241,6 +247,13 @@ begin
   FPoolMinerClient.OnMinerMustChangeValues := OnPoolMinerMustChangeValues;
   FPoolMinerClient.OnMinerMustChangeValues := OnPoolMinerMustChangeValues;
   FPoolMinerClient.OnConnect := OnPoolMinerClientConnectionChanged;
   FPoolMinerClient.OnConnect := OnPoolMinerClientConnectionChanged;
   FPoolMinerClient.OnDisconnect := OnPoolMinerClientConnectionChanged;
   FPoolMinerClient.OnDisconnect := OnPoolMinerClientConnectionChanged;
+  if Length(AUserName)>0 then begin
+    FPoolMinerClient.PoolType := ptPoolSubscription;
+    FPoolMinerClient.UserName := AUserName;
+    FPoolMinerClient.Password := APassword;
+  end else begin
+    FPoolMinerClient.PoolType := ptSolomine;
+  end;
   FOnConnectionStateChanged := Nil;
   FOnConnectionStateChanged := Nil;
   FDevicesList := TPCThreadList<TCustomMinerDeviceThread>.Create('TPoolMinerThread_DevicesList');
   FDevicesList := TPCThreadList<TCustomMinerDeviceThread>.Create('TPoolMinerThread_DevicesList');
   FMinerThreads := 0;
   FMinerThreads := 0;
@@ -351,12 +364,11 @@ begin
   else FTestingPoWLeftBits:=0;
   else FTestingPoWLeftBits:=0;
 end;
 end;
 
 
-procedure TPoolMinerThread.OnMinerNewBlockFound(sender : TCustomMinerDeviceThread; const usedMinerValuesForWork : TMinerValuesForWork; Timestamp : Cardinal; NOnce : Cardinal);
+procedure TPoolMinerThread.OnMinerNewBlockFound(sender : TCustomMinerDeviceThread; const usedMinerValuesForWork : TMinerValuesForWork; Timestamp : Cardinal; NOnce : Cardinal; const AObtainedPoW : TRawBytes);
 begin
 begin
   FDevicesList.LockList;
   FDevicesList.LockList;
   try
   try
-    TLog.NewLog(ltinfo,ClassName,'FOUND VALID NONCE!!! Block:'+IntToStr(usedMinerValuesForWork.block)+' Timestamp:'+Inttostr(Timestamp)+ ' Nonce:'+Inttostr(NOnce)+' Payload:'+usedMinerValuesForWork.payload_start.ToString);
-    FPoolMinerClient.SubmitBlockFound(usedMinerValuesForWork,usedMinerValuesForWork.payload_start,Timestamp,NOnce);
+    FPoolMinerClient.SubmitBlockFound(usedMinerValuesForWork,usedMinerValuesForWork.FinalPayload,Timestamp,NOnce,AObtainedPoW);
   finally
   finally
     FDevicesList.UnlockList;
     FDevicesList.UnlockList;
   end;
   end;
@@ -386,14 +398,19 @@ Var l : TList<TCustomMinerDeviceThread>;
   minervfw : TMinerValuesForWork;
   minervfw : TMinerValuesForWork;
   auxminervfw : TMinerValuesForWork;
   auxminervfw : TMinerValuesForWork;
   auxRaw : TRawBytes;
   auxRaw : TRawBytes;
+  s : String;
 begin
 begin
   FGlobalMinerValuesForWork := FPoolMinerClient.MinerValuesForWork;
   FGlobalMinerValuesForWork := FPoolMinerClient.MinerValuesForWork;
-  TLog.NewLog(ltupdate,ClassName,Format('New miner values. Block %d Target %s Payload %s',[FPoolMinerClient.MinerValuesForWork.block,
-    IntToHex(FPoolMinerClient.MinerValuesForWork.target,8), FPoolMinerClient.MinerValuesForWork.payload_start.ToPrintable]));
   l := FDevicesList.LockList;
   l := FDevicesList.LockList;
   Try
   Try
     for i := 0 to l.Count - 1 do begin
     for i := 0 to l.Count - 1 do begin
       minervfw := FGlobalMinerValuesForWork;
       minervfw := FGlobalMinerValuesForWork;
+      if (FGlobalMinerValuesForWork.IsStratum) And (FGlobalMinerValuesForWork.extraNOnce2_Size>0) then begin
+        s := IntToStr(i+1);
+        while Length(s)<FGlobalMinerValuesForWork.extraNOnce2_Size do s := '0' + s;
+        minervfw.extraNOnce2_Used.FromString( s );
+      end else begin
+
       auxRaw.FromString(FMinerAddName);
       auxRaw.FromString(FMinerAddName);
       TBaseType.Concat(minervfw.payload_start,auxRaw,minervfw.payload_start);
       TBaseType.Concat(minervfw.payload_start,auxRaw,minervfw.payload_start);
       if (l.count>1) then begin
       if (l.count>1) then begin
@@ -410,6 +427,8 @@ begin
           end;
           end;
         until (Ok);
         until (Ok);
       end;
       end;
+
+      end;
       If FTestingPoWLeftBits>0 then begin
       If FTestingPoWLeftBits>0 then begin
         auxminervfw := minervfw;
         auxminervfw := minervfw;
         auxminervfw.target:= ((((auxminervfw.target AND $FF000000) SHR 24)-FTestingPoWLeftBits) SHL 24) + (minervfw.target AND $00FFFFFF);
         auxminervfw.target:= ((((auxminervfw.target AND $FF000000) SHR 24)-FTestingPoWLeftBits) SHL 24) + (minervfw.target AND $00FFFFFF);
@@ -420,6 +439,10 @@ begin
         TCustomMinerDeviceThread(l[i]).SetMinerValuesForWork(minervfw);
         TCustomMinerDeviceThread(l[i]).SetMinerValuesForWork(minervfw);
       end;
       end;
     end;
     end;
+    TLog.NewLog(ltupdate,ClassName,Format('Block %d Target %s Payload %s Devices %d PoW:%s',[FPoolMinerClient.MinerValuesForWork.block,
+      IntToHex(FPoolMinerClient.MinerValuesForWork.target,8), FPoolMinerClient.MinerValuesForWork.payload_start.ToPrintable,
+      l.Count,
+      FGlobalMinerValuesForWork.target_pow.ToHexaString ]));
   Finally
   Finally
     FDevicesList.UnlockList;
     FDevicesList.UnlockList;
   End;
   End;
@@ -507,7 +530,7 @@ begin
     LHash := TCrypto.DoSha256(TCrypto.DoSha256(digest));
     LHash := TCrypto.DoSha256(TCrypto.DoSha256(digest));
   if (TBaseType.BinStrComp(LHash,usedMinerValuesForWork.target_pow)<=0) then begin
   if (TBaseType.BinStrComp(LHash,usedMinerValuesForWork.target_pow)<=0) then begin
     inc(FGlobaDeviceStats.WinsCount);
     inc(FGlobaDeviceStats.WinsCount);
-    FPoolMinerThread.OnMinerNewBlockFound(self,usedMinerValuesForWork,Timestamp,nOnce);
+    FPoolMinerThread.OnMinerNewBlockFound(self,usedMinerValuesForWork,Timestamp,nOnce,LHash);
     If Assigned(FOnFoundNOnce) then FOnFoundNOnce(Self,Timestamp,nOnce);
     If Assigned(FOnFoundNOnce) then FOnFoundNOnce(Self,Timestamp,nOnce);
   end else begin
   end else begin
     inc(FGlobaDeviceStats.Invalids);
     inc(FGlobaDeviceStats.Invalids);
@@ -523,15 +546,18 @@ end;
 procedure TCustomMinerDeviceThread.CreateDigest(const AMinerValuesForWork: TMinerValuesForWork; Timestamp, nOnce: Cardinal; var ODigest: TRawBytes);
 procedure TCustomMinerDeviceThread.CreateDigest(const AMinerValuesForWork: TMinerValuesForWork; Timestamp, nOnce: Cardinal; var ODigest: TRawBytes);
 begin
 begin
   // Validation
   // Validation
-  SetLength(ODigest,Length(AMinerValuesForWork.part1) + Length(AMinerValuesForWork.payload_start) + Length(AMinerValuesForWork.part3) + 8);
+  SetLength(ODigest,Length(AMinerValuesForWork.part1) + Length(AMinerValuesForWork.payload_start) + Length(AMinerValuesForWork.extraNOnce2_Used) + Length(AMinerValuesForWork.part3) + 8);
   move(AMinerValuesForWork.part1[0],
   move(AMinerValuesForWork.part1[0],
     ODigest[0],
     ODigest[0],
     Length(AMinerValuesForWork.part1));
     Length(AMinerValuesForWork.part1));
   move(AMinerValuesForWork.payload_start[0],
   move(AMinerValuesForWork.payload_start[0],
     ODigest[Length(AMinerValuesForWork.part1)],
     ODigest[Length(AMinerValuesForWork.part1)],
     Length(AMinerValuesForWork.payload_start));
     Length(AMinerValuesForWork.payload_start));
+  move(AMinerValuesForWork.extraNOnce2_Used[0],
+    ODigest[Length(AMinerValuesForWork.part1) + Length(AMinerValuesForWork.payload_start) ],
+    Length(AMinerValuesForWork.extraNOnce2_Used));
   move(AMinerValuesForWork.part3[0],
   move(AMinerValuesForWork.part3[0],
-    ODigest[ Length(AMinerValuesForWork.part1) + Length(AMinerValuesForWork.payload_start) ],
+    ODigest[ Length(AMinerValuesForWork.part1) + Length(AMinerValuesForWork.payload_start) + Length(AMinerValuesForWork.extraNOnce2_Used) ],
     Length(AMinerValuesForWork.part3));
     Length(AMinerValuesForWork.part3));
   // Add timestamp and nonce
   // Add timestamp and nonce
   move(Timestamp,ODigest[length(ODigest)-8],4);
   move(Timestamp,ODigest[length(ODigest)-8],4);
@@ -582,7 +608,8 @@ var aux : Integer;
 begin
 begin
   FMinerValuesForWork := Value;
   FMinerValuesForWork := Value;
   UpdateMinerValuesForWorkLength(FMinerValuesForWork,aux);
   UpdateMinerValuesForWorkLength(FMinerValuesForWork,aux);
-  TLog.NewLog(ltinfo,classname,Format('Updated MinerValuesForWork: Target:%s Payload:%s Target_PoW:%s',[IntToHex(FMinerValuesForWork.target,8),FMinerValuesForWork.payload_start.ToString,TCrypto.ToHexaString(FMinerValuesForWork.target_pow)]));
+  TLog.NewLog(ltdebug,classname,
+    Format('Updated MinerValuesForWork: Target:%s Payload:%s Target_PoW:%s',[IntToHex(FMinerValuesForWork.target,8),FMinerValuesForWork.payload_start.ToString,TCrypto.ToHexaString(FMinerValuesForWork.target_pow)]));
   If Assigned(FOnMinerValuesChanged) then FOnMinerValuesChanged(Self);
   If Assigned(FOnMinerValuesChanged) then FOnMinerValuesChanged(Self);
 end;
 end;
 
 

+ 252 - 71
src/core/UPoolMining.pas

@@ -39,8 +39,11 @@ Const
   CT_PoolMining_Method_MINER_NOTIFY = 'miner-notify'; // Server message to clients to update miners PoW data
   CT_PoolMining_Method_MINER_NOTIFY = 'miner-notify'; // Server message to clients to update miners PoW data
   CT_PoolMining_Method_MINER_SUBMIT = 'miner-submit'; // Client message to server to notify a PoW found
   CT_PoolMining_Method_MINER_SUBMIT = 'miner-submit'; // Client message to server to notify a PoW found
 
 
-  CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE = 'mining-authorize';
-  CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE = 'mining-subscribe';
+  CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE = 'mining.authorize';
+  CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE = 'mining.subscribe';
+  CT_PoolMining_Method_STRATUM_MINING_SET_DIFFICULTY = 'mining.set_difficulty';
+  CT_PoolMining_Method_STRATUM_MINING_NOTIFY = 'mining.notify';
+  CT_PoolMining_Method_STRATUM_MINING_SUBMIT = 'mining.submit';
 
 
 Type
 Type
   TMinerValuesForWork = Record
   TMinerValuesForWork = Record
@@ -52,10 +55,20 @@ Type
      target : Cardinal;
      target : Cardinal;
      timestamp : Cardinal;
      timestamp : Cardinal;
      target_pow : TRawBytes;
      target_pow : TRawBytes;
-     // Stratum jobid
+     // Stratum information
      jobid : String;
      jobid : String;
+     extraNOnce2_Size : Integer;
+     extraNOnce2_Used : TRawBytes;
   End;
   End;
 
 
+  { TMinerValuesForWork_HELPER }
+
+  TMinerValuesForWork_HELPER = record helper for TMinerValuesForWork
+     function FinalPayload : TRawBytes;
+     function IsStratum : Boolean;
+  end;
+
+
   TProcessJSONObjectEvent = Procedure (json : TPCJSONObject; method : String) of object;
   TProcessJSONObjectEvent = Procedure (json : TPCJSONObject; method : String) of object;
 
 
   { TJSONRPCTcpIpClient }
   { TJSONRPCTcpIpClient }
@@ -79,7 +92,7 @@ Type
     Function GetNewId : Cardinal;
     Function GetNewId : Cardinal;
   End;
   End;
 
 
-  TPoolType = (ptNone,ptIdentify);
+  TPoolType = (ptSolomine,ptPoolSubscription);
 
 
   { TPoolMinerClient }
   { TPoolMinerClient }
 
 
@@ -92,6 +105,8 @@ Type
     FPoolType: TPoolType;
     FPoolType: TPoolType;
     FStratum_Target_PoW: TRawBytes;
     FStratum_Target_PoW: TRawBytes;
     FUserName: String;
     FUserName: String;
+    FStratumAuthorized : Boolean;
+    FStratum_ExtraNOnce2_Size: Integer;
     procedure SetMinerValuesForWork(const Value: TMinerValuesForWork);
     procedure SetMinerValuesForWork(const Value: TMinerValuesForWork);
   protected
   protected
     Procedure DoOnConnect; Override;
     Procedure DoOnConnect; Override;
@@ -99,13 +114,15 @@ Type
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
     Property OnMinerMustChangeValues : TNotifyEvent read FOnMinerMustChangeValues write FOnMinerMustChangeValues;
     Property OnMinerMustChangeValues : TNotifyEvent read FOnMinerMustChangeValues write FOnMinerMustChangeValues;
     Property MinerValuesForWork : TMinerValuesForWork read FMinerValuesForWork write SetMinerValuesForWork;
     Property MinerValuesForWork : TMinerValuesForWork read FMinerValuesForWork write SetMinerValuesForWork;
-    Procedure SubmitBlockFound(Const MinerValuesToGenerateBlock : TMinerValuesForWork; const Payload: TRawBytes; Timestamp, NOnce: Cardinal);
+    Procedure SubmitBlockFound(Const MinerValuesToGenerateBlock : TMinerValuesForWork; const Payload: TRawBytes; Timestamp, NOnce: Cardinal; const AObtainedPoW : TRawBytes);
     Procedure DoProcessJSONObject(json : TPCJSONObject; ResponseMethod : String);
     Procedure DoProcessJSONObject(json : TPCJSONObject; ResponseMethod : String);
     Property PoolType : TPoolType read FPoolType write FPoolType;
     Property PoolType : TPoolType read FPoolType write FPoolType;
     Property UserName : String read FUserName write FUserName;
     Property UserName : String read FUserName write FUserName;
     Property Password : String read FPassword write FPassword;
     Property Password : String read FPassword write FPassword;
     Property PoolFinalMinerName : TRawBytes read FPoolFinalMinerName;
     Property PoolFinalMinerName : TRawBytes read FPoolFinalMinerName;
     Property Stratum_Target_PoW : TRawBytes read FStratum_Target_PoW;
     Property Stratum_Target_PoW : TRawBytes read FStratum_Target_PoW;
+    Property Stratum_Authorized : Boolean read FStratumAuthorized write FStratumAuthorized;
+    Property Stratum_ExtraNOnce2_Size : Integer read FStratum_ExtraNOnce2_Size write FStratum_ExtraNOnce2_Size;
   End;
   End;
 
 
   TPoolMiningServer = Class;
   TPoolMiningServer = Class;
@@ -166,7 +183,7 @@ Type
 Function TBytesToString(Const bytes : TBytes):AnsiString;
 Function TBytesToString(Const bytes : TBytes):AnsiString;
 
 
 Const
 Const
-  CT_TMinerValuesForWork_NULL : TMinerValuesForWork = (block:0;version:0;part1:Nil;payload_start:Nil;part3:Nil;target:0;timestamp:0;target_pow:Nil;jobid:'');
+  CT_TMinerValuesForWork_NULL : TMinerValuesForWork = (block:0;version:0;part1:Nil;payload_start:Nil;part3:Nil;target:0;timestamp:0;target_pow:Nil;jobid:'';extraNOnce2_Size:0;extraNOnce2_Used:Nil);
 
 
 implementation
 implementation
 
 
@@ -191,6 +208,27 @@ Begin
   end;
   end;
 End;
 End;
 
 
+{ TMinerValuesForWork_HELPER }
+
+function TMinerValuesForWork_HELPER.FinalPayload: TRawBytes;
+begin
+  if IsStratum then begin
+    // Check extraNOnce2 valid value
+    while ( Self.extraNOnce2_Size>Length(Self.extraNOnce2_Used) ) do begin
+      SetLength(Self.extraNOnce2_Used, Length(Self.extraNOnce2_Used) + 1);
+      Self.extraNOnce2_Used[ High(Self.extraNOnce2_Used) ] := 48; // 48 = Char '0'
+    end;
+  end;
+  SetLength(Result, Length(Self.payload_start) + Length(Self.extraNOnce2_Used) );
+  Move(Self.payload_start[0],Result[0],Length(Self.payload_start));
+  Move(Self.extraNOnce2_Used[0],Result[Length(Self.payload_start)],Length(Self.extraNOnce2_Used));
+end;
+
+function TMinerValuesForWork_HELPER.IsStratum: Boolean;
+begin
+  Result := Length(Self.jobid)>0;
+end;
+
 { TJSONRPCTcpIpClient }
 { TJSONRPCTcpIpClient }
 
 
 constructor TJSONRPCTcpIpClient.Create(AOwner: TComponent);
 constructor TJSONRPCTcpIpClient.Create(AOwner: TComponent);
@@ -317,10 +355,11 @@ begin
           Try
           Try
             if jsonData is TPCJSONObject then begin
             if jsonData is TPCJSONObject then begin
               jsonObject.Assign(jsonData);
               jsonObject.Assign(jsonData);
-              If (Not jsonObject.IsNull('id')) And (jsonObject.IndexOfName('method')<0) then begin
+              If (Not jsonObject.IsNull('id')) then begin
                 // Is a Response!
                 // Is a Response!
                 FlushBufferPendingMessages(true,jsonObject.AsInteger('id',0));
                 FlushBufferPendingMessages(true,jsonObject.AsInteger('id',0));
               end;
               end;
+              TLog.NewLog(ltdebug,ClassName,'Received JSON: '+jsonObject.ToJSON(false));
               Result := true;
               Result := true;
               exit;
               exit;
             end else begin
             end else begin
@@ -413,7 +452,7 @@ begin
       P^.method:=method;
       P^.method:=method;
       FPendingResponseMessages.Add(P);
       FPendingResponseMessages.Add(P);
     end;
     end;
-    {$IFDEF HIGHLOG}TLog.NewLog(ltInfo,Classname,'Sending JSON: '+json.ToJSON(false));{$ENDIF}
+    TLog.NewLog(ltDebug,Classname,'Sending JSON: '+json.ToJSON(false));
     stream := TMemoryStream.Create;
     stream := TMemoryStream.Create;
     try
     try
       json.SaveToStream(stream);
       json.SaveToStream(stream);
@@ -1057,11 +1096,13 @@ end;
 constructor TPoolMinerClient.Create(AOwner: TComponent);
 constructor TPoolMinerClient.Create(AOwner: TComponent);
 begin
 begin
   FMinerValuesForWork := CT_TMinerValuesForWork_NULL;
   FMinerValuesForWork := CT_TMinerValuesForWork_NULL;
-  FPoolType:=ptNone;
+  FPoolType:=ptSolomine;
   FUserName:='';
   FUserName:='';
   FPassword:='';
   FPassword:='';
   FPoolFinalMinerName:=Nil;
   FPoolFinalMinerName:=Nil;
   FStratum_Target_PoW:=Nil;
   FStratum_Target_PoW:=Nil;
+  FStratumAuthorized := False;
+  FStratum_ExtraNOnce2_Size := 0;
   inherited;
   inherited;
 end;
 end;
 
 
@@ -1073,44 +1114,24 @@ Var params : TPCJSONArray;
   i : Integer;
   i : Integer;
 begin
 begin
   inherited DoOnConnect;
   inherited DoOnConnect;
-  If FPoolType=ptIdentify then begin
+  If FPoolType=ptPoolSubscription then begin
     // Pool initialization
     // Pool initialization
     params := TPCJSONArray.Create;
     params := TPCJSONArray.Create;
     resultObject := TPCJSONObject.Create;
     resultObject := TPCJSONObject.Create;
     try
     try
-      params.GetAsVariant(0).Value:=UserName;
-      params.GetAsVariant(1).Value:=Password;
-      If SendJSONRPCMethodAndWait(CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE,params,1000,resultObject,nil) then begin
-        TLog.NewLog(ltInfo,Classname,CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE+' response: '+resultObject.ToJSON(false));
-        // Now subscribe
-        params.Clear;
-        resultObject.Clear;
-        If SendJSONRPCMethodAndWait(CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE,params,1000,resultObject,nil) then begin
-          //
-          TLog.NewLog(ltInfo,Classname,CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE+' response: '+resultObject.ToJSON(false));
-          // Decode response
-          If (resultObject.IsNull('error')) then begin
-            s := resultObject.GetAsArray('result').GetAsArray(0).GetAsArray(0).GetAsVariant(0).AsString('');
-            if (s<>'mining.nonce') then Raise Exception.Create('Not a mining.nonce');
-            s := resultObject.GetAsArray('result').GetAsVariant(1).AsString('');
-            raws := TCrypto.HexaToRaw(s);
-            If (length(s)>0) And (length(raws)=0) then begin
-              TLog.NewLog(lterror,ClassName,'Invalid value to assign as a Miner name. Not hexadecimal '+s);
-              FPoolFinalMinerName:=Nil;
-            end else begin
-              FPoolFinalMinerName := raws;
-              for i:=Low(raws) to High(raws) do begin
-                if Not (raws[i] in [32..254]) then begin
-                  TLog.NewLog(ltError,ClassName,'Invalid proposed miner name. Value at pos '+inttostr(i)+' is not #32..#254: '+IntToStr(integer(raws[i])));
-                  FPoolFinalMinerName:=Nil;
-                  break;
-                end;
-              end;
-            end;
-            TLog.NewLog(ltInfo,Classname,'Final miner name: "'+FPoolFinalMinerName.ToPrintable+'" (Length '+IntToStr(length(FPoolFinalMinerName)));
-          end;
-        end else raise Exception.Create('Not response to "'+CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE+'" method for user "'+UserName+'"');
-      end else raise Exception.Create('Not response to "'+CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE+'" method for user "'+UserName+'"');
+      If SendJSONRPCMethodAndWait(CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE,params,8000,resultObject,DoProcessJSONObject) then begin
+        //
+        DoProcessJSONObject(resultObject,CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE);
+        //
+        Sleep(100);
+        //
+        params.GetAsVariant(0).Value:=UserName;
+        params.GetAsVariant(1).Value:=Password;
+        If SendJSONRPCMethodAndWait(CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE,params,8000,resultObject,DoProcessJSONObject) then begin
+          DoProcessJSONObject(resultObject,CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE);
+          FStratumAuthorized := True;
+        end else raise Exception.Create('Not response to "'+CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE+'" method for user "'+UserName+'"');
+      end else raise Exception.Create('Not response to "'+CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE+'" method for user "'+UserName+'"');
     finally
     finally
       resultObject.free;
       resultObject.free;
       params.free;
       params.free;
@@ -1127,8 +1148,105 @@ Var method : String;
   params : TPCJSONData;
   params : TPCJSONData;
   mvfw : TMinerValuesForWork;
   mvfw : TMinerValuesForWork;
   prev_pow,proposed_pow : TRawBytes;
   prev_pow,proposed_pow : TRawBytes;
+
+  procedure StratumUpdatedDifficulty(ANewDifficultyValue : Double);
+  var LBigNumDiff : TBigNum;
+    LAuxPOW : TRawBytes;
+    LHexa : String;
+  begin
+    LBigNumDiff := TBigNum.Create('00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
+    try
+      if (ANewDifficultyValue<=0) then Exit;
+
+      if (ANewDifficultyValue<1) then begin
+        LBigNumDiff.Multiply( Round(1000.0/ANewDifficultyValue) ).Divide( 1000 );
+      end else begin
+        LBigNumDiff.Multiply( Round(ANewDifficultyValue*1000.0) ).Divide( 1000 );
+      end;
+      LHexa := LBigNumDiff.HexaValue;
+    finally
+      LBigNumDiff.Free;
+    end;
+    while (LHexa.Length<64) do LHexa.Insert(0,'0');
+    TCrypto.HexaToRaw( LHexa, LAuxPOW );
+    if TBaseType.Equals(LAuxPOW,FStratum_Target_PoW) then Exit; // Nothing to update
+
+    FStratum_Target_PoW := LAuxPOW;
+    TLog.NewLog(ltInfo,ClassName,Format('Set Difficulty to %.6f -> Target PoW:%s %s',[ANewDifficultyValue,
+      TPascalCoinProtocol.TargetToCompact(FStratum_Target_PoW,CT_PROTOCOL_4).ToHexString,
+      FStratum_Target_PoW.ToHexaString]));
+  end;
+
+  procedure ExtractStratumMinerValuesFromWork(const AJobID, ADigestPart_1, ADigestPart_2, AStratumTime : String);
+  var LMVFW : TMinerValuesForWork;
+    LStream : TStream;
+    LRaw : TRawBytes;
+  begin
+    LMVFW := CT_TMinerValuesForWork_NULL;
+    // Extracting Miner Values From Work from Digest parts:
+    if Not TCrypto.HexaToRaw( ADigestPart_1, LRaw) then begin
+      TLog.NewLog(ltError,ClassName,Format('Digest Part 1 obtained is not Hexadecimal: "%s" length %d',[ADigestPart_1,Length(ADigestPart_1)]));
+      Exit;
+    end;
+    if (Length(LRaw)<20) then begin
+      TLog.NewLog(ltError,ClassName,Format('Digest Part 1 is too short: "%s" length %d',[ADigestPart_1,Length(ADigestPart_1)]));
+      Exit;
+    end;
+    LMVFW.part1 := LRaw;
+    if Not TCrypto.HexaToRaw(ADigestPart_2,LMVFW.part3) then begin
+      TLog.NewLog(ltError,ClassName,Format('Digest Part 2 obtained is not Hexadecimal: "%s" length %d',[ADigestPart_2,Length(ADigestPart_2)]));
+      Exit;
+    end;
+    LStream := TMemoryStream.Create;
+    try
+      LStream.WriteBuffer( LRaw[0], Length(LRaw) );
+      LStream.Position := 0;
+      // Block number is stored as a Little Endian on first 4 bytes (8 hexa chars)
+      LStream.Read(LMVFW.block,4);
+
+      if LMVFW.block=0 then Exit;
+
+      // Latest 8 bytes are:
+      // 2 - protocol_version
+      // 2 - protocol_available
+      // 4 - target
+      LStream.Seek(-8,soFromEnd);
+      LStream.Read(LMVFW.version,2);
+      LStream.Seek(2,soFromCurrent);
+      LStream.Read(LMVFW.target,4);
+      LMVFW.jobid := AJobID;
+    finally
+      LStream.Free;
+    end;
+    // Capture timestamp
+    LMVFW.timestamp := StrToIntDef('$'+AStratumTime,0);
+    //
+    MinerValuesForWork := LMVFW;
+  end;
+
+  procedure ExtractStratumMinerValuesFromWorkFromParams;
+  var i : Integer;
+  begin
+    if Not Assigned(params_as_array) then Exit;
+    i := params_as_array.Count - 9;
+    if (i<0) or (i>1) then Exit;
+
+    if (i=1) then begin
+      // Extract difficulty from position 0
+      StratumUpdatedDifficulty( params_as_array.GetAsVariant(0).AsDouble(1) );
+    end;
+
+    // STRATUM
+    ExtractStratumMinerValuesFromWork(
+      params_as_array.GetAsVariant(0 + i).AsString(''),
+      params_as_array.GetAsVariant(2 + i).AsString(''),
+      params_as_array.GetAsVariant(3 + i).AsString(''),
+      params_as_array.GetAsVariant(7 + i).AsString('')
+    );
+  end;
+
+
 begin
 begin
-  TLog.NewLog(ltdebug,ClassName,'Received JSON: '+json.ToJSON(false));
   params := Nil;
   params := Nil;
   params_as_object := Nil;
   params_as_object := Nil;
   params_as_array := Nil;
   params_as_array := Nil;
@@ -1138,19 +1256,20 @@ begin
     if (i>=0) then begin
     if (i>=0) then begin
       params := json.Items[i];
       params := json.Items[i];
     end;
     end;
-    TLog.NewLog(ltinfo,classname,'Received response method:'+ResponseMethod+' JSON:'+json.ToJSON(false));
+    {$IFDEF HIGHLOG}TLog.NewLog(ltinfo,classname,'Received response method:'+ResponseMethod+' JSON:'+json.ToJSON(false));{$ENDIF}
   end else begin
   end else begin
     method := json.AsString('method','');
     method := json.AsString('method','');
-    i := json.IndexOfName('params');
-    if (i>=0) then begin
-      params := json.Items[i];
-    end;
+  end;
+  i := json.IndexOfName('params');
+  if (i>=0) then begin
+    params := json.Items[i];
   end;
   end;
   If Assigned(params) then begin
   If Assigned(params) then begin
     if (params is TPCJSONNameValue) then begin
     if (params is TPCJSONNameValue) then begin
       if (TPCJSONNameValue(params).Value is TPCJSONObject) then params_as_object := TPCJSONObject(TPCJSONNameValue(params).Value)
       if (TPCJSONNameValue(params).Value is TPCJSONObject) then params_as_object := TPCJSONObject(TPCJSONNameValue(params).Value)
       else if (TPCJSONNameValue(params).Value is TPCJSONArray) then params_as_array := TPCJSONArray(TPCJSONNameValue(params).Value);
       else if (TPCJSONNameValue(params).Value is TPCJSONArray) then params_as_array := TPCJSONArray(TPCJSONNameValue(params).Value);
-    end;
+    end else if (params is TPCJSONArray) then params_as_array := TPCJSONArray(params)
+    else if (params is TPCJSONObject) then params_as_object := TPCJSONObject(params)
   end;
   end;
   i := json.IndexOfName('id');
   i := json.IndexOfName('id');
   if i<0 then begin
   if i<0 then begin
@@ -1172,7 +1291,7 @@ begin
       mvfw.timestamp := pobject.AsInteger('timestamp',0);
       mvfw.timestamp := pobject.AsInteger('timestamp',0);
       mvfw.part1 := TCrypto.HexaToRaw(pobject.AsString('part1',''));
       mvfw.part1 := TCrypto.HexaToRaw(pobject.AsString('part1',''));
       mvfw.target_pow := TCrypto.HexaToRaw(pobject.AsString('target_pow',''));
       mvfw.target_pow := TCrypto.HexaToRaw(pobject.AsString('target_pow',''));
-      If FPoolType=ptIdentify then begin
+      If FPoolType=ptPoolSubscription then begin
         mvfw.jobid:=pobject.AsString('jobid','');
         mvfw.jobid:=pobject.AsString('jobid','');
       end;
       end;
       if (Not VarIsNull(id_value)) And (ResponseMethod='') then begin
       if (Not VarIsNull(id_value)) And (ResponseMethod='') then begin
@@ -1180,6 +1299,40 @@ begin
       end;
       end;
       MinerValuesForWork := mvfw;
       MinerValuesForWork := mvfw;
     end else TLog.NewLog(ltError,ClassName,'method '+method+' without JSON object '+params.ToJSON(false));
     end else TLog.NewLog(ltError,ClassName,'method '+method+' without JSON object '+params.ToJSON(false));
+  end else if (method=CT_PoolMining_Method_MINER_SUBMIT) then begin
+    //
+  end else if (method=CT_PoolMining_Method_STRATUM_MINING_AUTHORIZE) And
+    (PoolType=ptPoolSubscription) And (Assigned(params_as_array)) then begin
+    //
+    FStratumAuthorized := True;
+    ExtractStratumMinerValuesFromWorkFromParams;
+  end else if (method=CT_PoolMining_Method_STRATUM_MINING_SUBSCRIBE) And
+    (PoolType=ptPoolSubscription) And (Assigned(params_as_array)) then begin
+    // STRATUM
+    // {"id":2,"result":[[["mining.notify","00000000000000000000000000000000"]],"303030303030303030",8],"error":null}
+    // Explained at: https://slushpool.com/help/stratum-protocol/
+    // params[0] -> Subscription details
+    // params[1] -> Extranonce1
+    // params[2] -> Extranonce2_size
+    FPoolFinalMinerName := TCrypto.HexaToRaw( params_as_array.GetAsVariant(1).AsString('') );
+    FStratum_ExtraNOnce2_Size := params_as_array.GetAsVariant(2).AsInteger(0);
+  end else if (method=CT_PoolMining_Method_STRATUM_MINING_SET_DIFFICULTY) And
+    (PoolType=ptPoolSubscription) And (Assigned(params_as_array)) then begin
+    // STRATUM
+    // {"id":null,"method":"mining.set_difficulty","params":[0.0000152588]}
+    StratumUpdatedDifficulty( params_as_array.GetAsVariant(0).AsDouble(1) );
+
+  end else if (method=CT_PoolMining_Method_STRATUM_MINING_NOTIFY) And
+    (PoolType=ptPoolSubscription) And (Assigned(params_as_array)) then begin
+    ExtractStratumMinerValuesFromWorkFromParams;
+  end else if (method=CT_PoolMining_Method_STRATUM_MINING_SUBMIT) And
+    (PoolType=ptPoolSubscription) then begin
+    // Response to a mining submit event
+    if (json.GetAsVariant('error').AsBoolean(False)) then begin
+      TLog.NewLog(lterror,ClassName,Format('Invalid SHARE %s',[method,json.ToJSON(False)]));
+    end;
+  end else begin
+    TLog.NewLog(lterror,ClassName,Format('Unknown method received "%s": %s',[method,json.ToJSON(False)]));
   end;
   end;
 end;
 end;
 
 
@@ -1218,32 +1371,60 @@ begin
       end;
       end;
     end;
     end;
   end;
   end;
-  If (FPoolType=ptIdentify) And (Length(FPoolFinalMinerName)>0) then FMinerValuesForWork.payload_start:=FPoolFinalMinerName;
+  If (FPoolType=ptPoolSubscription) And (Length(FPoolFinalMinerName)>0) then begin
+    FMinerValuesForWork.payload_start:=FPoolFinalMinerName;
+    FMinerValuesForWork.extraNOnce2_Size:=FStratum_ExtraNOnce2_Size;
+    FMinerValuesForWork.extraNOnce2_Used:=Nil;
+  end;
   if Assigned(FOnMinerMustChangeValues) then FOnMinerMustChangeValues(Self);
   if Assigned(FOnMinerMustChangeValues) then FOnMinerMustChangeValues(Self);
 end;
 end;
 
 
-procedure TPoolMinerClient.SubmitBlockFound(Const MinerValuesToGenerateBlock : TMinerValuesForWork; const Payload: TRawBytes; Timestamp, NOnce: Cardinal);
-Var json, resultJSON : TPCJSONObject;
-  nOnceAsSignedInt : Int32;
+procedure TPoolMinerClient.SubmitBlockFound(Const MinerValuesToGenerateBlock : TMinerValuesForWork; const Payload: TRawBytes; Timestamp, NOnce: Cardinal; const AObtainedPoW : TRawBytes);
+Var json : TPCJSONObject;
+  LnOnceAsSignedInt : Int32;
+  LArrJSON : TPCJSONArray;
 begin
 begin
-  json := TPCJSONObject.Create;
-  Try
-    nOnceAsSignedInt := NOnce;
-    If FPoolType=ptIdentify then begin
-      json.GetAsVariant('jobid').Value := MinerValuesToGenerateBlock.jobid;
-    end;
-    json.GetAsVariant('payload').Value := TCrypto.ToHexaString(Payload);
-    json.GetAsVariant('timestamp').Value := Timestamp;
-    json.GetAsVariant('nonce').Value := nOnceAsSignedInt;
-    resultJSON := TPCJSONObject.Create;
-    try
+  LnOnceAsSignedInt := NOnce;
+  If FPoolType=ptPoolSubscription then begin
+    LArrJSON := TPCJSONArray.Create;
+    Try
+      LArrJSON.GetAsVariant(0).Value := UserName;
+      LArrJSON.GetAsVariant(1).Value := MinerValuesToGenerateBlock.jobid;
+      LArrJSON.GetAsVariant(2).Value := MinerValuesToGenerateBlock.extraNOnce2_Used.ToHexaString; //  Payload.ToHexaString;// + '1234567812345678'; // '1234567812345678'; //Payload.ToHexaString;
+      LArrJSON.GetAsVariant(3).Value := IntToHex(Timestamp,8);
+      LArrJSON.GetAsVariant(4).Value := IntToHex(LnOnceAsSignedInt,8);
+      SendJSONRPCMethod(CT_PoolMining_Method_STRATUM_MINING_SUBMIT,LArrJSON,GetNewId);
+      TLog.NewLog(ltInfo,ClassName,Format('SHARE for job %s block %d Time %s NOnce %s ExtraNOnce2 %s PoW %s',
+       [MinerValuesToGenerateBlock.jobid,
+        MinerValuesToGenerateBlock.block,
+        IntToHex(Timestamp,8),
+        IntToHex(LnOnceAsSignedInt,8),
+        MinerValuesToGenerateBlock.extraNOnce2_Used.ToHexaString,
+        AObtainedPoW.ToHexaString]));
+    Finally
+      LArrJSON.Free;
+    End;
+  end else begin
+    json := TPCJSONObject.Create;
+    Try
+      If FPoolType=ptPoolSubscription then begin
+        json.GetAsVariant('jobid').Value := MinerValuesToGenerateBlock.jobid;
+      end;
+      json.GetAsVariant('payload').Value := TCrypto.ToHexaString(Payload);
+      json.GetAsVariant('timestamp').Value := Timestamp;
+      json.GetAsVariant('nonce').Value := LnOnceAsSignedInt;
       SendJSONRPCMethod(CT_PoolMining_Method_MINER_SUBMIT,json,GetNewId);
       SendJSONRPCMethod(CT_PoolMining_Method_MINER_SUBMIT,json,GetNewId);
+      TLog.NewLog(ltInfo,ClassName,Format('FOUND SOLUTION for block %d Time %s NOnce %s Payload %s PoW %s',
+       [
+        MinerValuesToGenerateBlock.block,
+        IntToHex(Timestamp,8),
+        IntToHex(LnOnceAsSignedInt,8),
+        Payload.ToHexaString,
+        AObtainedPoW.ToHexaString]));
     Finally
     Finally
-      resultJSON.free;
-    end;
-  Finally
-    json.Free;
-  End;
+      json.Free;
+    End;
+  end;
 end;
 end;
 
 
 { TPoolMiningServerThread }
 { TPoolMiningServerThread }

+ 3 - 2
src/core/URPC.pas

@@ -420,8 +420,9 @@ Begin
   jsonObj.GetAsVariant('balance').Value:=TAccountComp.FormatMoneyDecimal(account.balance);
   jsonObj.GetAsVariant('balance').Value:=TAccountComp.FormatMoneyDecimal(account.balance);
   jsonObj.GetAsVariant('balance_s').Value:=TAccountComp.FormatMoney(account.balance);
   jsonObj.GetAsVariant('balance_s').Value:=TAccountComp.FormatMoney(account.balance);
   jsonObj.GetAsVariant('n_operation').Value:=account.n_operation;
   jsonObj.GetAsVariant('n_operation').Value:=account.n_operation;
-  jsonObj.GetAsVariant('updated_b').Value:=account.updated_on_block;
-  jsonObj.GetAsVariant('n_operation_updated_block').Value:=account.updated_on_block_active_mode;
+  jsonObj.GetAsVariant('updated_b').Value:=account.GetLastUpdatedBlock;
+  jsonObj.GetAsVariant('updated_b_active_mode').Value:=account.updated_on_block_active_mode;
+  jsonObj.GetAsVariant('updated_b_passive_mode').Value:=account.updated_on_block_passive_mode;
   case account.accountInfo.state of
   case account.accountInfo.state of
     as_Normal : jsonObj.GetAsVariant('state').Value:='normal';
     as_Normal : jsonObj.GetAsVariant('state').Value:='normal';
     as_ForSale : begin
     as_ForSale : begin

+ 17 - 18
src/core/URandomHash.pas

@@ -105,6 +105,7 @@ interface
 
 
 uses {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
 uses {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
      SysUtils, HlpIHash, HlpBits, HlpHashFactory,
      SysUtils, HlpIHash, HlpBits, HlpHashFactory,
+     UMurMur3Fast,
      UCommon;
      UCommon;
 
 
 type
 type
@@ -160,7 +161,7 @@ type
         FBytes : TList<TBytes>;
         FBytes : TList<TBytes>;
         FComputedIndex : Integer;
         FComputedIndex : Integer;
         FChecksum : UInt32;
         FChecksum : UInt32;
-        FMurMur3 : IHash;
+        FMurMur3Fast : TMurMur3Fast;
 
 
         function GetCount : Integer;
         function GetCount : Integer;
         function CalculateChecksum : UInt32;
         function CalculateChecksum : UInt32;
@@ -185,7 +186,7 @@ type
     private
     private
       function GetCachedHeader : TBytes;
       function GetCachedHeader : TBytes;
     {$IFNDEF UNITTESTS}private{$ELSE}public{$ENDIF}
     {$IFNDEF UNITTESTS}private{$ELSE}public{$ENDIF}
-      FMurmur3 : IHash;
+      FMurMur3Fast : TMurMur3Fast;
       FHashAlg : array[0..17] of IHash;  // declared here to avoid race-condition during mining
       FHashAlg : array[0..17] of IHash;  // declared here to avoid race-condition during mining
       FCachedHeader : TBytes;
       FCachedHeader : TBytes;
       FCachedNonce : UInt32;
       FCachedNonce : UInt32;
@@ -205,7 +206,7 @@ type
       function Compress(const AInputs: TChecksummedByteCollection): TBytes; inline;
       function Compress(const AInputs: TChecksummedByteCollection): TBytes; inline;
       function GetNonce(const ABlockHeader: TBytes) : UInt32;
       function GetNonce(const ABlockHeader: TBytes) : UInt32;
       function ChangeNonce(const ABlockHeader: TBytes; ANonce: UInt32): TBytes; inline;
       function ChangeNonce(const ABlockHeader: TBytes; ANonce: UInt32): TBytes; inline;
-      function Checksum(const AInput: TBytes; AOffset, ALength: Integer): UInt32; overload; inline;
+      function Checksum(const AInput: TBytes; AOffset, ALength: Integer): UInt32; overload;
       function Checksum(const AInput: TBytes): UInt32; overload; inline;
       function Checksum(const AInput: TBytes): UInt32; overload; inline;
       function Hash(const ABlockHeader: TBytes; ARound: Int32) : TChecksummedByteCollection; overload;
       function Hash(const ABlockHeader: TBytes; ARound: Int32) : TChecksummedByteCollection; overload;
     public
     public
@@ -593,7 +594,7 @@ end;
 
 
 constructor TRandomHashFast.Create;
 constructor TRandomHashFast.Create;
 begin
 begin
-  FMurmur3 := THashFactory.THash32.CreateMurmurHash3_x86_32();
+  FMurMur3Fast := CT_TMurMur3Fast_NUL;
   FHashAlg[0] := THashFactory.TCrypto.CreateSHA2_256();
   FHashAlg[0] := THashFactory.TCrypto.CreateSHA2_256();
   FHashAlg[1] := THashFactory.TCrypto.CreateSHA2_384();
   FHashAlg[1] := THashFactory.TCrypto.CreateSHA2_384();
   FHashAlg[2] := THashFactory.TCrypto.CreateSHA2_512();
   FHashAlg[2] := THashFactory.TCrypto.CreateSHA2_512();
@@ -620,7 +621,7 @@ end;
 destructor TRandomHashFast.Destroy;
 destructor TRandomHashFast.Destroy;
 var i : integer;
 var i : integer;
 begin
 begin
- FMurmur3 := nil;
+ FMurMur3Fast := CT_TMurMur3Fast_NUL;
  for i := Low(FHashAlg) to High(FHashAlg) do
  for i := Low(FHashAlg) to High(FHashAlg) do
    FHashAlg[i] := nil;
    FHashAlg[i] := nil;
  if Assigned(FCachedOutput) then
  if Assigned(FCachedOutput) then
@@ -763,9 +764,7 @@ end;
 
 
 function TRandomHashFast.Checksum(const AInput: TBytes; AOffset, ALength: Integer): UInt32;
 function TRandomHashFast.Checksum(const AInput: TBytes; AOffset, ALength: Integer): UInt32;
 begin
 begin
-  FMurmur3.Initialize;
-  FMurmur3.TransformBytes(AInput, AOffset, ALength);
-  Result := FMurmur3.TransformFinal.GetUInt32();
+  Result := FMurMur3Fast.Hash(AInput[AOffset],ALength);
 end;
 end;
 
 
 function TRandomHashFast.Compress(const AInputs : TChecksummedByteCollection): TBytes;
 function TRandomHashFast.Compress(const AInputs : TChecksummedByteCollection): TBytes;
@@ -1008,14 +1007,14 @@ begin
   FBytes := TList<TBytes>.Create;
   FBytes := TList<TBytes>.Create;
   FComputedIndex := -1;
   FComputedIndex := -1;
   FChecksum := 0;
   FChecksum := 0;
-  FMurMur3 := THashFactory.THash32.CreateMurmurHash3_x86_32();
+  FMurMur3Fast := CT_TMurMur3Fast_NUL;
   AddRange(AManyBytes);
   AddRange(AManyBytes);
 end;
 end;
 
 
 destructor TRandomHashFast.TChecksummedByteCollection.Destroy;
 destructor TRandomHashFast.TChecksummedByteCollection.Destroy;
 begin
 begin
   FreeAndNil(FBytes);
   FreeAndNil(FBytes);
-  FMurMur3 := nil;
+  FMurMur3Fast := CT_TMurMur3Fast_NUL;
   {$IFDEF FPC}
   {$IFDEF FPC}
   Dec(FInstances);
   Dec(FInstances);
   {$ENDIF}
   {$ENDIF}
@@ -1029,7 +1028,7 @@ begin
   Result.FBytes := TList<TBytes>.Create(Self.FBytes);
   Result.FBytes := TList<TBytes>.Create(Self.FBytes);
   Result.FComputedIndex:= Self.FComputedIndex;
   Result.FComputedIndex:= Self.FComputedIndex;
   Result.FChecksum:= Self.FChecksum;
   Result.FChecksum:= Self.FChecksum;
-  Result.FMurMur3 := Self.FMurMur3.Clone();
+  Result.FMurMur3Fast := Self.FMurMur3Fast.Clone();
 end;
 end;
 
 
 function TRandomHashFast.TChecksummedByteCollection.GetCount : Integer;
 function TRandomHashFast.TChecksummedByteCollection.GetCount : Integer;
@@ -1059,7 +1058,7 @@ begin
     // Is empty so just copy checksum from argument
     // Is empty so just copy checksum from argument
     FComputedIndex := ACollection.FComputedIndex;
     FComputedIndex := ACollection.FComputedIndex;
     FChecksum := ACollection.FChecksum;
     FChecksum := ACollection.FChecksum;
-    FMurMur3 := ACollection.FMurMur3.Clone;
+    FMurMur3Fast := ACollection.FMurMur3Fast.Clone;
   end;
   end;
   FBytes.AddRange(ACollection.FBytes);
   FBytes.AddRange(ACollection.FBytes);
 end;
 end;
@@ -1067,19 +1066,19 @@ end;
 function TRandomHashFast.TChecksummedByteCollection.CalculateChecksum : UInt32;
 function TRandomHashFast.TChecksummedByteCollection.CalculateChecksum : UInt32;
 var
 var
   i : integer;
   i : integer;
-  LClonedMurMur3 : IHash;
+  LClonedMurMur3Fast : TMurMur3Fast;
 begin
 begin
   if (FComputedIndex = FBytes.Count - 1) then
   if (FComputedIndex = FBytes.Count - 1) then
     Exit(FChecksum); // already computed
     Exit(FChecksum); // already computed
 
 
   for i := (FComputedIndex + 1) to Pred(FBytes.Count) do begin
   for i := (FComputedIndex + 1) to Pred(FBytes.Count) do begin
-    FMurMur3.TransformBytes(FBytes[i]);
+    FMurMur3Fast.Add(FBytes[i]);
     Inc(FComputedIndex);
     Inc(FComputedIndex);
   end;
   end;
 
 
-  LClonedMurMur3 := FMurMur3.Clone;
-  FChecksum := FMurMur3.TransformFinal().GetUInt32();
-  FMurMur3 := LClonedMurMur3; // note: original instance should collect with implicit dereference
+  LClonedMurMur3Fast := FMurMur3Fast.Clone;
+  FChecksum := FMurMur3Fast.ComputeFinal;
+  FMurMur3Fast := LClonedMurMur3Fast;
   Result := FChecksum;
   Result := FChecksum;
 end;
 end;
 
 
@@ -1088,7 +1087,7 @@ begin
   FBytes.Clear;
   FBytes.Clear;
   FComputedIndex := -1;
   FComputedIndex := -1;
   FChecksum := 0;
   FChecksum := 0;
-  FMurMur3 := THashFactory.THash32.CreateMurmurHash3_x86_32(); // note: original instance should collect with implicit dereference
+  FMurMur3Fast := CT_TMurMur3Fast_NUL;
 end;
 end;
 
 
 function TRandomHashFast.TChecksummedByteCollection.ToByteArray : TBytes;
 function TRandomHashFast.TChecksummedByteCollection.ToByteArray : TBytes;

+ 3 - 1
src/core/UTCPIP.pas

@@ -264,7 +264,6 @@ begin
       if (FConnected) then begin
       if (FConnected) then begin
         FRemoteHost := FTcpBlockSocket.GetRemoteSinIP;
         FRemoteHost := FTcpBlockSocket.GetRemoteSinIP;
         FRemotePort := FTcpBlockSocket.GetRemoteSinPort;
         FRemotePort := FTcpBlockSocket.GetRemoteSinPort;
-        DoOnConnect;
       end{$IFDEF HIGHLOG} else TLog.NewLog(ltdebug,Classname,'Cannot connect to a server at: '+ClientRemoteAddr+' Reason: '+FTcpBlockSocket.GetErrorDescEx){$ENDIF};
       end{$IFDEF HIGHLOG} else TLog.NewLog(ltdebug,Classname,'Cannot connect to a server at: '+ClientRemoteAddr+' Reason: '+FTcpBlockSocket.GetErrorDescEx){$ENDIF};
     Except
     Except
       On E:Exception do begin
       On E:Exception do begin
@@ -278,6 +277,9 @@ begin
     FLock.Release;
     FLock.Release;
   end;
   end;
   Result := FConnected;
   Result := FConnected;
+  if FConnected then begin
+    DoOnConnect;
+  end;
 end;
 end;
 
 
 constructor TNetTcpIpClient.Create(AOwner : TComponent);
 constructor TNetTcpIpClient.Create(AOwner : TComponent);

+ 101 - 138
src/gui-classic/UFRMAbout.dfm

@@ -21,148 +21,109 @@ object FRMAbout: TFRMAbout
   object Image1: TImage
   object Image1: TImage
     Left = 15
     Left = 15
     Top = 15
     Top = 15
-    Width = 60
-    Height = 60
+    Width = 64
+    Height = 64
     AutoSize = True
     AutoSize = True
     Picture.Data = {
     Picture.Data = {
-      0954506E67496D61676589504E470D0A1A0A0000000D494844520000003C0000
-      003C08060000003AFCD9720000000473424954080808087C0864880000000970
-      48597300000B1200000B1201D2DD7EFC0000001C74455874536F667477617265
-      0041646F62652046697265776F726B7320435336E8BCB28C00000FBA49444154
-      78DAD59B095C55D79DC77F7779F72DF0001F48004571C17D091A318AC11D9D8C
-      4B1A6B4D9A38666BBA24699A34B669D3345A5BA78E6DDA8C33934C938989ADCD
-      A2C4246615B728EA68558C1A10104454400494F5DD77DF5DE67FEE7B1AC4FB14
-      788A99FF87F7B9EFC33DF7DDFBBDE77FFEDB3987330C033752CA8A8F0E104521
-      9317F80C4972DCEA70B9539C2E770C3BE76D69BC207B1BCB149F7C48D7F45DAA
-      AAED48491D5674239F87BBDEC047F3F6B905811B27F0C2644110D20551E84BC0
-      71F4DD61B33B05872B8A734644996DBDCD0D90BD0D865FF66A243201D768AA56
-      4ADFF769BAB64DD78C3D43D3D21BBF91C0797B733304817F90C066F38210CF0B
-      2278D10EC12641147988BC0E49E0E170D8E1B43B03C03E2F649F0F8AAA43D579
-      A874D4FC0A74D5075D53E9A35513FC464DD357A78D9DB0EB1B01BC6FE7B63B09
-      7431414EA20F389B13ECE8305AE0F4D7C2E1AF865DA985A8D483D7BCE0743FDD
-      5437AF35381E066F832E38A14AD1F049B1906DF1F0DAE8C8B918300CBFD73CD2
-      673B81AF4CBF63F22737053877CBE7B792DAFEAB20F23379C1068340ED9C0FD1
-      4A05A2E512B8E40A882A69A3A1B1DB98700001D277F6172036CFD0173DF812D8
-      3F04A8A21B2D8E24D43BFAA15E4A82CFB083F3CB04ED07A9FC67A4EEBF983075
-      C6A12E03DEB1E99317785E789EA7C109D10527E745BC52048F5C483D7ADE6CA3
-      7322410A9DEC050DBCA19ADF655B37D43906A25A1A00AF4143416D219557355D
-      D7966566DDB9F486026FFE64632F9EE3FE4A2A9C09C10151E090A41523493E02
-      BB564F903613F47A0A03E70D3F7C42342A1CC35121A442D5E8993519A4E23B74
-      C35838EDCED9E5D71D78D387EF67F03CB79EC667822E3A41EF1DA9FE0388D22A
-      49211968E77AB3FDE0D4EBF0A3414844B16D34CEC3035E35C77795AE1BDFCE9A
-      7357BB8C5ABB803FDD903D8BE7F96CB2BC924196B7378EA3BF9A0781DEBECA49
-      61C370C1316DF528E639C3FC3345341468A44525621ACAD01F5CC0A22BBAAECF
-      FBA76FCDFB286CE08FB2D7CD1278FE03907562C669080E21D9288246BD6A800F
-      8F94EE2D3A6D686DC554AFFFD21B105DF432353266E4CEC87741F5EB08D83C1D
-      02F5F6296E00F271AB69CCC89A51ECA2CF9D356FFE55A1AF0AFCE1BA77C6D198
-      FD82136C36E66AD2F8FD48C049A87084071A14816073FEB70CCBDE3A6042FFEA
-      9E34648DEB0BDDAB80B78B7861F55EE4E49D46A2C785FF7A3C13F174D4FDDAA5
-      EB45C8A8227DCBD36F0BB830CDEFA7313D71CEFC057B3A0CBCE19DBFF710383E
-      8FE3C5EE048CD1E27E2472A708D61EB8305C5AFA01C1ED40D64FDE33A1983C92
-      D90BAF3E3F833ADA8EAA730D48BC6FCDA5E69B7F7907A64E1E06D5A75FA6FB22
-      7CA834927140BD8D01C3D0D5739AA1A77D6BC177CFB41BF8ED37D6C06E177753
-      FC3B4EE31D18251D410A5F1280656AE82035A4E809E1C42C64E1412ADAE7FE35
-      283B1B881EDFFEE1282C98D90F888EC3EE8355C8787A83F97FB743C4993F4D83
-      3B211A8889A3FB923F272DD074E3127499DE0F79CA70F03AF3D7FA1E9F4F1B7F
-      CF030BDB079CBDF66FE467F9252AB99E81D2498CB01D866A4826A018E5C0EE03
-      E558BAF600C289D2C8E2435634EC3C4A563EF83B63FAC6C01361632771EABC82
-      FCF2804F774902320678E014398CE81B8749E9FD31616802ECF42C46938FC075
-      889C1F87FD2350A8F486482E8B8CD89279F7DD7F859FBE02F8DD356F0E21D823
-      BA60E7E36C8D98E8D86B46433ABD55911EE6745523463FB60ED517BC61746FF8
-      92DA231A4FCC1D8E27EE1A616A9DE60B18BB2FE4B1A8F1BB298CF511B33EFC3B
-      FFB228FF5AC05B385E98C251F03F39623F6285F3D4BB22449B00992C66C68FB3
-      71B0A4E6A6C2B696AC51C9C85E321311928DC24F2FEAF46ED8DA3C86C6B34AE3
-      59DB4AC0534302BFF3E6EAE9F4963669BC13831DE54873E69BAACCD48F8F9030
-      FFB98FB17E57E9CD66BC42EE4A4FC686E5B329F862EE4A469E77080AE45E1075
-      2F1B76590B163D986309FCD6EAD77791551EEF100DCC88DA47C98062FA5AC16D
-      C7E2553BF087EC2F6F365B48C9F96526A64D19069D54DBA7D9F079433A649563
-      567BF7BD0F3E947105F04B2B56A47B3CDDF672921B2322CA30C25964F62E0B0C
-      3EDB5582452BB74092AE6F9CDC1161B14875BD0F3E55B73CFFC81D3DF1EA5319
-      506DD1E440C88035A7E2704B0A0CA51175B575639F7CF6D97D9701AF5CB6ECF5
-      F85B6E79D0E5B46366F401440A5E6864A840EADC50DF02B1B18EFA9A453A2CBA
-      BAB165A12B60E923512032E577B9C82DAAB36C33775402DE7F662C0564026C1E
-      0F9A75173EBD300A2D5E1FAAABCEAE5EFCEBE71FBA04BCF03BF7BA060F4A3D95
-      98DCC793EABE8009EEA3A6A1BA286662AF2AD0EBCE51DEA77F1DFC0685E10BF4
-      6238DB55424D3FAB6A189D0A58D8353CF9E2494B77E08B63B5966DEEBE2D11D9
-      CFDC0E5FA30F9CDD01C913835D4DC351D440595679695D7E4161F2DAF5EFB698
-      C03F7AF87BD313136ED9D4B34F2AA6C616A29774F632E00035C1F8C9D95B40B3
-      AFAC4C535CD51CF2A17B789C8821B766E81DD70EB3870978E26F766247E13580
-      9BFDE6F3490E01A72286616BDD2094971C43456555D62BAB5FCF31817FF8D0C3
-      BF4F4848FCF9E0FEBD303BFE30C5530AAB415CF9AB046DF8AFEC69BBCB868FFF
-      5181592FEE0DF9D0B9BF9A808CC171F0C96A27FA98EEE11431F5B7B9D89A6FED
-      122F0346208F56A4687CAC4E417E51392A2B4EAFF8EF37DF78D6047E74D1035B
-      137BF69E3C616034A6C7159805B59062016D774B58F2D65758BAA1D0F292187A
-      21252BA7520F4BF06B3A3A230C781A8DE12D5FB50F98898D82E1CDC644E496CA
-      4CADB7BDF6D73553B82913EEE8D72725656B52AFFEBDE60E0346C75036A45DC3
-      1AB781B6474A98B3620F36E6555936CF48F520F7854C283EB5D3E68E69D1D465
-      3BDBDDC3E635E456F7EB23F1E109374E9F282C2F292D9DC2CDCA9AF1487CF7EE
-      7F4A4E498D5C38B219FD226B09B81DD58B203477A186525115839EDD8EB29A16
-      CBA68F4FEF8355DF4B2383A2740ED64ED92F4B349ECEC199F3720780FD28D67A
-      E16F279371F2784153F5B9734F71B367CC7C232E36EEBE3EFDFA8BDF4FBB8078
-      7BD3D555BA0DB4080D855F9DC0909F6FB99404B495F79F4CC75C824653078183
-      36A2A959C14FD71CC15FB69F0CD9F4AED109D8B078DCE52ACD6938AB7BF05A59
-      2A8E1F2F54CFD5D4AC65C0876263E3460CECDF97FBD1A83A44893EB2D0ED771E
-      22E5B41B728EE1EEDF6D0AD966DAD0EE88A571AE77D04233DE669F86BCB27A54
-      5C90AFDA767E7A12DEFD29F570AB972A703A1A8D08BC5236100545A5464DCDB9
-      C34CA5EB6363BB470D1B9882C708D841518AD611E068079EFBCF5C2C7FE760C7
-      7AEF3ACBAA85C3F1F8ACD436C00645D676BC7C62208E149D444D4D7503033608
-      182307F53681454E25D5EC003059DE998B3FC0E7074EDD34D8F8283B0AFE6D2A
-      A2C957ABADBC002BFBAB9C0D2F970D425E61396A6BAA1116308BAE7C7E0DFD1F
-      7E0B676A9BDB75CDF516365FF5C9E2DB3175E42D81F1DBEAD14301775AA5458A
-      6FF34B6B30F407EFDE14D8F47EDDF012A9F2ED2CA0611EA0CD635BAA7438464B
-      A4B4F1ED4F0B70EF8ACD21DBB8296010B9E00C1259F106EFD79156149DE3E91C
-      334E32B91DAF12A84832CD61D7B576DA46B03793631D18D3B79B992CCC18110F
-      5EE4E16B512DAB8A96462B1CB7C40CD6337FFE027F7CCF3A4FEED1CD817D4B32
-      61A7A442A0F1B52EF7141E7D3DD036292670CE21F1B091A67C77D53FF0F1A1B3
-      E6B9451392F1E7876F85D2CA0031601B017B226D00FD16A921FC5E35A42B6462
-      E9966665CDA4C023AEC381077BA1824BC2E4A7DEC3F6C315966D66520F7C4A31
-      B4410FC6915B7AF29583F8F74D818AC92452C36D4B3341D93AABA1A3FFE22D97
-      029797178DC00FE60C80D1C66FB33098552ADBEBDD2C038F4E8596AC77E96D37
-      79FDE8F7D0DF2931B72EE83D470FFDDBFB8799E38B859F3FF99F43782908BC7C
-      FE60FCE2DB83A1B5F8D142C069CF6D47497533F52287FDBF9988E1BDA32914D5
-      AEF91C5707B6082D3B9C3C5C0476D870A8F02CD21E5F1FB24DF68FC7E0EEF13D
-      4DEBC9D140F513D8FE1317CC1A597ADF1873EC328D14681C56D679517CB6D974
-      31437AB8CDB6E18A441E27476F933C74283D6C0D1CE5C09B1F1CC1032F6EB33C
-      CF0C4FFEEFA7604062247CAD8C912805868B9F7AEFD2F8A3031BE7601F1A9B17
-      DB8723AC3AA3704E7C644C47C1F153A83CD32A3D6C5701A02D70B4134FACDC82
-      FFD878D4F27CDFEE2E1398416A9D48FAC315893AED24DF17DBF5F1283FCE0A00
-      955F1700AE55E2692BA6C122956635EADD05D629A15963FAD9E5C17C5703E70A
-      93705C4D4245D9F1BAFCFCC2E4B5D9C1120F9390453C0B61AB72EA1B7DE84306
-      EB7C93CFB2CDD2BB07E1D7F70CE9744A188E0894C1357391D824FEB375118F49
-      A832AD25B0D3867D472A31965C5228D9F8F458CC1A93444141D7F7B09DE2AB43
-      C2181CE547C290EBADCBB44CAC0AF1BAC5A43733587F597F08DF5FB5C3F2862C
-      40285C31057DE25D146B876F6D3B22AC776532569B6DB321EB029B42B52EC433
-      0935D572053045588F2ECFC1AB9F1558DE742059E6A3CB279BDFBBDA60D90D19
-      07A50C1CE38742D49AAF3ED5C224D464DAA50BD844B62462CC63EBB0BFF89CE5
-      4DAD92F1AE109BA1A05648C00EC79DD055FFB527D382C0D6D3A541D56606ABF6
-      82D734588D5EEBF1B962C110FC6CDEA02E3558E6AC08C94ED71CD4C2034E95DB
-      375DCA24E4843802097FCE9E32643D177AEDC8A6C5E3303D2D013E6FD7192CC9
-      F0E24B17B921713804B5B9FD13E24CAEB6E481250C39BB4BF0DA077981D98836
-      2252A0F1E27DC3D09D5247B59335E88E8A5D6F41A9330D5F3A330996DCA9A675
-      6CC90393908B5A0CBB39390E7F23D0D418840E2EA60A8A4AD95167E7913A2A12
-      C1563806212F72065964854D84777C51CB45B9EAB22502D5EBCFC3686EB4ECE9
-      1B2F06C17A51E91C8C2FA366909162CB9694CE2F5BBA28A117A64930782108DD
-      C0A618BB0C952D3E150D1F4E45DE866351934C8B0CCD1FFEC2B48B1272E92161
-      ABBCBD4B7B5AD07DE622D652CF2494BBD2983566C0D76FE9E145B15E5CBA1F51
-      5A157482561B1A6E28349B0D64B0F5AE1494C64EC7795B2278A5E9C62C2EBD28
-      96CB87D562242947C95236107413B416EF7585662BE8055D81CF1E8B2ACF7854
-      46A59906117EEF8D5D3EDC5A2C1788FB8B112B17C1565B0283ACB74EAA1FD602
-      712D10B4F89CF1A8F38C424D741ABC7C24C07AB5AB1688B716EB2D000AA2D50A
-      B8AB0FC279BED8DCE7009D051FBC69E0CCD5B7E60459AB3D008661AE8EE57456
-      E520BFCDDBA0DA63E075A7A0A1DB303444F6838F92014E612BE11556F0EBFA2D
-      00ADC56A93077931D8D54638BC5570349F86D4520541AE85E06F06C77A4E0F96
-      70D84B102468B608688E5828AE04C8113D213B294A13DDAC27E97D7903C79BBD
-      C9A3AD586EE3B13928D1B007B6F130474663DE214970DA03CB8FBD3E19B25F81
-      A21AE4DB85C0361E85ACB0B9A1E31BBA8DA7AD5C73A3564414E77405376AB534
-      406EF97FBA512B94B47B2B9EAAEF52B51BBF15EFFF000BB1F477942997640000
-      000049454E44AE426082}
+      0954506E67496D61676589504E470D0A1A0A0000000D49484452000000400000
+      00400806000000AA6971DE0000000467414D410000B18F0BFC61050000000970
+      48597300000EC200000EC20115284A800000001874455874536F667477617265
+      007061696E742E6E657420342E312E36FD4E09E800000AD54944415478DAD55B
+      0B7854C515FE67EEDD17848780402860B21BE4258A8116FD1004A4F889852282
+      A808A2541113146DB5AD521A3EABD54AA186243E2A55D17E060111A42A5A9487
+      F8E04D4185920DB18809280884ECFBCEF4DC0D6CB264F766B30F361EF86EF6EE
+      3DF3F8FF397BE6CCB9334C4A89944A415FB3BF93B79F4F139733C97A32862C06
+      7402581B6AD9060649FF3C7439C1192A85645F7326BFD2A0ED6AF95DD65E14AC
+      0FA4B27B2C1504B84B72BA494DDEC0384613B8218CB116F1D4437DAB26823630
+      897F694C7BAB655E4555B32560FB0B034D7D7CC7C7017C06757A388D324F6647
+      C9420290EC7D29C4732D320FBE8389526B1E0410708FF7C434C9E42334D259C9
+      041D950C29F7D3E54FB6CE075F4F94888408A829768CE6600B69B42F3E1FC023
+      50B15B61E27ED3BD07379C5F025EE8D9C1E50B1473C66E4A0FF07A14D06F839C
+      E662B3C67FCDEE3B702AE504788A728651A97F52D12EE9061F4E842C975CDEDC
+      E2DEF2AD292380C0CFA2DFFA0206A6A61B70441220BD749961CB77BE92640218
+      F314DBE7D3DF07530980B5EB09D6BE07E03D09ED7F1F074384FAC2330702199D
+      21ABBF85ACDA118584E0FFB9B6FCF2C71103B8180860CC5BEC2821AD7B52091E
+      ADBBC17AEB0780526B5CBE8DF320F6BC5AD78B6E436119FB8F332825BC6F4D81
+      FCF633830AC553D6BCF2DF254C80A7C8B180387820A5E049949EE3601A393F74
+      EFDF58006DCF6BA17BF5CA87A0E6CE08DD7B57DE4A046C69041CE658F2CB1E8F
+      9B006F91E37EC9D8DF520D3E08F0AA39502F9B16BAF7AD980851B533746F1AF3
+      3294EE57D5DED0D4EFFE7B2E98BFC6B04E7D8600D36EB7E51D7C359A4E54023C
+      2539C3A5901F5070A3843DC8E802F3354F20E97EB0FDC5E0D676A15B51B51DD0
+      FC751DED781998C976E66100A2721BA4D0204F7E0D796417F98C4D80EBBB4835
+      BB158E21A69965DB6326E0F4B38E8EAA865D64FA99618CAA2D60B971297887DE
+      C9059F0C21ABD00E6D46605B3164653856C25856E332E57678785F754C04B88B
+      1CCB68E427845542A1BDF9BA1228F691E986DA1813087CB914810DF3C852EA2C
+      88603E6FCB2F6BE0C81B10E02AB48FE10A5F7DAEA27AE5C3E484EE4E37BA9845
+      73AE85EFBDFCD0544A57012187DA6639374725E040610F4B572EF6D2E8E7D457
+      527A8D8769C453FA8C986E5C4D12DF477320BE2C0DDD13D4EDB6EF9D3F438114
+      1109A0606726851B25610C650E8069EC1270D5926E3C4D1671EA10BCAF8E080B
+      A824B449342BBCD180802F0AFA9AB33B780F7086EE216D732B98473F0BD4F3CE
+      CD4AAC6DC15B763454F1965E0F796C7F1D0152FE87A2C4FE417BA84F807B51CE
+      24C6518A1F91A8FDEF803AF851431DDFEAA910873E09FF528A51D6FCF20FC209
+      28767C448B9C61E906755E08805C61CD734E0811F04371F6455628E5C94E6335
+      5702F455A3D7AF756E3BBBE244900057916336676C6142BD69D515A621730C55
+      84F35D68FB57258D00A5DF6D300D2D683201B5246853F510394800053E6B69EA
+      1B954867F8C5E360FEF97C431DDFFBB3210EAC491E01974C86E9EA7971114052
+      6ACD2BBB85C93FF631BB3B787E8837757D56D42173A15E3AD550C7B3641850FD
+      4DF32040A2CA9A5F96C96A4A1C03B8C0B6443B631AFF0694CCDCA8CF85E738BC
+      8B073548722444C0A5B7D3CFEE0FF11110EC94DFCEDC85D9D3C1F98B89744472
+      132CBFDA096EB246D5D1576BFEB7EF481A785D4C239E84D27B82A18E110142CA
+      F1CCBDC8F1171A968712EA49FBDEB0DEFCB6A18A9F5669DAE789F9D9FAC23AF6
+      83F986525A951B47A84604D06CF07B56B3C8BE34D1F436EF3309E6E1868917F8
+      B716421EFE2CC61AA3C2066CEDC0BB0C82AA8FBC6A6DB4846FD514886F3E8D4C
+      80C073CC55644F380052873D0EB5EFA404C1A5408420C73B04A83912F9B9C49B
+      CCB5C8BE836680CB1369C77CD36AF00BFBA41B6E43FC95DBE17B33FAC05004B0
+      8E7C807D2F2D73FBC6DD8A6A83951CE0D96C6EB3111A7DEFAADB8C13A7526E60
+      1404EDA18F97C4DB0EEBD41F9609CBD30DF75C64F06F7E0ADAAE4626379D00D7
+      22C716C6F0D3789B52FA4DA570746EBA118744D41C4560D363C1B0BB719AE45A
+      DD072414069B463E0DA5E70DE9451DF0401CDD0DEDBF6B68ADB132781F135914
+      0EEB16F01259C0B4B809B8652D94768EE88D545722F0C91361DFA9B9F790D33C
+      E376C813F9D73F02E93B1D7A6ED6C3DB334918E9AD0E3E8F248CE63171EA30E4
+      0F6531830E17B940B780B96401F3E2281DCC1859A76FA74020FA2A5A94BD03DF
+      DAFBC2BEB3DEBE31F87E21F8BCE63B785FBE1267B38DD2D412B6BB7610BADAD7
+      11DAE1CFE17F6B725CDD6B4CC84FCE623545D91338F8B2782AE03FB902E671AF
+      19EAF8373F19E68C180532963B3F07CE40D6BEDE00FF9AE975CF3BE7C2726328
+      6587C0AEC5086CFE734A08A058F81A76624177BBC56C72C6535EE97F174C837F
+      6BA873EE3B3C49D19B65D21AF0B659C19719BE0F1F81D8B7A2AE40ABAE304F5C
+      096EBB00D2EF868FD60FB232E1B55A03D1D3E4367FA03DA30F7A2C70989DF316
+      2816315D5B0825677474052D00F78BB960015778E364DEBC457B48FD77EB6DB8
+      A9432A16706B9B5ABFE077211522A5FCC296EFBC249810F1143996503034A589
+      0CC232652378EBE81B45C4F103F0BD7E5D4A00244C8010CFD86695CF3E9311B2
+      4F648CBFD1A41A6CED61BD535FDC447F5912D8B7128175892D345348C1486B9E
+      735D9080A3C57D335A4B4F25594146ACC579F7AB611EB3D850E7DC4D0ECD46A4
+      ACB2762AEFAA6FB1AB4B8B173916931FB833D63A948179300D32DE37E15D7E23
+      E491DDE9861B8981F934FA41D30C11E02A720C2402B630239BAE27A6D1CF43C9
+      BE26BA42C0470EF07230CD9B6EB4E7820F40E3BDACF71D708611A00B59C18744
+      C2F046AB208E2CD33E016F7961541DEDE85EF8978D4B37DA48BD5F46A31F4A00
+      8513509C3D948C7B7DA356909149D1DC264395C0DE52043618BF2738EFD0A5D4
+      1405FDCD339D7B2312102461916315E36CAC51453C7B14CCA34B8C546A039CAF
+      9A36B1A49C00E0255B5E59989F6B40C0C9C21E0EB322F7E8D9B76815A957FC06
+      EA00E35D73DED25F401EDB976ECCF5E11F0F04649F8CFBCBC3F26351B6C8D81F
+      A4B8E0AFD1AA328D7D054AB7C1519B123E17BCBA034CCE8EF6E4C097725AA41D
+      A49177892D638AFBA8FD3D06D6704310E3B04CDF0A666913B531AD7207FC6FA6
+      7D1F757DF0CB09FCC448CFA26E93AB29CEEAAC40D94A2A5DC30AB4C982E5B67F
+      1B3618D8FD0A021F3F966EDC67C1EFF79831E882BB9D279B44802EAE67730670
+      4DAE0F8B10DB66436D2403242AD641348B00481E637E31D832FBE0FE681A316C
+      95CDB95632B98A7E0E3FAE4D42529EA67865942DBFEC5323B598768B7B4BECD7
+      0BC1973386C65FC5340B91A768CDFD4B6B7ED9FAC634633E2FE029CC190E8E15
+      14225D906E788DC811C1C498580F4E34E9C0447549566F55282B295CEE996E94
+      9145EE845F1B6F9D5D51116B89261F993956D8A3754B2E4AC831A62653190F6C
+      7D57B814CFDB5A890730ADA249E9E1B84F8DB90AED13B8C29E49F7D921427E90
+      1CF4BDD6BCB2F7E2299FD0B1B95A6B908F4A865946A1734A80EBA74A81F9569F
+      EF69F6E02177BCF524E5E468CDC28B32B9497D886689E95465EB14033F4E643F
+      6735AB0B71F7FEEF13AD2FA96787E5E25EADDC6EFF640E4C918C5D91AC7D87FA
+      32966C7D1311BCE4F8F7EEA55D0ABE4D5AAA382587A7839D2EEADEC50B55CF99
+      8FD0C9A0A6B262CD3605B7B6034EEADCA7F4F9434DC1BB19339D4753D1CF9411
+      D0405E70B471F9955E4C882CCE652721D13618589117231FE2A1CB0972665592
+      6B15AED3E67D914E77A442FE0F6724BE5B75E29AC60000000049454E44AE4260
+      82}
   end
   end
   object Label1: TLabel
   object Label1: TLabel
     Left = 90
     Left = 90
     Top = 15
     Top = 15
-    Width = 382
+    Width = 384
     Height = 25
     Height = 25
-    Caption = 'Pascal Coin Wallet, Miner && Explorer'
+    Caption = 'Pascal full node Wallet (Classic GUI)'
     Font.Charset = DEFAULT_CHARSET
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clBlack
     Font.Color = clBlack
     Font.Height = -21
     Font.Height = -21
@@ -260,9 +221,11 @@ object FRMAbout: TFRMAbout
       'Based on Albert Molina original source code'
       'Based on Albert Molina original source code'
       ''
       ''
       
       
-        'Pascal Coin is P2P cryptocurrency without the need for historica' +
-        'l operations. This '
-      'software comprises a node within the PascalCoin network.'
+        'Pascal (aka Pascal Coin) is P2P cryptocurrency without the need ' +
+        'for historical '
+      
+        'operations. This software comprises a node within the Pascal net' +
+        'work.'
       ''
       ''
       
       
         'Distributed under the MIT software license, see the accompanying' +
         'Distributed under the MIT software license, see the accompanying' +

+ 82 - 135
src/gui-classic/UFRMAbout.lfm

@@ -1,7 +1,7 @@
 object FRMAbout: TFRMAbout
 object FRMAbout: TFRMAbout
-  Left = 764
+  Left = 781
   Height = 405
   Height = 405
-  Top = 516
+  Top = 436
   Width = 585
   Width = 585
   ActiveControl = bbClose
   ActiveControl = bbClose
   BorderIcons = [biSystemMenu]
   BorderIcons = [biSystemMenu]
@@ -18,147 +18,94 @@ object FRMAbout: TFRMAbout
   LCLVersion = '1.8.0.6'
   LCLVersion = '1.8.0.6'
   object Image1: TImage
   object Image1: TImage
     Left = 15
     Left = 15
-    Height = 60
+    Height = 64
     Top = 15
     Top = 15
-    Width = 60
+    Width = 64
     AutoSize = True
     AutoSize = True
     Picture.Data = {
     Picture.Data = {
-      1754506F727461626C654E6574776F726B47726170686963E20F000089504E47
-      0D0A1A0A0000000D494844520000003C0000003C08060000003AFCD972000000
-      0473424954080808087C086488000000097048597300000B1200000B1201D2DD
-      7EFC0000001C74455874536F6674776172650041646F62652046697265776F72
-      6B7320435336E8BCB28C00000F5C494441546881D59B7D8C5DC579879F7766CE
-      39F7DEFDBE8B1D7B8D61B13160B05D2F5027C68E8190409B929084006D5A42A3
-      5651D4964655152591924292A65594A66A451B45AA541250207C8990A4348921
-      14624330181BB049B0F1DAF1826D6C76D7FB79EF39673EFAC75DDB6B7BEFB26B
-      AF4DFB938E567B66CE9C79EECCBCF3CE9C772484C0A9D4AEED5BCE3346AF515A
-      AD8AE3C2F242A9A9B3586A6A05A88C0E1DAC568676656975B3777EBDB5EEA9CE
-      454BB69DCAFAC84C036FD9B4A1496B59A995BE526BBD421BBDC0187D86D6BA10
-      25455D28354BB1A11980CAC820D5CA60C8AB15E79CAB5AEBDE72D6753BE73638
-      EF9EF02E3C7351D78AA199ACDF8C016F7A76DD2AADD5A7B4D61F525ACF56DAA0
-      4C828E628C5118E589B5A25048282645002A69856A9A92598FF50A6B3D2ECFF0
-      36C53B8B776EBF73EEC7CEF93BBBDEBD7AFD4CD4F3A48137FCF2890F6AAD3EA7
-      B4BE42698D444594D614C228C5BC9742BE9F24EBC564032857417C8E040F4010
-      4550115E17B1710B69DC4E359A4D256AA72A25BC7384BC82770EEFDCFF38E7BF
-      B9E2BD573EFA8E00AF7BFC67CBB5D2FFA88DFA3DA5234254249194966C0F2DD5
-      1D94AA7B307608820384200A50040464AC90004200FCD88F104034D634315AE8
-      60A0B09081B8833424485EC5BB1C67DD4F9D775F5C7DD5359B4F1BF0533F7FF4
-      36A5F49795311A53A228156667DB28575FA590F703E0C510449F489D90E050C1
-      02508DDAE82B9CCFFEF83C2AA10876146FADF3DE7D6DCDD51FFCCAF4CB9E06F0
-      638FFEF82C2572B7D66A0DBA80D14287DB4E47F56512378097082F66BA759854
-      2A5854C849750B7B0A4BD9A317615D0057C539FF940FE1E6F77FF043BBA75ADE
-      94817FFEA31FAE524A1E545ACFF1A6481B7D2CCA37D2ECF6E289F027D89A5395
-      0A0E45CEA09ECBF6E812FA29A36C05EFDC3EEFC3C7AFFEF047A664D4A604FCDF
-      0F3F74AD52EA21A54D1C4CC2D9BCC6B976133A58ACC4270D2363637AA2AA8800
-      010E259990E1C4B0C374B18B73919A45CFBCF7D7FFFE47AFFFC9DBBEEBED807F
-      F2D003D76AA51E411BA574C4856C667ED8862322A0A689768C42C01423C65B31
-      5BC90FFF02A61483F3A01564169B7B6A36CFA3C9E991F37885E5789783B3DE79
-      7FDDB5D7DF3029F4A4C03F7AE0BE954AE449D151A4B4A64B3DCF1C7E8BA57072
-      A063D2C588B5BFDAC5D7EEDD08085FFAC32EAE5EB9005FC95089E1B63B9F65ED
-      A6D7995B2EF1EDBF5AC3EC72099FBBC3CF1BAAECE36C36F94B6B5398CB731FC2
-      E51FBEE1A667EABDB36E133D7CDF3DF308E191808A028AE5F21C73D87D18564E
-      F6129048F34F0FBDC8BAADFB58B7752F0FAEDD8284149DC4BC796098AFDDBB91
-      5FFDE64D1E7E7A275BB774A33447FA3F60293087DD2C97E70828022A2284471E
-      BEEF9E79D302FEC177EF02CF030166E51896E897982B3D58925A374C0CBA2146
-      974EE26A4C20736CDF3370F8BDEFBFE80C183D08B1A3FBCD231E6553C1B0627E
-      030CF7611A0CA621412B19834E982B3D2CD12F6131049885E7811F7CF7EE0981
-      279C43A248DD06ACCC8839DFECA45377634302014C7391A737EEE62BDFDFC8C9
-      78694A09D5CCB17BFFF0E17BDFFA593777AEEB01A5E8E9CF0EDF773E70FDBF6F
-      A46884650BCEE08A15E7B2FAA23924CD05C2708AF5319DBA9B41D3C8ABD9D918
-      AA2BA3486E038E9BA78F1BC3F7DFF5BD0B95522F7B9DA833A2212E2F3C8B10F0
-      41611A225EDF37C4257FF900FB0F564E187626B4685E0BB75EB7945B3FB20C42
-      C0A53563F764F5DDBC9537A15CEABDF74B6FFCE42DAF8C7F6EA22E7D474094C2
-      F33BF1AFD1E2F0284CACA9562DD7FDDDA3EF382CC0F63706F8EB6FAFE39A2FFC
-      98E1D4A2E2188D6579FC0A0A4F401470C7B1CF1D057CDFF7EEFC4020BC2F2762
-      61D443BBEEC50683520205C3CDFFB0961776BC75DAA0A6A29FBFD0C3CD7FFF53
-      C4809384B2EE6361D4434E0484F7DDF7BD3B3F303EFF51C0DE87DB435094A4CA
-      05C92E7C3008A01A623E77C7533CB8BEFB34A24C5D3FDCD0C363BFD8822E28BC
-      445C90ECA224557C50781F6E1F9FF7F018FED76F7C6345B9DCF6ACC44D2C6BD8
-      C5B2E2366C8831C5889FAEDFC12DDF7C9C389E593F793A1281FD0329A9F513A6
-      FFF97BCFE43FFE6615366AC1A89C974616F1D26827211BA2AFB7EFDD9FFDC217
-      36C0382B9D65D9677C8092CA3827DE4B184BB2A965C5A2596CFFD6D5283CB5A1
-      716AB7858E9500716278DFD7D7B16E5BDF84790E8C58A856F1C339A15C664161
-      1FAF563B180D9065F9678023C037DFF847A5C5172CBACE4BC4DCA88F263D820D
-      63BF850FB4B636228D31BEEF00F843D0471400AD0489267135738FF501A99F63
-      526015EBC373EF44D24A4029425A25EFEBA3B1ECE988FBD9566D21CBB3EBFEF8
-      E33796BEFFE0FDA306A0A9A9719573BE8C28CE4A0E1C5798770E7404AD67E0FA
-      0ED4FCDB711E8F085453C7F6DF8ED4ADD0BC7291D68688E0A7DF3B04887D9870
-      71719CC6A043FF01E637EC67BB2AE39C2B373535AE02D61A8010FC553E40834A
-      99150DE2C3044B3DEF218A51E559E35ABA061D1723D63EB7876BFFF9D9BAF558
-      F7A5D5AC5A7C0669D54E1B388C511B3DC5FEA11436CD690FDD9454273E2882F7
-      57016B1580736E85174D9B19A6A8527CBD8EE73D32068D5247D6735A786EE7C1
-      BAEF6F2D452C9EDB88CF27363853954C633C783114F3015A7D1F5E199CF72B00
-      D455EF5DB3D07BBF30A02947C3206F53A989A07DE0855D03751FB9685E13E596
-      02D69D04B0C8D4BAF43829F194E903D178EF175EBEF2B285AA542A5D1942282B
-      8156330253312BE3A0B5D1A4C3292FF70CD6CDDED5D902B13A61DB9E249ABC6A
-      7975EFF0DB673E4A424B38880878EFCB0D0D0D571A11591D0205AD024D268330
-      C57E33066D66BD8B1D5B77B2BBB7BEBBF9FE0B6741292299AEC11AEBC3C32319
-      7F7BD7CBBCD15FAD5F9D099ADFA36894510C9E000544561B6079001D89A7A0EC
-      D481A166B89A8ABC32A0267CE121FDDB633BB9F7D937F0D304168191D4B169D7
-      007B0ED6870588B43A6E907B84826418B184209AC0721342382704C4284FA4FC
-      F4BB9D82E75F9BDCBF7E6CEBF153DD4C6BCDF9ED13DC152271185CED1FC2390A
-      6806D012D012A60F6C3D1B5F3BF54093697673C22756CDC7558E9EF242008D1F
-      CFD57C52BB705A09D5C12A5B764DECEE9D0EC55A71CF5F5C42B925C1D6F1B3C7
-      4B0183002E082EC8B45C3F8934DDFB0679A3B7BE87752AB562611B4F7E793557
-      75CD211DC98F9B6044C0A1C6730D1A11D929C232EB95E45E519C4E9BC79A9776
-      4EDEBA4D458391B12F48213038AEDB35170D4AA4E69AE69E4A56DB91D44A682A
-      9AA3D628815A6BCE6F2FF0BB0BDAB8EEE2395CB36C36CA28D2A1ACCE6C1AC883
-      C6A2C78A909D06D82C70511E94A97A43B354A76EA995F0FCF6FAE3775E5B810D
-      B7AF218914BA6078605D0F9FFECF1701E868ADA515624594183E71C773FCD7E6
-      3701F893CBCEE45FFE6C39D9F0917DAD40CD12971B2328187081BC62C9735BD7
-      755004AA21C606834870089B4D08AC13E17AE7A571C8C6CC2E4CCD6C09403EB9
-      C15A3ABF998EB98D848A459A62B6BC7E6427F2BCB98DCCEB6884D4E1AC67EBB8
-      B4F72C6CA3B539211CB33A0A21905B8F1FCA988A149EE150C2A210A812C23A35
-      3A3AF28488F4F900076D03535DEB6AAD183E58E195DFF6D7CD7349672B0099F5
-      901FEDA15FBD64160470D6336AFDE1A55FA485CBCE2B132A3999F5475DB90B4C
-      6F2A0F0C482B218052AA6F6464E409F3F82F9FDAF1E95BFE7487E0CEEACB5B20
-      4C7110479AD7BADF62FF407D0FEBE2CE160ED5301BC9F9FAC717F3D14BE6A294
-      B062412BD9484608508C354F7CF132B6BF39C2ECE6840BE73591A5AE6EB953C7
-      55F45186504529B5E3C9679EDE6100B4D61B547057F6DB462A3E2121ABBF623A
-      A458F362776FDD64AD84256736C3D80A29844012292E5F320B803C7587BD3397
-      7BE6978BCC7F5703B8409A9D3CACC2334A03FDD2860A3D68A536D4EE0322EA71
-      2530E2130EE4CD2899C20B65728375767B91B3DB8B47CD8DCE07D2AA25ADDAA3
-      5D5181D47AD28A9D11580083E580CCA242A91677A0D4E330063C3434BC5E6BD5
-      47F0EC4E67BD6D6102905A5E98C4A55C3ABF99A421C29DC00EC74CA947CE2204
-      8FD6AA6F6870783D8C01DF7DFFBDA351143DA242CEDEBCCC906B404FB22ED646
-      31D03FCAAF7BEA1BAC8B3B5B61923DA853298D63505AD8A73A502E258EE247BE
-      FFD0FDA3306E5F3A8EE3EF2881D4C7ECCCE6224CB21513695E7D6380FEE1B46E
-      968B3B5BC0BD33AD6BC8D9A9CE25A5801288E3E83B87D20E037FF6F39FDF608C
-      79DA90D39D7650F1A5DAB6EC448A349BBBEB77E7482B2EEA68827C66C6E374A4
-      710C4B33BBF4799890618C79FAD09E341CF3E54129B95DC4331A0AFC26ED4449
-      9D56162635580B669798DF5EAC059F9C669990B3CD2C65541A50389492DBC7A7
-      1F057CD32D9F5A2BC82F227276E4F3E975ED9863A04580AA65D324DF9896CD6F
-      C6944EBFC18A42C601DDC1CE6831514801F9C54DB77C6AEDF83C137919B70AC1
-      7B142F668B71411FD5B5B556F4F68EF0EAEBF577292F3DA7754A5B63332985C7
-      89E1E5C265781442F0C0ADC7E73B46377EF2965744E4AB11965EDFC656BBF8E8
-      AE9D185EE8EE65A892D77D79D7592D604F6FEB9A90B2B5B8923E3D07137244E4
-      ABC77E1B863A110079EEBF9224EA9A986CE56BF61C9AD5309D6A079684102078
-      C70D97CEA96DD31E5BA012969ED58C9B2107622A4AFC28DDC52E7626CB886D05
-      07CFE47998304AAF6E14CFC3F7DD334F8BDA24CACC121D718979BE16E711124C
-      A4211F82E1A131E8B160AA31D98A3DE1EF48D355EC47D953B8804D8DD7105C46
-      70F6800BBEEBA3377DE28D89F29F78D89252F8817EC2C8D0842D7DEA15887D85
-      BDC5C5BCD87C0DDE3A82CB4E3C6C09E0C337DCF40C221F53780F8117E53DF4C8
-      F91852C43B544B1BD2D004FEF4CEB7121C91AFB0BBF1525E6EFB03080185F388
-      7C6C32D8DAB327137A88C3AAE4B4B6B4F6295E22BACB57B0BBD485D82ADEE633
-      177A78481307973E4FB3DB8757097670F09442AB60D13E65A0D44977FB07E88F
-      E6A2B2E153135C7A4813860FDBED74645B48FC20767018375A995168F139DA67
-      A4493BFBCA97B1B7B90BEB03E495531B3E3C5E130688E7DB69AF6E23EADD4118
-      1EC29BE4E402C45D6DDF2A2DCEA6AF7C316FB57451518D900D9FBE00F1F19AF8
-      0840468BDD43D3FE1728F66FC76403E073401194AE45DFCAA1684BA8C5050704
-      8F78077850113669A5D2D4C960DB12061B17924A11C946F136C3597FFA8F008C
-      D744873C741491D8210A957D14465E271EDD87AEF6A2F311C46547ACBAD2041D
-      E3A2065CA19DAC34876AC399548B73484D13DE5A7C5EA9FD7DA70F791CAB098F
-      F14405749CD48EF1E088B55088638A492D22B79256A9E619990D5874ED184F96
-      E2F3EAFFDD633CC7EA6D0F6A35344BB13476506B7490EAE8FFD3835AF534E5A3
-      78D6AFB7EED41FC5FB5F0935D0C88CEACBC00000000049454E44AE426082
+      1754506F727461626C654E6574776F726B477261706869632509000089504E47
+      0D0A1A0A0000000D4948445200000040000000400806000000AA6971DE000000
+      0467414D410000B18F0BFC6105000000097048597300000EC200000EC2011528
+      4A800000001874455874536F667477617265007061696E742E6E657420342E31
+      2E36FD4E09E8000008A349444154785ED59B7B8C54D51DC7873E6C6BAAF58FA6
+      AD8DB23BE72E62E92334565BFB02FB480D6A5A5B5762D5A8AD4DB4416D6CDAD8
+      6AD9B6E98B1A1677EE1D96557141ADAB2C60B12162770B2CD294E862A1A0222A
+      161528C8222C7BDF8FD3EF99B9C3CE99FB9BBBF35AE7F24B3ED9ECF99DDF39BF
+      DFB9E77DE7A638E7934BC78C539CC5CA79636AFA463DC3EE3654D66FAA6C93A9
+      2ADB0D55D96D68CA4BF8BB5D57D990A9B14775555980BFD78F692D3379C7ACF7
+      9065361032B15E8CAC723682BDD5D0D83A04AC9B9AC26B01B6A328E36F68B09B
+      D0201FA3EAAA1732B116867BCE7BAFA1A6DBF13407F1547D2AA07A4043B8287B
+      ADDE95BE8CAF48BD9BF2A116C8C4AA40E06646F9119ED66B94E39301EADA6564
+      D2D734A221C8C44A19D3D81C31862927DF19D83627DB3A8BF2AD52C8C409E939
+      E7C398B41EA39D7A67C1B0082C8DDD1774B59D4EFA3A0164621C98BD67A3E5F7
+      51CE34130C8B57F56CFA7CCAE738C8C47220F85BC46444399004E09B8586B88E
+      F2BD1C646294D4143CF58554A58DC47A640EB79FBA8DDB4F5C8F60DA227A7BD5
+      DC9CDE5AD91ED115C09C14A021EE426853E85864C84499D4144B53BAA9CA1ACA
+      83B339F75C5499177BE8D792DE5A7343A8810401B7565F2DE9A3A4FF849C443C
+      32646231D88474D215341667E0A7A86E5C9CA10E49EF6E5D126AF262ADBE4AD2
+      5358AA7227B292711520130B582ABB8D2A783270B7F5A2CA71B1575E21E9BDBD
+      4F871A48E071A3E733929E42AC1086D67A2D2CC8F80464A2C0CC2A176142F122
+      052FFB0AF7DF789AFB6FFEABB19823A8765CFC03C3923E708C5003F1DD5C9AF7
+      FA66EEEEF80B77067FC6CD07BE20FB398E21CE22B022E324138F2F661F41D7DF
+      5F5A98B1E4D3DC7FEB056449A0A057787B87B8B5EA4AC9E79CDF2A7BF9AD05D3
+      4F43AE48AC9104010CFA238568D3B8F7EA00D4499780BBCFF77173F1B9B2FFAA
+      22269148AC910471D828362CE06EED81FAE411EF9575D2522A0E6846867D092A
+      295EE99FDD5D6DEF13DDA5387081186362E939D9C45E7FA714077AC130EF48BD
+      0B2ABA01B076DE5C6C201063CA772DA84F3EF18FBD1ED9506155B812AA6803EC
+      EC98718AAE2A7B8B339BF7CECCCFC2875F4A266307E17ABC587D73E40650D976
+      847B629778A2018C8C32B738E3C980BBF977703D5EEC35D7466DD5F437A12A69
+      008D6D88644C38353780C6564235DE0047B4D696C9B8C69A6C6A6D00716A7C7B
+      51CB1950E71B4057D94F4A3355CDF259DCDB33108B33703B6D5B23E2BC3091D0
+      3D203719E6B6C8F9EEAFB2A7A84CD560FF5D3ECC50228EB2946DAD381BE78725
+      9797720D00FAA0460360F64703D47C755DC0DDBE3C5F638C885E42D9D64A5D0D
+      A02A07A04EA5741C14C80C55E2EDDF9AAFB18C88C30E75C9510FCEA6DF86A597
+      97981EC0CDCCD474CACCA47F482AABC0C0BEDB77CCB04A5ABCBD9B48DB7AF05E
+      E80F4B2F2F710D80B9EF7271CFF7674A59157D9786D59517E7598DB6AD116BC5
+      777850C10E35AE01B01ADC215680BAAFB7EDF5BF0CAB2B2FCE335DDC7EFCAA3A
+      F93EB7D7CDE3EE7F1EE2DC8DEF7105B1FF7A0DE9B3009BBFEE866C80DC9D8F86
+      D5254C7C9F9BBD5F247DCEA12AABC412F81CA9AC02FFD0F3618DC9127FFF30E9
+      6F019C0E07C5A5E74E4A59314B3E25DDE62646F0F427BC3855D9461C81951D11
+      451558FDDF0B6B4C9204DCD9FC47D25F09D100E806CF90CA0A71867E13569A0C
+      114764FBC979A4AFA560FE5B57F736D8DBB53AACBA898215C1DFB7853B1BEEC2
+      90FC24E927858EEDB0E801BD94B252BC9157422F68F147F7E796AE62FC433B43
+      2D2440775D7F87A4E74557E481352AE98A719EFC31B71EFB765541CBB085A207
+      CCA7951570EFCCDC641327FECB6B2376FCF8BE502BBAEC2174C5719D78E121AE
+      B80BE2BDB945B26D247A469997D2B5F41594B212ECC7AF0EDD2C2FA59391B554
+      BCC11EBF60F5FEBB51D6AF6C0F357971FF7DBFA46F2819F6B5D4D1CEA98C5456
+      80B359BC7F8C97D2A5C84077F5DF7E2DAFC493B6077F2EE9C589D1378EE4D58E
+      C1AD5573657D831017407C51CB19291C08A7601844DE02558287EE1D2BD81F88
+      B749A57646F61C6EF55EC8CDFB3E1BD1E5F4DD33F2FA9EA86DA340CC6222CA5F
+      88603D7C90CA148718B7FEB1F1B14C893FB29BB44D0246267D0F5C2CDC08A5DB
+      A94CB12CBD00A6F12F4BDC1757D3B689807D1D2EE61BE0A036E383E805C7E98C
+      34F6133FC8051927A53F72480C2A3B50F8895DAE010418134BC9CC6570B6748A
+      1863C5EAFF2E69DB7CD8DD702F17F78906D055F6398CEB803688E2ED1984598C
+      B8766E32A36C9B0B73CDAE366C464A1A40805EB09E369211777B62031327DEC1
+      1DA46DF3612BE0DE8998E506D05ABF5A512F58F665648F1777471F6DDB44F080
+      3D7B31C3F9BD4C03088C0C5B43191763AFBD1959E3C5FEC72F48DB668287FB00
+      5C93E295FE111CC5F84046832AA0803BDC8DACF162F55D42DA360F3672FC9EF4
+      47E19A14AFF44F01EC0B6EA70BC9237E9C1427BEADE7767B946DB340F7277F41
+      1A49C88135D2D0D8005590999D8623EA51642B2FE2250969DB2410BC788140C6
+      4A260AC4171AE8366F9416663D243650F1E26E5B26D9341304BFEB480FFB10DC
+      22E324130BE45E9B95EE101FFE06779FCDC662276603C40E5B8B5AA753B11520
+      138B3155E55BE27D3A5D4182C1833354E5422AA662C8C452AC6CFA1214669215
+      2512760C0F6E36154B29642285D9A55C84428FD015268AFF55F3E10499588ED1
+      6CCB27C4A442549A10D873E6A29656CAF7729089711CEE6A3B1DE3EB61DA81E6
+      80E11918997437EF6D793FE5731C646225E85DE232B5F9DF0E6182DE83BF1753
+      3E5602995829F9DEA02C9868EB3C1960288E82F9C1C2B33E40F956296462B58C
+      754E3D13CE74E6665FC2D946827A4630047F2F3EDDA37CA91632B15682FBA79F
+      A6ABEC2638F84FF48A86FDEE10417B38A56E40B937ECEB38F354AAEE5A21131B
+      41A09EFD71534DDF081E11E3B4A27B8610D1786037025E8EE0AF131F70507534
+      02327152C07E5CD7A67D5EFC26D9D2D8AD62FC62C8FC41746734D0AF74F14DA2
+      DAD62ED6F0725F77341E9EFA3F3F3AD63CC0721F160000000049454E44AE4260
+      82
     }
     }
   end
   end
   object Label1: TLabel
   object Label1: TLabel
     Left = 90
     Left = 90
     Height = 25
     Height = 25
     Top = 15
     Top = 15
-    Width = 382
-    Caption = 'Pascal Coin Wallet, Miner && Explorer'
+    Width = 384
+    Caption = 'Pascal full node Wallet (Classic GUI)'
     Font.Color = clBlack
     Font.Color = clBlack
     Font.Height = -21
     Font.Height = -21
     Font.Name = 'Tahoma'
     Font.Name = 'Tahoma'
@@ -253,7 +200,7 @@ object FRMAbout: TFRMAbout
       'Copyright (c) 2016 - 2019 PascalCoin developers'
       'Copyright (c) 2016 - 2019 PascalCoin developers'
       'Based on Albert Molina original source code'
       'Based on Albert Molina original source code'
       ''
       ''
-      'Pascal Coin is P2P cryptocurrency without the need for historical operations. This software comprises a node within the PascalCoin network.'
+      'Pascal (aka Pascal Coin) is P2P cryptocurrency without the need for historical operations. This software comprises a node within the Pascal network.'
       ''
       ''
       'Distributed under the MIT software license, see the accompanying file LICENSE  or visit http://www.opensource.org/licenses/mit-license.php.'
       'Distributed under the MIT software license, see the accompanying file LICENSE  or visit http://www.opensource.org/licenses/mit-license.php.'
       ''
       ''

+ 96 - 162
src/gui-classic/UFRMWallet.dfm

@@ -1,7 +1,7 @@
 object FRMWallet: TFRMWallet
 object FRMWallet: TFRMWallet
   Left = 389
   Left = 389
   Top = 201
   Top = 201
-  Caption = 'Pascal Coin Wallet, JSON-RPC Miner & Explorer'
+  Caption = 'Pascal full node Wallet (Classic GUI)'
   ClientHeight = 580
   ClientHeight = 580
   ClientWidth = 865
   ClientWidth = 865
   Color = clBtnFace
   Color = clBtnFace
@@ -30,140 +30,102 @@ object FRMWallet: TFRMWallet
     object Image1: TImage
     object Image1: TImage
       Left = 15
       Left = 15
       Top = 15
       Top = 15
-      Width = 62
-      Height = 62
+      Width = 64
+      Height = 64
+      AutoSize = True
       Picture.Data = {
       Picture.Data = {
-        0954506E67496D61676589504E470D0A1A0A0000000D494844520000003C0000
-        003C08060000003AFCD9720000000473424954080808087C0864880000000970
-        48597300000B1200000B1201D2DD7EFC0000001C74455874536F667477617265
-        0041646F62652046697265776F726B7320435336E8BCB28C00000FBA49444154
-        78DAD59B095C55D79DC77F7779F72DF0001F48004571C17D091A318AC11D9D8C
-        4B1A6B4D9A38666BBA24699A34B669D3345A5BA78E6DDA8C33934C938989ADCD
-        A2C4246615B728EA68558C1A10104454400494F5DD77DF5DE67FEE7B1AC4FB14
-        788A99FF87F7B9EFC33DF7DDFBBDE77FFEDB3987330C033752CA8A8F0E104521
-        9317F80C4972DCEA70B9539C2E770C3BE76D69BC207B1BCB149F7C48D7F45DAA
-        AAED48491D5674239F87BBDEC047F3F6B905811B27F0C2644110D20551E84BC0
-        71F4DD61B33B05872B8A734644996DBDCD0D90BD0D865FF66A243201D768AA56
-        4ADFF769BAB64DD78C3D43D3D21BBF91C0797B733304817F90C066F38210CF0B
-        2278D10EC12641147988BC0E49E0E170D8E1B43B03C03E2F649F0F8AAA43D579
-        A874D4FC0A74D5075D53E9A35513FC464DD357A78D9DB0EB1B01BC6FE7B63B09
-        7431414EA20F389B13ECE8305AE0F4D7C2E1AF865DA985A8D483D7BCE0743FDD
-        5437AF35381E066F832E38A14AD1F049B1906DF1F0DAE8C8B918300CBFD73CD2
-        673B81AF4CBF63F22737053877CBE7B792DAFEAB20F23379C1068340ED9C0FD1
-        4A05A2E512B8E40A882A69A3A1B1DB98700001D277F6172036CFD0173DF812D8
-        3F04A8A21B2D8E24D43BFAA15E4A82CFB083F3CB04ED07A9FC67A4EEBF983075
-        C6A12E03DEB1E99317785E789EA7C109D10527E745BC52048F5C483D7ADE6CA3
-        7322410A9DEC050DBCA19ADF655B37D43906A25A1A00AF4143416D219557355D
-        D7966566DDB9F486026FFE64632F9EE3FE4A2A9C09C10151E090A41523493E02
-        BB564F903613F47A0A03E70D3F7C42342A1CC35121A442D5E8993519A4E23B74
-        C35838EDCED9E5D71D78D387EF67F03CB79EC667822E3A41EF1DA9FE0388D22A
-        49211968E77AB3FDE0D4EBF0A3414844B16D34CEC3035E35C77795AE1BDFCE9A
-        7357BB8C5ABB803FDD903D8BE7F96CB2BC924196B7378EA3BF9A0781DEBECA49
-        61C370C1316DF528E639C3FC3345341468A44525621ACAD01F5CC0A22BBAAECF
-        FBA76FCDFB286CE08FB2D7CD1278FE03907562C669080E21D9288246BD6A800F
-        8F94EE2D3A6D686DC554AFFFD21B105DF432353266E4CEC87741F5EB08D83C1D
-        02F5F6296E00F271AB69CCC89A51ECA2CF9D356FFE55A1AF0AFCE1BA77C6D198
-        FD82136C36E66AD2F8FD48C049A87084071A14816073FEB70CCBDE3A6042FFEA
-        9E34648DEB0BDDAB80B78B7861F55EE4E49D46A2C785FF7A3C13F174D4FDDAA5
-        EB45C8A8227DCBD36F0BB830CDEFA7313D71CEFC057B3A0CBCE19DBFF710383E
-        8FE3C5EE048CD1E27E2472A708D61EB8305C5AFA01C1ED40D64FDE33A1983C92
-        D90BAF3E3F833ADA8EAA730D48BC6FCDA5E69B7F7907A64E1E06D5A75FA6FB22
-        7CA834927140BD8D01C3D0D5739AA1A77D6BC177CFB41BF8ED37D6C06E177753
-        FC3B4EE31D18251D410A5F1280656AE82035A4E809E1C42C64E1412ADAE7FE35
-        283B1B881EDFFEE1282C98D90F888EC3EE8355C8787A83F97FB743C4993F4D83
-        3B211A8889A3FB923F272DD074E3127499DE0F79CA70F03AF3D7FA1E9F4F1B7F
-        CF030BDB079CBDF66FE467F9252AB99E81D2498CB01D866A4826A018E5C0EE03
-        E558BAF600C289D2C8E2435634EC3C4A563EF83B63FAC6C01361632771EABC82
-        FCF2804F774902320678E014398CE81B8749E9FD31616802ECF42C46938FC075
-        889C1F87FD2350A8F486482E8B8CD89279F7DD7F859FBE02F8DD356F0E21D823
-        BA60E7E36C8D98E8D86B46433ABD55911EE6745523463FB60ED517BC61746FF8
-        92DA231A4FCC1D8E27EE1A616A9DE60B18BB2FE4B1A8F1BB298CF511B33EFC3B
-        FFB228FF5AC05B385E98C251F03F39623F6285F3D4BB22449B00992C66C68FB3
-        71B0A4E6A6C2B696AC51C9C85E321311928DC24F2FEAF46ED8DA3C86C6B34AE3
-        59DB4AC0534302BFF3E6EAE9F4963669BC13831DE54873E69BAACCD48F8F9030
-        FFB98FB17E57E9CD66BC42EE4A4FC686E5B329F862EE4A469E77080AE45E1075
-        2F1B76590B163D986309FCD6EAD77791551EEF100DCC88DA47C98062FA5AC16D
-        C7E2553BF087EC2F6F365B48C9F96526A64D19069D54DBA7D9F079433A649563
-        567BF7BD0F3E947105F04B2B56A47B3CDDF672921B2322CA30C25964F62E0B0C
-        3EDB5582452BB74092AE6F9CDC1161B14875BD0F3E55B73CFFC81D3DF1EA5319
-        506DD1E440C88035A7E2704B0A0CA51175B575639F7CF6D97D9701AF5CB6ECF5
-        F85B6E79D0E5B46366F401440A5E6864A840EADC50DF02B1B18EFA9A453A2CBA
-        BAB165A12B60E923512032E577B9C82DAAB36C33775402DE7F662C0564026C1E
-        0F9A75173EBD300A2D5E1FAAABCEAE5EFCEBE71FBA04BCF03BF7BA060F4A3D95
-        98DCC793EABE8009EEA3A6A1BA286662AF2AD0EBCE51DEA77F1DFC0685E10BF4
-        6238DB55424D3FAB6A189D0A58D8353CF9E2494B77E08B63B5966DEEBE2D11D9
-        CFDC0E5FA30F9CDD01C913835D4DC351D440595679695D7E4161F2DAF5EFB698
-        C03F7AF87BD313136ED9D4B34F2AA6C616A29774F632E00035C1F8C9D95B40B3
-        AFAC4C535CD51CF2A17B789C8821B766E81DD70EB3870978E26F766247E13580
-        9BFDE6F3490E01A72286616BDD2094971C43456555D62BAB5FCF31817FF8D0C3
-        BF4F4848FCF9E0FEBD303BFE30C5530AAB415CF9AB046DF8AFEC69BBCB868FFF
-        5181592FEE0DF9D0B9BF9A808CC171F0C96A27FA98EEE11431F5B7B9D89A6FED
-        122F0346208F56A4687CAC4E417E51392A2B4EAFF8EF37DF78D6047E74D1035B
-        137BF69E3C616034A6C7159805B59062016D774B58F2D65758BAA1D0F292187A
-        21252BA7520F4BF06B3A3A230C781A8DE12D5FB50F98898D82E1CDC644E496CA
-        4CADB7BDF6D73553B82913EEE8D72725656B52AFFEBDE60E0346C75036A45DC3
-        1AB781B6474A98B3620F36E6555936CF48F520F7854C283EB5D3E68E69D1D465
-        3BDBDDC3E635E456F7EB23F1E109374E9F282C2F292D9DC2CDCA9AF1487CF7EE
-        7F4A4E498D5C38B219FD226B09B81DD58B203477A186525115839EDD8EB29A16
-        CBA68F4FEF8355DF4B2383A2740ED64ED92F4B349ECEC199F3720780FD28D67A
-        E16F279371F2784153F5B9734F71B367CC7C232E36EEBE3EFDFA8BDF4FBB8078
-        7BD3D555BA0DB4080D855F9DC0909F6FB99404B495F79F4CC75C824653078183
-        36A2A959C14FD71CC15FB69F0CD9F4AED109D8B078DCE52ACD6938AB7BF05A59
-        2A8E1F2F54CFD5D4AC65C0876263E3460CECDF97FBD1A83A44893EB2D0ED771E
-        22E5B41B728EE1EEDF6D0AD966DAD0EE88A571AE77D04233DE669F86BCB27A54
-        5C90AFDA767E7A12DEFD29F570AB972A703A1A8D08BC5236100545A5464DCDB9
-        C34CA5EB6363BB470D1B9882C708D841518AD611E068079EFBCF5C2C7FE760C7
-        7AEF3ACBAA85C3F1F8ACD436C00645D676BC7C62208E149D444D4D7503033608
-        182307F53681454E25D5EC003059DE998B3FC0E7074EDD34D8F8283B0AFE6D2A
-        A2C957ABADBC002BFBAB9C0D2F970D425E61396A6BAA1116308BAE7C7E0DFD1F
-        7E0B676A9BDB75CDF516365FF5C9E2DB3175E42D81F1DBEAD14301775AA5458A
-        6FF34B6B30F407EFDE14D8F47EDDF012A9F2ED2CA0611EA0CD635BAA7438464B
-        A4B4F1ED4F0B70EF8ACD21DBB8296010B9E00C1259F106EFD79156149DE3E91C
-        334E32B91DAF12A84832CD61D7B576DA46B03793631D18D3B79B992CCC18110F
-        5EE4E16B512DAB8A96462B1CB7C40CD6337FFE027F7CCF3A4FEED1CD817D4B32
-        61A7A442A0F1B52EF7141E7D3DD036292670CE21F1B091A67C77D53FF0F1A1B3
-        E6B9451392F1E7876F85D2CA0031601B017B226D00FD16A921FC5E35A42B6462
-        E9966665CDA4C023AEC381077BA1824BC2E4A7DEC3F6C315966D66520F7C4A31
-        B4410FC6915B7AF29583F8F74D818AC92452C36D4B3341D93AABA1A3FFE22D97
-        029797178DC00FE60C80D1C66FB33098552ADBEBDD2C038F4E8596AC77E96D37
-        79FDE8F7D0DF2931B72EE83D470FFDDBFB8799E38B859F3FF99F43782908BC7C
-        FE60FCE2DB83A1B5F8D142C069CF6D47497533F52287FDBF9988E1BDA32914D5
-        AEF91C5707B6082D3B9C3C5C0476D870A8F02CD21E5F1FB24DF68FC7E0EEF13D
-        4DEBC9D140F513D8FE1317CC1A597ADF1873EC328D14681C56D679517CB6D974
-        31437AB8CDB6E18A441E27476F933C74283D6C0D1CE5C09B1F1CC1032F6EB33C
-        CF0C4FFEEFA7604062247CAD8C912805868B9F7AEFD2F8A3031BE7601F1A9B17
-        DB8723AC3AA3704E7C644C47C1F153A83CD32A3D6C5701A02D70B4134FACDC82
-        FFD878D4F27CDFEE2E1398416A9D48FAC315893AED24DF17DBF5F1283FCE0A00
-        955F1700AE55E2692BA6C122956635EADD05D629A15963FAD9E5C17C5703E70A
-        93705C4D4245D9F1BAFCFCC2E4B5D9C1120F9390453C0B61AB72EA1B7DE84306
-        EB7C93CFB2CDD2BB07E1D7F70CE9744A188E0894C1357391D824FEB375118F49
-        A832AD25B0D3867D472A31965C5228D9F8F458CC1A93444141D7F7B09DE2AB43
-        C2181CE547C290EBADCBB44CAC0AF1BAC5A43733587F597F08DF5FB5C3F2862C
-        40285C31057DE25D146B876F6D3B22AC776532569B6DB321EB029B42B52EC433
-        0935D572053045588F2ECFC1AB9F1558DE742059E6A3CB279BDFBBDA60D90D19
-        07A50C1CE38742D49AAF3ED5C224D464DAA50BD844B62462CC63EBB0BFF89CE5
-        4DAD92F1AE109BA1A05648C00EC79DD055FFB527D382C0D6D3A541D56606ABF6
-        82D734588D5EEBF1B962C110FC6CDEA02E3558E6AC08C94ED71CD4C2034E95DB
-        375DCA24E4843802097FCE9E32643D177AEDC8A6C5E3303D2D013E6FD7192CC9
-        F0E24B17B921713804B5B9FD13E24CAEB6E481250C39BB4BF0DA077981D98836
-        2252A0F1E27DC3D09D5247B59335E88E8A5D6F41A9330D5F3A330996DCA9A675
-        6CC90393908B5A0CBB39390E7F23D0D418840E2EA60A8A4AD95167E7913A2A12
-        C1563806212F72065964854D84777C51CB45B9EAB22502D5EBCFC3686EB4ECE9
-        1B2F06C17A51E91C8C2FA366909162CB9694CE2F5BBA28A117A64930782108DD
-        C0A618BB0C952D3E150D1F4E45DE866351934C8B0CCD1FFEC2B48B1272E92161
-        ABBCBD4B7B5AD07DE622D652CF2494BBD2983566C0D76FE9E145B15E5CBA1F51
-        5A157482561B1A6E28349B0D64B0F5AE1494C64EC7795B2278A5E9C62C2EBD28
-        96CB87D562242947C95236107413B416EF7585662BE8055D81CF1E8B2ACF7854
-        46A59906117EEF8D5D3EDC5A2C1788FB8B112B17C1565B0283ACB74EAA1FD602
-        712D10B4F89CF1A8F38C424D741ABC7C24C07AB5AB1688B716EB2D000AA2D50A
-        B8AB0FC279BED8DCE7009D051FBC69E0CCD5B7E60459AB3D008661AE8EE57456
-        E520BFCDDBA0DA63E075A7A0A1DB303444F6838F92014E612BE11556F0EBFA2D
-        00ADC56A93077931D8D54638BC5570349F86D4520541AE85E06F06C77A4E0F96
-        70D84B102468B608688E5828AE04C8113D213B294A13DDAC27E97D7903C79BBD
-        C9A3AD586EE3B13928D1B007B6F130474663DE214970DA03CB8FBD3E19B25F81
-        A21AE4DB85C0361E85ACB0B9A1E31BBA8DA7AD5C73A3564414E77405376AB534
-        406EF97FBA512B94B47B2B9EAAEF52B51BBF15EFFF000BB1F477942997640000
-        000049454E44AE426082}
+        0954506E67496D61676589504E470D0A1A0A0000000D49484452000000400000
+        00400806000000AA6971DE0000000467414D410000B18F0BFC61050000000970
+        48597300000EC200000EC20115284A800000001874455874536F667477617265
+        007061696E742E6E657420342E312E36FD4E09E800000AD54944415478DAD55B
+        0B7854C515FE67EEDD17848780402860B21BE4258A8116FD1004A4F889852282
+        A808A2541113146DB5AD521A3EABD54AA186243E2A55D17E060111A42A5A9487
+        F8E04D4185920DB18809280884ECFBCEF4DC0D6CB264F766B30F361EF86EF6EE
+        3DF3F8FF397BE6CCB9334C4A89944A415FB3BF93B79F4F139733C97A32862C06
+        7402581B6AD9060649FF3C7439C1192A85645F7326BFD2A0ED6AF95DD65E14AC
+        0FA4B27B2C1504B84B72BA494DDEC0384613B8218CB116F1D4437DAB26823630
+        897F694C7BAB655E4555B32560FB0B034D7D7CC7C7017C06757A388D324F6647
+        C9420290EC7D29C4732D320FBE8389526B1E0410708FF7C434C9E42334D259C9
+        041D950C29F7D3E54FB6CE075F4F94888408A829768CE6600B69B42F3E1FC023
+        50B15B61E27ED3BD07379C5F025EE8D9C1E50B1473C66E4A0FF07A14D06F839C
+        E662B3C67FCDEE3B702AE504788A728651A97F52D12EE9061F4E842C975CDEDC
+        E2DEF2AD292380C0CFA2DFFA0206A6A61B70441220BD749961CB77BE92640218
+        F314DBE7D3DF07530980B5EB09D6BE07E03D09ED7F1F074384FAC2330702199D
+        21ABBF85ACDA118584E0FFB9B6FCF2C71103B8180860CC5BEC2821AD7B52091E
+        ADBBC17AEB0780526B5CBE8DF320F6BC5AD78B6E436119FB8F332825BC6F4D81
+        FCF633830AC553D6BCF2DF254C80A7C8B180387820A5E049949EE3601A393F74
+        EFDF58006DCF6BA17BF5CA87A0E6CE08DD7B57DE4A046C69041CE658F2CB1E8F
+        9B006F91E37EC9D8DF520D3E08F0AA39502F9B16BAF7AD980851B533746F1AF3
+        3294EE57D5DED0D4EFFE7B2E98BFC6B04E7D8600D36EB7E51D7C359A4E54023C
+        2539C3A5901F5070A3843DC8E802F3354F20E97EB0FDC5E0D676A15B51B51DD0
+        FC751DED781998C976E66100A2721BA4D0204F7E0D796417F98C4D80EBBB4835
+        BB158E21A69965DB6326E0F4B38E8EAA865D64FA99618CAA2D60B971297887DE
+        C9059F0C21ABD00E6D46605B3164653856C25856E332E57678785F754C04B88B
+        1CCB68E427845542A1BDF9BA1228F691E986DA1813087CB914810DF3C852EA2C
+        88603E6FCB2F6BE0C81B10E02AB48FE10A5F7DAEA27AE5C3E484EE4E37BA9845
+        73AE85EFBDFCD0544A57012187DA6639374725E040610F4B572EF6D2E8E7D457
+        527A8D8769C453FA8C986E5C4D12DF477320BE2C0DDD13D4EDB6EF9D3F438114
+        1109A0606726851B25610C650E8069EC1270D5926E3C4D1671EA10BCAF8E080B
+        A824B449342BBCD180802F0AFA9AB33B780F7086EE216D732B98473F0BD4F3CE
+        CD4AAC6DC15B763454F1965E0F796C7F1D0152FE87A2C4FE417BA84F807B51CE
+        24C6518A1F91A8FDEF803AF851431DDFEAA910873E09FF528A51D6FCF20FC209
+        28767C448B9C61E906755E08805C61CD734E0811F04371F6455628E5C94E6335
+        5702F455A3D7AF756E3BBBE244900057916336676C6142BD69D515A621730C55
+        84F35D68FB57258D00A5DF6D300D2D683201B5246853F510394800053E6B69EA
+        1B954867F8C5E360FEF97C431DDFFBB3210EAC491E01974C86E9EA7971114052
+        6ACD2BBB85C93FF631BB3B787E8837757D56D42173A15E3AD550C7B3641850FD
+        4DF32040A2CA9A5F96C96A4A1C03B8C0B6443B631AFF0694CCDCA8CF85E738BC
+        8B073548722444C0A5B7D3CFEE0FF11110EC94DFCEDC85D9D3C1F98B89744472
+        132CBFDA096EB246D5D1576BFEB7EF481A785D4C239E84D27B82A18E110142CA
+        F1CCBDC8F1171A968712EA49FBDEB0DEFCB6A18A9F5669DAE789F9D9FAC23AF6
+        83F986525A951B47A84604D06CF07B56B3C8BE34D1F436EF3309E6E1868917F8
+        B716421EFE2CC61AA3C2066CEDC0BB0C82AA8FBC6A6DB4846FD514886F3E8D4C
+        80C073CC55644F380052873D0EB5EFA404C1A5408420C73B04A83912F9B9C49B
+        CCB5C8BE836680CB1369C77CD36AF00BFBA41B6E43FC95DBE17B33FAC05004B0
+        8E7C807D2F2D73FBC6DD8A6A83951CE0D96C6EB3111A7DEFAADB8C13A7526E60
+        1404EDA18F97C4DB0EEBD41F9609CBD30DF75C64F06F7E0ADAAE4626379D00D7
+        22C716C6F0D3789B52FA4DA570746EBA118744D41C4560D363C1B0BB719AE45A
+        DD072414069B463E0DA5E70DE9451DF0401CDD0DEDBF6B68ADB132781F135914
+        0EEB16F01259C0B4B809B8652D94768EE88D545722F0C91361DFA9B9F790D33C
+        E376C813F9D73F02E93B1D7A6ED6C3DB334918E9AD0E3E8F248CE63171EA30E4
+        0F6531830E17B940B780B96401F3E2281DCC1859A76FA74020FA2A5A94BD03DF
+        DAFBC2BEB3DEBE31F87E21F8BCE63B785FBE1267B38DD2D412B6BB7610BADAD7
+        11DAE1CFE17F6B725CDD6B4CC84FCE623545D91338F8B2782AE03FB902E671AF
+        19EAF8373F19E68C180532963B3F07CE40D6BEDE00FF9AE975CF3BE7C2726328
+        6587C0AEC5086CFE734A08A058F81A76624177BBC56C72C6535EE97F174C837F
+        6BA873EE3B3C49D19B65D21AF0B659C19719BE0F1F81D8B7A2AE40ABAE304F5C
+        096EBB00D2EF868FD60FB232E1B55A03D1D3E4367FA03DA30F7A2C70989DF316
+        2816315D5B0825677474052D00F78BB960015778E364DEBC457B48FD77EB6DB8
+        A9432A16706B9B5ABFE077211522A5FCC296EFBC249810F1143996503034A589
+        0CC232652378EBE81B45C4F103F0BD7E5D4A00244C8010CFD86695CF3E9311B2
+        4F648CBFD1A41A6CED61BD535FDC447F5912D8B7128175892D345348C1486B9E
+        735D9080A3C57D335A4B4F25594146ACC579F7AB611EB3D850E7DC4D0ECD46A4
+        ACB2762AEFAA6FB1AB4B8B173916931FB833D63A948179300D32DE37E15D7E23
+        E491DDE9861B8981F934FA41D30C11E02A720C2402B630239BAE27A6D1CF43C9
+        BE26BA42C0470EF07230CD9B6EB4E7820F40E3BDACF71D708611A00B59C18744
+        C2F046AB208E2CD33E016F7961541DEDE85EF8978D4B37DA48BD5F46A31F4A00
+        8513509C3D948C7B7DA356909149D1DC264395C0DE52043618BF2738EFD0A5D4
+        1405FDCD339D7B2312102461916315E36CAC51453C7B14CCA34B8C546A039CAF
+        9A36B1A49C00E0255B5E59989F6B40C0C9C21E0EB322F7E8D9B76815A957FC06
+        EA00E35D73DED25F401EDB976ECCF5E11F0F04649F8CFBCBC3F26351B6C8D81F
+        A4B8E0AFD1AA328D7D054AB7C1519B123E17BCBA034CCE8EF6E4C097725AA41D
+        A49177892D638AFBA8FD3D06D6704310E3B04CDF0A666913B531AD7207FC6FA6
+        7D1F757DF0CB09FCC448CFA26E93AB29CEEAAC40D94A2A5DC30AB4C982E5B67F
+        1B3618D8FD0A021F3F966EDC67C1EFF79831E882BB9D279B44802EAE67730670
+        4DAE0F8B10DB66436D2403242AD641348B00481E637E31D832FBE0FE681A316C
+        95CDB95632B98A7E0E3FAE4D42529EA67865942DBFEC5323B598768B7B4BECD7
+        0BC1973386C65FC5340B91A768CDFD4B6B7ED9FAC634633E2FE029CC190E8E15
+        14225D906E788DC811C1C498580F4E34E9C0447549566F55282B295CEE996E94
+        9145EE845F1B6F9D5D51116B89261F993956D8A3754B2E4AC831A62653190F6C
+        7D57B814CFDB5A890730ADA249E9E1B84F8DB90AED13B8C29E49F7D921427E90
+        1CF4BDD6BCB2F7E2299FD0B1B95A6B908F4A865946A1734A80EBA74A81F9569F
+        EF69F6E02177BCF524E5E468CDC28B32B9497D886689E95465EB14033F4E643F
+        6735AB0B71F7FEEF13AD2FA96787E5E25EADDC6EFF640E4C918C5D91AC7D87FA
+        32966C7D1311BCE4F8F7EEA55D0ABE4D5AAA382587A7839D2EEADEC50B55CF99
+        8FD0C9A0A6B262CD3605B7B6034EEADCA7F4F9434DC1BB19339D4753D1CF9411
+        D0405E70B471F9955E4C882CCE652721D13618589117231FE2A1CB0972665592
+        6B15AED3E67D914E77A442FE0F6724BE5B75E29AC60000000049454E44AE4260
+        82}
     end
     end
     object lblCurrentBlockCaption: TLabel
     object lblCurrentBlockCaption: TLabel
       Left = 90
       Left = 90
@@ -671,10 +633,6 @@ object FRMWallet: TFRMWallet
         object tsMultiSelectAccounts: TTabSheet
         object tsMultiSelectAccounts: TTabSheet
           Caption = 'Selected Accounts For Batch Operation'
           Caption = 'Selected Accounts For Batch Operation'
           ImageIndex = 1
           ImageIndex = 1
-          ExplicitLeft = 0
-          ExplicitTop = 0
-          ExplicitWidth = 0
-          ExplicitHeight = 0
           object dgSelectedAccounts: TDrawGrid
           object dgSelectedAccounts: TDrawGrid
             Left = 41
             Left = 41
             Top = 31
             Top = 31
@@ -866,10 +824,6 @@ object FRMWallet: TFRMWallet
     object tsPendingOperations: TTabSheet
     object tsPendingOperations: TTabSheet
       Caption = 'Pending Operations'
       Caption = 'Pending Operations'
       ImageIndex = 5
       ImageIndex = 5
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object dgPendingOperations: TDrawGrid
       object dgPendingOperations: TDrawGrid
         Left = 0
         Left = 0
         Top = 86
         Top = 86
@@ -916,10 +870,6 @@ object FRMWallet: TFRMWallet
     object tsBlockChain: TTabSheet
     object tsBlockChain: TTabSheet
       Caption = 'Block Explorer'
       Caption = 'Block Explorer'
       ImageIndex = 1
       ImageIndex = 1
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object Panel2: TPanel
       object Panel2: TPanel
         Left = 0
         Left = 0
         Top = 0
         Top = 0
@@ -1012,10 +962,6 @@ object FRMWallet: TFRMWallet
     object tsOperations: TTabSheet
     object tsOperations: TTabSheet
       Caption = 'Operations Explorer'
       Caption = 'Operations Explorer'
       ImageIndex = 1
       ImageIndex = 1
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object Panel1: TPanel
       object Panel1: TPanel
         Left = 0
         Left = 0
         Top = 0
         Top = 0
@@ -1064,10 +1010,6 @@ object FRMWallet: TFRMWallet
     object tsLogs: TTabSheet
     object tsLogs: TTabSheet
       Caption = 'Logs'
       Caption = 'Logs'
       ImageIndex = 2
       ImageIndex = 2
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object pnlTopLogs: TPanel
       object pnlTopLogs: TPanel
         Left = 0
         Left = 0
         Top = 0
         Top = 0
@@ -1099,10 +1041,6 @@ object FRMWallet: TFRMWallet
     object tsNodeStats: TTabSheet
     object tsNodeStats: TTabSheet
       Caption = 'Node Stats'
       Caption = 'Node Stats'
       ImageIndex = 3
       ImageIndex = 3
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       DesignSize = (
       DesignSize = (
         857
         857
         438)
         438)
@@ -1172,10 +1110,6 @@ object FRMWallet: TFRMWallet
     object tsMessages: TTabSheet
     object tsMessages: TTabSheet
       Caption = 'Messages'
       Caption = 'Messages'
       ImageIndex = 6
       ImageIndex = 6
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       DesignSize = (
       DesignSize = (
         857
         857
         438)
         438)

+ 83 - 136
src/gui-classic/UFRMWallet.lfm

@@ -1,9 +1,9 @@
 object FRMWallet: TFRMWallet
 object FRMWallet: TFRMWallet
-  Left = -1233
+  Left = 634
   Height = 600
   Height = 600
-  Top = -403
+  Top = 201
   Width = 865
   Width = 865
-  Caption = 'Pascal Coin Wallet, JSON-RPC Miner & Explorer'
+  Caption = 'Pascal full node Wallet (Classic GUI)'
   ClientHeight = 580
   ClientHeight = 580
   ClientWidth = 865
   ClientWidth = 865
   Color = clBtnFace
   Color = clBtnFace
@@ -16,7 +16,7 @@ object FRMWallet: TFRMWallet
   OnCreate = FormCreate
   OnCreate = FormCreate
   OnDestroy = FormDestroy
   OnDestroy = FormDestroy
   Position = poScreenCenter
   Position = poScreenCenter
-  LCLVersion = '2.0.2.0'
+  LCLVersion = '1.8.0.6'
   object pnlTop: TPanel
   object pnlTop: TPanel
     Left = 0
     Left = 0
     Height = 91
     Height = 91
@@ -29,139 +29,86 @@ object FRMWallet: TFRMWallet
     TabOrder = 0
     TabOrder = 0
     object Image1: TImage
     object Image1: TImage
       Left = 15
       Left = 15
-      Height = 60
+      Height = 64
       Top = 15
       Top = 15
-      Width = 60
+      Width = 64
       AutoSize = True
       AutoSize = True
       Picture.Data = {
       Picture.Data = {
-        1754506F727461626C654E6574776F726B47726170686963E20F000089504E47
-        0D0A1A0A0000000D494844520000003C0000003C08060000003AFCD972000000
-        0473424954080808087C086488000000097048597300000B1200000B1201D2DD
-        7EFC0000001C74455874536F6674776172650041646F62652046697265776F72
-        6B7320435336E8BCB28C00000F5C494441546881D59B7D8C5DC579879F7766CE
-        39F7DEFDBE8B1D7B8D61B13160B05D2F5027C68E8190409B929084006D5A42A3
-        5651D4964655152591924292A65594A66A451B45AA541250207C8990A4348921
-        14624330181BB049B0F1DAF1826D6C76D7FB79EF39673EFAC75DDB6B7BEFB26B
-        AF4DFB938E567B66CE9C79EECCBCF3CE9C772484C0A9D4AEED5BCE3346AF515A
-        AD8AE3C2F242A9A9B3586A6A05A88C0E1DAC568676656975B3777EBDB5EEA9CE
-        454BB69DCAFAC84C036FD9B4A1496B59A995BE526BBD421BBDC0187D86D6BA10
-        25455D28354BB1A11980CAC820D5CA60C8AB15E79CAB5AEBDE72D6753BE73638
-        EF9EF02E3C7351D78AA199ACDF8C016F7A76DD2AADD5A7B4D61F525ACF56DAA0
-        4C828E628C5118E589B5A25048282645002A69856A9A92598FF50A6B3D2ECFF0
-        36C53B8B776EBF73EEC7CEF93BBBDEBD7AFD4CD4F3A48137FCF2890F6AAD3EA7
-        B4BE42698D444594D614C228C5BC9742BE9F24EBC564032857417C8E040F4010
-        4550115E17B1710B69DC4E359A4D256AA72A25BC7384BC82770EEFDCFF38E7BF
-        B9E2BD573EFA8E00AF7BFC67CBB5D2FFA88DFA3DA5234254249194966C0F2DD5
-        1D94AA7B307608820384200A50040464AC90004200FCD88F104034D634315AE8
-        60A0B09081B8833424485EC5BB1C67DD4F9D775F5C7DD5359B4F1BF0533F7FF4
-        36A5F49795311A53A228156667DB28575FA590F703E0C510449F489D90E050C1
-        02508DDAE82B9CCFFEF83C2AA10876146FADF3DE7D6DCDD51FFCCAF4CB9E06F0
-        638FFEF82C2572B7D66A0DBA80D14287DB4E47F56512378097082F66BA759854
-        2A5854C849750B7B0A4BD9A317615D0057C539FF940FE1E6F77FF043BBA75ADE
-        94817FFEA31FAE524A1E545ACFF1A6481B7D2CCA37D2ECF6E289F027D89A5395
-        0A0E45CEA09ECBF6E812FA29A36C05EFDC3EEFC3C7AFFEF047A664D4A604FCDF
-        0F3F74AD52EA21A54D1C4CC2D9BCC6B976133A58ACC4270D2363637AA2AA8800
-        010E259990E1C4B0C374B18B73919A45CFBCF7D7FFFE47AFFFC9DBBEEBED807F
-        F2D003D76AA51E411BA574C4856C667ED8862322A0A689768C42C01423C65B31
-        5BC90FFF02A61483F3A01564169B7B6A36CFA3C9E991F37885E5789783B3DE79
-        7FDDB5D7DF3029F4A4C03F7AE0BE954AE449D151A4B4A64B3DCF1C7E8BA57072
-        A063D2C588B5BFDAC5D7EEDD08085FFAC32EAE5EB9005FC95089E1B63B9F65ED
-        A6D7995B2EF1EDBF5AC3EC72099FBBC3CF1BAAECE36C36F94B6B5398CB731FC2
-        E51FBEE1A667EABDB36E133D7CDF3DF308E191808A028AE5F21C73D87D18564E
-        F6129048F34F0FBDC8BAADFB58B7752F0FAEDD8284149DC4BC796098AFDDBB91
-        5FFDE64D1E7E7A275BB774A33447FA3F60293087DD2C97E70828022A2284471E
-        BEEF9E79D302FEC177EF02CF030166E51896E897982B3D58925A374C0CBA2146
-        974EE26A4C20736CDF3370F8BDEFBFE80C183D08B1A3FBCD231E6553C1B0627E
-        030CF7611A0CA621412B19834E982B3D2CD12F6131049885E7811F7CF7EE0981
-        279C43A248DD06ACCC8839DFECA45377634302014C7391A737EEE62BDFDFC8C9
-        78694A09D5CCB17BFFF0E17BDFFA593777AEEB01A5E8E9CF0EDF773E70FDBF6F
-        A46884650BCEE08A15E7B2FAA23924CD05C2708AF5319DBA9B41D3C8ABD9D918
-        AA2BA3486E038E9BA78F1BC3F7DFF5BD0B95522F7B9DA833A2212E2F3C8B10F0
-        41611A225EDF37C4257FF900FB0F564E187626B4685E0BB75EB7945B3FB20C42
-        C0A53563F764F5DDBC9537A15CEABDF74B6FFCE42DAF8C7F6EA22E7D474094C2
-        F33BF1AFD1E2F0284CACA9562DD7FDDDA3EF382CC0F63706F8EB6FAFE39A2FFC
-        98E1D4A2E2188D6579FC0A0A4F401470C7B1CF1D057CDFF7EEFC4020BC2F2762
-        61D443BBEEC50683520205C3CDFFB0961776BC75DAA0A6A29FBFD0C3CD7FFF53
-        C4809384B2EE6361D4434E0484F7DDF7BD3B3F303EFF51C0DE87DB435094A4CA
-        05C92E7C3008A01A623E77C7533CB8BEFB34A24C5D3FDCD0C363BFD8822E28BC
-        445C90ECA224557C50781F6E1F9FF7F018FED76F7C6345B9DCF6ACC44D2C6BD8
-        C5B2E2366C8831C5889FAEDFC12DDF7C9C389E593F793A1281FD0329A9F513A6
-        FFF97BCFE43FFE6615366AC1A89C974616F1D26827211BA2AFB7EFDD9FFDC217
-        36C0382B9D65D9677C8092CA3827DE4B184BB2A965C5A2596CFFD6D5283CB5A1
-        716AB7858E9500716278DFD7D7B16E5BDF84790E8C58A856F1C339A15C664161
-        1FAF563B180D9065F9678023C037DFF847A5C5172CBACE4BC4DCA88F263D820D
-        63BF850FB4B636228D31BEEF00F843D0471400AD0489267135738FF501A99F63
-        526015EBC373EF44D24A4029425A25EFEBA3B1ECE988FBD9566D21CBB3EBFEF8
-        E33796BEFFE0FDA306A0A9A9719573BE8C28CE4A0E1C5798770E7404AD67E0FA
-        0ED4FCDB711E8F085453C7F6DF8ED4ADD0BC7291D68688E0A7DF3B04887D9870
-        71719CC6A043FF01E637EC67BB2AE39C2B373535AE02D61A8010FC553E40834A
-        99150DE2C3044B3DEF218A51E559E35ABA061D1723D63EB7876BFFF9D9BAF558
-        F7A5D5AC5A7C0669D54E1B388C511B3DC5FEA11436CD690FDD9454273E2882F7
-        57016B1580736E85174D9B19A6A8527CBD8EE73D32068D5247D6735A786EE7C1
-        BAEF6F2D452C9EDB88CF27363853954C633C783114F3015A7D1F5E199CF72B00
-        D455EF5DB3D07BBF30A02947C3206F53A989A07DE0855D03751FB9685E13E596
-        02D69D04B0C8D4BAF43829F194E903D178EF175EBEF2B285AA542A5D1942282B
-        8156330253312BE3A0B5D1A4C3292FF70CD6CDDED5D902B13A61DB9E249ABC6A
-        7975EFF0DB673E4A424B38880878EFCB0D0D0D571A11591D0205AD024D268330
-        C57E33066D66BD8B1D5B77B2BBB7BEBBF9FE0B6741292299AEC11AEBC3C32319
-        7F7BD7CBBCD15FAD5F9D099ADFA36894510C9E000544561B6079001D89A7A0EC
-        D481A166B89A8ABC32A0267CE121FDDB633BB9F7D937F0D304168191D4B169D7
-        007B0ED6870588B43A6E907B84826418B184209AC0721342382704C4284FA4FC
-        F4BB9D82E75F9BDCBF7E6CEBF153DD4C6BCDF9ED13DC152271185CED1FC2390A
-        6806D012D012A60F6C3D1B5F3BF54093697673C22756CDC7558E9EF242008D1F
-        CFD57C52BB705A09D5C12A5B764DECEE9D0EC55A71CF5F5C42B925C1D6F1B3C7
-        4B0183002E082EC8B45C3F8934DDFB0679A3B7BE87752AB562611B4F7E793557
-        75CD211DC98F9B6044C0A1C6730D1A11D929C232EB95E45E519C4E9BC79A9776
-        4EDEBA4D458391B12F48213038AEDB35170D4AA4E69AE69E4A56DB91D44A682A
-        9AA3D628815A6BCE6F2FF0BB0BDAB8EEE2395CB36C36CA28D2A1ACCE6C1AC883
-        C6A2C78A909D06D82C70511E94A97A43B354A76EA995F0FCF6FAE3775E5B810D
-        B7AF218914BA6078605D0F9FFECF1701E868ADA515624594183E71C773FCD7E6
-        3701F893CBCEE45FFE6C39D9F0917DAD40CD12971B2328187081BC62C9735BD7
-        755004AA21C606834870089B4D08AC13E17AE7A571C8C6CC2E4CCD6C09403EB9
-        C15A3ABF998EB98D848A459A62B6BC7E6427F2BCB98DCCEB6884D4E1AC67EBB8
-        B4F72C6CA3B539211CB33A0A21905B8F1FCA988A149EE150C2A210A812C23A35
-        3A3AF28488F4F900076D03535DEB6AAD183E58E195DFF6D7CD7349672B0099F5
-        901FEDA15FBD64160470D6336AFDE1A55FA485CBCE2B132A3999F5475DB90B4C
-        6F2A0F0C482B218052AA6F6464E409F3F82F9FDAF1E95BFE7487E0CEEACB5B20
-        4C7110479AD7BADF62FF407D0FEBE2CE160ED5301BC9F9FAC717F3D14BE6A294
-        B062412BD9484608508C354F7CF132B6BF39C2ECE6840BE73591A5AE6EB953C7
-        55F45186504529B5E3C9679EDE6100B4D61B547057F6DB462A3E2121ABBF623A
-        A458F362776FDD64AD84256736C3D80A29844012292E5F320B803C7587BD3397
-        7BE6978BCC7F5703B8409A9D3CACC2334A03FDD2860A3D68A536D4EE0322EA71
-        2530E2130EE4CD2899C20B65728375767B91B3DB8B47CD8DCE07D2AA25ADDAA3
-        5D5181D47AD28A9D11580083E580CCA242A91677A0D4E330063C3434BC5E6BD5
-        47F0EC4E67BD6D6102905A5E98C4A55C3ABF99A421C29DC00EC74CA947CE2204
-        8FD6AA6F6870783D8C01DF7DFFBDA351143DA242CEDEBCCC906B404FB22ED646
-        31D03FCAAF7BEA1BAC8B3B5B61923DA853298D63505AD8A73A502E258EE247BE
-        FFD0FDA3306E5F3A8EE3EF2881D4C7ECCCE6224CB21513695E7D6380FEE1B46E
-        968B3B5BC0BD33AD6BC8D9A9CE25A5801288E3E83B87D20E037FF6F39FDF608C
-        79DA90D39D7650F1A5DAB6EC448A349BBBEB77E7482B2EEA68827C66C6E374A4
-        710C4B33BBF4799890618C79FAD09E341CF3E54129B95DC4331A0AFC26ED4449
-        9D56162635580B669798DF5EAC059F9C669990B3CD2C65541A50389492DBC7A7
-        1F057CD32D9F5A2BC82F227276E4F3E975ED9863A04580AA65D324DF9896CD6F
-        C6944EBFC18A42C601DDC1CE6831514801F9C54DB77C6AEDF83C137919B70AC1
-        7B142F668B71411FD5B5B556F4F68EF0EAEBF577292F3DA7754A5B63332985C7
-        89E1E5C265781442F0C0ADC7E73B46377EF2965744E4AB11965EDFC656BBF8E8
-        AE9D185EE8EE65A892D77D79D7592D604F6FEB9A90B2B5B8923E3D07137244E4
-        ABC77E1B863A110079EEBF9224EA9A986CE56BF61C9AD5309D6A079684102078
-        C70D97CEA96DD31E5BA012969ED58C9B2107622A4AFC28DDC52E7626CB886D05
-        07CFE47998304AAF6E14CFC3F7DD334F8BDA24CACC121D718979BE16E711124C
-        A4211F82E1A131E8B160AA31D98A3DE1EF48D355EC47D953B8804D8DD7105C46
-        70F6800BBEEBA3377DE28D89F29F78D89252F8817EC2C8D0842D7DEA15887D85
-        BDC5C5BCD87C0DDE3A82CB4E3C6C09E0C337DCF40C221F53780F8117E53DF4C8
-        F91852C43B544B1BD2D004FEF4CEB7121C91AFB0BBF1525E6EFB03080185F388
-        7C6C32D8DAB327137A88C3AAE4B4B6B4F6295E22BACB57B0BBD485D82ADEE633
-        177A78481307973E4FB3DB8757097670F09442AB60D13E65A0D44977FB07E88F
-        E6A2B2E153135C7A4813860FDBED74645B48FC20767018375A995168F139DA67
-        A4493BFBCA97B1B7B90BEB03E495531B3E3C5E130688E7DB69AF6E23EADD4118
-        1EC29BE4E402C45D6DDF2A2DCEA6AF7C316FB57451518D900D9FBE00F1F19AF8
-        0840468BDD43D3FE1728F66FC76403E073401194AE45DFCAA1684BA8C5050704
-        8F78077850113669A5D2D4C960DB12061B17924A11C946F136C3597FFA8F008C
-        D744873C741491D8210A957D14465E271EDD87AEF6A2F311C46547ACBAD2041D
-        E3A2065CA19DAC34876AC399548B73484D13DE5A7C5EA9FD7DA70F791CAB098F
-        F14405749CD48EF1E088B55088638A492D22B79256A9E619990D5874ED184F96
-        E2F3EAFFDD633CC7EA6D0F6A35344BB13476506B7490EAE8FFD3835AF534E5A3
-        78D6AFB7EED41FC5FB5F0935D0C88CEACBC00000000049454E44AE426082
+        1754506F727461626C654E6574776F726B477261706869632509000089504E47
+        0D0A1A0A0000000D4948445200000040000000400806000000AA6971DE000000
+        0467414D410000B18F0BFC6105000000097048597300000EC200000EC2011528
+        4A800000001874455874536F667477617265007061696E742E6E657420342E31
+        2E36FD4E09E8000008A349444154785ED59B7B8C54D51DC7873E6C6BAAF58FA6
+        AD8DB23BE72E62E92334565BFB02FB480D6A5A5B5762D5A8AD4DB4416D6CDAD8
+        6AD9B6E98B1A1677EE1D96557141ADAB2C60B12162770B2CD294E862A1A0222A
+        161528C8222C7BDF8FD3EF99B9C3CE99FB9BBBF35AE7F24B3ED9ECF99DDF39BF
+        DFB9E77DE7A638E7934BC78C539CC5CA79636AFA463DC3EE3654D66FAA6C93A9
+        2ADB0D55D96D68CA4BF8BB5D57D990A9B14775555980BFD78F692D3379C7ACF7
+        9065361032B15E8CAC723682BDD5D0D83A04AC9B9AC26B01B6A328E36F68B09B
+        D0201FA3EAAA1732B116867BCE7BAFA1A6DBF13407F1547D2AA07A4043B8287B
+        ADDE95BE8CAF48BD9BF2A116C8C4AA40E06646F9119ED66B94E39301EADA6564
+        D2D734A221C8C44A19D3D81C31862927DF19D83627DB3A8BF2AD52C8C409E939
+        E7C398B41EA39D7A67C1B0082C8DDD1774B59D4EFA3A0164621C98BD67A3E5F7
+        51CE34130C8B57F56CFA7CCAE738C8C47220F85BC46444399004E09B8586B88E
+        F2BD1C646294D4143CF58554A58DC47A640EB79FBA8DDB4F5C8F60DA227A7BD5
+        DC9CDE5AD91ED115C09C14A021EE426853E85864C84499D4144B53BAA9CA1ACA
+        83B339F75C5499177BE8D792DE5A7343A8810401B7565F2DE9A3A4FF849C443C
+        32646231D88474D215341667E0A7A86E5C9CA10E49EF6E5D126AF262ADBE4AD2
+        5358AA7227B292711520130B582ABB8D2A783270B7F5A2CA71B1575E21E9BDBD
+        4F871A48E071A3E733929E42AC1086D67A2D2CC8F80464A2C0CC2A176142F122
+        052FFB0AF7DF789AFB6FFEABB19823A8765CFC03C3923E708C5003F1DD5C9AF7
+        FA66EEEEF80B77067FC6CD07BE20FB398E21CE22B022E324138F2F661F41D7DF
+        5F5A98B1E4D3DC7FEB056449A0A057787B87B8B5EA4AC9E79CDF2A7BF9AD05D3
+        4F43AE48AC9104010CFA238568D3B8F7EA00D4499780BBCFF77173F1B9B2FFAA
+        22269148AC910471D828362CE06EED81FAE411EF9575D2522A0E6846867D092A
+        295EE99FDD5D6DEF13DDA5387081186362E939D9C45E7FA714077AC130EF48BD
+        0B2ABA01B076DE5C6C201063CA772DA84F3EF18FBD1ED9506155B812AA6803EC
+        EC98718AAE2A7B8B339BF7CECCCFC2875F4A266307E17ABC587D73E40650D976
+        847B629778A2018C8C32B738E3C980BBF977703D5EEC35D7466DD5F437A12A69
+        008D6D88644C38353780C6564235DE0047B4D696C9B8C69A6C6A6D00716A7C7B
+        51CB1950E71B4057D94F4A3355CDF259DCDB33108B33703B6D5B23E2BC3091D0
+        3D203719E6B6C8F9EEAFB2A7A84CD560FF5D3ECC50228EB2946DAD381BE78725
+        9797720D00FAA0460360F64703D47C755DC0DDBE3C5F638C885E42D9D64A5D0D
+        A02A07A04EA5741C14C80C55E2EDDF9AAFB18C88C30E75C9510FCEA6DF86A597
+        97981EC0CDCCD474CACCA47F482AABC0C0BEDB77CCB04A5ABCBD9B48DB7AF05E
+        E80F4B2F2F710D80B9EF7271CFF7674A59157D9786D59517E7598DB6AD116BC5
+        777850C10E35AE01B01ADC215680BAAFB7EDF5BF0CAB2B2FCE335DDC7EFCAA3A
+        F93EB7D7CDE3EE7F1EE2DC8DEF7105B1FF7A0DE9B3009BBFEE866C80DC9D8F86
+        D5254C7C9F9BBD5F247DCEA12AABC412F81CA9AC02FFD0F3618DC9127FFF30E9
+        6F019C0E07C5A5E74E4A59314B3E25DDE62646F0F427BC3855D9461C81951D11
+        451558FDDF0B6B4C9204DCD9FC47D25F09D100E806CF90CA0A71867E13569A0C
+        114764FBC979A4AFA560FE5B57F736D8DBB53AACBA898215C1DFB7853B1BEEC2
+        90FC24E927858EEDB0E801BD94B252BC9157422F68F147F7E796AE62FC433B43
+        2D2440775D7F87A4E74557E481352AE98A719EFC31B71EFB765541CBB085A207
+        CCA7951570EFCCDC641327FECB6B2376FCF8BE502BBAEC2174C5719D78E121AE
+        B80BE2BDB945B26D247A469997D2B5F41594B212ECC7AF0EDD2C2FA59391B554
+        BCC11EBF60F5FEBB51D6AF6C0F357971FF7DBFA46F2819F6B5D4D1CEA98C5456
+        80B359BC7F8C97D2A5C84077F5DF7E2DAFC493B6077F2EE9C589D1378EE4D58E
+        C1AD5573657D831017407C51CB19291C08A7601844DE02558287EE1D2BD81F88
+        B749A57646F61C6EF55EC8CDFB3E1BD1E5F4DD33F2FA9EA86DA340CC6222CA5F
+        88603D7C90CA148718B7FEB1F1B14C893FB29BB44D0246267D0F5C2CDC08A5DB
+        A94CB12CBD00A6F12F4BDC1757D3B689807D1D2EE61BE0A036E383E805C7E98C
+        34F6133FC8051927A53F72480C2A3B50F8895DAE010418134BC9CC6570B6748A
+        1863C5EAFF2E69DB7CD8DD702F17F78906D055F6398CEB803688E2ED1984598C
+        B8766E32A36C9B0B73CDAE366C464A1A40805EB09E369211777B62031327DEC1
+        1DA46DF3612BE0DE8998E506D05ABF5A512F58F665648F1777471F6DDB44F080
+        3D7B31C3F9BD4C03088C0C5B43191763AFBD1959E3C5FEC72F48DB668287FB00
+        5C93E295FE111CC5F84046832AA0803BDC8DACF162F55D42DA360F3672FC9EF4
+        47E19A14AFF44F01EC0B6EA70BC9237E9C1427BEADE7767B946DB340F7277F41
+        1A49C88135D2D0D8005590999D8623EA51642B2FE2250969DB2410BC788140C6
+        4A260AC4171AE8366F9416663D243650F1E26E5B26D9341304BFEB480FFB10DC
+        22E324130BE45E9B95EE101FFE06779FCDC662276603C40E5B8B5AA753B11520
+        138B3155E55BE27D3A5D4182C1833354E5422AA662C8C452AC6CFA1214669215
+        2512760C0F6E36154B29642285D9A55C84428FD015268AFF55F3E10499588ED1
+        6CCB27C4A442549A10D873E6A29656CAF7729089711CEE6A3B1DE3EB61DA81E6
+        80E11918997437EF6D793FE5731C646225E85DE232B5F9DF0E6182DE83BF1753
+        3E5602995829F9DEA02C9868EB3C1960288E82F9C1C2B33E40F956296462B58C
+        754E3D13CE74E6665FC2D946827A4630047F2F3EDDA37CA91632B15682FBA79F
+        A6ABEC2638F84FF48A86FDEE10417B38A56E40B937ECEB38F354AAEE5A21131B
+        41A09EFD71534DDF081E11E3B4A27B8610D1786037025E8EE0AF131F70507534
+        02327152C07E5CD7A67D5EFC26D9D2D8AD62FC62C8FC41746734D0AF74F14DA2
+        DAD62ED6F0725F77341E9EFA3F3F3AD63CC0721F160000000049454E44AE4260
+        82
       }
       }
     end
     end
     object lblCurrentBlockCaption: TLabel
     object lblCurrentBlockCaption: TLabel
@@ -1245,8 +1192,8 @@ object FRMWallet: TFRMWallet
   end
   end
   object TimerUpdateStatus: TTimer
   object TimerUpdateStatus: TTimer
     OnTimer = TimerUpdateStatusTimer
     OnTimer = TimerUpdateStatusTimer
-    left = 25
-    top = 45
+    left = 32
+    top = 56
   end
   end
   object MainMenu: TMainMenu
   object MainMenu: TMainMenu
     left = 165
     left = 165

+ 2 - 2
src/gui-classic/UFRMWallet.pas

@@ -902,7 +902,7 @@ begin
   Strings.Add('');
   Strings.Add('');
   Strings.Add(Format('Current balance: %s',[TAccountComp.FormatMoney(account.balance)]));
   Strings.Add(Format('Current balance: %s',[TAccountComp.FormatMoney(account.balance)]));
   Strings.Add('');
   Strings.Add('');
-  Strings.Add(Format('Updated on block: %d  (%d blocks ago)',[account.updated_on_block,FNode.Bank.BlocksCount-account.updated_on_block]));
+  Strings.Add(Format('Updated on block: %d  (%d blocks ago)',[account.GetLastUpdatedBlock,FNode.Bank.BlocksCount-account.GetLastUpdatedBlock]));
   Strings.Add(Format('Updated on block as active mode: %d  (%d blocks ago)',[account.updated_on_block_active_mode,FNode.Bank.BlocksCount-account.updated_on_block_active_mode]));
   Strings.Add(Format('Updated on block as active mode: %d  (%d blocks ago)',[account.updated_on_block_active_mode,FNode.Bank.BlocksCount-account.updated_on_block_active_mode]));
   Strings.Add(Format('Public key type: %s',[TAccountComp.GetECInfoTxt(account.accountInfo.accountKey.EC_OpenSSL_NID)]));
   Strings.Add(Format('Public key type: %s',[TAccountComp.GetECInfoTxt(account.accountInfo.accountKey.EC_OpenSSL_NID)]));
   Strings.Add(Format('Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.accountKey)]));
   Strings.Add(Format('Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.accountKey)]));
@@ -1326,7 +1326,7 @@ begin
   MinersBlocksFound := 0;
   MinersBlocksFound := 0;
   lblBuild.Caption := 'Build: '+CT_ClientAppVersion;
   lblBuild.Caption := 'Build: '+CT_ClientAppVersion;
   {$IFDEF TESTNET}
   {$IFDEF TESTNET}
-  Image1.visible := false;
+  lblBuild.Font.Color := clRed;
   {$ENDIF}
   {$ENDIF}
   PageControl.Enabled := False;
   PageControl.Enabled := False;
   PageControl.Visible := False;
   PageControl.Visible := False;

+ 2 - 2
src/gui-classic/UGridUtils.pas

@@ -672,7 +672,7 @@ begin
     n_acc := AccountNumber(ARow);
     n_acc := AccountNumber(ARow);
     if (n_acc>=0) then begin
     if (n_acc>=0) then begin
       BufferGetAccount(n_acc,account,LNodeBlocksCount,LNodeAccountsCount);
       BufferGetAccount(n_acc,account,LNodeBlocksCount,LNodeAccountsCount);
-      ndiff := LNodeBlocksCount - account.updated_on_block;
+      ndiff := LNodeBlocksCount - account.GetLastUpdatedBlock;
       if (gdSelected in State) then
       if (gdSelected in State) then
         If (gdFocused in State) then DrawGrid.Canvas.Brush.Color := clGradientActiveCaption
         If (gdFocused in State) then DrawGrid.Canvas.Brush.Color := clGradientActiveCaption
         else DrawGrid.Canvas.Brush.Color := clGradientInactiveCaption
         else DrawGrid.Canvas.Brush.Color := clGradientInactiveCaption
@@ -702,7 +702,7 @@ begin
           Canvas_TextRect(DrawGrid.Canvas,Rect,s,State,[tfRight,tfVerticalCenter,tfSingleLine]);
           Canvas_TextRect(DrawGrid.Canvas,Rect,s,State,[tfRight,tfVerticalCenter,tfSingleLine]);
         End;
         End;
         act_updated : Begin
         act_updated : Begin
-          s := Inttostr(account.updated_on_block);
+          s := Inttostr(account.GetLastUpdatedBlock);
           Canvas_TextRect(DrawGrid.Canvas,Rect,s,State,[tfRight,tfVerticalCenter,tfSingleLine]);
           Canvas_TextRect(DrawGrid.Canvas,Rect,s,State,[tfRight,tfVerticalCenter,tfSingleLine]);
         End;
         End;
         act_n_operation : Begin
         act_n_operation : Begin

+ 5 - 14
src/pascalcoin_miner.lpi

@@ -1,16 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <CONFIG>
 <CONFIG>
   <ProjectOptions>
   <ProjectOptions>
-    <Version Value="12"/>
+    <Version Value="10"/>
     <PathDelim Value="\"/>
     <PathDelim Value="\"/>
     <General>
     <General>
       <Flags>
       <Flags>
         <MainUnitHasCreateFormStatements Value="False"/>
         <MainUnitHasCreateFormStatements Value="False"/>
         <MainUnitHasTitleStatement Value="False"/>
         <MainUnitHasTitleStatement Value="False"/>
-        <CompatibilityMode Value="True"/>
       </Flags>
       </Flags>
       <SessionStorage Value="InProjectDir"/>
       <SessionStorage Value="InProjectDir"/>
-      <Title Value="PascalCoinMiner"/>
+      <MainUnit Value="0"/>      
       <UseAppBundle Value="False"/>
       <UseAppBundle Value="False"/>
       <ResourceType Value="res"/>
       <ResourceType Value="res"/>
     </General>
     </General>
@@ -25,16 +24,9 @@
     </PublishOptions>
     </PublishOptions>
     <RunParams>
     <RunParams>
       <local>
       <local>
+        <FormatVersion Value="1"/>
         <CommandLineParams Value="-c 1 -s -n TEST"/>
         <CommandLineParams Value="-c 1 -s -n TEST"/>
       </local>
       </local>
-      <FormatVersion Value="2"/>
-      <Modes Count="1">
-        <Mode0 Name="default">
-          <local>
-            <CommandLineParams Value="-c 1 -s -n TEST"/>
-          </local>
-        </Mode0>
-      </Modes>
     </RunParams>
     </RunParams>
     <RequiredPackages Count="1">
     <RequiredPackages Count="1">
       <Item1>
       <Item1>
@@ -44,8 +36,7 @@
     <Units Count="1">
     <Units Count="1">
       <Unit0>
       <Unit0>
         <Filename Value="pascalcoin_miner.pp"/>
         <Filename Value="pascalcoin_miner.pp"/>
-        <IsPartOfProject Value="True"/>
-        <UnitName Value="PascalCoinMiner"/>
+        <IsPartOfProject Value="True"/>        
       </Unit0>
       </Unit0>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
@@ -62,7 +53,7 @@
     </SearchPaths>
     </SearchPaths>
     <CodeGeneration>
     <CodeGeneration>
       <Optimizations>
       <Optimizations>
-        <OptimizationLevel Value="4"/>
+        <OptimizationLevel Value="3"/>
       </Optimizations>
       </Optimizations>
     </CodeGeneration>
     </CodeGeneration>
     <Linking>
     <Linking>

+ 24 - 29
src/pascalcoin_miner.pp

@@ -46,7 +46,6 @@ type
   protected
   protected
     FWindow32X1,FWindow32Y1,FWindow32X2,FWindow32Y2: DWord;
     FWindow32X1,FWindow32Y1,FWindow32X2,FWindow32Y2: DWord;
     FLock : TCriticalSection;
     FLock : TCriticalSection;
-    FPrivateKey : TECPrivateKey;
     FPoolMinerThread : TPoolMinerThread;
     FPoolMinerThread : TPoolMinerThread;
     FDeviceThreads : TList;
     FDeviceThreads : TList;
     FAppStartTime : TDateTime;
     FAppStartTime : TDateTime;
@@ -58,7 +57,7 @@ type
   end;
   end;
 
 
 Const
 Const
-  CT_MINER_VERSION = {$IFDEF PRODUCTION}'5.0'{$ELSE}{$IFDEF TESTNET}'5.0 TESTNET'{$ELSE}ERROR{$ENDIF}{$ENDIF};
+  CT_MINER_VERSION = {$IFDEF PRODUCTION}'5.1'{$ELSE}{$IFDEF TESTNET}'5.1 TESTNET'{$ELSE}ERROR{$ENDIF}{$ENDIF};
   CT_Line_DeviceStatus = 3;
   CT_Line_DeviceStatus = 3;
   CT_Line_ConnectionStatus = 4;
   CT_Line_ConnectionStatus = 4;
   CT_Line_MinerValues = 7;
   CT_Line_MinerValues = 7;
@@ -105,7 +104,7 @@ Const CT_state : Array[boolean] of String = ('Disconnected','Connected');
 var i : Integer;
 var i : Integer;
   s : String;
   s : String;
 begin
 begin
-  If FPoolMinerThread.PoolMinerClient.PoolType=ptNone then s:='MINING'
+  If FPoolMinerThread.PoolMinerClient.PoolType=ptSolomine then s:='MINING'
   else s:='POOL MINING USER "'+FPoolMinerThread.PoolMinerClient.UserName+'"';
   else s:='POOL MINING USER "'+FPoolMinerThread.PoolMinerClient.UserName+'"';
   If FPoolMinerThread.PoolMinerClient.Connected then begin
   If FPoolMinerThread.PoolMinerClient.Connected then begin
     WriteLine(CT_Line_ConnectionStatus,s + ' server: '+FPoolMinerThread.PoolMinerClient.ClientRemoteAddr);
     WriteLine(CT_Line_ConnectionStatus,s + ' server: '+FPoolMinerThread.PoolMinerClient.ClientRemoteAddr);
@@ -203,6 +202,7 @@ var
   ErrorMsg: String;
   ErrorMsg: String;
   s : String;
   s : String;
   nsarr : TNodeServerAddressArray;
   nsarr : TNodeServerAddressArray;
+  LLog : TLog;
 
 
   Function AddMiners : Boolean;
   Function AddMiners : Boolean;
   var p,d,c,i : Integer;
   var p,d,c,i : Integer;
@@ -345,17 +345,11 @@ var
 
 
   Procedure DoVisualprocess(minerName, UserName, Password : String);
   Procedure DoVisualprocess(minerName, UserName, Password : String);
   Var sc : tcrtcoord;
   Var sc : tcrtcoord;
-    Flog : TLog;
     devt : TCustomMinerDeviceThread;
     devt : TCustomMinerDeviceThread;
     i : Integer;
     i : Integer;
   Begin
   Begin
-    FPoolMinerThread := TPoolMinerThread.Create(nsarr[0].ip,nsarr[0].port,FPrivateKey.PublicKey);
+    FPoolMinerThread := TPoolMinerThread.Create(nsarr[0].ip,nsarr[0].port,UserName,Password);
     try
     try
-      If (UserName<>'') then begin
-        FPoolMinerThread.PoolMinerClient.PoolType:=ptIdentify;
-        FPoolMinerThread.PoolMinerClient.UserName:=UserName;
-        FPoolMinerThread.PoolMinerClient.Password:=Password;
-      end;
       If Not AddMiners then exit;
       If Not AddMiners then exit;
       if HasOption('t','testmode') then begin
       if HasOption('t','testmode') then begin
         i := StrToIntDef(GetOptionValue('t','testmode'),-1);
         i := StrToIntDef(GetOptionValue('t','testmode'),-1);
@@ -393,12 +387,11 @@ var
         end else begin
         end else begin
           WriteLine(2,'Mining using '+IntToStr(FDeviceThreads.Count)+' devices');
           WriteLine(2,'Mining using '+IntToStr(FDeviceThreads.Count)+' devices');
         end;
         end;
-        Flog := TLog.Create(Nil);
+        LLog.OnInThreadNewLog:=OnInThreadNewLog;
         try
         try
-          Flog.OnInThreadNewLog:=OnInThreadNewLog;
           DoWaitAndLog;
           DoWaitAndLog;
         finally
         finally
-          FLog.free;
+          LLog.OnInThreadNewLog:=Nil;
         end;
         end;
       finally
       finally
         cursoron;
         cursoron;
@@ -411,11 +404,21 @@ var
 
 
 Var username,password : String;
 Var username,password : String;
 begin
 begin
+  LLog := TLog.Create(Self);
+  Try
+    If HasOption('l','logfile') then begin
+      s := Trim(GetOptionValue('l','logile'));
+      if s='' then s := 'PascalCoinMiner_'+FormatDateTime('yyyy-mm-dd_hh_nn_ss',Now)+'.log';
+      if HasOption('logall') then LLog.SaveTypes:=CT_TLogTypes_ALL
+      else LLog.SaveTypes:=CT_TLogTypes_DEFAULT;
+      LLog.FileName:=ExtractFileDir(ExeName)+PathDelim+s;
+    end;
+
   FLastLogs := TStringList.Create;
   FLastLogs := TStringList.Create;
   FLock := TCriticalSection.Create;
   FLock := TCriticalSection.Create;
   Try
   Try
     // quick check parameters
     // quick check parameters
-    ErrorMsg:=CheckOptions('hp:d:s::c:n::t:u::x::', 'help platform device server cpu minername testmode user pwd');
+    ErrorMsg:=CheckOptions('hp:d:s::c:n::t:u::x::l::', 'help platform device server cpu minername testmode user pwd logfile logall');
     if ErrorMsg<>'' then begin
     if ErrorMsg<>'' then begin
       //ShowException(Exception.Create(ErrorMsg));
       //ShowException(Exception.Create(ErrorMsg));
       WriteLn(ErrorMsg);
       WriteLn(ErrorMsg);
@@ -486,37 +489,27 @@ begin
         WriteLn('Input Pool username (or empty for non pool connection):');
         WriteLn('Input Pool username (or empty for non pool connection):');
         Readln(username);
         Readln(username);
       end;
       end;
-      if (password='') And (username<>'') then begin
-        WriteLn('Input Pool password for user ',username,':');
-        Readln(password);
-      end;
     end;
     end;
 
 
-    FPrivateKey := TECPrivateKey.Create;
-    Try
-      FPrivateKey.GenerateRandomPrivateKey(CT_Default_EC_OpenSSL_NID);
-      DoVisualprocess(s,username,password);
-    finally
-      FreeAndNil(FPrivateKey);
-    end;
+    DoVisualprocess(s,username,password);
   finally
   finally
     FreeAndNil(FLock);
     FreeAndNil(FLock);
     FreeAndNil(FLastLogs);
     FreeAndNil(FLastLogs);
     if not terminated then
     if not terminated then
       Terminate;
       Terminate;
   end;
   end;
+
+  finally
+    FreeAndNil(LLog);
+  end;
 end;
 end;
 
 
 constructor TPascalMinerApp.Create(TheOwner: TComponent);
 constructor TPascalMinerApp.Create(TheOwner: TComponent);
-Var FLog : TLog;
 begin
 begin
   inherited Create(TheOwner);
   inherited Create(TheOwner);
   FDeviceThreads := TList.Create;
   FDeviceThreads := TList.Create;
   StopOnException:=True;
   StopOnException:=True;
   FAppStartTime := Now;
   FAppStartTime := Now;
-  FLog := TLog.Create(self);
-  FLog.SaveTypes:=CT_TLogTypes_DEFAULT;
-  FLog.FileName:=ExtractFileDir(ExeName)+PathDelim+'PascalCoinMiner.log';
 end;
 end;
 
 
 destructor TPascalMinerApp.Destroy;
 destructor TPascalMinerApp.Destroy;
@@ -537,6 +530,8 @@ begin
   writeln('    Y can be multiple devices. Example -d 0,2,3  Will use devices 0, 2 and 3');
   writeln('    Y can be multiple devices. Example -d 0,2,3  Will use devices 0, 2 and 3');
   writeln('  -c N  (For CPU mining, where N is CPU''s to use. Activating this disable GPU mining)');
   writeln('  -c N  (For CPU mining, where N is CPU''s to use. Activating this disable GPU mining)');
   writeln('  -n MYNAME  (Will add MYNAME value to miner name assigned by server)');
   writeln('  -n MYNAME  (Will add MYNAME value to miner name assigned by server)');
+  writeln('  -l LOG_FILENAME  (Will log to specified filename or will generate a new filename)');
+  writeln('    --logall log filename will include extra information (like full JSON commands)');
   writeln('  ** POOL IDENTIFICATION PROTOCOL **');
   writeln('  ** POOL IDENTIFICATION PROTOCOL **');
   writeln('  (Not needed for PascalCoin core, only some third party pools)');
   writeln('  (Not needed for PascalCoin core, only some third party pools)');
   writeln('  -u USERNAME');
   writeln('  -u USERNAME');