Browse Source

Fix some bugs caused by bad usage of ProtocolVerion in operations

PascalCoin 6 years ago
parent
commit
df9129318c

+ 6 - 5
src/core/UAccounts.pas

@@ -3820,10 +3820,11 @@ begin
       end;
     end else begin
       // If we are here protocol didn't changed... make sure it's not a upgrade block!
-      if (newOperationBlock.block = CT_Protocol_Upgrade_v2_MinBlock)
-           or (newOperationBlock.block = CT_Protocol_Upgrade_v3_MinBlock)
-           or (newOperationBlock.block = CT_Protocol_Upgrade_v4_MinBlock)
-           or (newOperationBlock.block = CT_Protocol_Upgrade_v5_MinBlock) then begin
+      if ((newOperationBlock.block = CT_Protocol_Upgrade_v2_MinBlock) and (newOperationBlock.protocol_version<>CT_PROTOCOL_2))
+           or ((newOperationBlock.block = CT_Protocol_Upgrade_v3_MinBlock) and (newOperationBlock.protocol_version<>CT_PROTOCOL_3))
+           or ((newOperationBlock.block = CT_Protocol_Upgrade_v4_MinBlock) and (newOperationBlock.protocol_version<>CT_PROTOCOL_4))
+           or ((newOperationBlock.block = CT_Protocol_Upgrade_v5_MinBlock) and (newOperationBlock.protocol_version<>CT_PROTOCOL_5))
+           then begin
          errors := Format('In block %d protocol must be upgraded! Current %d',[newOperationBlock.block,newOperationBlock.protocol_version]);
          exit;
       end;
@@ -4446,7 +4447,7 @@ begin
     end;
     for i := 0 to FOrderedList.FList.Count - 1 do begin
       PSealed := PSealedAccount(FOrderedList.FList[i]);
-      Pa := PSealed^.AccountSealed; // PSealedAccount (FOrderedList.FList[i])^.AccountSealed; XXXXXXXXX
+      Pa := PSealed^.AccountSealed;
       FFreezedAccounts.UpdateAccount(Pa^.account,
             Pa^.accountInfo,
             Pa^.name,

+ 36 - 22
src/core/UBlockChain.pas

@@ -237,7 +237,7 @@ Type
     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; current_protocol : Word; const Signature: TECDSA_SIG): Boolean;
+    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;
     function LoadOperationPayloadFromStream(const AStream : TStream; out APayload : TOperationPayload) : Boolean;
@@ -250,7 +250,7 @@ Type
     procedure AffectedAccounts(list : TList<Cardinal>); virtual; abstract;
     class function OpType: Byte; virtual; abstract;
     Class Function OperationToOperationResume(Block : Cardinal; Operation : TPCOperation; getInfoForAllAccounts : Boolean; Affected_account_number : Cardinal; var OperationResume : TOperationResume) : Boolean; virtual;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; virtual; abstract;
+    Function GetDigestToSign : TRawBytes; virtual; abstract;
     function OperationAmount : Int64; virtual; abstract;
     function OperationAmountByAccount(account : Cardinal) : Int64; virtual;
     function OperationFee: Int64; virtual; abstract;
@@ -360,7 +360,7 @@ Type
     Property TotalAmount : Int64 read FTotalAmount;
     Property TotalFee : Int64 read FTotalFee;
     function SaveOperationsHashTreeToStream(Stream: TStream; SaveToStorage : Boolean): Boolean;
-    function LoadOperationsHashTreeFromStream(Stream: TStream; LoadingFromStorage : Boolean; LoadProtocolVersion : Word; PreviousUpdatedBlocks : TAccountPreviousBlockInfo; var errors : String): Boolean;
+    function LoadOperationsHashTreeFromStream(Stream: TStream; LoadingFromStorage : Boolean; ASetOperationsToProtocolVersion : Word; ALoadVersion : Word; PreviousUpdatedBlocks : TAccountPreviousBlockInfo; var errors : String): Boolean;
     function IndexOfOperation(op : TPCOperation) : Integer;
     function CountOperationsBySameSignerWithoutFee(account_number : Cardinal) : Integer;
     Procedure Delete(index : Integer);
@@ -1229,6 +1229,11 @@ Begin
         errors := 'Bank blockcount<>OperationBlock.Block';
         exit;
       end;
+      if OperationBlock.protocol_version <> op.ProtocolVersion then begin
+        errors := Format('Operation protocol:%d <> current protocol:%d on %s',[op.ProtocolVersion,OperationBlock.protocol_version, op.ToString]);
+        Tlog.NewLog(lterror,ClassName,errors);
+        Exit;
+      end;
       // Only process when in current address, prevent do it when reading operations from file
       if FOperationsHashTree.CanAddOperationToHashTree(op) then begin
         Result := op.DoOperation(FPreviousUpdatedBlocks, FSafeBoxTransaction, errors);
@@ -1653,7 +1658,7 @@ begin
     if FOperationBlock.protocol_version>=CT_PROTOCOL_4 then begin
       FOperationsHashTree.Max0feeOperationsBySigner := 1;
     end else FOperationsHashTree.Max0feeOperationsBySigner := -1;
-    Result := FOperationsHashTree.LoadOperationsHashTreeFromStream(Stream,LoadingFromStorage,load_protocol_version,FPreviousUpdatedBlocks,errors);
+    Result := FOperationsHashTree.LoadOperationsHashTreeFromStream(Stream,LoadingFromStorage,FOperationBlock.protocol_version,load_protocol_version,FPreviousUpdatedBlocks,errors);
     if not Result then begin
       exit;
     end;
@@ -1768,17 +1773,22 @@ begin
       lastn := FOperationsHashTree.OperationsCount;
       for i:=0 to lastn-1 do begin
         op := FOperationsHashTree.GetOperation(i);
-        if (aux.CanAddOperationToHashTree(op)) then begin
-          if (op.DoOperation(FPreviousUpdatedBlocks, SafeBoxTransaction,errors)) then begin
-            if aux.AddOperationToHashTree(op) then begin
-              inc(n);
-              inc(FOperationBlock.fee,op.OperationFee);
-              {$IFDEF HIGHLOG}TLog.NewLog(ltdebug,Classname,'Sanitizing (pos:'+inttostr(i+1)+'/'+inttostr(lastn)+'): '+op.ToString){$ENDIF};
-            end else begin
-              TLog.NewLog(lterror,ClassName,Format('Undo operation.DoExecute at Sanitize due limits reached. Executing %d operations',[aux.OperationsCount]));
-              FPreviousUpdatedBlocks.Clear;
-              FSafeBoxTransaction.Rollback;
-              for iUndo := 0 to aux.OperationsCount-1 do aux.GetOperation(iUndo).DoOperation(FPreviousUpdatedBlocks, FSafeBoxTransaction, auxs);
+        if OperationBlock.protocol_version <> op.ProtocolVersion then begin
+          errors := Format('Sanitize Operation protocol:%d <> current protocol:%d on %s',[op.ProtocolVersion,OperationBlock.protocol_version, op.ToString]);
+          Tlog.NewLog(lterror,ClassName,errors);
+        end else begin
+          if (aux.CanAddOperationToHashTree(op)) then begin
+            if (op.DoOperation(FPreviousUpdatedBlocks, SafeBoxTransaction,errors)) then begin
+              if aux.AddOperationToHashTree(op) then begin
+                inc(n);
+                inc(FOperationBlock.fee,op.OperationFee);
+                {$IFDEF HIGHLOG}TLog.NewLog(ltdebug,Classname,'Sanitizing (pos:'+inttostr(i+1)+'/'+inttostr(lastn)+'): '+op.ToString){$ENDIF};
+              end else begin
+                TLog.NewLog(lterror,ClassName,Format('Undo operation.DoExecute at Sanitize due limits reached. Executing %d operations',[aux.OperationsCount]));
+                FPreviousUpdatedBlocks.Clear;
+                FSafeBoxTransaction.Rollback;
+                for iUndo := 0 to aux.OperationsCount-1 do aux.GetOperation(iUndo).DoOperation(FPreviousUpdatedBlocks, FSafeBoxTransaction, auxs);
+              end;
             end;
           end;
         end;
@@ -1793,7 +1803,7 @@ begin
     Calc_Digest_Parts; // Does not need to recalc PoW
     Unlock;
   End;
-  if (n>0) then begin
+  if (n>0) or (lastn<>n) then begin
     TLog.NewLog(ltdebug,Classname,Format('Sanitize operations (before %d - after %d)',[lastn,n]));
   end;
 end;
@@ -2011,8 +2021,12 @@ begin
     TPCOperationsSignatureValidator.MultiThreadPreValidateSignatures(SafeBoxTransaction,OperationsHashTree,Nil);
     //
     for i := 0 to Count - 1 do begin
+      if (Operation[i].ProtocolVersion<>OperationBlock.protocol_version) then begin
+        errors := 'Error executing operation invalid protocol at '+inttostr(i+1)+'/'+inttostr(Count)+': '+errors+' Op:'+Operation[i].ToString;
+        exit;
+      end;
       If Not Operation[i].DoOperation(FPreviousUpdatedBlocks, SafeBoxTransaction,errors) then begin
-        errors := 'Error executing operation '+inttostr(i+1)+'/'+inttostr(Count)+': '+errors;
+        errors := 'Error executing operation '+inttostr(i+1)+'/'+inttostr(Count)+': '+errors+' Op:'+Operation[i].ToString;
         exit;
       end;
     end;
@@ -2615,7 +2629,7 @@ begin
   Index := L;
 end;
 
-function TOperationsHashTree.LoadOperationsHashTreeFromStream(Stream: TStream; LoadingFromStorage : Boolean; LoadProtocolVersion : Word; PreviousUpdatedBlocks : TAccountPreviousBlockInfo; var errors: String): Boolean;
+function TOperationsHashTree.LoadOperationsHashTreeFromStream(Stream: TStream; LoadingFromStorage : Boolean; ASetOperationsToProtocolVersion : Word; ALoadVersion : Word; PreviousUpdatedBlocks : TAccountPreviousBlockInfo; var errors: String): Boolean;
 Var c, i: Cardinal;
   OpType: Cardinal;
   bcop: TPCOperation;
@@ -2648,10 +2662,10 @@ begin
         errors := 'Invalid operation structure ' + inttostr(i) + '/' + inttostr(c) + ' optype not valid:' + InttoHex(OpType, 4);
         exit;
       end;
-      bcop := OpClass.Create(LoadProtocolVersion);
+      bcop := OpClass.Create(ASetOperationsToProtocolVersion);
       Try
         if LoadingFromStorage then begin
-          If not bcop.LoadFromStorage(Stream,LoadProtocolVersion,PreviousUpdatedBlocks) then begin
+          If not bcop.LoadFromStorage(Stream,ALoadVersion,PreviousUpdatedBlocks) then begin
             errors := 'Invalid operation load from storage ' + inttostr(i) + '/' + inttostr(c)+' Class:'+OpClass.ClassName;
             exit;
           end;
@@ -3093,7 +3107,7 @@ begin
   //
 end;
 
-function TPCOperation.IsValidECDSASignature(const PubKey: TECDSA_Public; current_protocol: Word; const Signature: TECDSA_SIG): Boolean;
+function TPCOperation.IsValidECDSASignature(const PubKey: TECDSA_Public; const Signature: TECDSA_SIG): Boolean;
 begin
   // Will reuse FHasValidSignature if checked previously and was True
   // Introduced on Build 4.0.2 to increase speed using MEMPOOL verified operations instead of verify again everytime
@@ -3105,7 +3119,7 @@ begin
     end;
   end;
   if (Not FHasValidSignature) then begin
-    FHasValidSignature := TCrypto.ECDSAVerify(PubKey,GetDigestToSign(current_protocol),Signature);
+    FHasValidSignature := TCrypto.ECDSAVerify(PubKey,GetDigestToSign,Signature);
     If FHasValidSignature then begin;
       FUsedPubkeyForSignature := PubKey;
     end;

+ 1 - 1
src/core/UFileStorage.pas

@@ -325,7 +325,7 @@ begin
     if fs.Size>0 then begin
       if Assigned(Bank) then LCurrentProtocol := Bank.SafeBox.CurrentProtocol
       else LCurrentProtocol := CT_BUILD_PROTOCOL;
-      If OperationsHashTree.LoadOperationsHashTreeFromStream(fs,true,LCurrentProtocol,Nil,errors) then begin
+      If OperationsHashTree.LoadOperationsHashTreeFromStream(fs,true,LCurrentProtocol,LCurrentProtocol, Nil,errors) then begin
         TLog.NewLog(ltInfo,ClassName,Format('DoLoadPendingBufferOperations loaded operations:%d',[OperationsHashTree.OperationsCount]));
       end else TLog.NewLog(ltError,ClassName,Format('DoLoadPendingBufferOperations ERROR (Protocol %d): loaded operations:%d errors:%s',[LCurrentProtocol,OperationsHashTree.OperationsCount,errors]));
     end;

+ 1 - 1
src/core/UNetProtocol.pas

@@ -3266,7 +3266,7 @@ begin
       //
       opht := TOperationsHashTree.Create;
       try
-        If Not opht.LoadOperationsHashTreeFromStream(dataReceived,False,0,Nil,errors) then begin
+        If Not opht.LoadOperationsHashTreeFromStream(dataReceived,False,TNode.Node.Bank.SafeBox.CurrentProtocol,TNode.Node.Bank.SafeBox.CurrentProtocol,Nil,errors) then begin
           DisconnectInvalidClient(False,'Invalid operations hash tree stream: '+errors);
           Exit;
         end;

+ 51 - 50
src/core/UOpTransaction.pas

@@ -106,7 +106,7 @@ Type
 
     Constructor CreateTransaction(ACurrentProtocol : Word; sender, n_operation, target: Cardinal; key: TECPrivateKey; amount, fee: UInt64; const payload: TOperationPayload);
     Function toString : String; Override;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; override;
+    Function GetDigestToSign : TRawBytes; override;
 
     function IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction : TPCSafeBoxTransaction) : Boolean; override;
   End;
@@ -137,7 +137,7 @@ Type
     Constructor Create(ACurrentProtocol : Word; account_signer, n_operation, account_target: Cardinal; key:TECPrivateKey; new_account_key : TAccountKey; fee: UInt64; const payload: TOperationPayload);
     Property Data : TOpChangeKeyData read FData;
     Function toString : String; Override;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; override;
+    Function GetDigestToSign : TRawBytes; override;
 
     function IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction : TPCSafeBoxTransaction) : Boolean; override;
   End;
@@ -175,7 +175,7 @@ Type
     Constructor Create(ACurrentProtocol : word; account_number, n_operation: Cardinal; fee: UInt64; new_accountkey : TAccountKey);
     Property Data : TOpRecoverFoundsData read FData;
     Function toString : String; Override;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; override;
+    Function GetDigestToSign : TRawBytes; override;
     function IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction : TPCSafeBoxTransaction) : Boolean; override;
   End;
 
@@ -247,7 +247,7 @@ Type
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     Property Data : TOpListAccountData read FData;
     Function toString : String; Override;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; override;
+    Function GetDigestToSign : TRawBytes; override;
     function IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction : TPCSafeBoxTransaction) : Boolean; override;
   End;
 
@@ -308,7 +308,7 @@ Type
       fee: UInt64; const payload: TOperationPayload);
     Property Data : TOpChangeAccountInfoData read FData;
     Function toString : String; Override;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; override;
+    Function GetDigestToSign : TRawBytes; override;
 
     function IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction : TPCSafeBoxTransaction) : Boolean; override;
   End;
@@ -354,7 +354,7 @@ Type
     Constructor CreateOpData( ACurrentProtocol : word; account_signer, account_sender, account_target : Cardinal; signer_key:TECPrivateKey; n_operation : Cardinal; dataType, dataSequence : Word; AGUID : TGUID; amount, fee : UInt64; const payload: TOperationPayload);
     Property Data : TOpDataData read FData;
     Function toString : String; Override;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; override;
+    Function GetDigestToSign : TRawBytes; override;
     function IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction : TPCSafeBoxTransaction) : Boolean; override;
   End;
 
@@ -394,7 +394,7 @@ function TOpChangeAccountInfo.IsValidSignatureBasedOnCurrentSafeboxState(ASafeBo
 var LAccount : TAccount;
 begin
   LAccount := ASafeBoxTransaction.Account(FData.account_signer);
-  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,ASafeBoxTransaction.FreezedSafeBox.CurrentProtocol,FData.sign);
+  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,FData.sign);
 end;
 
 function TOpChangeAccountInfo.SaveOpToStream(Stream: TStream; SaveExtendedData: Boolean): Boolean;
@@ -526,7 +526,7 @@ begin
   end;
   if (length(FData.payload.payload_raw)>CT_MaxPayloadSize) then begin
     errors := 'Invalid Payload size:'+inttostr(length(FData.payload.payload_raw))+' (Max: '+inttostr(CT_MaxPayloadSize)+')';
-    If (AccountTransaction.FreezedSafeBox.CurrentProtocol>=CT_PROTOCOL_2) then begin
+    If (ProtocolVersion>=CT_PROTOCOL_2) then begin
       Exit; // BUG from protocol 1
     end;
   end;
@@ -535,7 +535,7 @@ begin
     errors := 'Account signer is currently locked';
     exit;
   end;
-  if (AccountTransaction.FreezedSafeBox.CurrentProtocol<CT_PROTOCOL_2) then begin
+  if (ProtocolVersion<CT_PROTOCOL_2) then begin
     errors := 'NOT ALLOWED ON PROTOCOL 1';
     exit;
   end;
@@ -590,7 +590,7 @@ begin
   end;
 
   // Check signature
-  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,AccountTransaction.FreezedSafeBox.CurrentProtocol,FData.sign) then begin
+  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,FData.sign) then begin
     errors := 'Invalid ECDSA signature';
     Exit;
   end;
@@ -696,7 +696,7 @@ begin
   end;
 
   if Assigned(key) then begin
-    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign(ACurrentProtocol));
+    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign);
     FHasValidSignature := true;
     FUsedPubkeyForSignature := key.PublicKey;
   end else begin
@@ -728,7 +728,7 @@ begin
      TAccountComp.FormatMoney(FData.fee),FData.n_operation,Length(FData.payload.payload_raw)]);
 end;
 
-function TOpChangeAccountInfo.GetDigestToSign(current_protocol : Word): TRawBytes;
+function TOpChangeAccountInfo.GetDigestToSign: TRawBytes;
 var Stream : TMemoryStream;
   b : Byte;
 begin
@@ -749,10 +749,10 @@ begin
     TStreamOp.WriteAccountKey(Stream,FData.new_accountkey);
     TStreamOp.WriteAnsiString(Stream,FData.new_name);
     Stream.Write(FData.new_type,Sizeof(FData.new_type));
-    if (current_protocol>=CT_PROTOCOL_5) then begin
+    if (ProtocolVersion>=CT_PROTOCOL_5) then begin
       TStreamOp.WriteAnsiString(Stream,FData.new_data);
     end;
-    if (current_protocol<=CT_PROTOCOL_3) then begin
+    if (ProtocolVersion<=CT_PROTOCOL_3) then begin
       Stream.Position := 0;
       setlength(Result,Stream.Size);
       Stream.ReadBuffer(Result[Low(Result)],Stream.Size);
@@ -791,7 +791,7 @@ begin
   // V2: No need to store public key because it's at safebox. Saving at least 64 bytes!
   // FData.public_key := key.PublicKey;
   if Assigned(key) then begin
-    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign(ACurrentProtocol));
+    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign);
     FHasValidSignature := true;
     FUsedPubkeyForSignature := key.PublicKey;
   end else begin
@@ -811,7 +811,7 @@ begin
   Result := false;
   AErrors := '';
   LCurrentBlock := ASafeBoxTransaction.FreezedSafeBox.BlocksCount;
-  LCurrentProtocol := ASafeBoxTransaction.FreezedSafeBox.CurrentProtocol;
+  LCurrentProtocol := ProtocolVersion;
 
   {$region 'Common Validation'}
 
@@ -890,10 +890,10 @@ begin
     exit;
   end;
   // Check signature
-  if LRecipientSignable AND (NOT IsValidECDSASignature(LSender.accountInfo.new_publicKey, LCurrentProtocol, FData.sign)) then begin
+  if LRecipientSignable AND (NOT IsValidECDSASignature(LSender.accountInfo.new_publicKey, FData.sign)) then begin
     AErrors := 'Invalid recipient-signed ECDSA signature';
     Exit;
-  end else If (NOT LRecipientSignable) AND (NOT IsValidECDSASignature(LSender.accountInfo.accountkey, ASafeBoxTransaction.FreezedSafeBox.CurrentProtocol, FData.sign)) then begin
+  end else If (NOT LRecipientSignable) AND (NOT IsValidECDSASignature(LSender.accountInfo.accountkey, FData.sign)) then begin
     AErrors := 'Invalid ECDSA signature';
     Exit;
   end;
@@ -1109,7 +1109,7 @@ function TOpTransaction.IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTrans
 var LAccount : TAccount;
 begin
   LAccount := ASafeBoxTransaction.Account(FData.sender);
-  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,ASafeBoxTransaction.FreezedSafeBox.CurrentProtocol,FData.sign);
+  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,FData.sign);
 end;
 
 function TOpTransaction.LoadOpFromStream(Stream: TStream; LoadExtendedData : Boolean): Boolean;
@@ -1314,7 +1314,7 @@ begin
   end;
 end;
 
-function TOpTransaction.GetDigestToSign(current_protocol : Word): TRawBytes;
+function TOpTransaction.GetDigestToSign: TRawBytes;
 Var ms : TMemoryStream;
   b : Byte;
 begin
@@ -1325,7 +1325,7 @@ begin
     ms.Write(FData.target,Sizeof(FData.target));
     ms.Write(FData.amount,Sizeof(FData.amount));
     ms.Write(FData.fee,Sizeof(FData.fee));
-    if current_protocol>=CT_PROTOCOL_5 then begin
+    if ProtocolVersion>=CT_PROTOCOL_5 then begin
       ms.Write(FData.payload.payload_type,SizeOf(FData.payload.payload_type));
     end;
     if Length(FData.payload.payload_raw)>0 then
@@ -1344,7 +1344,7 @@ begin
       if Length(FData.new_accountkey.y)>0 then
         ms.WriteBuffer(FData.new_accountkey.y[Low(FData.new_accountkey.y)],Length(FData.new_accountkey.y));
     end;
-    if (current_protocol<=CT_PROTOCOL_3) then begin
+    if (ProtocolVersion<=CT_PROTOCOL_3) then begin
       ms.Position := 0;
       SetLength(Result,ms.Size);
       ms.ReadBuffer(Result[Low(Result)],ms.Size);
@@ -1389,7 +1389,7 @@ begin
   // FData.public_key := key.PublicKey;
   FData.new_accountkey := new_account_key;
   if Assigned(key) then begin
-    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign(ACurrentProtocol));
+    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign);
     FHasValidSignature := true;
     FUsedPubkeyForSignature := key.PublicKey;
   end else begin
@@ -1436,7 +1436,7 @@ begin
   end;
   if (length(FData.payload.payload_raw)>CT_MaxPayloadSize) then begin
     errors := 'Invalid Payload size:'+inttostr(length(FData.payload.payload_raw))+' (Max: '+inttostr(CT_MaxPayloadSize)+')';
-    If (AccountTransaction.FreezedSafeBox.CurrentProtocol>=CT_PROTOCOL_2) then begin
+    If (ProtocolVersion>=CT_PROTOCOL_2) then begin
       Exit; // BUG from protocol 1
     end;
   end;
@@ -1449,7 +1449,7 @@ begin
     exit;
   end;
   // NEW v2 protocol protection: Does not allow to change key for same key
-  if (AccountTransaction.FreezedSafeBox.CurrentProtocol>=CT_PROTOCOL_2) then begin
+  if (ProtocolVersion>=CT_PROTOCOL_2) then begin
     if (TAccountComp.EqualAccountKeys(account_target.accountInfo.accountKey,FData.new_accountkey)) then begin
       errors := 'New public key is the same public key';
       exit;
@@ -1473,14 +1473,14 @@ begin
       errors := 'Signer and target accounts have different public key';
       exit;
     end;
-    if (AccountTransaction.FreezedSafeBox.CurrentProtocol<CT_PROTOCOL_2) then begin
+    if (ProtocolVersion<CT_PROTOCOL_2) then begin
       errors := 'NOT ALLOWED ON PROTOCOL 1';
       exit;
     end;
   end;
 
   // Check signature
-  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,AccountTransaction.FreezedSafeBox.CurrentProtocol,FData.sign) then begin
+  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,FData.sign) then begin
     errors := 'Invalid ECDSA signature';
     Exit;
   end;
@@ -1548,7 +1548,7 @@ function TOpChangeKey.IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransac
 var LAccount : TAccount;
 begin
   LAccount := ASafeBoxTransaction.Account(FData.account_signer);
-  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,ASafeBoxTransaction.FreezedSafeBox.CurrentProtocol,FData.sign);
+  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,FData.sign);
 end;
 
 function TOpChangeKey.LoadOpFromStream(Stream: TStream; LoadExtendedData : Boolean): Boolean;
@@ -1660,7 +1660,7 @@ begin
     TAccountComp.FormatMoney(FData.fee),FData.n_operation,Length(FData.payload.payload_raw)]);
 end;
 
-function TOpChangeKey.GetDigestToSign(current_protocol : Word): TRawBytes;
+function TOpChangeKey.GetDigestToSign: TRawBytes;
 var ms : TMemoryStream;
   raw : TRawBytes;
   b : Byte;
@@ -1671,7 +1671,7 @@ begin
     if (FData.account_signer<>FData.account_target) then ms.Write(FData.account_target,Sizeof(FData.account_target));
     ms.Write(FData.n_operation,Sizeof(FData.n_operation));
     ms.Write(FData.fee,Sizeof(FData.fee));
-    if current_protocol>=CT_PROTOCOL_5 then begin
+    if ProtocolVersion>=CT_PROTOCOL_5 then begin
       ms.Write(FData.payload.payload_type,SizeOf(FData.payload.payload_type));
     end;
     if Length(FData.payload.payload_raw)>0 then
@@ -1684,7 +1684,7 @@ begin
     raw := TAccountComp.AccountKey2RawString(FData.new_accountkey);
     if Length(raw)>0 then
       ms.WriteBuffer(raw[Low(raw)],Length(raw));
-    if (current_protocol<=CT_PROTOCOL_3) then begin
+    if (ProtocolVersion<=CT_PROTOCOL_3) then begin
       ms.Position := 0;
       SetLength(Result,ms.Size);
       ms.ReadBuffer(Result[Low(Result)],ms.Size);
@@ -1873,7 +1873,7 @@ begin
     TAccountComp.AccountKey2RawString(FData.new_accountkey).ToHexaString]);
 end;
 
-function TOpRecoverFounds.GetDigestToSign(current_protocol : Word): TRawBytes;
+function TOpRecoverFounds.GetDigestToSign: TRawBytes;
 begin
   SetLength(Result,0); // Nothing to be signed!
 end;
@@ -1893,7 +1893,8 @@ begin
   else Result := 0;
 end;
 
-function TOpListAccount.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean;Var
+function TOpListAccount.DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean;
+Var
   account_signer, account_target : TAccount;
   LIsDelist, LIsSale, LIsPrivateSale, LIsPublicSale, LIsSwap, LIsAccountSwap, LIsCoinSwap : boolean;
   LCurrentProtocol : Integer;
@@ -1928,7 +1929,7 @@ begin
     LIsCoinSwap := false;
   end;
 
-  LCurrentProtocol := AccountTransaction.FreezedSafeBox.CurrentProtocol;
+  LCurrentProtocol := ProtocolVersion;
   if (LCurrentProtocol<CT_PROTOCOL_2) then begin
     errors := 'List/Delist Account is not allowed on Protocol 1';
     exit;
@@ -2056,7 +2057,7 @@ begin
   end;
 
   // Check signature
-  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,LCurrentProtocol,FData.sign) then begin
+  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,FData.sign) then begin
     errors := 'Invalid ECDSA signature';
     Exit;
   end;
@@ -2116,7 +2117,7 @@ function TOpListAccount.IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTrans
 var LAccount : TAccount;
 begin
   LAccount := ASafeBoxTransaction.Account(FData.account_signer);
-  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,ASafeBoxTransaction.FreezedSafeBox.CurrentProtocol,FData.sign);
+  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,FData.sign);
 end;
 
 function TOpListAccount.LoadOpFromStream(Stream: TStream; LoadExtendedData : Boolean): Boolean;
@@ -2332,7 +2333,7 @@ begin
   end;
 end;
 
-function TOpListAccount.GetDigestToSign(current_protocol : Word): TRawBytes;
+function TOpListAccount.GetDigestToSign: TRawBytes;
 var ms : TMemoryStream;
   s : TRawBytes;
   b : Byte;
@@ -2348,7 +2349,7 @@ begin
     ms.Write(FData.account_price,Sizeof(FData.account_price));
     ms.Write(FData.account_to_pay,Sizeof(FData.account_to_pay));
     ms.Write(FData.fee,Sizeof(FData.fee));
-    if current_protocol>=CT_PROTOCOL_5 then begin
+    if ProtocolVersion>=CT_PROTOCOL_5 then begin
       ms.Write(FData.payload.payload_type,SizeOf(FData.payload.payload_type));
     end;
     if Length(FData.payload.payload_raw)>0 then
@@ -2363,12 +2364,12 @@ begin
       ms.WriteBuffer(s[Low(s)],Length(s));
     ms.Write(FData.locked_until_block,Sizeof(FData.locked_until_block));
     // VERSION 5: write the new account state and hash-lock
-    if (current_protocol >= CT_PROTOCOL_5) then begin
+    if (ProtocolVersion >= CT_PROTOCOL_5) then begin
       w := Word(FData.account_state);
       ms.Write(w, 2);
       TStreamOp.WriteAnsiString(ms, FData.hash_lock); // the hash-lock if any
     end;
-    if (current_protocol<=CT_PROTOCOL_3) then begin
+    if (ProtocolVersion<=CT_PROTOCOL_3) then begin
       ms.Position := 0;
       SetLength(Result,ms.Size);
       ms.ReadBuffer(Result[Low(Result)],ms.Size);
@@ -2423,7 +2424,7 @@ begin
 
 
   if Assigned(AKey) then begin
-    FData.sign := TCrypto.ECDSASign(AKey.PrivateKey, GetDigestToSign(ACurrentProtocol));
+    FData.sign := TCrypto.ECDSASign(AKey.PrivateKey, GetDigestToSign);
     FHasValidSignature := true;
     FUsedPubkeyForSignature := AKey.PublicKey;
   end else begin
@@ -2459,7 +2460,7 @@ begin
   FData.fee := fee;
   FData.payload := payload;
   if Assigned(key) then begin
-    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign(ACurrentProtocol));
+    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign);
     FHasValidSignature := true;
     FUsedPubkeyForSignature := key.PublicKey;
   end else begin
@@ -2494,7 +2495,7 @@ begin
   FData.new_accountkey := new_public_key;
 
   if Assigned(key) then begin
-    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign(ACurrentProtocol));
+    FData.sign := TCrypto.ECDSASign(key.PrivateKey, GetDigestToSign);
     FHasValidSignature := true;
     FUsedPubkeyForSignature := key.PublicKey;
   end else begin
@@ -2527,7 +2528,7 @@ function TOpData.IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction:
 var LAccount : TAccount;
 begin
   LAccount := ASafeBoxTransaction.Account(FData.account_signer);
-  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,ASafeBoxTransaction.FreezedSafeBox.CurrentProtocol,FData.sign);
+  Result := IsValidECDSASignature(LAccount.accountInfo.accountkey,FData.sign);
 end;
 
 function TOpData.SaveOpToStream(Stream: TStream; SaveExtendedData: Boolean): Boolean;
@@ -2642,7 +2643,7 @@ function TOpData.DoOperation(
 Var account_signer, account_sender, account_target : TAccount;
 begin
   Result := false;
-  if (AccountTransaction.FreezedSafeBox.CurrentProtocol<CT_PROTOCOL_4) then begin
+  if (ProtocolVersion<CT_PROTOCOL_4) then begin
     errors := 'OpData is not allowed on Protocol < 4';
     exit;
   end;
@@ -2726,7 +2727,7 @@ begin
   end;
 
   // Check signature
-  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,AccountTransaction.FreezedSafeBox.CurrentProtocol,FData.sign) then begin
+  If Not IsValidECDSASignature(account_signer.accountInfo.accountkey,FData.sign) then begin
     errors := 'Invalid ECDSA signature';
     Exit;
   end;
@@ -2808,7 +2809,7 @@ begin
   FData.dataType:=dataType;
   FData.guid := AGUID;
   if Assigned(signer_key) then begin
-    FData.sign := TCrypto.ECDSASign(signer_key.PrivateKey, GetDigestToSign(ACurrentProtocol));
+    FData.sign := TCrypto.ECDSASign(signer_key.PrivateKey, GetDigestToSign);
     FHasValidSignature := true;
     FUsedPubkeyForSignature := signer_key.PublicKey;
   end else begin
@@ -2824,7 +2825,7 @@ begin
      TAccountComp.FormatMoney(FData.amount)]);
 end;
 
-function TOpData.GetDigestToSign(current_protocol: Word): TRawBytes;
+function TOpData.GetDigestToSign: TRawBytes;
 var Stream : TMemoryStream;
   b : Byte;
 begin
@@ -2835,7 +2836,7 @@ begin
     Stream.Write(FData.account_target,Sizeof(FData.account_target));
     Stream.Write(FData.n_operation,Sizeof(FData.n_operation));
     // VERSION 5: write the GUID to the digest
-    if current_protocol >= CT_PROTOCOL_5 then begin
+    if ProtocolVersion >= CT_PROTOCOL_5 then begin
       TStreamOp.WriteGUID(Stream,FData.guid);
     end;
     Stream.Write(FData.dataType,Sizeof(FData.dataType));
@@ -2845,7 +2846,7 @@ begin
     SaveOperationPayloadToStream(Stream,FData.payload);
     b := OpType;
     Stream.Write(b,1);
-    if (current_protocol<=CT_PROTOCOL_4) then begin
+    if (ProtocolVersion<=CT_PROTOCOL_4) then begin
       Result := TStreamOp.SaveStreamToRaw(Stream);
     end else begin
       Result := TCrypto.DoSha256(Stream.Memory,Stream.Size);

+ 2 - 2
src/core/URPC.pas

@@ -530,7 +530,7 @@ begin
   jsonObject.GetAsVariant('fee').Value:=TAccountComp.FormatMoneyDecimal( multiOperation.OperationFee );
   // New params for third party signing: (3.0.2)
   if (current_protocol>CT_PROTOCOL_3) then begin
-    jsonObject.GetAsVariant('digest').Value:=TCrypto.ToHexaString(multiOperation.GetDigestToSign(current_protocol));
+    jsonObject.GetAsVariant('digest').Value:=TCrypto.ToHexaString(multiOperation.GetDigestToSign);
   end;
 
   jsonObject.GetAsVariant('senders_count').Value:=Length(multiOperation.Data.txSenders);
@@ -569,7 +569,7 @@ Begin
     ms.Position := 0;
     AOperationsHashTree := TOperationsHashTree.Create;
     if (Length(Lraw)>0) then begin
-      If not AOperationsHashTree.LoadOperationsHashTreeFromStream(ms,False,ACurrentProtocol,Nil,AErrors) then begin
+      If not AOperationsHashTree.LoadOperationsHashTreeFromStream(ms,False,ACurrentProtocol,ACurrentProtocol,Nil,AErrors) then begin
         FreeAndNil(AOperationsHashTree);
         Exit;
       end;

+ 5 - 5
src/core/UTxMultiOperation.pas

@@ -155,7 +155,7 @@ Type
     //
     Function toString : String; Override;
     Property Data : TOpMultiOperationData read FData;
-    Function GetDigestToSign(current_protocol : Word) : TRawBytes; override;
+    Function GetDigestToSign : TRawBytes; override;
 
     function IsValidSignatureBasedOnCurrentSafeboxState(ASafeBoxTransaction : TPCSafeBoxTransaction) : Boolean; override;
   End;
@@ -501,7 +501,7 @@ begin
   Result := False;
   // Do check it!
   Try
-    ophtosign := GetDigestToSign(AccountTransaction.FreezedSafeBox.CurrentProtocol);
+    ophtosign := GetDigestToSign;
     // Tx verification
     For i:=Low(FData.txSenders) to High(FData.txSenders) do begin
       acc := AccountTransaction.Account(FData.txSenders[i].Account);
@@ -784,7 +784,7 @@ begin
   If Not key.HasPrivateKey then begin
     exit;
   end;
-  raw := GetDigestToSign(current_protocol);
+  raw := GetDigestToSign;
   Try
     _sign := TCrypto.ECDSASign(key.PrivateKey,raw);
   Except
@@ -1107,7 +1107,7 @@ begin
      TAccountComp.FormatMoney(FTotalFee)]);
 end;
 
-function TOpMultiOperation.GetDigestToSign(current_protocol : Word): TRawBytes;
+function TOpMultiOperation.GetDigestToSign: TRawBytes;
 Var ms : TMemoryStream;
   rb : TRawBytes;
   old : Boolean;
@@ -1122,7 +1122,7 @@ begin
     finally
       FSaveSignatureValue:=old;
     end;
-    if (current_protocol<=CT_PROTOCOL_3) then begin
+    if (ProtocolVersion<=CT_PROTOCOL_3) then begin
       ms.Position := 0;
       SetLength(Result,ms.Size);
       ms.ReadBuffer(Result[Low(Result)],ms.Size);