Browse Source

Fix same bugs than 2.1.7

PascalCoin 7 years ago
parent
commit
5ba02fcca3
4 changed files with 88 additions and 97 deletions
  1. 32 21
      src/core/UBlockChain.pas
  2. 21 60
      src/core/UOpTransaction.pas
  3. 21 0
      src/core/UPoolMinerThreads.pas
  4. 14 16
      src/core/UTxMultiOperation.pas

+ 32 - 21
src/core/UBlockChain.pas

@@ -190,8 +190,6 @@ Type
   Private
     Ftag: integer;
   Protected
-    FSignatureChecked : Boolean; // Improvement TPCOperation speed 2.1.6
-    //
     FPrevious_Signer_updated_block: Cardinal;
     FPrevious_Destination_updated_block : Cardinal;
     FPrevious_Seller_updated_block : Cardinal;
@@ -217,6 +215,7 @@ Type
     function OperationFee: UInt64; virtual; abstract;
     function OperationPayload : TRawBytes; virtual; abstract;
     function SignerAccount : Cardinal; virtual; abstract;
+    procedure SignerAccounts(list : TList); virtual;
     function IsSignerAccount(account : Cardinal) : Boolean; virtual;
     function IsAffectedAccount(account : Cardinal) : Boolean; virtual;
     function DestinationAccount : Int64; virtual;
@@ -1854,7 +1853,8 @@ begin
       for i := 0 to l.Count - 1 do begin
         P := l[i];
         // Include to hash tree
-        TCrypto.DoSha256(FHashTree+P^.Op.Sha256,FHashTree);
+        // TCrypto.DoSha256(FHashTree+P^.Op.Sha256,FHashTree);  COMPILER BUG 2.1.6: Using FHashTree as a "out" param can be initialized prior to be updated first parameter!
+        FHashTree := TCrypto.DoSha256(FHashTree+P^.Op.Sha256);
       end;
     Finally
       FHashTreeOperations.UnlockList;
@@ -1938,8 +1938,8 @@ Var msCopy : TMemoryStream;
   h : TRawBytes;
   P : POperationHashTreeReg;
   PaccData : POperationsHashAccountsData;
-  i,npos : Integer;
-  auxs : AnsiString;
+  i,npos,iListSigners : Integer;
+  listSigners : TList;
 begin
   msCopy := TMemoryStream.Create;
   try
@@ -1952,15 +1952,14 @@ begin
     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;
-    P^.Op.FSignatureChecked:=op.FSignatureChecked;
-    h := op.Sha256;
+    h := FHashTree + op.Sha256;
     P^.Op.FBufferedSha256:=op.FBufferedSha256;
     P^.Op.tag := list.Count;
     // Improvement TOperationsHashTree speed 2.1.6
     // Include to hash tree (Only if CalcNewHashTree=True)
     If (CalcNewHashTree) And (Length(FHashTree)=32) then begin
-      TCrypto.DoSha256(FHashTree+h,FHashTree);
+      // TCrypto.DoSha256(FHashTree+op.Sha256,FHashTree);  COMPILER BUG 2.1.6: Using FHashTree as a "out" param can be initialized prior to be updated first parameter!
+      TCrypto.DoSha256(h,FHashTree);
     end;
     npos := list.Add(P);
     // Improvement: Will allow to add duplicate Operations, so add only first to orderedBySha
@@ -1970,16 +1969,24 @@ begin
     end;
     // Improvement TOperationsHashTree speed 2.1.6
     // Mantain an ordered Accounts list with data
-    If Not FindOrderedByAccountData(list,op.SignerAccount,i) then begin
-      New(PaccData);
-      PaccData^.account_number:=op.SignerAccount;
-      PaccData^.account_count:=0;
-      PaccData^.account_without_fee:=0;
-      FListOrderedByAccountsData.Insert(i,PaccData);
-    end else PaccData := FListOrderedByAccountsData[i];
-    Inc(PaccData^.account_count);
-    If op.OperationFee=0 then begin
-      Inc(PaccData^.account_without_fee);
+    listSigners := TList.Create;
+    try
+      op.SignerAccounts(listSigners);
+      for iListSigners:=0 to listSigners.Count-1 do begin
+        If Not FindOrderedByAccountData(list,PtrInt(listSigners[iListSigners]),i) then begin
+          New(PaccData);
+          PaccData^.account_number:=PtrInt(listSigners[iListSigners]);
+          PaccData^.account_count:=0;
+          PaccData^.account_without_fee:=0;
+          FListOrderedByAccountsData.Insert(i,PaccData);
+        end else PaccData := FListOrderedByAccountsData[i];
+        Inc(PaccData^.account_count);
+        If op.OperationFee=0 then begin
+          Inc(PaccData^.account_without_fee);
+        end;
+      end;
+    finally
+      listSigners.Free;
     end;
   finally
     msCopy.Free;
@@ -2243,7 +2250,6 @@ end;
 
 constructor TPCOperation.Create;
 begin
-  FSignatureChecked := False;
   FHasValidSignature := False;
   FBufferedSha256:='';
   InitializeData;
@@ -2278,6 +2284,12 @@ begin
   end else Raise Exception.Create('ERROR DEV 20170426-1'); // This should never happen, if good coded
 end;
 
+procedure TPCOperation.SignerAccounts(list: TList);
+begin
+  list.Clear;
+  list.Add(TObject(SignerAccount));
+end;
+
 class function TPCOperation.DecodeOperationHash(const operationHash: TRawBytes;
   var block, account, n_operation: Cardinal; var md160Hash : TRawBytes) : Boolean;
   { Decodes a previously generated OperationHash }
@@ -2354,7 +2366,6 @@ begin
   FPrevious_Seller_updated_block := 0;
   FHasValidSignature := false;
   FBufferedSha256:='';
-  FSignatureChecked := False;
 end;
 
 procedure TPCOperation.FillOperationResume(Block: Cardinal; getInfoForAllAccounts : Boolean; Affected_account_number: Cardinal; var OperationResume: TOperationResume);

+ 21 - 60
src/core/UOpTransaction.pas

@@ -506,19 +506,11 @@ begin
     end;
   end;
 
-  If Not FSignatureChecked then begin
-    If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    exit;
+  end else FHasValidSignature := true;
   FPrevious_Signer_updated_block := account_signer.updated_block;
   FPrevious_Destination_updated_block := account_target.updated_block;
   If (public_key in FData.changes_type) then begin
@@ -607,7 +599,6 @@ begin
   end else begin
     FHasValidSignature := true;
   end;
-  FSignatureChecked:=True;
 end;
 
 function TOpChangeAccountInfo.toString: String;
@@ -658,7 +649,6 @@ begin
   end else begin
     FHasValidSignature := true;
   end;
-  FSignatureChecked:=True;
 end;
 
 function TOpTransaction.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : AnsiString) : Boolean;
@@ -736,20 +726,12 @@ begin
   end;
 
   // Check signature
-  If Not FSignatureChecked then begin
-    _h := GetTransactionHashToSign(FData);
-    if (Not TCrypto.ECDSAVerify(sender.accountInfo.accountkey,_h,FData.sign)) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      Exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  _h := GetTransactionHashToSign(FData);
+  if (Not TCrypto.ECDSAVerify(sender.accountInfo.accountkey,_h,FData.sign)) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    Exit;
+  end else FHasValidSignature := true;
   //
   FPrevious_Signer_updated_block := sender.updated_block;
   FPrevious_Destination_updated_block := target.updated_block;
@@ -1084,7 +1066,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a new Change key');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 function TOpChangeKey.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : AnsiString) : Boolean;
@@ -1168,19 +1149,11 @@ begin
     end;
   end;
 
-  If Not FSignatureChecked then begin
-    If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    exit;
+  end else FHasValidSignature := true;
 
   FPrevious_Signer_updated_block := account_signer.updated_block;
   FPrevious_Destination_updated_block := account_target.updated_block;
@@ -1393,7 +1366,6 @@ begin
   FData.n_operation := n_operation;
   FData.fee := fee;
   FHasValidSignature := true; // Recover founds doesn't need a signature
-  FSignatureChecked := True;
 end;
 
 function TOpRecoverFounds.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : AnsiString) : Boolean;
@@ -1623,19 +1595,11 @@ begin
     exit;
   end;
 
-  If Not FSignatureChecked then begin
-    If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
-      errors := 'Invalid sign';
-      FHasValidSignature := false;
-      exit;
-    end else FHasValidSignature := true;
-    FSignatureChecked:=True;
-  end else begin
-    If Not FHasValidSignature then begin
-      errors := 'Invalid sign';
-      exit;
-    end;
-  end;
+  If Not TCrypto.ECDSAVerify(account_signer.accountInfo.accountkey,GetOperationHashToSign(FData),FData.sign) then begin
+    errors := 'Invalid sign';
+    FHasValidSignature := false;
+    exit;
+  end else FHasValidSignature := true;
 
   FPrevious_Signer_updated_block := account_signer.updated_block;
   FPrevious_Destination_updated_block := account_target.updated_block;
@@ -1872,7 +1836,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a new list account for sale operation');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 function TOpListAccountForSale.IsDelist: Boolean;
@@ -1900,7 +1863,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a delist account operation');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 function TOpDelistAccountForSale.IsDelist: Boolean;
@@ -1936,7 +1898,6 @@ begin
     TLog.NewLog(lterror,Classname,'Error signing a new Buy operation');
     FHasValidSignature := false;
   end else FHasValidSignature := true;
-  FSignatureChecked:=True;
 end;
 
 procedure TOpBuyAccount.InitializeData;

+ 21 - 0
src/core/UPoolMinerThreads.pas

@@ -716,13 +716,20 @@ Var
   resultPoW : TRawBytes;
   //
   AuxStats : TMinerStats;
+  dstep : Integer;
 begin
+  DebugStep := '----------';
   AuxStats := CT_TMinerStats_NULL;
   nonce := 0;
+  dstep := 0;
+  Try
     while (Not Terminated) do begin
+      Try
+      dstep := 1;
       AuxStats := CT_TMinerStats_NULL;
       If (FCPUDeviceThread.Paused) then sleep(1)
       else begin
+        dstep := 2;
         FLock.Acquire;
         try
           baseRealTC := GetTickCount;
@@ -735,6 +742,7 @@ begin
               FDigestStreamMsg.Position:=FDigestStreamMsg.Size - 8;
               FDigestStreamMsg.Write(ts,4);
               baseHashingTC:=GetTickCount;
+              dstep := 4;
               for i := 1 to CT_Rounds do begin
                 FDigestStreamMsg.Position := FDigestStreamMsg.Size - 4;
                 FDigestStreamMsg.Write(nonce,4);
@@ -742,12 +750,16 @@ begin
                 if resultPoW < FCPUDeviceThread.FMinerValuesForWork.target_pow then begin
                   if Terminated then exit;
                   inc(AuxStats.WinsCount);
+                  dstep := 5;
                   FLock.Release;
                   try
+                    dstep := 6;
                     FCPUDeviceThread.FoundNOnce(ts,nonce);
+                    dstep := 7;
                   finally
                     FLock.Acquire;
                   end;
+                  dstep := 8;
                 end;
                 if (nonce)<FMaxNOnce then inc(nonce) else nonce := FMinNOnce;
               end;
@@ -774,13 +786,22 @@ begin
             AuxStats.RoundsCount:=CT_Rounds;
             AuxStats.WorkingMillisecondsTotal:=GetTickCount - baseRealTC;
             AuxStats.WorkingMillisecondsHashing:= finalHashingTC - baseHashingTC;
+            dstep := 9;
             FCPUDeviceThread.UpdateDeviceStats(AuxStats);
           end; // FDigestStreamMsg.size>8
         finally
           FLock.Release;
         end;
       end; // Not paused
+      Except
+        On E:Exception do begin
+          TLog.NewLog(ltError,ClassName,'EXCEPTION step:'+IntToStr(dstep)+' ' +E.ClassName+':'+E.Message);
+        end;
+      end;
     end; // while
+  Finally
+    DebugStep := IntToStr(dstep);
+  End;
 end;
 
 constructor TCPUOpenSSLMinerThread.Create(CPUDeviceThread : TCPUDeviceThread);

+ 14 - 16
src/core/UTxMultiOperation.pas

@@ -121,6 +121,7 @@ Type
     function OperationFee : UInt64; override;
     function OperationPayload : TRawBytes; override;
     function SignerAccount : Cardinal; override;
+    procedure SignerAccounts(list : TList); override;
     function IsSignerAccount(account : Cardinal) : Boolean; override;
     function DestinationAccount : Int64; override;
     function SellerAccount : Int64; override;
@@ -333,7 +334,6 @@ begin
   SetLength(FData.changesInfo,0);
   FTotalAmount:=0;
   FTotalFee:=0;
-  FSignatureChecked:=False;
   FHasValidSignature:=False;
 
   SetLength(txsenders,0);
@@ -430,7 +430,6 @@ var i : Integer;
   ophtosign : TRawBytes;
 begin
   // Init
-  FSignatureChecked:=True;
   FHasValidSignature:=False;
   SetLength(errors,0);
   // Do check it!
@@ -620,14 +619,7 @@ begin
     end;
   end;
   // Check signatures!
-  If Not FSignatureChecked then begin
-    If Not CheckSignatures(AccountTransaction,errors) then Exit;
-  end else begin
-    If Not FHasValidSignature then begin
-      Errors := 'Not valid signatures found!';
-      Exit;
-    end;
-  end;
+  If Not CheckSignatures(AccountTransaction,errors) then Exit;
   // Execute!
   If (length(senders)>0) then begin
     If Not AccountTransaction.TransferAmounts(AccountPreviousUpdatedBlock,
@@ -741,7 +733,6 @@ begin
     end;
   end;
   If (Result>0) Then begin
-    FSignatureChecked := False;
     FHasValidSignature := False;
   end;
 end;
@@ -775,6 +766,18 @@ begin
   else Result := MaxInt;
 end;
 
+procedure TOpMultiOperation.SignerAccounts(list: TList);
+var i : Integer;
+begin
+  list.Clear;
+  for i := 0 to High(FData.txSenders) do begin
+    list.Add(TObject(FData.txSenders[i].Account));
+  end;
+  for i:= 0 to High(FData.changesInfo) do begin
+    if list.IndexOf(TObject(FData.changesInfo[i].Account))<0 then list.Add(TObject(FData.changesInfo[i].Account));
+  end;
+end;
+
 function TOpMultiOperation.IsSignerAccount(account: Cardinal): Boolean;
 begin
   // This function will override previous due it can be Multi signed
@@ -844,7 +847,6 @@ begin
   AddTx(senders,receivers,True);
   AddChangeInfos(changes,True);
   // Protection for "Exit"
-  FSignatureChecked:=True;
   FHasValidSignature:=False;
   If (length(senders_keys)<>length(senders)) then exit; // Cannot sign!
   If (length(changes_keys)<>length(changes)) then exit; // Cannot sign!
@@ -860,8 +862,6 @@ begin
       Exit;
     end;
   end;
-  FSignatureChecked:=False;
-  FHasValidSignature:=False;
 end;
 
 function TOpMultiOperation.AddTx(const senders: TMultiOpSenders; const receivers: TMultiOpReceivers; setInRandomOrder : Boolean) : Boolean;
@@ -884,7 +884,6 @@ begin
   end;
   // Ok, let's go
   FHasValidSignature:=False;
-  FSignatureChecked:=False;
   If setInRandomOrder then begin
     // Important:
     // When a sender/receiver is added, everybody must sign again
@@ -942,7 +941,6 @@ begin
   end;
   // Ok, let's go
   FHasValidSignature:=False;
-  FSignatureChecked:=False;
   // Important:
   // When a change is added, everybody must sign again
   // In order to create high anonymity, will add in random order