Browse Source

add new "get safebox" protection

PascalCoin 6 years ago
parent
commit
48e857970f
4 changed files with 22 additions and 10 deletions
  1. 16 4
      src/core/UAccounts.pas
  2. 4 4
      src/core/UBlockChain.pas
  3. 1 1
      src/core/UFileStorage.pas
  4. 1 1
      src/core/UNetProtocol.pas

+ 16 - 4
src/core/UAccounts.pas

@@ -365,7 +365,7 @@ Type
     Class Function CalcBlockHash(const block : TBlockAccount; useProtocol2Method : Boolean):TRawBytes;
     Class Function BlockAccountToText(Const block : TBlockAccount):AnsiString;
     Function LoadSafeBoxFromStream(Stream : TStream; checkAll : Boolean; var LastReadBlock : TBlockAccount; var errors : AnsiString) : Boolean; overload;
-    Function LoadSafeBoxFromStream(Stream : TStream; checkAll : Boolean; progressNotify : TProgressNotify; var LastReadBlock : TBlockAccount; var errors : AnsiString) : Boolean; overload;
+    Function LoadSafeBoxFromStream(Stream : TStream; checkAll : Boolean; checkSafeboxHash : TRawBytes; progressNotify : TProgressNotify; var LastReadBlock : TBlockAccount; var errors : AnsiString) : Boolean; overload;
     Class Function LoadSafeBoxStreamHeader(Stream : TStream; var sbHeader : TPCSafeBoxHeader) : Boolean;
     Class Function SaveSafeBoxStreamHeader(Stream : TStream; protocol : Word; OffsetStartBlock, OffsetEndBlock, CurrentSafeBoxBlocksCount : Cardinal) : Boolean;
     Class Function MustSafeBoxBeSaved(BlocksCount : Cardinal) : Boolean;
@@ -2765,7 +2765,7 @@ begin
   FLock.Release;
 end;
 
-function TPCSafeBox.LoadSafeBoxFromStream(Stream : TStream; checkAll : Boolean; progressNotify : TProgressNotify; var LastReadBlock : TBlockAccount; var errors : AnsiString) : Boolean;
+function TPCSafeBox.LoadSafeBoxFromStream(Stream : TStream; checkAll : Boolean; checkSafeboxHash : TRawBytes; progressNotify : TProgressNotify; var LastReadBlock : TBlockAccount; var errors : AnsiString) : Boolean;
 Var
   iblock,iacc : Cardinal;
   s : AnsiString;
@@ -2875,12 +2875,17 @@ begin
         if checkAll then begin
           // Check is valid:
           // STEP 1: Validate the block
-          if ((iblock + (CT_BankToDiskEveryNBlocks * 20)) >= sbHeader.blockscount) then begin
+          {$IFDEF TESTNET}
+            // For TESTNET increase speed purposes, will only check latests blocks
+          if ((iblock + (CT_BankToDiskEveryNBlocks * 10)) >= sbHeader.blockscount) then begin
+          {$ENDIF}
             If not IsValidNewOperationsBlock(block.blockchainInfo,False,s) then begin
               errors := errors + ' > ' + s;
               exit;
             end;
+          {$IFDEF TESTNET}
           end;
+          {$ENDIF}
           // STEP 2: Check if valid block hash
           if CalcBlockHash(block,FCurrentProtocol>=CT_PROTOCOL_2)<>block.block_hash then begin
             errors := errors + ' > Invalid block hash '+inttostr(iblock+1)+'/'+inttostr(sbHeader.blockscount);
@@ -2945,6 +2950,13 @@ begin
         errors := 'Invalid SafeBoxHash value in stream '+TCrypto.ToHexaString(FSafeBoxHash)+'<>'+TCrypto.ToHexaString(savedSBH)+' Last block:'+IntToStr(LastReadBlock.blockchainInfo.block);
         exit;
       end;
+      // Check that checkSafeboxHash is as expected
+      if (checkSafeboxHash<>'') then begin
+        if (TBaseType.BinStrComp(checkSafeboxHash,FSafeBoxHash)<>0) then begin
+          errors := 'Invalid SafeboxHash, does not match '+TCrypto.ToHexaString(FSafeBoxHash)+'<>'+TCrypto.ToHexaString(checkSafeboxHash)+' Last block:'+IntToStr(LastReadBlock.blockchainInfo.block);
+          Exit;
+        end;
+      end;
       Result := true;
     Finally
       if Not Result then Clear else errors := '';
@@ -2958,7 +2970,7 @@ function TPCSafeBox.LoadSafeBoxFromStream(Stream: TStream; checkAll: Boolean; va
 var pn : TProgressNotify;
 begin
   pn := Nil;
-  Result := LoadSafeBoxFromStream(Stream,checkAll,pn,LastReadBlock,errors);
+  Result := LoadSafeBoxFromStream(Stream,checkAll,'',pn,LastReadBlock,errors);
 end;
 
 class function TPCSafeBox.LoadSafeBoxStreamHeader(Stream: TStream; var sbHeader : TPCSafeBoxHeader) : Boolean;

+ 4 - 4
src/core/UBlockChain.pas

@@ -477,7 +477,7 @@ Type
     procedure AssignTo(Dest: TPersistent); Override;
     function GetActualTargetSecondsAverage(BackBlocks : Cardinal): Real;
     function GetTargetSecondsAverage(FromBlock,BackBlocks : Cardinal): Real;
-    function LoadBankFromStream(Stream : TStream; useSecureLoad : Boolean; progressNotify : TProgressNotify; var errors : AnsiString) : Boolean;
+    function LoadBankFromStream(Stream : TStream; useSecureLoad : Boolean; checkSafeboxHash : TRawBytes; progressNotify : TProgressNotify; var errors : AnsiString) : Boolean;
     Procedure Clear;
     Function LoadOperations(Operations : TPCOperationsComp; Block : Cardinal) : Boolean;
     Property SafeBox : TPCSafeBox read FSafeBox;
@@ -816,7 +816,7 @@ begin
   end else Result := true;
 end;
 
-function TPCBank.LoadBankFromStream(Stream: TStream; useSecureLoad : Boolean; progressNotify : TProgressNotify; var errors: AnsiString): Boolean;
+function TPCBank.LoadBankFromStream(Stream: TStream; useSecureLoad : Boolean; checkSafeboxHash : TRawBytes; progressNotify : TProgressNotify; var errors: AnsiString): Boolean;
 Var LastReadBlock : TBlockAccount;
   i : Integer;
   auxSB : TPCSafeBox;
@@ -826,7 +826,7 @@ begin
     If useSecureLoad then begin
       // When on secure load will load Stream in a separate SafeBox, changing only real SafeBox if successfully
       auxSB := TPCSafeBox.Create;
-      Result := auxSB.LoadSafeBoxFromStream(Stream,true,progressNotify,LastReadBlock,errors);
+      Result := auxSB.LoadSafeBoxFromStream(Stream,true,checkSafeboxHash,progressNotify,LastReadBlock,errors);
       If Not Result then Exit;
     end;
     TPCThread.ProtectEnterCriticalSection(Self,FBankLock);
@@ -834,7 +834,7 @@ begin
       If Assigned(auxSB) then begin
         SafeBox.CopyFrom(auxSB);
       end else begin
-        Result := SafeBox.LoadSafeBoxFromStream(Stream,False,progressNotify,LastReadBlock,errors);
+        Result := SafeBox.LoadSafeBoxFromStream(Stream,False,checkSafeboxHash,progressNotify,LastReadBlock,errors);
       end;
       If Not Result then exit;
       If SafeBox.BlocksCount>0 then FLastOperationBlock := SafeBox.Block(SafeBox.BlocksCount-1).blockchainInfo

+ 1 - 1
src/core/UFileStorage.pas

@@ -482,7 +482,7 @@ begin
           ms.CopyFrom(fs,0);
           fs.Position := 0;
           ms.Position := 0;
-          if not Bank.LoadBankFromStream(ms,False,restoreProgressNotify,errors) then begin
+          if not Bank.LoadBankFromStream(ms,False,'',restoreProgressNotify,errors) then begin
             TLog.NewLog(lterror,ClassName,'Error reading bank from file: '+filename+ ' Error: '+errors);
           end;
         Finally

+ 1 - 1
src/core/UNetProtocol.pas

@@ -1889,7 +1889,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
       try
           FNewBlockChainFromClientStatus := Format('Received new safebox with %d blocks from %s',[_blockcount,Connection.ClientRemoteAddr]);
           receiveData.Position:=0;
-          If TNode.Node.Bank.LoadBankFromStream(receiveData,True,OnReadingNewSafeboxProgressNotify,errors) then begin
+          If TNode.Node.Bank.LoadBankFromStream(receiveData,True,op.initial_safe_box_hash,OnReadingNewSafeboxProgressNotify,errors) then begin
             TLog.NewLog(ltInfo,ClassName,'Received new safebox!');
             If Not IsMyBlockchainValid then begin
               TNode.Node.Bank.Storage.EraseStorage;