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
   - 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
+- 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
-  - 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)
 - Fixed important security issue related to PIP-0003 caused by possible "parallelization" of the Proof-of-work
   - 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
     - "data" : (HEXASTRING) will return the Account Data stored with PIP-0024
     - "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:
     - "senders" : ARRAY
       - "payload_type" : (Byte) as described on PIP-0027
@@ -68,7 +74,9 @@
   - Updated "Multi Operation Object" values:
     - "changers" : ARRAY
       - "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: RPC calls for PIP-0029
 - 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;
   end;
 
+  { TAccount }
+
   TAccount = Record
     account: Cardinal;        // FIXED value. Account number
     accountInfo : TAccountInfo;
     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)
     n_operation: Cardinal;    // count number of owner operations (when receive, this is not updated)
     name : TRawBytes;         // Protocol 2. Unique name
     account_type : Word;      // Protocol 2. Layer 2 use case
     account_data : TRawBytes; // Protocol 5. PIP-0024 RAW data information
     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;
   PAccount = ^TAccount;
 
@@ -310,8 +312,8 @@ Type
     Procedure UpdateAccount(account_number : Cardinal; const newAccountInfo: TAccountInfo; const newName : TRawBytes; newType : Word;
          newBalance: UInt64; newN_operation: Cardinal;
          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 DoUpgradeToProtocol2 : Boolean;
     function DoUpgradeToProtocol3 : Boolean;
@@ -439,6 +441,7 @@ Type
       LatestOpIDUsedForSeal : TRawBytes;
       AccountSealed : PAccount;
       SealChangesCounter : Integer;
+      UsedAsPasiveMode : Boolean;
       UsedAsActiveMode : Boolean;
     End;
     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;
     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_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 = (
     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);
     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;
     accumulatedWork:0);
@@ -605,8 +608,8 @@ Begin
     for i:=0 to sb.BlocksCount-1 do begin
       bl_my := sb.Block(i);
       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;
       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;
 
+{ 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;
 Var
   bnact, bnaux: TBigNum;
@@ -1259,6 +1270,7 @@ class procedure TAccountComp.SaveAccountToAStream(Stream: TStream; const Account
 var w : Word;
   LTmpSeal : T20Bytes;
   LTmpRaw : TRawBytes;
+  LCardinal : Cardinal;
 begin
   if current_protocol<CT_PROTOCOL_5 then
     w := CT_PROTOCOL_4
@@ -1267,9 +1279,12 @@ begin
   Stream.Write(Account.account,Sizeof(Account.account));
   TStreamOp.WriteAnsiString(Stream,AccountInfo2RawString(Account.accountInfo));
   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
+    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));
+  end else begin
+    LCardinal := Account.GetLastUpdatedBlock;
+    Stream.Write(LCardinal,Sizeof(LCardinal));
   end;
   Stream.Write(Account.n_operation,Sizeof(Account.n_operation));
   TStreamOp.WriteAnsiString(Stream,Account.name);
@@ -1297,10 +1312,10 @@ begin
   TAccountComp.RawString2AccountInfo(raw,Account.accountInfo);
   if (Stream.Size - Stream.Position<20) then Exit;
   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
     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));
   if TStreamOp.ReadAnsiString(Stream,Account.name)<0 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)
           And (EqualAccountInfos(account1.accountInfo,account2.accountInfo))
           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.n_operation = account2.n_operation)
           And (TBaseType.Equals(account1.name,account2.name))
           And (account1.account_type = account2.account_type)
           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;
 
 class function TAccountComp.EqualOperationBlocks(const opBlock1, opBlock2: TOperationBlock): Boolean;
@@ -1726,7 +1740,7 @@ end;
 class function TAccountComp.AccountToTxt(const Account: TAccount): String;
 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),
-    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.account_data.ToHexaString,Account.account_seal.ToHexaString ]);
 end;
@@ -1988,14 +2002,13 @@ Type
     accountInfo : TDynRawBytes;
     {$ENDIF}
     balance: UInt64;
-    updated_on_block: Cardinal;
+    updated_on_block_passive_mode: Cardinal;
     updated_on_block_active_mode: Cardinal;
     n_operation: Cardinal;
     name : TRawBytes;
     account_type : Word;
     account_data : TDynRawBytes;
     account_seal : T20Bytes;
-    previous_updated_block : Cardinal;
   End;
 
   TMemOperationBlock = Record // TOperationBlock with less memory usage
@@ -2053,14 +2066,13 @@ begin
   TBaseType.To256RawBytes(raw,dest.accountInfo);
   {$ENDIF}
   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.n_operation:=source.n_operation;
   dest.name:=source.name;
   dest.account_type:=source.account_type;
   dest.account_data:=Copy(source.account_data);
   dest.account_seal:=TBaseType.To20Bytes(source.account_seal);
-  dest.previous_updated_block:=source.previous_updated_block;
   {$ELSE}
   dest := source;
   {$ENDIF}
@@ -2086,14 +2098,13 @@ begin
   TAccountComp.RawString2AccountInfo(raw,dest.accountInfo);
   {$ENDIF}
   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.n_operation:=source.n_operation;
   dest.name:=source.name;
   dest.account_type:=source.account_type;
   dest.account_data:=Copy(source.account_data);
   dest.account_seal:=TBaseType.T20BytesToRawBytes(source.account_seal);
-  dest.previous_updated_block:=source.previous_updated_block;
   {$ELSE}
   dest := source;
   {$ENDIF}
@@ -2245,6 +2256,7 @@ var i, base_addr : Integer;
   //
   account_dev,
   account_0 : TAccount;
+  LAccountKey: TAccountKey;
   //
   acc_0_miner_reward,acc_4_dev_reward : Int64;
   acc_4_for_dev : Boolean;
@@ -2261,6 +2273,11 @@ begin
     If (AccountsCount>account_0.account_type) then begin
       account_dev := Account(account_0.account_type);
     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;
 
   base_addr := BlocksCount * CT_AccountsPerBlock;
@@ -2270,11 +2287,11 @@ begin
     Result.accounts[i] := CT_Account_NUL;
     Result.accounts[i].account := base_addr + i;
     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].n_operation := 0;
     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);
       accs_dev[High(accs_dev)] := base_addr + i;
       Result.accounts[i].balance := acc_4_dev_reward;
@@ -2307,7 +2324,7 @@ begin
     AccountKeyListAddAccounts(blockChain.account_key,accs_miner);
   end;
   If (length(accs_dev)>0) then begin
-    AccountKeyListAddAccounts(account_dev.accountInfo.accountKey,accs_dev);
+    AccountKeyListAddAccounts(LAccountKey,accs_dev);
   end;
   // Calculating new value of safebox
   FSafeBoxHash := CalcSafeBoxHash;
@@ -2834,10 +2851,10 @@ procedure TPCSafeBox.CommitToPrevious;
           blockAccount.accounts[j].account_data,
           blockAccount.accounts[j].account_seal,
           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].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;
@@ -2970,9 +2987,9 @@ procedure TPCSafeBox.RollBackToSnapshot(snapshotBlock: Cardinal);
            blockAccount.accounts[j].account_data,
            blockAccount.accounts[j].account_seal,
            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].previous_updated_block,
+           False,  // Not used when aus_rollback
            False); // Not used when aus_rollback
        end;
      end;
@@ -3145,8 +3162,8 @@ begin
   for LBlockNumber := 0 to BlocksCount - 1 do begin
     LPtrBlockAccount := PBlockAccount(FBlockAccountsList.Items[LBlockNumber]);
     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;
     {$IFDEF uselowmem}
     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;
 Var
-  iblock,iacc : Cardinal;
+  iblock,iacc, LTempCardinal : Cardinal;
   raw, LPreviousProofOfWork : TRawBytes;
   block : TBlockAccount;
   P : PBlockAccount;
@@ -3262,10 +3279,10 @@ begin
           if TStreamOp.ReadAnsiString(Stream,raw)<0 then exit;
           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].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 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 FCurrentProtocol>=CT_PROTOCOL_2 then begin
             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 (Length(block.accounts[iacc].account_data)>CT_MaxAccountDataSize) 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;
           //
-          if Stream.Read(block.accounts[iacc].previous_updated_block,4)<4 then exit;
           // check valid
           If (Length(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;
   iacc : integer;
   Stream : TStream;
+  LCardinal : Cardinal;
 begin
   b := Block(nblock);
   if DestStream is TMemoryStream then Stream := DestStream
@@ -3537,9 +3556,12 @@ begin
       Stream.Write(b.accounts[iacc].account,Sizeof(b.accounts[iacc].account));
       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].updated_on_block,Sizeof(b.accounts[iacc].updated_on_block));
       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));
+      end else begin
+        LCardinal := b.accounts[iacc].GetLastUpdatedBlock;
+        Stream.Write(LCardinal,SizeOf(LCardinal));
       end;
       Stream.Write(b.accounts[iacc].n_operation,Sizeof(b.accounts[iacc].n_operation));
       If FCurrentProtocol>=CT_PROTOCOL_2 then begin
@@ -3549,8 +3571,10 @@ begin
       if FCurrentProtocol>=CT_PROTOCOL_5 then begin
         TStreamOp.WriteAnsiString(Stream,b.accounts[iacc].account_data);
         TStreamOp.WriteAnsiString(Stream,b.accounts[iacc].account_seal);
+      end else begin
+        LCardinal := 0;
+        Stream.Write(LCardinal,Sizeof(LCardinal));
       end;
-      Stream.Write(b.accounts[iacc].previous_updated_block,Sizeof(b.accounts[iacc].previous_updated_block));
     end;
     TStreamOp.WriteAnsiString(Stream,b.block_hash);
     Stream.Write(b.accumulatedWork,Sizeof(b.accumulatedWork));
@@ -4178,7 +4202,7 @@ procedure TPCSafeBox.SearchBlockWhenOnSeparatedChain(blockNumber: Cardinal; out
     // Is valid?
     maxUB := 0;
     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;
     Result := (maxUB <= FPreviousSafeboxOriginBlock);
   end;
@@ -4219,8 +4243,8 @@ end;
 procedure TPCSafeBox.UpdateAccount(account_number : Cardinal; const newAccountInfo: TAccountInfo;
   const newName : TRawBytes; newType : Word; newBalance: UInt64; newN_operation: Cardinal;
   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;
   i,j,iAccount, iDeleted, iAdded : Integer;
   lastbalance : UInt64;
@@ -4258,9 +4282,8 @@ begin
   If (accountUpdateStyle In [aus_rollback,aus_commiting_from_otherchain]) then begin
     // Directly update name and updated values
     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].previous_updated_block:=newPrevious_Updated_block;
   end else begin
     // Name:
     If Not TBaseType.Equals(blockAccount.accounts[iAccount].name,newName) then begin
@@ -4325,15 +4348,19 @@ begin
         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;
     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
       blockAccount.accounts[iAccount].updated_on_block_active_mode := BlocksCount;
     end;
+    if (AHasBenUpdatedOnPasiveMode) then begin
+      blockAccount.accounts[iAccount].updated_on_block_passive_mode := BlocksCount;
+    end;
   end;
 
   // New Protocol 5 fields
@@ -4477,29 +4504,14 @@ begin
   // NOTE:
   // 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(LPAccountToBuy_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
   LPBuyerAccount^.n_operation := ANOperation;
   // Set new balance values
@@ -4558,8 +4570,10 @@ begin
             Pa^.account_data,
             Pa^.account_seal,
             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;
     //
     if (Origin_TotalBalance<>FTotalBalance) then begin
@@ -4782,37 +4796,18 @@ begin
     Exit;
   end;
 
+  previous.UpdateIfLower(PaccSender^.account,PaccSender^.GetLastUpdatedBlock);
+  previous.UpdateIfLower(PaccTarget^.account,PaccTarget^.GetLastUpdatedBlock);
+
   UpdateSealAndActiveModeFlag(PaccSender_Sealed,AOpID,True);
   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
+    previous.UpdateIfLower(PaccSigner^.account,PaccSigner^.GetLastUpdatedBlock);
     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^.balance := PaccSender^.balance - (fee);
     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
     PaccSender^.n_operation := n_operation;
     PaccSender^.balance := PaccSender^.balance - (amount + fee);
@@ -4923,26 +4918,20 @@ begin
   for i:=Low(senders) to High(senders) do begin
     PaccSender := GetInternalAccount(senders[i],PaccSender_Sealed);
 
+    previous.UpdateIfLower(PaccSender^.account,PaccSender^.GetLastUpdatedBlock);
+
     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);
     PaccSender^.balance := PaccSender^.balance - (sender_amounts[i]);
   end;
   for i:=Low(receivers) to High(receivers) do begin
     PaccTarget := GetInternalAccount(receivers[i],PaccTarget_Sealed);
 
+    previous.UpdateIfLower(PaccTarget^.account,PaccTarget^.GetLastUpdatedBlock);
+
     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];
   end;
   Dec(FTotalBalance,nTotalFee);
@@ -5034,28 +5023,13 @@ begin
   end;
   // 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_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;
-  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^.name := newName;
@@ -5072,6 +5046,15 @@ begin
   FOrderedList.DoUpdateSealIfNeeded(APtrSealedAccount,AOpID);
   if ASetUsedAsActiveMode then begin
     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;
 
@@ -5104,6 +5087,7 @@ begin
     New(p^.AccountSealed);
     p^.AccountSealed^ := PSealedAccount(ASource.FList[i])^.AccountSealed^;
     p^.SealChangesCounter := PSealedAccount(ASource.FList[i])^.SealChangesCounter;
+    p^.UsedAsPasiveMode := PSealedAccount(ASource.FList[i])^.UsedAsPasiveMode;
     p^.UsedAsActiveMode := PSealedAccount(ASource.FList[i])^.UsedAsActiveMode;
     FList.Add(p);
   end;
@@ -5185,6 +5169,7 @@ begin
     New( Result^.AccountSealed );
     Result^.AccountSealed^ := FSafeBoxTransaction.FreezedSafeBox.Account(account_number);
     Result^.SealChangesCounter := 0;
+    Result^.UsedAsPasiveMode := False;
     Result^.UsedAsActiveMode := False;
     FList.Insert(i,Result);
   end else begin
@@ -5957,6 +5942,7 @@ end;
 
 procedure TAccount_Helper.SerializeAccount(AStream: TStream; current_protocol : Word);
 var LRaw : TRawBytes;
+  LCardinal : Cardinal;
 begin
   if current_protocol>=CT_PROTOCOL_5 then TAccountComp.SaveAccountToAStream(AStream,Self,current_protocol)
   else begin
@@ -5964,7 +5950,8 @@ begin
     LRaw := TAccountComp.AccountInfo2RawString(Self.accountInfo);
     AStream.WriteBuffer(LRaw[Low(LRaw)],Length(LRaw));
     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);
     if (current_protocol>=2) then begin
         // Use new Protocol 2 fields

+ 7 - 18
src/core/UBlockChain.pas

@@ -223,9 +223,6 @@ Type
   TPCOperation = Class
   Protected
     FProtocolVersion : Word;
-    FPrevious_Signer_updated_block: Cardinal;
-    FPrevious_Destination_updated_block : Cardinal;
-    FPrevious_Seller_updated_block : Cardinal;
     FHasValidSignature : Boolean;
     FUsedPubkeyForSignature : TECDSA_Public;
     FBufferedSha256 : TRawBytes;
@@ -234,9 +231,6 @@ Type
     function SaveOpToStream(Stream: TStream; SaveExtendedData : 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;
-    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;
     procedure CopyUsedPubkeySignatureFrom(SourceOperation : TPCOperation); virtual;
     function SaveOperationPayloadToStream(const AStream : TStream; const APayload : TOperationPayload) : Boolean;
@@ -2464,9 +2458,6 @@ begin
         op.SaveOpToStream(msCopy,true);
         msCopy.Position := 0;
         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.FUsedPubkeyForSignature := op.FUsedPubkeyForSignature;
         P^.Op.FBufferedSha256:=op.FBufferedSha256;
@@ -3091,9 +3082,6 @@ end;
 procedure TPCOperation.InitializeData(AProtocolVersion : Word);
 begin
   FProtocolVersion := AProtocolVersion;
-  FPrevious_Signer_updated_block := 0;
-  FPrevious_Destination_updated_block := 0;
-  FPrevious_Seller_updated_block := 0;
   FHasValidSignature := false;
   FUsedPubkeyForSignature:=CT_TECDSA_Public_Nul;
   FBufferedSha256 := Nil;
@@ -3136,24 +3124,25 @@ begin
 end;
 
 function TPCOperation.LoadFromStorage(Stream: TStream; LoadProtocolVersion:Word; APreviousUpdatedBlocks : TAccountPreviousBlockInfo): Boolean;
+var LPrevious_Signer, LPrevious_Destination, LPrevious_Seller : Cardinal;
 begin
   Result := false;
   If LoadOpFromStream(Stream, LoadProtocolVersion>=CT_PROTOCOL_2) then begin
     If LoadProtocolVersion<CT_PROTOCOL_3 then begin
       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
-        Stream.Read(FPrevious_Seller_updated_block,Sizeof(FPrevious_Seller_updated_block));
+        Stream.Read(LPrevious_Seller,Sizeof(LPrevious_Seller));
       end;
       if Assigned(APreviousUpdatedBlocks) then begin
         // Add to previous list!
         if SignerAccount>=0 then
-          APreviousUpdatedBlocks.UpdateIfLower(SignerAccount,FPrevious_Signer_updated_block);
+          APreviousUpdatedBlocks.UpdateIfLower(SignerAccount,LPrevious_Signer);
         if DestinationAccount>=0 then
-          APreviousUpdatedBlocks.UpdateIfLower(DestinationAccount,FPrevious_Destination_updated_block);
+          APreviousUpdatedBlocks.UpdateIfLower(DestinationAccount,LPrevious_Destination);
         if SellerAccount>=0 then
-          APreviousUpdatedBlocks.UpdateIfLower(SellerAccount,FPrevious_Seller_updated_block);
+          APreviousUpdatedBlocks.UpdateIfLower(SellerAccount,LPrevious_Seller);
       end;
     end;
     Result := true;

+ 7 - 7
src/core/UConst.pas

@@ -41,9 +41,9 @@ Const
     {$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_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_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
   // IMPORTANT NOTE!!!
@@ -138,9 +138,9 @@ Const
 
   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;
   // Value of Operations type in Protocol 1
@@ -195,7 +195,7 @@ Const
   CT_OpSubtype_Data_Signer                = 103;
   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'
                     {$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 StartOperation>EndOperation then Exit;
   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;
     end else begin
       startBlock := SearchBackwardsStartingAtBlock;
       lastBalance := -1;
     end;
-    DoGetFromBlock(startBlock,lastBalance,MaxDepth,0,startBlock<>acc.updated_on_block);
+    DoGetFromBlock(startBlock,lastBalance,MaxDepth,0,startBlock<>acc.GetLastUpdatedBlock);
   end;
 end;
 
@@ -1093,7 +1093,7 @@ begin
           end;
         end;
       end;
-      block := Bank.SafeBox.Account(account).updated_on_block;
+      block := Bank.SafeBox.Account(account).GetLastUpdatedBlock;
     finally
       UnlockMempoolRead;
     end;
@@ -1208,7 +1208,7 @@ begin
       UnlockMempoolRead;
     End;
     // 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
   end;
   if (block=0) or (block>=Bank.BlocksCount) then exit;

+ 0 - 12
src/core/UOpTransaction.pas

@@ -595,8 +595,6 @@ begin
     Exit;
   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
     account_target.accountInfo.accountKey := FData.new_accountkey;
   end;
@@ -906,8 +904,6 @@ begin
 
   {$endregion}
 
-  FPrevious_Signer_updated_block := LSender.updated_on_block;
-  FPrevious_Destination_updated_block := LTarget.updated_on_block;
 
   // Is buy account ?
   if (FData.opTransactionStyle = buy_Account ) then begin
@@ -979,7 +975,6 @@ begin
     If Not (TAccountComp.IsValidAccountKey(FData.new_accountkey,AErrors)) then exit; // BUG 20171511
     LBuyAccountNewPubkey := FData.new_accountkey;
     {$endregion}
-    FPrevious_Seller_updated_block := LSeller.updated_on_block;
   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
@@ -1030,7 +1025,6 @@ begin
     FData.AccountPrice := LTarget.accountInfo.price;
     FData.SellerAccount := 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
       // We will save extra info that account key has not changed
       FData.new_accountkey := CT_TECDSA_Public_Nul;
@@ -1508,8 +1502,6 @@ begin
     Exit;
   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;
   // Set to normal:
   account_target.accountInfo.state := as_Normal;
@@ -1781,7 +1773,6 @@ begin
   if Not TAccountComp.IsValidAccountKey(FData.new_accountkey,errors) then begin
     Exit;
   end;
-  FPrevious_Signer_updated_block := acc.updated_on_block;
   Result := AccountTransaction.UpdateAccountInfo(AccountPreviousUpdatedBlock,
     GetOpID,
     FData.account,FData.n_operation, FData.account,
@@ -2085,9 +2076,6 @@ begin
     Exit;
   end;
 
-  FPrevious_Signer_updated_block := account_signer.updated_on_block;
-  FPrevious_Destination_updated_block := account_target.updated_on_block;
-
   if LIsDelist then begin
     account_target.accountInfo.state := as_Normal;
     account_target.accountInfo.locked_until_block := CT_AccountInfo_NUL.locked_until_block;

+ 1 - 1
src/core/UPCRPCOpData.pas

@@ -276,7 +276,7 @@ begin
       Exit;
     end;
     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
   end;
 

+ 42 - 15
src/core/UPoolMinerThreads.pas

@@ -63,14 +63,14 @@ Type
     FTestingMode: Boolean;
     Procedure OnPoolMinerClientConnectionChanged(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 SetMinerAddName(AValue: String);
     procedure SetTestingPoWLeftBits(AValue: Byte);
   protected
     procedure BCExecute; override;
   public
-    Constructor Create(RemoteHost : String; RemotePort : Integer; InitialAccountKey : TAccountKey);
+    Constructor Create(RemoteHost : String; RemotePort : Integer; const AUserName, APassword : String);
     Destructor Destroy; override;
     Property PoolMinerClient : TPoolMinerClient read FPoolMinerClient;
     Property OnConnectionStateChanged : TNotifyEvent read FOnConnectionStateChanged write FOnConnectionStateChanged;
@@ -185,12 +185,15 @@ Var nID : Cardinal;
   i : Integer;
   ResponseMethod : String;
   l : TList<TCustomMinerDeviceThread>;
+  LParams : TPCJSONArray;
+  LPoolResult : TPCJSONObject;
 begin
   DebugStep:='Starting';
   Try
     while not Terminated do begin
       if FTestingMode then begin
       end else if not FPoolMinerClient.Connected then begin
+        FPoolMinerClient.Stratum_Authorized := False;
         DebugStep:='Not connected';
         If Not FPoolMinerClient.Connect then begin
         end else begin
@@ -198,9 +201,12 @@ begin
         end;
       end else begin
           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;
           try
             DebugStep:='Starting repeat';
@@ -232,7 +238,7 @@ begin
   End;
 end;
 
-constructor TPoolMinerThread.Create(RemoteHost: String; RemotePort: Integer; InitialAccountKey : TAccountKey);
+constructor TPoolMinerThread.Create(RemoteHost: String; RemotePort: Integer; const AUserName, APassword : String);
 begin
   FGlobalMinerValuesForWork := CT_TMinerValuesForWork_NULL;
   FPoolMinerClient := TPoolMinerClient.Create(Nil);
@@ -241,6 +247,13 @@ begin
   FPoolMinerClient.OnMinerMustChangeValues := OnPoolMinerMustChangeValues;
   FPoolMinerClient.OnConnect := 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;
   FDevicesList := TPCThreadList<TCustomMinerDeviceThread>.Create('TPoolMinerThread_DevicesList');
   FMinerThreads := 0;
@@ -351,12 +364,11 @@ begin
   else FTestingPoWLeftBits:=0;
 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
   FDevicesList.LockList;
   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
     FDevicesList.UnlockList;
   end;
@@ -386,14 +398,19 @@ Var l : TList<TCustomMinerDeviceThread>;
   minervfw : TMinerValuesForWork;
   auxminervfw : TMinerValuesForWork;
   auxRaw : TRawBytes;
+  s : String;
 begin
   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;
   Try
     for i := 0 to l.Count - 1 do begin
       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);
       TBaseType.Concat(minervfw.payload_start,auxRaw,minervfw.payload_start);
       if (l.count>1) then begin
@@ -410,6 +427,8 @@ begin
           end;
         until (Ok);
       end;
+
+      end;
       If FTestingPoWLeftBits>0 then begin
         auxminervfw := minervfw;
         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);
       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
     FDevicesList.UnlockList;
   End;
@@ -507,7 +530,7 @@ begin
     LHash := TCrypto.DoSha256(TCrypto.DoSha256(digest));
   if (TBaseType.BinStrComp(LHash,usedMinerValuesForWork.target_pow)<=0) then begin
     inc(FGlobaDeviceStats.WinsCount);
-    FPoolMinerThread.OnMinerNewBlockFound(self,usedMinerValuesForWork,Timestamp,nOnce);
+    FPoolMinerThread.OnMinerNewBlockFound(self,usedMinerValuesForWork,Timestamp,nOnce,LHash);
     If Assigned(FOnFoundNOnce) then FOnFoundNOnce(Self,Timestamp,nOnce);
   end else begin
     inc(FGlobaDeviceStats.Invalids);
@@ -523,15 +546,18 @@ end;
 procedure TCustomMinerDeviceThread.CreateDigest(const AMinerValuesForWork: TMinerValuesForWork; Timestamp, nOnce: Cardinal; var ODigest: TRawBytes);
 begin
   // 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],
     ODigest[0],
     Length(AMinerValuesForWork.part1));
   move(AMinerValuesForWork.payload_start[0],
     ODigest[Length(AMinerValuesForWork.part1)],
     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],
-    ODigest[ Length(AMinerValuesForWork.part1) + Length(AMinerValuesForWork.payload_start) ],
+    ODigest[ Length(AMinerValuesForWork.part1) + Length(AMinerValuesForWork.payload_start) + Length(AMinerValuesForWork.extraNOnce2_Used) ],
     Length(AMinerValuesForWork.part3));
   // Add timestamp and nonce
   move(Timestamp,ODigest[length(ODigest)-8],4);
@@ -582,7 +608,8 @@ var aux : Integer;
 begin
   FMinerValuesForWork := Value;
   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);
 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_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
   TMinerValuesForWork = Record
@@ -52,10 +55,20 @@ Type
      target : Cardinal;
      timestamp : Cardinal;
      target_pow : TRawBytes;
-     // Stratum jobid
+     // Stratum information
      jobid : String;
+     extraNOnce2_Size : Integer;
+     extraNOnce2_Used : TRawBytes;
   End;
 
+  { TMinerValuesForWork_HELPER }
+
+  TMinerValuesForWork_HELPER = record helper for TMinerValuesForWork
+     function FinalPayload : TRawBytes;
+     function IsStratum : Boolean;
+  end;
+
+
   TProcessJSONObjectEvent = Procedure (json : TPCJSONObject; method : String) of object;
 
   { TJSONRPCTcpIpClient }
@@ -79,7 +92,7 @@ Type
     Function GetNewId : Cardinal;
   End;
 
-  TPoolType = (ptNone,ptIdentify);
+  TPoolType = (ptSolomine,ptPoolSubscription);
 
   { TPoolMinerClient }
 
@@ -92,6 +105,8 @@ Type
     FPoolType: TPoolType;
     FStratum_Target_PoW: TRawBytes;
     FUserName: String;
+    FStratumAuthorized : Boolean;
+    FStratum_ExtraNOnce2_Size: Integer;
     procedure SetMinerValuesForWork(const Value: TMinerValuesForWork);
   protected
     Procedure DoOnConnect; Override;
@@ -99,13 +114,15 @@ Type
     Constructor Create(AOwner : TComponent); override;
     Property OnMinerMustChangeValues : TNotifyEvent read FOnMinerMustChangeValues write FOnMinerMustChangeValues;
     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);
     Property PoolType : TPoolType read FPoolType write FPoolType;
     Property UserName : String read FUserName write FUserName;
     Property Password : String read FPassword write FPassword;
     Property PoolFinalMinerName : TRawBytes read FPoolFinalMinerName;
     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;
 
   TPoolMiningServer = Class;
@@ -166,7 +183,7 @@ Type
 Function TBytesToString(Const bytes : TBytes):AnsiString;
 
 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
 
@@ -191,6 +208,27 @@ Begin
   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 }
 
 constructor TJSONRPCTcpIpClient.Create(AOwner: TComponent);
@@ -317,10 +355,11 @@ begin
           Try
             if jsonData is TPCJSONObject then begin
               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!
                 FlushBufferPendingMessages(true,jsonObject.AsInteger('id',0));
               end;
+              TLog.NewLog(ltdebug,ClassName,'Received JSON: '+jsonObject.ToJSON(false));
               Result := true;
               exit;
             end else begin
@@ -413,7 +452,7 @@ begin
       P^.method:=method;
       FPendingResponseMessages.Add(P);
     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;
     try
       json.SaveToStream(stream);
@@ -1057,11 +1096,13 @@ end;
 constructor TPoolMinerClient.Create(AOwner: TComponent);
 begin
   FMinerValuesForWork := CT_TMinerValuesForWork_NULL;
-  FPoolType:=ptNone;
+  FPoolType:=ptSolomine;
   FUserName:='';
   FPassword:='';
   FPoolFinalMinerName:=Nil;
   FStratum_Target_PoW:=Nil;
+  FStratumAuthorized := False;
+  FStratum_ExtraNOnce2_Size := 0;
   inherited;
 end;
 
@@ -1073,44 +1114,24 @@ Var params : TPCJSONArray;
   i : Integer;
 begin
   inherited DoOnConnect;
-  If FPoolType=ptIdentify then begin
+  If FPoolType=ptPoolSubscription then begin
     // Pool initialization
     params := TPCJSONArray.Create;
     resultObject := TPCJSONObject.Create;
     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
       resultObject.free;
       params.free;
@@ -1127,8 +1148,105 @@ Var method : String;
   params : TPCJSONData;
   mvfw : TMinerValuesForWork;
   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
-  TLog.NewLog(ltdebug,ClassName,'Received JSON: '+json.ToJSON(false));
   params := Nil;
   params_as_object := Nil;
   params_as_array := Nil;
@@ -1138,19 +1256,20 @@ begin
     if (i>=0) then begin
       params := json.Items[i];
     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
     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;
   If Assigned(params) then begin
     if (params is TPCJSONNameValue) then begin
       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);
-    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;
   i := json.IndexOfName('id');
   if i<0 then begin
@@ -1172,7 +1291,7 @@ begin
       mvfw.timestamp := pobject.AsInteger('timestamp',0);
       mvfw.part1 := TCrypto.HexaToRaw(pobject.AsString('part1',''));
       mvfw.target_pow := TCrypto.HexaToRaw(pobject.AsString('target_pow',''));
-      If FPoolType=ptIdentify then begin
+      If FPoolType=ptPoolSubscription then begin
         mvfw.jobid:=pobject.AsString('jobid','');
       end;
       if (Not VarIsNull(id_value)) And (ResponseMethod='') then begin
@@ -1180,6 +1299,40 @@ begin
       end;
       MinerValuesForWork := mvfw;
     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;
 
@@ -1218,32 +1371,60 @@ begin
       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);
 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
-  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);
+      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
-      resultJSON.free;
-    end;
-  Finally
-    json.Free;
-  End;
+      json.Free;
+    End;
+  end;
 end;
 
 { TPoolMiningServerThread }

+ 3 - 2
src/core/URPC.pas

@@ -420,8 +420,9 @@ Begin
   jsonObj.GetAsVariant('balance').Value:=TAccountComp.FormatMoneyDecimal(account.balance);
   jsonObj.GetAsVariant('balance_s').Value:=TAccountComp.FormatMoney(account.balance);
   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
     as_Normal : jsonObj.GetAsVariant('state').Value:='normal';
     as_ForSale : begin

+ 17 - 18
src/core/URandomHash.pas

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

+ 3 - 1
src/core/UTCPIP.pas

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

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

@@ -21,148 +21,109 @@ object FRMAbout: TFRMAbout
   object Image1: TImage
     Left = 15
     Top = 15
-    Width = 60
-    Height = 60
+    Width = 64
+    Height = 64
     AutoSize = True
     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
   object Label1: TLabel
     Left = 90
     Top = 15
-    Width = 382
+    Width = 384
     Height = 25
-    Caption = 'Pascal Coin Wallet, Miner && Explorer'
+    Caption = 'Pascal full node Wallet (Classic GUI)'
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clBlack
     Font.Height = -21
@@ -260,9 +221,11 @@ object FRMAbout: TFRMAbout
       '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' +

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

@@ -1,7 +1,7 @@
 object FRMAbout: TFRMAbout
-  Left = 764
+  Left = 781
   Height = 405
-  Top = 516
+  Top = 436
   Width = 585
   ActiveControl = bbClose
   BorderIcons = [biSystemMenu]
@@ -18,147 +18,94 @@ object FRMAbout: TFRMAbout
   LCLVersion = '1.8.0.6'
   object Image1: TImage
     Left = 15
-    Height = 60
+    Height = 64
     Top = 15
-    Width = 60
+    Width = 64
     AutoSize = True
     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
   object Label1: TLabel
     Left = 90
     Height = 25
     Top = 15
-    Width = 382
-    Caption = 'Pascal Coin Wallet, Miner && Explorer'
+    Width = 384
+    Caption = 'Pascal full node Wallet (Classic GUI)'
     Font.Color = clBlack
     Font.Height = -21
     Font.Name = 'Tahoma'
@@ -253,7 +200,7 @@ object FRMAbout: TFRMAbout
       'Copyright (c) 2016 - 2019 PascalCoin developers'
       '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.'
       ''

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

@@ -1,7 +1,7 @@
 object FRMWallet: TFRMWallet
   Left = 389
   Top = 201
-  Caption = 'Pascal Coin Wallet, JSON-RPC Miner & Explorer'
+  Caption = 'Pascal full node Wallet (Classic GUI)'
   ClientHeight = 580
   ClientWidth = 865
   Color = clBtnFace
@@ -30,140 +30,102 @@ object FRMWallet: TFRMWallet
     object Image1: TImage
       Left = 15
       Top = 15
-      Width = 62
-      Height = 62
+      Width = 64
+      Height = 64
+      AutoSize = True
       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
     object lblCurrentBlockCaption: TLabel
       Left = 90
@@ -671,10 +633,6 @@ object FRMWallet: TFRMWallet
         object tsMultiSelectAccounts: TTabSheet
           Caption = 'Selected Accounts For Batch Operation'
           ImageIndex = 1
-          ExplicitLeft = 0
-          ExplicitTop = 0
-          ExplicitWidth = 0
-          ExplicitHeight = 0
           object dgSelectedAccounts: TDrawGrid
             Left = 41
             Top = 31
@@ -866,10 +824,6 @@ object FRMWallet: TFRMWallet
     object tsPendingOperations: TTabSheet
       Caption = 'Pending Operations'
       ImageIndex = 5
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object dgPendingOperations: TDrawGrid
         Left = 0
         Top = 86
@@ -916,10 +870,6 @@ object FRMWallet: TFRMWallet
     object tsBlockChain: TTabSheet
       Caption = 'Block Explorer'
       ImageIndex = 1
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object Panel2: TPanel
         Left = 0
         Top = 0
@@ -1012,10 +962,6 @@ object FRMWallet: TFRMWallet
     object tsOperations: TTabSheet
       Caption = 'Operations Explorer'
       ImageIndex = 1
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object Panel1: TPanel
         Left = 0
         Top = 0
@@ -1064,10 +1010,6 @@ object FRMWallet: TFRMWallet
     object tsLogs: TTabSheet
       Caption = 'Logs'
       ImageIndex = 2
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object pnlTopLogs: TPanel
         Left = 0
         Top = 0
@@ -1099,10 +1041,6 @@ object FRMWallet: TFRMWallet
     object tsNodeStats: TTabSheet
       Caption = 'Node Stats'
       ImageIndex = 3
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       DesignSize = (
         857
         438)
@@ -1172,10 +1110,6 @@ object FRMWallet: TFRMWallet
     object tsMessages: TTabSheet
       Caption = 'Messages'
       ImageIndex = 6
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       DesignSize = (
         857
         438)

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

@@ -1,9 +1,9 @@
 object FRMWallet: TFRMWallet
-  Left = -1233
+  Left = 634
   Height = 600
-  Top = -403
+  Top = 201
   Width = 865
-  Caption = 'Pascal Coin Wallet, JSON-RPC Miner & Explorer'
+  Caption = 'Pascal full node Wallet (Classic GUI)'
   ClientHeight = 580
   ClientWidth = 865
   Color = clBtnFace
@@ -16,7 +16,7 @@ object FRMWallet: TFRMWallet
   OnCreate = FormCreate
   OnDestroy = FormDestroy
   Position = poScreenCenter
-  LCLVersion = '2.0.2.0'
+  LCLVersion = '1.8.0.6'
   object pnlTop: TPanel
     Left = 0
     Height = 91
@@ -29,139 +29,86 @@ object FRMWallet: TFRMWallet
     TabOrder = 0
     object Image1: TImage
       Left = 15
-      Height = 60
+      Height = 64
       Top = 15
-      Width = 60
+      Width = 64
       AutoSize = True
       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
     object lblCurrentBlockCaption: TLabel
@@ -1245,8 +1192,8 @@ object FRMWallet: TFRMWallet
   end
   object TimerUpdateStatus: TTimer
     OnTimer = TimerUpdateStatusTimer
-    left = 25
-    top = 45
+    left = 32
+    top = 56
   end
   object MainMenu: TMainMenu
     left = 165

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

@@ -902,7 +902,7 @@ begin
   Strings.Add('');
   Strings.Add(Format('Current balance: %s',[TAccountComp.FormatMoney(account.balance)]));
   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('Public key type: %s',[TAccountComp.GetECInfoTxt(account.accountInfo.accountKey.EC_OpenSSL_NID)]));
   Strings.Add(Format('Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.accountKey)]));
@@ -1326,7 +1326,7 @@ begin
   MinersBlocksFound := 0;
   lblBuild.Caption := 'Build: '+CT_ClientAppVersion;
   {$IFDEF TESTNET}
-  Image1.visible := false;
+  lblBuild.Font.Color := clRed;
   {$ENDIF}
   PageControl.Enabled := False;
   PageControl.Visible := False;

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

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

+ 5 - 14
src/pascalcoin_miner.lpi

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

+ 24 - 29
src/pascalcoin_miner.pp

@@ -46,7 +46,6 @@ type
   protected
     FWindow32X1,FWindow32Y1,FWindow32X2,FWindow32Y2: DWord;
     FLock : TCriticalSection;
-    FPrivateKey : TECPrivateKey;
     FPoolMinerThread : TPoolMinerThread;
     FDeviceThreads : TList;
     FAppStartTime : TDateTime;
@@ -58,7 +57,7 @@ type
   end;
 
 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_ConnectionStatus = 4;
   CT_Line_MinerValues = 7;
@@ -105,7 +104,7 @@ Const CT_state : Array[boolean] of String = ('Disconnected','Connected');
 var i : Integer;
   s : String;
 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+'"';
   If FPoolMinerThread.PoolMinerClient.Connected then begin
     WriteLine(CT_Line_ConnectionStatus,s + ' server: '+FPoolMinerThread.PoolMinerClient.ClientRemoteAddr);
@@ -203,6 +202,7 @@ var
   ErrorMsg: String;
   s : String;
   nsarr : TNodeServerAddressArray;
+  LLog : TLog;
 
   Function AddMiners : Boolean;
   var p,d,c,i : Integer;
@@ -345,17 +345,11 @@ var
 
   Procedure DoVisualprocess(minerName, UserName, Password : String);
   Var sc : tcrtcoord;
-    Flog : TLog;
     devt : TCustomMinerDeviceThread;
     i : Integer;
   Begin
-    FPoolMinerThread := TPoolMinerThread.Create(nsarr[0].ip,nsarr[0].port,FPrivateKey.PublicKey);
+    FPoolMinerThread := TPoolMinerThread.Create(nsarr[0].ip,nsarr[0].port,UserName,Password);
     try
-      If (UserName<>'') then begin
-        FPoolMinerThread.PoolMinerClient.PoolType:=ptIdentify;
-        FPoolMinerThread.PoolMinerClient.UserName:=UserName;
-        FPoolMinerThread.PoolMinerClient.Password:=Password;
-      end;
       If Not AddMiners then exit;
       if HasOption('t','testmode') then begin
         i := StrToIntDef(GetOptionValue('t','testmode'),-1);
@@ -393,12 +387,11 @@ var
         end else begin
           WriteLine(2,'Mining using '+IntToStr(FDeviceThreads.Count)+' devices');
         end;
-        Flog := TLog.Create(Nil);
+        LLog.OnInThreadNewLog:=OnInThreadNewLog;
         try
-          Flog.OnInThreadNewLog:=OnInThreadNewLog;
           DoWaitAndLog;
         finally
-          FLog.free;
+          LLog.OnInThreadNewLog:=Nil;
         end;
       finally
         cursoron;
@@ -411,11 +404,21 @@ var
 
 Var username,password : String;
 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;
   FLock := TCriticalSection.Create;
   Try
     // 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
       //ShowException(Exception.Create(ErrorMsg));
       WriteLn(ErrorMsg);
@@ -486,37 +489,27 @@ begin
         WriteLn('Input Pool username (or empty for non pool connection):');
         Readln(username);
       end;
-      if (password='') And (username<>'') then begin
-        WriteLn('Input Pool password for user ',username,':');
-        Readln(password);
-      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
     FreeAndNil(FLock);
     FreeAndNil(FLastLogs);
     if not terminated then
       Terminate;
   end;
+
+  finally
+    FreeAndNil(LLog);
+  end;
 end;
 
 constructor TPascalMinerApp.Create(TheOwner: TComponent);
-Var FLog : TLog;
 begin
   inherited Create(TheOwner);
   FDeviceThreads := TList.Create;
   StopOnException:=True;
   FAppStartTime := Now;
-  FLog := TLog.Create(self);
-  FLog.SaveTypes:=CT_TLogTypes_DEFAULT;
-  FLog.FileName:=ExtractFileDir(ExeName)+PathDelim+'PascalCoinMiner.log';
 end;
 
 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('  -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('  -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('  (Not needed for PascalCoin core, only some third party pools)');
   writeln('  -u USERNAME');