Browse Source

Merge downstream

Herman Schoenfeld 7 năm trước cách đây
mục cha
commit
2a25b555bd

+ 4 - 0
README.md

@@ -38,6 +38,9 @@ Also, consider a donation at PascalCoin development account: "0-10"
 - TODO: Explore possible modification to sinoidial effect on blocks time (No PIP) 
 - TODO: PIP - 0010
 - TODO: Add new network operations
+- New Safebox Snapshoting
+  - This allow quickly rollback/commit directly to Safebox instead of create a separate Safebox on memory (read from disk... use more ram...)
+  - Is usefull when detecting posible orphan blocks in order to check which chain is the highest chain without duplicating a safebox to compare
 - New Node network operations
   - Get pending operations (code $0030)
     - Implementation of the PIP-0013 (not exactly but with similar features)	
@@ -79,6 +82,7 @@ Also, consider a donation at PascalCoin development account: "0-10"
   - Protection on GetBlocks and GetBlockOperations
 - Merged new GUI with current stable core
 - New folders organization
+- Bugs solved
 
 ### Build 2.1.6 - 2018-02-14
 - Important improvements

+ 6 - 0
src/config.inc

@@ -41,6 +41,12 @@
   // HighLog will result in a higher log generation
   {.$DEFINE HIGHLOG}
 
+  // Warning: This define is only for testing purposes! Never enable it!
+  {.$DEFINE TESTING_NO_POW_CHECK}
+
+  // This will allow check safebox names list. Warning: This will slow app
+  {.$DEFINE Check_Safebox_Names_Consistency}
+
 { ********************************************************************
   Don't touch more code, it will addapt based on your preferences
   ******************************************************************** }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 802 - 75
src/core/UAccounts.pas


+ 1 - 1
src/core/UBaseTypes.pas

@@ -299,7 +299,7 @@ end;
 
 class function TPlatform.GetElapsedMilliseconds(const previousTickCount: TTickCount): Int64;
 begin
-  Result := (Self.GetTickCount - previousTickCount){$IFDEF CPU64} DIV 1000{$ENDIF};
+  Result := (Self.GetTickCount - previousTickCount);
 end;
 
 class function TPlatform.GetTickCount: TTickCount;

+ 53 - 19
src/core/UBlockChain.pas

@@ -455,6 +455,7 @@ Type
     Property SafeBox : TPCSafeBox read FSafeBox;
     Function AddNewBlockChainBlock(Operations: TPCOperationsComp; MaxAllowedTimestamp : Cardinal; var newBlock: TBlockAccount; var errors: AnsiString): Boolean;
     Procedure DiskRestoreFromOperations(max_block : Int64);
+    Procedure UpdateValuesFromSafebox;
     Procedure NewLog(Operations: TPCOperationsComp; Logtype: TLogType; Logtxt: AnsiString);
     Property OnLog: TPCBankLog read FOnLog write FOnLog;
     Property LastOperationBlock : TOperationBlock read FLastOperationBlock; // TODO: Use
@@ -688,6 +689,39 @@ begin
   end;
 end;
 
+procedure TPCBank.UpdateValuesFromSafebox;
+Var aux : AnsiString;
+  i : Integer;
+begin
+  { Will update current Bank state based on Safbox state
+    Used when commiting a Safebox or rolling back }
+  Try
+    TPCThread.ProtectEnterCriticalSection(Self,FBankLock);
+    try
+      FLastBlockCache.Clear(True);
+      FLastOperationBlock := TPCOperationsComp.GetFirstBlock;
+      FLastOperationBlock.initial_safe_box_hash := TCrypto.DoSha256(CT_Genesis_Magic_String_For_Old_Block_Hash); // Genesis hash
+      If FSafeBox.BlocksCount>0 then begin
+        Storage.Initialize;
+        If Storage.LoadBlockChainBlock(FLastBlockCache,FSafeBox.BlocksCount-1) then begin
+          FLastOperationBlock := FLastBlockCache.OperationBlock;
+        end else begin
+          aux := 'Cannot read last operations block '+IntToStr(FSafeBox.BlocksCount-1)+' from blockchain';
+          TLog.NewLog(lterror,ClassName,aux);
+          Raise Exception.Create(aux);
+        end;
+      end;
+      TLog.NewLog(ltinfo,ClassName,Format('Updated Bank with Safebox values. Current block:%d ',[FLastOperationBlock.block]));
+    finally
+      FBankLock.Release;
+    end;
+  finally
+    for i := 0 to FNotifyList.Count - 1 do begin
+      TPCBankNotify(FNotifyList.Items[i]).NotifyNewBlock;
+    end;
+  end;
+end;
+
 function TPCBank.GetActualTargetSecondsAverage(BackBlocks: Cardinal): Real;
 Var ts1, ts2: Int64;
 begin
@@ -736,7 +770,7 @@ begin
   Result := FStorage;
 end;
 
-function TPCBank.IsReady(var CurrentProcess: AnsiString): Boolean;
+function TPCBank.IsReady(Var CurrentProcess: AnsiString): Boolean;
 begin
   Result := false;
   CurrentProcess := '';
@@ -922,18 +956,18 @@ begin
 
     FOperationBlock.timestamp := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
     if Assigned(FBank) then begin
-      FOperationBlock.protocol_version := bank.SafeBox.CurrentProtocol;
+      FOperationBlock.protocol_version := FBank.SafeBox.CurrentProtocol;
       If (FOperationBlock.protocol_version=CT_PROTOCOL_1) And (FBank.SafeBox.CanUpgradeToProtocol(CT_PROTOCOL_2)) then begin
         FOperationBlock.protocol_version := CT_PROTOCOL_2; // If minting... upgrade to Protocol 2
       end else if (FOperationBlock.protocol_version=CT_PROTOCOL_2) And (FBank.SafeBox.CanUpgradeToProtocol(CT_PROTOCOL_3)) then begin
         FOperationBlock.protocol_version := CT_PROTOCOL_3; // If minting... upgrade to Protocol 3
       end;
-      FOperationBlock.block := bank.BlocksCount;
-      FOperationBlock.reward := TPascalCoinProtocol.GetRewardForNewLine(bank.BlocksCount);
-      FOperationBlock.compact_target := bank.Safebox.GetActualCompactTargetHash(FOperationBlock.protocol_version);
-      FOperationBlock.initial_safe_box_hash := bank.SafeBox.SafeBoxHash;
-      If Bank.LastOperationBlock.timestamp>FOperationBlock.timestamp then
-        FOperationBlock.timestamp := Bank.LastOperationBlock.timestamp;
+      FOperationBlock.block := FBank.BlocksCount;
+      FOperationBlock.reward := TPascalCoinProtocol.GetRewardForNewLine(FBank.BlocksCount);
+      FOperationBlock.compact_target := FBank.Safebox.GetActualCompactTargetHash(FOperationBlock.protocol_version);
+      FOperationBlock.initial_safe_box_hash := FBank.SafeBox.SafeBoxHash;
+      If FBank.LastOperationBlock.timestamp>FOperationBlock.timestamp then
+        FOperationBlock.timestamp := FBank.LastOperationBlock.timestamp;
     end else begin
       FOperationBlock.block := 0;
       FOperationBlock.reward := TPascalCoinProtocol.GetRewardForNewLine(0);
@@ -987,7 +1021,7 @@ begin
     lastopb := FOperationBlock;
     FOperationBlock := Operations.FOperationBlock;
     FOperationBlock.account_key := lastopb.account_key; // Except AddressKey
-    FOperationBlock.compact_target := Bank.Safebox.GetActualCompactTargetHash(FOperationBlock.protocol_version);
+    FOperationBlock.compact_target := FBank.Safebox.GetActualCompactTargetHash(FOperationBlock.protocol_version);
     FIsOnlyOperationBlock := Operations.FIsOnlyOperationBlock;
     FOperationsHashTree.CopyFromHashTree(Operations.FOperationsHashTree);
     FOperationBlock.operations_hash := FOperationsHashTree.HashTree;
@@ -1021,7 +1055,7 @@ begin
   FSafeBoxTransaction := Nil;
   FPreviousUpdatedBlocks := TAccountPreviousBlockInfo.Create;
   if Assigned(AOwner) And (AOwner is TPCBank) then begin
-    Bank := TPCBank(AOwner);
+    SetBank( TPCBank(AOwner) );
   end else Clear(true);
 end;
 
@@ -1267,7 +1301,7 @@ begin
   Try
     FOperationBlock.timestamp := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
     if Assigned(FBank) then begin
-      FOperationBlock.protocol_version := bank.SafeBox.CurrentProtocol;
+      FOperationBlock.protocol_version := FBank.SafeBox.CurrentProtocol;
       If (FOperationBlock.protocol_version=CT_PROTOCOL_1) And (FBank.SafeBox.CanUpgradeToProtocol(CT_PROTOCOL_2)) then begin
         TLog.NewLog(ltinfo,ClassName,'New miner protocol version to 2 at sanitize');
         FOperationBlock.protocol_version := CT_PROTOCOL_2;
@@ -1275,12 +1309,12 @@ begin
         TLog.NewLog(ltinfo,ClassName,'New miner protocol version to 3 at sanitize');
         FOperationBlock.protocol_version := CT_PROTOCOL_3;
       end;
-      FOperationBlock.block := bank.BlocksCount;
-      FOperationBlock.reward := TPascalCoinProtocol.GetRewardForNewLine(bank.BlocksCount);
-      FOperationBlock.compact_target := bank.SafeBox.GetActualCompactTargetHash(FOperationBlock.protocol_version);
-      FOperationBlock.initial_safe_box_hash := bank.SafeBox.SafeBoxHash;
-      If Bank.LastOperationBlock.timestamp>FOperationBlock.timestamp then
-        FOperationBlock.timestamp := Bank.LastOperationBlock.timestamp;
+      FOperationBlock.block := FBank.BlocksCount;
+      FOperationBlock.reward := TPascalCoinProtocol.GetRewardForNewLine(FBank.BlocksCount);
+      FOperationBlock.compact_target := FBank.SafeBox.GetActualCompactTargetHash(FOperationBlock.protocol_version);
+      FOperationBlock.initial_safe_box_hash := FBank.SafeBox.SafeBoxHash;
+      If FBank.LastOperationBlock.timestamp>FOperationBlock.timestamp then
+        FOperationBlock.timestamp := FBank.LastOperationBlock.timestamp;
     end else begin
       FOperationBlock.block := 0;
       FOperationBlock.reward := TPascalCoinProtocol.GetRewardForNewLine(0);
@@ -1484,8 +1518,8 @@ begin
   Lock;
   Try
     ts := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
-    if Assigned(bank) then begin
-      If Bank.FLastOperationBlock.timestamp>ts then ts := Bank.FLastOperationBlock.timestamp;
+    if Assigned(FBank) then begin
+      If FBank.FLastOperationBlock.timestamp>ts then ts := FBank.FLastOperationBlock.timestamp;
     end;
     timestamp := ts;
   finally

+ 2 - 0
src/core/UConst.pas

@@ -160,6 +160,8 @@ Const
   CT_MAX_MultiOperation_Receivers = 10000;
   CT_MAX_MultiOperation_Changers = 1000;
 
+  CT_DEFAULT_MaxSafeboxSnapshots = 10;
+
   // App Params
   CT_PARAM_GridAccountsStream = 'GridAccountsStreamV2';
   CT_PARAM_GridAccountsPos = 'GridAccountsPos';

+ 3 - 1
src/core/UFileStorage.pas

@@ -234,7 +234,9 @@ begin
     if Not GetBlockHeaderFirstBytePosition(stream,StartingDeleteBlock,False,iBlockHeaders,BlockHeaderFirstBlock) then exit;
     If Not StreamReadBlockHeader(Stream,iBlockHeaders,BlockHeaderFirstBlock,StartingDeleteBlock,True,_Header) then exit;
     _intBlockIndex := (_Header.BlockNumber-BlockHeaderFirstBlock);
-    p := Int64(_intBlockIndex) * Int64(CT_SizeOfBlockHeader);
+//XXXXXXXXXX BUG !!!    p := Int64(_intBlockIndex) * Int64(CT_SizeOfBlockHeader);
+    p := FBlockHeadersFirstBytePosition[iBlockHeaders] + (Int64(_intBlockIndex) * Int64(CT_SizeOfBlockHeader));
+
     Stream.Position:=p;
     // Write null data until end of header
     GrowStreamUntilPos(Stream,FBlockHeadersFirstBytePosition[iBlockHeaders] + GetBlockHeaderFixedSize,true);

+ 32 - 4
src/core/UNetProtocol.pas

@@ -1536,7 +1536,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     finished : Boolean;
     Bank : TPCBank;
     ms : TMemoryStream;
-    IsAScam : Boolean;
+    IsAScam, IsUsingSnapshot : Boolean;
   Begin
     IsAScam := false;
     TLog.NewLog(ltdebug,CT_LogSender,Format('GetNewBank(new_start_block:%d)',[start_block]));
@@ -1547,8 +1547,20 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
       Bank.Storage.ReadOnly := true;
       Bank.Storage.CopyConfiguration(TNode.Node.Bank.Storage);
       if start_block>=0 then begin
-        // Restore a part
-        Bank.DiskRestoreFromOperations(start_block-1);
+        If (TNode.Node.Bank.SafeBox.GetMinimumAvailableSnapshotBlock<start_block) then begin
+          // XXXXXXXXXXXXX
+          // XXXXXXXXXXXXX
+          // Restore from a Snapshot (New on V3) instead of restore reading from File
+          // XXXXXXXXXXXXX
+          // XXXXXXXXXXXXX
+          Bank.SafeBox.SetToPrevious(TNode.Node.Bank.SafeBox,start_block-1);
+          Bank.UpdateValuesFromSafebox;
+          IsUsingSnapshot := True;
+        end else begin
+          // Restore a part from disk
+          Bank.DiskRestoreFromOperations(start_block-1);
+          IsUsingSnapshot := False;
+        end;
         start := start_block;
       end else begin
         start := 0;
@@ -1631,10 +1643,26 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
             end;
             TNode.Node.Bank.Storage.MoveBlockChainBlocks(start_block,Inttostr(start_block)+'_'+FormatDateTime('yyyymmddhhnnss',DateTime2UnivDateTime(now)),Nil);
             Bank.Storage.MoveBlockChainBlocks(start_block,TNode.Node.Bank.Storage.Orphan,TNode.Node.Bank.Storage);
-            TNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
+            //
+            If IsUsingSnapshot then begin
+              TLog.NewLog(ltInfo,ClassName,'Commiting new chain to Safebox');
+              Bank.SafeBox.CommitToPrevious;
+              Bank.UpdateValuesFromSafebox;
+              {$IFDEF Check_Safebox_Names_Consistency}
+              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);
+                Sleep(1000);
+                halt(0);
+              end;
+              {$ENDIF}
+            end else begin
+              TLog.NewLog(ltInfo,ClassName,'Restoring modified Safebox from Disk');
+              TNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
+            end;
           Finally
             TNode.Node.EnableNewBlocks;
           End;
+          TNode.Node.NotifyBlocksChanged;
           // Finally add new operations:
           // Rescue old operations from old blockchain to new blockchain
           If oldBlockchainOperations.OperationsCount>0 then begin

+ 6 - 1
src/core/UNode.pas

@@ -106,6 +106,7 @@ Type
     Procedure SynchronizedProcess;
   protected
     procedure BCExecute; override;
+  public
     Constructor Create(ANodeNotifyEvents : TNodeNotifyEvents);
   End;
 
@@ -120,10 +121,11 @@ Type
     FOnOperationsChanged: TNotifyEvent;
     FMessages : TStringList;
     FOnNodeMessageEvent: TNodeMessageEvent;
-    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
     procedure SetNode(const Value: TNode);
     Procedure NotifyBlocksChanged;
     Procedure NotifyOperationsChanged;
+  protected
+    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
   public
     Constructor Create(AOwner : TComponent); override;
     Destructor Destroy; override;
@@ -264,6 +266,7 @@ begin
         end;
         TLog.NewLog(ltdebug,ClassName,'Buffer Sent operations: '+IntToStr(FSentOperations.Count));
         // Notify to clients
+        {$IFnDEF TESTING_NO_POW_CHECK}
         j := TNetData.NetData.ConnectionsCountAll;
         for i:=0 to j-1 do begin
           if (TNetData.NetData.GetConnection(i,nc)) then begin
@@ -272,6 +275,7 @@ begin
             end;
           end;
         end;
+        {$ENDIF}
       Finally
         opsht.Free;
       End;
@@ -1020,6 +1024,7 @@ end;
 procedure TNode.OnBankNewBlock(Sender: TObject);
 begin
   FOperations.SanitizeOperations;
+  NotifyBlocksChanged;
 end;
 
 function TNode.SendNodeMessage(Target: TNetConnection; TheMessage: AnsiString; var errors: AnsiString): Boolean;

+ 4 - 2
src/gui/UFRMLogs.pas

@@ -72,8 +72,10 @@ begin
       memoLogs.Lines.EndUpdate;
     end;
   end;
-  memoLogs.Lines.Add('%s %s %p [%s] <%s> %s',
-    [FormatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time), s, ThreadID, CT_LogType[Logtype], sender, logtext]);
+  //memoLogs.Lines.Add('%s %s %p [%s] <%s> %s',                                                             XXXXXXXXXXXXXXXX Windows %p is invalid (not a pointer)
+  //  [FormatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time), s, ThreadID, CT_LogType[Logtype], sender, logtext]); XXXXXXXXXXXXXXXX Windows %p is invalid (not a pointer)
+  memoLogs.Lines.Add('%s %s %s [%s] <%s> %s',
+    [FormatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time), s, IntToHex(PtrInt(ThreadID),8), CT_LogType[Logtype], sender, logtext]);
 end;
 
 end.

+ 2 - 1
src/gui/UFRMNodes.pas

@@ -220,7 +220,8 @@ begin
     strings.BeginUpdate;
     Try
       strings.Clear;
-      strings.Add('BlackList Updated: %s by TID: %p', [DateTimeToStr(now), TThread.CurrentThread.ThreadID]);
+//      strings.Add('BlackList Updated: %s by TID: %p', [DateTimeToStr(now), TThread.CurrentThread.ThreadID]);  XXXXXXXXXXXXXXXX Windows %p is invalid (not a pointer)
+      strings.Add('BlackList Updated: %s by TID: %s', [DateTimeToStr(now), IntToHex(PtrInt(TThread.CurrentThread.ThreadID),8)]);
       j := 0; n:=0;
       for i := 0 to l.Count - 1 do begin
         P := l[i];

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác