Browse Source

Updating gui-classic with Node Mempool object using locking/unlocking

PascalCoin 6 years ago
parent
commit
464afd7a7d

+ 15 - 15
src/gui-classic/UFRMOperation.pas

@@ -254,7 +254,7 @@ begin
     for iAcc := 0 to Length(_senderAccounts) - 1 do begin
 loop_start:
       op := Nil;
-      account := FNode.Operations.SafeBoxTransaction.Account(_senderAccounts[iAcc]);
+      account := FNode.GetMempoolAccount(_senderAccounts[iAcc]);
       If Not UpdatePayload(account, errors) then
         raise Exception.Create('Error encoding payload of sender account '+TAccountComp.AccountNumberToAccountTxtNumber(account.account)+': '+errors);
       i := WalletKeys.IndexOfAccountKey(account.accountInfo.accountKey);
@@ -612,7 +612,7 @@ end;
 
 function TFRMOperation.GetDefaultSenderAccount: TAccount;
 begin
-  if FSenderAccounts.Count>=1 then Result := FNode.Operations.SafeBoxTransaction.Account( FSenderAccounts.Get(0) )
+  if FSenderAccounts.Count>=1 then Result := FNode.GetMempoolAccount( FSenderAccounts.Get(0) )
   else Result := CT_Account_NUL;
 end;
 
@@ -667,8 +667,8 @@ begin
   end;
   If SenderAccounts.Count>=1 then begin
     ebSignerAccount.text := TAccountComp.AccountNumberToAccountTxtNumber(SenderAccounts.Get(0));
-    ebChangeName.Text := FNode.Operations.SafeBoxTransaction.Account(SenderAccounts.Get(0)).name.ToPrintable;
-    ebChangeType.Text := IntToStr(FNode.Operations.SafeBoxTransaction.Account(SenderAccounts.Get(0)).account_type);
+    ebChangeName.Text := FNode.GetMempoolAccount(SenderAccounts.Get(0)).name.ToPrintable;
+    ebChangeType.Text := IntToStr(FNode.GetMempoolAccount(SenderAccounts.Get(0)).account_type);
   end else begin
     ebSignerAccount.text := '';
     ebChangeName.Text := '';
@@ -759,7 +759,7 @@ begin
       ebSenderAccount.Text := TAccountComp.AccountNumberToAccountTxtNumber(SenderAccounts.Get(0));
       memoAccounts.Visible := false;
       ebSenderAccount.Visible := true;
-      balance := TNode.Node.Operations.SafeBoxTransaction.Account(SenderAccounts.Get(0)).balance;
+      balance := TNode.Node.GetMempoolAccount(SenderAccounts.Get(0)).balance;
     end else begin
       // Multiple sender accounts
       lblAccountCaption.Caption := 'Accounts';
@@ -767,7 +767,7 @@ begin
       ebSenderAccount.Visible := false;
       accountstext := '';
       for i := 0 to SenderAccounts.Count - 1 do begin
-         acc := TNode.Node.Operations.SafeBoxTransaction.Account(SenderAccounts.Get(i));
+         acc := TNode.Node.GetMempoolAccount(SenderAccounts.Get(i));
          balance := balance + acc.balance;
          if (accountstext<>'') then accountstext:=accountstext+'; ';
          accountstext := accountstext+TAccountComp.AccountNumberToAccountTxtNumber(acc.account)+' ('+TAccountComp.FormatMoney(acc.balance)+')';
@@ -820,7 +820,7 @@ begin
       errors := 'Invalid account number';
       exit;
     end;
-    AccountToBuy := FNode.Operations.SafeBoxTransaction.Account(c);
+    AccountToBuy := FNode.GetMempoolAccount(c);
     If not TAccountComp.IsAccountForSale(AccountToBuy.accountInfo) then begin
       errors := 'Account '+TAccountComp.AccountNumberToAccountTxtNumber(c)+' is not for sale';
       exit;
@@ -882,7 +882,7 @@ begin
       errors := 'Signer account does not exists '+TAccountComp.AccountNumberToAccountTxtNumber(auxC);
       exit;
     end;
-    SignerAccount := FNode.Operations.SafeBoxTransaction.Account(auxC);
+    SignerAccount := FNode.GetMempoolAccount(auxC);
     if (TAccountComp.IsAccountLocked(SignerAccount.accountInfo,FNode.Bank.BlocksCount)) then begin
       errors := 'Signer account '+TAccountComp.AccountNumberToAccountTxtNumber(SignerAccount.account)+' is locked until block '+IntToStr(SignerAccount.accountInfo.locked_until_block);
       exit;
@@ -981,7 +981,7 @@ begin
         errors := 'Signer account does not exists '+TAccountComp.AccountNumberToAccountTxtNumber(auxC);
         exit;
       end;
-      SignerAccount := FNode.Operations.SafeBoxTransaction.Account(auxC);
+      SignerAccount := FNode.GetMempoolAccount(auxC);
       if (TAccountComp.IsAccountLocked(SignerAccount.accountInfo,FNode.Bank.BlocksCount)) then begin
         errors := 'Signer account '+TAccountComp.AccountNumberToAccountTxtNumber(SignerAccount.account)+' is locked until block '+IntToStr(SignerAccount.accountInfo.locked_until_block);
         exit;
@@ -1027,7 +1027,7 @@ begin
       errors := 'Signer account does not exists '+TAccountComp.AccountNumberToAccountTxtNumber(auxC);
       exit;
     end;
-    SignerAccount := FNode.Operations.SafeBoxTransaction.Account(auxC);
+    SignerAccount := FNode.GetMempoolAccount(auxC);
     if (TAccountComp.IsAccountLocked(SignerAccount.accountInfo,FNode.Bank.BlocksCount)) then begin
       errors := 'Signer account '+TAccountComp.AccountNumberToAccountTxtNumber(SignerAccount.account)+' is locked until block '+IntToStr(SignerAccount.accountInfo.locked_until_block);
       exit;
@@ -1199,7 +1199,7 @@ begin
         errors := 'Signer account does not exists '+TAccountComp.AccountNumberToAccountTxtNumber(auxC);
         exit;
       end;
-      SignerAccount := FNode.Operations.SafeBoxTransaction.Account(auxC);
+      SignerAccount := FNode.GetMempoolAccount(auxC);
       // Seller
       If Not TAccountComp.AccountTxtNumberToAccountNumber(ebSellerAccount.Text,auxC) then begin
         errors := 'Invalid seller account';
@@ -1214,7 +1214,7 @@ begin
         exit;
       end;
 
-      SellerAccount := FNode.Operations.SafeBoxTransaction.Account(auxC);
+      SellerAccount := FNode.GetMempoolAccount(auxC);
       if rbListAccountForPrivateSale.Checked then begin
         lblSaleNewOwnerPublicKey.Enabled := true;
         ebSaleNewOwnerPublicKey.Enabled := true;
@@ -1275,7 +1275,7 @@ begin
     lblTransactionErrors.Caption := errors;
     exit;
   end;
-  DestAccount := TNode.Node.Operations.SafeBoxTransaction.Account(c);
+  DestAccount := TNode.Node.GetMempoolAccount(c);
   if SenderAccounts.Count=1 then begin
     if not TAccountComp.TxtToMoney(ebAmount.Text,amount) then begin
       errors := 'Invalid amount ('+ebAmount.Text+')';
@@ -1322,7 +1322,7 @@ begin
     if (rbEncryptedWithOldEC.Checked) then begin
       // Use sender
       errors := 'Error encrypting';
-      account := FNode.Operations.SafeBoxTransaction.Account(SenderAccount.account);
+      account := FNode.GetMempoolAccount(SenderAccount.account);
       TPCEncryption.DoPascalCoinECIESEncrypt(account.accountInfo.accountKey,TEncoding.ANSI.GetBytes(payload_u),payload_encrypted);
       valid := Length(payload_encrypted)>0;
     end else if (rbEncryptedWithEC.Checked) then begin
@@ -1358,7 +1358,7 @@ begin
           errors := 'Invalid payload encrypted account number: '+TAccountComp.AccountNumberToAccountTxtNumber(dest_account_number);
           exit;
         end;
-        account := FNode.Operations.SafeBoxTransaction.Account(dest_account_number);
+        account := FNode.GetMempoolAccount(dest_account_number);
         TPCEncryption.DoPascalCoinECIESEncrypt(account.accountInfo.accountKey,TEncoding.ANSI.GetBytes(payload_u),payload_encrypted);
         valid := Length(payload_encrypted)>0;
       end else if (PageControlOpType.ActivePage=tsChangePrivateKey) then begin

+ 7 - 1
src/gui-classic/UFRMOperationsExplorer.pas

@@ -604,11 +604,17 @@ begin
 end;
 
 procedure TFRMOperationsExplorer.SetSourceNode(AValue: TNode);
+var LLockedMempool : TPCOperationsComp;
 begin
   if FSourceNode=AValue then Exit;
   FSourceNode:=AValue;
   If Assigned(FSourceNode) then begin
-    FOperationsHashTree.CopyFromHashTree(FSourceNode.Operations.OperationsHashTree);
+    LLockedMempool := FSourceNode.LockMempoolRead;
+    try
+      FOperationsHashTree.CopyFromHashTree(LLockedMempool.OperationsHashTree);
+    finally
+      FSourceNode.UnlockMempoolRead;
+    end;
   end else FOperationsHashTree.ClearHastThree;
 end;
 

+ 21 - 8
src/gui-classic/UFRMWallet.pas

@@ -347,7 +347,7 @@ var pct : String;
 begin
   If TPlatform.GetElapsedMilliseconds(FLastTC)>500 then begin
     FLastTC := TPlatform.GetTickCount;
-    if (totalCount>0) then pct := Format('%.1f',[curPos*100/totalCount])+'%'
+    if (totalCount>0) then pct := Format('%.2f',[curPos*100/totalCount])+'%'
     else pct := '';
     FLastMsg:='Please wait until finished: '+mesage+' '+pct;
     Synchronize(ThreadSafeNotify);
@@ -799,6 +799,7 @@ begin
 end;
 
 procedure TFRMWallet.FinishedLoadingApp;
+var LLockedMempool : TPCOperationsComp;
 begin
   FNodeNotifyEvents.Node := FNode;
   // Init
@@ -815,7 +816,12 @@ begin
   FPoolMiningServer.Port := FAppParams.ParamByName[CT_PARAM_JSONRPCMinerServerPort].GetAsInteger(CT_JSONRPCMinerServer_Port);
   FPoolMiningServer.MinerAccountKey := GetAccountKeyForMiner;
   FPoolMiningServer.MinerPayload := TEncoding.ANSI.GetBytes( FAppParams.ParamByName[CT_PARAM_MinerName].GetAsString('') );
-  FNode.Operations.AccountKey := GetAccountKeyForMiner;
+  LLockedMempool := FNode.LockMempoolWrite;
+  try
+    LLockedMempool.AccountKey := GetAccountKeyForMiner;
+  finally
+    FNode.UnlockMempoolWrite;
+  end;
   FPoolMiningServer.Active := FAppParams.ParamByName[CT_PARAM_JSONRPCMinerServerActive].GetAsBoolean(true);
   FPoolMiningServer.OnMiningServerNewBlockFound := OnMiningServerNewBlockFound;
   FreeAndNil(FBackgroundLabel);
@@ -835,7 +841,7 @@ Var account : TAccount;
   s : String;
 begin
   if AccountNumber<0 then exit;
-  account := FNode.Operations.SafeBoxTransaction.Account(AccountNumber);
+  account := FNode.GetMempoolAccount(AccountNumber);
   if Length(account.name)>0 then s:='Name: '+TEncoding.ANSI.GetString(account.name)
   else s:='';
   Strings.Add(Format('Account: %s %s Type:%d',[TAccountComp.AccountNumberToAccountTxtNumber(AccountNumber),s,account.account_type]));
@@ -2089,6 +2095,7 @@ Var isMining : boolean;
   i,mc : Integer;
   s : String;
   f, favg : real;
+  LLockedMempool : TPCOperationsComp;
 begin
   UpdateNodeStatus;
   mc := 0;
@@ -2098,12 +2105,12 @@ begin
     end else lblCurrentBlock.Caption :=  '(none)';
     lblCurrentAccounts.Caption := Inttostr(FNode.Bank.AccountsCount);
     lblCurrentBlockTime.Caption := UnixTimeToLocalElapsedTime(FNode.Bank.LastOperationBlock.timestamp);
-    FNode.Operations.Lock;
+    LLockedMempool := FNode.LockMempoolRead;
     try
-      lblOperationsPending.Caption := Inttostr(FNode.Operations.Count);
-      lblCurrentDifficulty.Caption := InttoHex(FNode.Operations.OperationBlock.compact_target,8);
+      lblOperationsPending.Caption := Inttostr(LLockedMempool.Count);
+      lblCurrentDifficulty.Caption := InttoHex(LLockedMempool.OperationBlock.compact_target,8);
     finally
-      FNode.Operations.Unlock;
+      FNode.UnlockMempoolRead;
     end;
     favg := FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage);
     f := (CT_NewLineSecondsAvg - favg) / CT_NewLineSecondsAvg;
@@ -2148,6 +2155,7 @@ end;
 procedure TFRMWallet.UpdateConfigChanged;
 Var wa : Boolean;
   i : Integer;
+  LLockedMempool : TPCOperationsComp;
 begin
   tsLogs.TabVisible := FAppParams.ParamByName[CT_PARAM_ShowLogs].GetAsBoolean(false);
   if (Not tsLogs.TabVisible) then begin
@@ -2166,7 +2174,12 @@ begin
     wa := FNode.NetServer.Active;
     FNode.NetServer.Port := FAppParams.ParamByName[CT_PARAM_InternetServerPort].GetAsInteger(CT_NetServer_Port);
     FNode.NetServer.Active := wa;
-    FNode.Operations.BlockPayload := TEncoding.ANSI.GetBytes(FAppParams.ParamByName[CT_PARAM_MinerName].GetAsString(''));
+    LLockedMempool := FNode.LockMempoolWrite;
+    try
+      LLockedMempool.BlockPayload := TEncoding.ANSI.GetBytes(FAppParams.ParamByName[CT_PARAM_MinerName].GetAsString(''));
+    finally
+      FNode.UnlockMempoolWrite;
+    end;
     FNode.NodeLogFilename := TFolderHelper.GetPascalCoinDataFolder+PathDelim+'blocks.log';
   end;
   if Assigned(FPoolMiningServer) then begin

+ 35 - 18
src/gui-classic/UGridUtils.pas

@@ -482,7 +482,7 @@ begin
     n_acc := AccountNumber(ARow);
     if (n_acc>=0) then begin
       if (n_acc>=Node.Bank.AccountsCount) then account := CT_Account_NUL
-      else account := Node.Operations.SafeBoxTransaction.Account(n_acc);
+      else account := Node.GetMempoolAccount(n_acc);
       ndiff := Node.Bank.BlocksCount - account.updated_block;
       if (gdSelected in State) then
         If (gdFocused in State) then DrawGrid.Canvas.Brush.Color := clGradientActiveCaption
@@ -681,6 +681,7 @@ Var list : TList<Cardinal>;
   opc : TPCOperationsComp;
   bstart,bend : int64;
   LOperationsResume : TOperationsResumeList;
+  LLockedMempool : TPCOperationsComp;
 begin
   if Not Assigned(ANode) then exit;
   AList.Clear;
@@ -688,14 +689,19 @@ begin
     if (FOperationsGrid.MustShowAlwaysAnAccount) And (FOperationsGrid.AccountNumber<0) then exit;
 
     if FOperationsGrid.FPendingOperations then begin
-      for i := ANode.Operations.Count - 1 downto 0 do begin
-        Op := ANode.Operations.OperationsHashTree.GetOperation(i);
-        If TPCOperation.OperationToOperationResume(0,Op,True,Op.SignerAccount,OPR) then begin
-          OPR.NOpInsideBlock := i;
-          OPR.Block := ANode.Bank.BlocksCount;
-          OPR.Balance := ANode.Operations.SafeBoxTransaction.Account(Op.SignerAccount).balance;
-          AList.Add(OPR);
+      LLockedMempool := ANode.LockMempoolRead;
+      try
+        for i := LLockedMempool.Count - 1 downto 0 do begin
+          Op := LLockedMempool.OperationsHashTree.GetOperation(i);
+          If TPCOperation.OperationToOperationResume(0,Op,True,Op.SignerAccount,OPR) then begin
+            OPR.NOpInsideBlock := i;
+            OPR.Block := ANode.Bank.BlocksCount;
+            OPR.Balance := LLockedMempool.SafeBoxTransaction.Account(Op.SignerAccount).balance;
+            AList.Add(OPR);
+          end;
         end;
+      finally
+        ANode.UnlockMempoolRead;
       end;
     end else begin
       if FOperationsGrid.AccountNumber<0 then begin
@@ -745,15 +751,20 @@ begin
       end else begin
         list := TList<Cardinal>.Create;
         Try
-          ANode.Operations.OperationsHashTree.GetOperationsAffectingAccount(FOperationsGrid.AccountNumber,list);
-          for i := list.Count - 1 downto 0 do begin
-            Op := ANode.Operations.OperationsHashTree.GetOperation((list[i]));
-            If TPCOperation.OperationToOperationResume(0,Op,False,FOperationsGrid.AccountNumber,OPR) then begin
-              OPR.NOpInsideBlock := i;
-              OPR.Block := ANode.Operations.OperationBlock.block;
-              OPR.Balance := ANode.Operations.SafeBoxTransaction.Account(FOperationsGrid.AccountNumber).balance;
-              AList.Add(OPR);
+          LLockedMempool := ANode.LockMempoolRead;
+          try
+            LLockedMempool.OperationsHashTree.GetOperationsAffectingAccount(FOperationsGrid.AccountNumber,list);
+            for i := list.Count - 1 downto 0 do begin
+              Op := LLockedMempool.OperationsHashTree.GetOperation((list[i]));
+              If TPCOperation.OperationToOperationResume(0,Op,False,FOperationsGrid.AccountNumber,OPR) then begin
+                OPR.NOpInsideBlock := i;
+                OPR.Block := LLockedMempool.OperationBlock.block;
+                OPR.Balance := LLockedMempool.SafeBoxTransaction.Account(FOperationsGrid.AccountNumber).balance;
+                AList.Add(OPR);
+              end;
             end;
+          finally
+            ANode.UnlockMempoolRead;
           end;
         Finally
           list.Free;
@@ -931,6 +942,7 @@ end;
 
 procedure TOperationsGrid.OnNodeNewOperation(Sender: TObject);
 Var l : TList<Cardinal>;
+  LLockedMempool : TPCOperationsComp;
 begin
   Try
     if (AccountNumber<0) then begin
@@ -938,8 +950,13 @@ begin
     end else begin
       l := TList<Cardinal>.Create;
       Try
-        If Node.Operations.OperationsHashTree.GetOperationsAffectingAccount(AccountNumber,l)>0 then begin
-          if l.IndexOf(AccountNumber)>=0 then UpdateAccountOperations;
+        LLockedMempool := Node.LockMempoolRead;
+        try
+          If LLockedMempool.OperationsHashTree.GetOperationsAffectingAccount(AccountNumber,l)>0 then begin
+            if l.IndexOf(AccountNumber)>=0 then UpdateAccountOperations;
+          end;
+        finally
+          Node.UnlockMempoolRead;
         end;
       Finally
         l.Free;