Browse Source

code modifications for V3

Some modifications to allow V3 blockchain file and node work
Pascal Coin 7 years ago
parent
commit
1ea4faecca
3 changed files with 95 additions and 48 deletions
  1. 52 27
      src/core/UBlockChain.pas
  2. 6 3
      src/core/UNetProtocol.pas
  3. 37 18
      src/core/UNode.pas

+ 52 - 27
src/core/UBlockChain.pas

@@ -213,6 +213,7 @@ Type
     class function OpType: Byte; virtual; abstract;
     class function OpType: Byte; virtual; abstract;
     Class Function OperationToOperationResume(Block : Cardinal; Operation : TPCOperation; Affected_account_number : Cardinal; var OperationResume : TOperationResume) : Boolean; virtual;
     Class Function OperationToOperationResume(Block : Cardinal; Operation : TPCOperation; Affected_account_number : Cardinal; var OperationResume : TOperationResume) : Boolean; virtual;
     function OperationAmount : Int64; virtual; abstract;
     function OperationAmount : Int64; virtual; abstract;
+    function OperationAmountByAccount(account : Cardinal) : Int64; virtual;
     function OperationFee: UInt64; virtual; abstract;
     function OperationFee: UInt64; virtual; abstract;
     function OperationPayload : TRawBytes; virtual; abstract;
     function OperationPayload : TRawBytes; virtual; abstract;
     function SignerAccount : Cardinal; virtual; abstract;
     function SignerAccount : Cardinal; virtual; abstract;
@@ -541,7 +542,7 @@ begin
       Result := true;
       Result := true;
     Finally
     Finally
       if Not Result then begin
       if Not Result then begin
-        NewLog(Operations, lterror, 'Invalid new block '+inttostr(Operations.OperationBlock.block)+': ' + errors);
+        NewLog(Operations, lterror, 'Invalid new block '+inttostr(Operations.OperationBlock.block)+': ' + errors+ ' > '+TPCOperationsComp.OperationBlockToText(Operations.OperationBlock));
       end;
       end;
       Operations.Unlock;
       Operations.Unlock;
     End;
     End;
@@ -1193,23 +1194,28 @@ begin
     // In build prior to 1.0.4 soob only can have 2 values: 0 or 1
     // In build prior to 1.0.4 soob only can have 2 values: 0 or 1
     // In build 1.0.4 soob can has 2 more values: 2 or 3
     // In build 1.0.4 soob can has 2 more values: 2 or 3
     // In build 2.0 soob can has 1 more value: 4
     // In build 2.0 soob can has 1 more value: 4
+    // In build 3.0 soob can hast value: 5
     // In future, old values 0 and 1 will no longer be used!
     // In future, old values 0 and 1 will no longer be used!
     // - Value 0 and 2 means that contains also operations
     // - Value 0 and 2 means that contains also operations
     // - Value 1 and 3 means that only contains operationblock info
     // - Value 1 and 3 means that only contains operationblock info
     // - Value 2 and 3 means that contains protocol info prior to block number
     // - Value 2 and 3 means that contains protocol info prior to block number
     // - Value 4 means that is loading from storage using protocol v2 (so, includes always operations)
     // - Value 4 means that is loading from storage using protocol v2 (so, includes always operations)
+    // - Value 5 means that is loading from storage using TAccountPreviousBlockInfo
     load_protocol_version := CT_PROTOCOL_1;
     load_protocol_version := CT_PROTOCOL_1;
     if (soob in [0,2]) then FIsOnlyOperationBlock:=false
     if (soob in [0,2]) then FIsOnlyOperationBlock:=false
     else if (soob in [1,3]) then FIsOnlyOperationBlock:=true
     else if (soob in [1,3]) then FIsOnlyOperationBlock:=true
     else if (soob in [4]) then begin
     else if (soob in [4]) then begin
       FIsOnlyOperationBlock:=false;
       FIsOnlyOperationBlock:=false;
       load_protocol_version := CT_PROTOCOL_2;
       load_protocol_version := CT_PROTOCOL_2;
+    end else if (soob in [5]) then begin
+      FIsOnlyOperationBlock:=False;
+      load_protocol_version := CT_PROTOCOL_3;
     end else begin
     end else begin
       errors := 'Invalid value in protocol header! Found:'+inttostr(soob)+' - Check if your application version is Ok';
       errors := 'Invalid value in protocol header! Found:'+inttostr(soob)+' - Check if your application version is Ok';
       exit;
       exit;
     end;
     end;
 
 
-    if (soob in [2,3,4]) then begin
+    if (soob in [2,3,4,5]) then begin
       Stream.Read(FOperationBlock.protocol_version, Sizeof(FOperationBlock.protocol_version));
       Stream.Read(FOperationBlock.protocol_version, Sizeof(FOperationBlock.protocol_version));
       Stream.Read(FOperationBlock.protocol_available, Sizeof(FOperationBlock.protocol_available));
       Stream.Read(FOperationBlock.protocol_available, Sizeof(FOperationBlock.protocol_available));
     end else begin
     end else begin
@@ -1242,6 +1248,13 @@ begin
     if not Result then begin
     if not Result then begin
       exit;
       exit;
     end;
     end;
+    If load_protocol_version>=CT_PROTOCOL_3 then begin
+      Result := FPreviousUpdatedBlocks.LoadFromStream(Stream);
+      If Not Result then begin
+        errors := 'Invalid PreviousUpdatedBlock stream';
+        Exit;
+      end;
+    end;
     //
     //
     FOperationBlock.fee := FOperationsHashTree.TotalFee;
     FOperationBlock.fee := FOperationsHashTree.TotalFee;
     FOperationBlock.operations_hash := FOperationsHashTree.HashTree;
     FOperationBlock.operations_hash := FOperationsHashTree.HashTree;
@@ -1390,6 +1403,8 @@ begin
       if (SaveToStorage) then begin
       if (SaveToStorage) then begin
         // Introduced on protocol v2: soob = 4 when saving to storage
         // Introduced on protocol v2: soob = 4 when saving to storage
         soob := 4;
         soob := 4;
+        // XXXXXXXXXXXXXXXX
+        soob := 5; // V3 will always save PreviousUpdatedBlocks
       end;
       end;
     end;
     end;
     Stream.Write(soob,1);
     Stream.Write(soob,1);
@@ -1421,6 +1436,9 @@ begin
     }
     }
     if (Not save_only_OperationBlock) then begin
     if (Not save_only_OperationBlock) then begin
       Result := FOperationsHashTree.SaveOperationsHashTreeToStream(Stream,SaveToStorage);
       Result := FOperationsHashTree.SaveOperationsHashTreeToStream(Stream,SaveToStorage);
+      If (Result) And (SaveToStorage) And (soob=5) then begin
+        FPreviousUpdatedBlocks.SaveToStream(Stream);
+      end;
     end else Result := true;
     end else Result := true;
   finally
   finally
     Unlock;
     Unlock;
@@ -1944,12 +1962,11 @@ begin
       TCrypto.DoSha256(FHashTree+h,FHashTree);
       TCrypto.DoSha256(FHashTree+h,FHashTree);
     end;
     end;
     npos := list.Add(P);
     npos := list.Add(P);
-    If FindOrderedBySha(list,op.Sha256,i) then begin
-      // Is inserting a value already found!
-      auxs :=Format('MyListCount:%d OrderedBySha Pos:%d from %d Hash:%s PointsTo:%d',[list.Count,i,FListOrderedBySha256.Count,TCrypto.ToHexaString(Op.Sha256),PtrInt(FListOrderedBySha256[i])]);
-      TLog.NewLog(ltError,ClassName,'DEV ERROR 20180213-2 Inserting a duplicate Sha256! '+Op.ToString+' > '+auxs );
+    // Improvement: Will allow to add duplicate Operations, so add only first to orderedBySha
+    If Not FindOrderedBySha(list,op.Sha256,i) then begin
+      // Protection: Will add only once
+      FListOrderedBySha256.Insert(i,TObject(npos));
     end;
     end;
-    FListOrderedBySha256.Insert(i,TObject(npos));
     // Improvement TOperationsHashTree speed 2.1.6
     // Improvement TOperationsHashTree speed 2.1.6
     // Mantain an ordered Accounts list with data
     // Mantain an ordered Accounts list with data
     If Not FindOrderedByAccountData(list,op.SignerAccount,i) then begin
     If Not FindOrderedByAccountData(list,op.SignerAccount,i) then begin
@@ -2353,26 +2370,25 @@ begin
 end;
 end;
 
 
 function TPCOperation.LoadFromStorage(Stream: TStream; LoadProtocolVersion:Word; APreviousUpdatedBlocks : TAccountPreviousBlockInfo): Boolean;
 function TPCOperation.LoadFromStorage(Stream: TStream; LoadProtocolVersion:Word; APreviousUpdatedBlocks : TAccountPreviousBlockInfo): Boolean;
-Var w : Word;
-  i : Integer;
-  cAccount,cPreviousUpdated : Cardinal;
 begin
 begin
   Result := false;
   Result := false;
-  If LoadOpFromStream(Stream, LoadProtocolVersion>=2) 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));
-    if (LoadProtocolVersion=2) then begin
-      Stream.Read(FPrevious_Seller_updated_block,Sizeof(FPrevious_Seller_updated_block));
-    end;
-    if Assigned(APreviousUpdatedBlocks) then begin
-      // Add to previous list!
-      if SignerAccount>=0 then
-        APreviousUpdatedBlocks.UpdateIfLower(SignerAccount,FPrevious_Signer_updated_block);
-      if DestinationAccount>=0 then
-        APreviousUpdatedBlocks.UpdateIfLower(DestinationAccount,FPrevious_Destination_updated_block);
-      if SellerAccount>=0 then
-        APreviousUpdatedBlocks.UpdateIfLower(SellerAccount,FPrevious_Seller_updated_block);
+  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));
+      if (LoadProtocolVersion=CT_PROTOCOL_2) then begin
+        Stream.Read(FPrevious_Seller_updated_block,Sizeof(FPrevious_Seller_updated_block));
+      end;
+      if Assigned(APreviousUpdatedBlocks) then begin
+        // Add to previous list!
+        if SignerAccount>=0 then
+          APreviousUpdatedBlocks.UpdateIfLower(SignerAccount,FPrevious_Signer_updated_block);
+        if DestinationAccount>=0 then
+          APreviousUpdatedBlocks.UpdateIfLower(DestinationAccount,FPrevious_Destination_updated_block);
+        if SellerAccount>=0 then
+          APreviousUpdatedBlocks.UpdateIfLower(SellerAccount,FPrevious_Seller_updated_block);
+      end;
     end;
     end;
     Result := true;
     Result := true;
   end;
   end;
@@ -2579,7 +2595,8 @@ begin
       OperationResume.isMultiOperation:=True;
       OperationResume.isMultiOperation:=True;
       OperationResume.OpSubtype := CT_OpSubtype_MultiOperation;
       OperationResume.OpSubtype := CT_OpSubtype_MultiOperation;
       OperationResume.OperationTxt := Operation.ToString;
       OperationResume.OperationTxt := Operation.ToString;
-      OperationResume.Amount := Operation.OperationAmount * (-1);
+      OperationResume.Amount := Operation.OperationAmountByAccount(Affected_account_number);
+      OperationResume.Fee := 0;
       Result := True;
       Result := True;
     end
     end
   else Exit;
   else Exit;
@@ -2637,10 +2654,13 @@ function TPCOperation.SaveToStorage(Stream: TStream): Boolean;
 
 
 begin
 begin
   Result := SaveOpToStream(Stream,True);
   Result := SaveOpToStream(Stream,True);
+  { XXXXXXXXXXXXXXX
+  DEPRECATED on V3, will use TPreviousUpdatedBlocks
   Stream.Write(FPrevious_Signer_updated_block,Sizeof(FPrevious_Signer_updated_block));
   Stream.Write(FPrevious_Signer_updated_block,Sizeof(FPrevious_Signer_updated_block));
   Stream.Write(FPrevious_Destination_updated_block,SizeOf(FPrevious_Destination_updated_block));
   Stream.Write(FPrevious_Destination_updated_block,SizeOf(FPrevious_Destination_updated_block));
   Stream.Write(FPrevious_Seller_updated_block,SizeOf(FPrevious_Seller_updated_block));
   Stream.Write(FPrevious_Seller_updated_block,SizeOf(FPrevious_Seller_updated_block));
-  Result := true;
+
+  Result := true; }
 end;
 end;
 
 
 function TPCOperation.Sha256: TRawBytes;
 function TPCOperation.Sha256: TRawBytes;
@@ -2651,6 +2671,11 @@ begin
   Result := FBufferedSha256;
   Result := FBufferedSha256;
 end;
 end;
 
 
+function TPCOperation.OperationAmountByAccount(account: Cardinal): Int64;
+begin
+  Result := 0;
+end;
+
 { TOperationsResumeList }
 { TOperationsResumeList }
 
 
 Type POperationResume = ^TOperationResume;
 Type POperationResume = ^TOperationResume;

+ 6 - 3
src/core/UNetProtocol.pas

@@ -1646,18 +1646,18 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
             Bank.Storage.MoveBlockChainBlocks(start_block,TNode.Node.Bank.Storage.Orphan,TNode.Node.Bank.Storage);
             Bank.Storage.MoveBlockChainBlocks(start_block,TNode.Node.Bank.Storage.Orphan,TNode.Node.Bank.Storage);
             //
             //
             If IsUsingSnapshot then begin
             If IsUsingSnapshot then begin
-              TLog.NewLog(ltInfo,ClassName,'Commiting new chain to Safebox');
+              TLog.NewLog(ltInfo,CT_LogSender,'Commiting new chain to Safebox');
               Bank.SafeBox.CommitToPrevious;
               Bank.SafeBox.CommitToPrevious;
               Bank.UpdateValuesFromSafebox;
               Bank.UpdateValuesFromSafebox;
               {$IFDEF Check_Safebox_Names_Consistency}
               {$IFDEF Check_Safebox_Names_Consistency}
               If Not Check_Safebox_Names_Consistency(Bank.SafeBox,'Commited',errors) then begin
               If Not Check_Safebox_Names_Consistency(Bank.SafeBox,'Commited',errors) then begin
-                TLog.NewLog(lterror,ClassName,'Fatal safebox consistency error getting bank at block '+IntTosTr(start_block)+' : '+errors);
+                TLog.NewLog(lterror,CT_LogSender,'Fatal safebox consistency error getting bank at block '+IntTosTr(start_block)+' : '+errors);
                 Sleep(1000);
                 Sleep(1000);
                 halt(0);
                 halt(0);
               end;
               end;
               {$ENDIF}
               {$ENDIF}
             end else begin
             end else begin
-              TLog.NewLog(ltInfo,ClassName,'Restoring modified Safebox from Disk');
+              TLog.NewLog(ltInfo,CT_LogSender,'Restoring modified Safebox from Disk');
               TNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
               TNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
             end;
             end;
           Finally
           Finally
@@ -2820,6 +2820,9 @@ Var dataSend, dataReceived : TMemoryStream;
   errors : AnsiString;
   errors : AnsiString;
   i : Integer;
   i : Integer;
 begin
 begin
+  {$IFDEF PRODUCTION}
+  If FNetProtocolVersion.protocol_available<=6 then Exit; // Note: GetPendingOperations started on protocol_available=7
+  {$ENDIF}
   request_id := 0;
   request_id := 0;
   cAddedOperations := 0;
   cAddedOperations := 0;
   if Not Connected then exit;
   if Not Connected then exit;

+ 37 - 18
src/core/UNode.pas

@@ -63,6 +63,7 @@ Type
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
   public
   public
     Class Function Node : TNode;
     Class Function Node : TNode;
+    Class Function NodeExists : Boolean;
     Class Procedure DecodeIpStringToNodeServerAddressArray(Const Ips : AnsiString; Var NodeServerAddressArray : TNodeServerAddressArray);
     Class Procedure DecodeIpStringToNodeServerAddressArray(Const Ips : AnsiString; Var NodeServerAddressArray : TNodeServerAddressArray);
     Class Function EncodeNodeServerAddressArrayToIpString(Const NodeServerAddressArray : TNodeServerAddressArray) : AnsiString;
     Class Function EncodeNodeServerAddressArrayToIpString(Const NodeServerAddressArray : TNodeServerAddressArray) : AnsiString;
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
@@ -516,7 +517,7 @@ begin
 end;
 end;
 
 
 class procedure TNode.DecodeIpStringToNodeServerAddressArray(
 class procedure TNode.DecodeIpStringToNodeServerAddressArray(
-  const Ips: AnsiString; var NodeServerAddressArray: TNodeServerAddressArray);
+  const Ips: AnsiString; Var NodeServerAddressArray: TNodeServerAddressArray);
   Function GetIp(var ips_string : AnsiString; var nsa : TNodeServerAddress) : Boolean;
   Function GetIp(var ips_string : AnsiString; var nsa : TNodeServerAddress) : Boolean;
   Const CT_IP_CHARS = ['a'..'z','A'..'Z','0'..'9','.','-','_'];
   Const CT_IP_CHARS = ['a'..'z','A'..'Z','0'..'9','.','-','_'];
   var i : Integer;
   var i : Integer;
@@ -658,7 +659,7 @@ begin
   Result := true;
   Result := true;
 end;
 end;
 
 
-function TNode.IsReady(var CurrentProcess: AnsiString): Boolean;
+function TNode.IsReady(Var CurrentProcess: AnsiString): Boolean;
 begin
 begin
   Result := false;
   Result := false;
   CurrentProcess := '';
   CurrentProcess := '';
@@ -690,6 +691,11 @@ begin
   Result := _Node;
   Result := _Node;
 end;
 end;
 
 
+class function TNode.NodeExists: Boolean;
+begin
+  Result := Assigned(_Node);
+end;
+
 procedure TNode.Notification(AComponent: TComponent; Operation: TOperation);
 procedure TNode.Notification(AComponent: TComponent; Operation: TOperation);
 begin
 begin
   inherited;
   inherited;
@@ -716,6 +722,8 @@ procedure TNode.GetStoredOperationsFromAccount(const OperationsResume: TOperatio
     i : Integer;
     i : Integer;
     last_block_number : Integer;
     last_block_number : Integer;
     found_in_block : Boolean;
     found_in_block : Boolean;
+    acc_0_miner_reward, acc_4_dev_reward : Int64;
+    acc_4_for_dev : Boolean;
   begin
   begin
     if (act_depth<=0) then exit;
     if (act_depth<=0) then exit;
     opc := TPCOperationsComp.Create(Nil);
     opc := TPCOperationsComp.Create(Nil);
@@ -753,23 +761,34 @@ procedure TNode.GetStoredOperationsFromAccount(const OperationsResume: TOperatio
           end;
           end;
 
 
           // Is a new block operation?
           // Is a new block operation?
-          if (TAccountComp.AccountBlock(account_number)=block_number) And ((account_number MOD CT_AccountsPerBlock)=0) then begin
-            OPR := CT_TOperationResume_NUL;
-            OPR.valid := true;
-            OPR.Block := block_number;
-            OPR.time := opc.OperationBlock.timestamp;
-            OPR.AffectedAccount := account_number;
-            OPR.Amount := opc.OperationBlock.reward;
-            OPR.Fee := opc.OperationBlock.fee;
-            If last_balance>=0 then begin
-              OPR.Balance := last_balance;
-            end else OPR.Balance := -1; // Undetermined
-            OPR.OperationTxt := 'Blockchain reward';
-            if (nOpsCounter>=StartOperation) And (nOpsCounter<=EndOperation) then begin
-              OperationsResume.Add(OPR);
+          if (TAccountComp.AccountBlock(account_number)=block_number) then begin
+            TPascalCoinProtocol.GetRewardDistributionForNewBlock(opc.OperationBlock,acc_0_miner_reward,acc_4_dev_reward,acc_4_for_dev);
+            If ((account_number MOD CT_AccountsPerBlock)=0) Or
+               (  ((account_number MOD CT_AccountsPerBlock)=CT_AccountsPerBlock-1) AND (acc_4_for_dev)  ) then begin
+              OPR := CT_TOperationResume_NUL;
+              OPR.OpType:=CT_PseudoOp_Reward;
+              OPR.valid := true;
+              OPR.Block := block_number;
+              OPR.time := opc.OperationBlock.timestamp;
+              OPR.AffectedAccount := account_number;
+              If ((account_number MOD CT_AccountsPerBlock)=0) then begin
+                OPR.Amount := acc_0_miner_reward;
+                OPR.OperationTxt := 'Miner reward';
+                OPR.OpSubtype:=CT_PseudoOpSubtype_Miner;
+              end else begin
+                OPR.Amount := acc_4_dev_reward;
+                OPR.OperationTxt := 'Dev reward';
+                OPR.OpSubtype:=CT_PseudoOpSubtype_Developer;
+              end;
+              If last_balance>=0 then begin
+               OPR.Balance := last_balance;
+              end else OPR.Balance := -1; // Undetermined
+              if (nOpsCounter>=StartOperation) And (nOpsCounter<=EndOperation) then begin
+               OperationsResume.Add(OPR);
+              end;
+              inc(nOpsCounter);
+              found_in_block := True;
             end;
             end;
-            inc(nOpsCounter);
-            found_in_block := True;
           end;
           end;
           //
           //
           dec(act_depth);
           dec(act_depth);