فهرست منبع

Build 2.1.9

Searchs last valid block found on corrupted BlockChainStream.blocks file
and allows to continue from last valid one. On prior versions, app
halted and needed manually file deletion
PascalCoin 7 سال پیش
والد
کامیت
48088e4928
4فایلهای تغییر یافته به همراه56 افزوده شده و 17 حذف شده
  1. 3 0
      README.md
  2. 3 0
      README.txt
  3. 1 1
      Units/PascalCoin/UConst.pas
  4. 49 16
      Units/PascalCoin/UFileStorage.pas

+ 3 - 0
README.md

@@ -34,6 +34,9 @@ Also, consider a donation at PascalCoin development account: "0-10"
 
 ## History:  
 
+### Build 2.1.9 - 2018-04-16
+- Searchs last valid block found on corrupted BlockChainStream.blocks file and allows to continue from last valid one. On prior versions, app halted and needed manually file deletion
+
 ### Build 2.1.8 - 2018-04-16
 - Solved bug that can cause to corrupt BlockChainStream.blocks file when detecting an orphan block and creating new BlockHeaders row (every 1000 blocks). Very rare bug, but fatal error
 

+ 3 - 0
README.txt

@@ -34,6 +34,9 @@ Also, consider a donation at PascalCoin development account: "0-10"
 
 ## History:  
 
+### Build 2.1.9 - 2018-04-16
+- Searchs last valid block found on corrupted BlockChainStream.blocks file and allows to continue from last valid one. On prior versions, app halted and needed manually file deletion
+
 ### Build 2.1.8 - 2018-04-16
 - Solved bug that can cause to corrupt BlockChainStream.blocks file when detecting an orphan block and creating new BlockHeaders row (every 1000 blocks). Very rare bug, but fatal error
 

+ 1 - 1
Units/PascalCoin/UConst.pas

@@ -138,7 +138,7 @@ Const
   CT_OpSubtype_ChangeKeySigned            = 71;
   CT_OpSubtype_ChangeAccountInfo          = 81;
 
-  CT_ClientAppVersion : AnsiString = {$IFDEF PRODUCTION}'2.1.8'{$ELSE}{$IFDEF TESTNET}'TESTNET 2.1.8'{$ELSE}{$ENDIF}{$ENDIF};
+  CT_ClientAppVersion : AnsiString = {$IFDEF PRODUCTION}'2.1.9'{$ELSE}{$IFDEF TESTNET}'TESTNET 2.1.9'{$ELSE}{$ENDIF}{$ENDIF};
 
   CT_Discover_IPs =  'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin1.dynamic-dns.net;pascalcoin2.dynamic-dns.net;pascalcoin1.dns1.us;pascalcoin2.dns1.us;pascalcoin1.dns2.us;pascalcoin2.dns2.us';
 

+ 49 - 16
Units/PascalCoin/UFileStorage.pas

@@ -235,6 +235,8 @@ begin
     If Not StreamReadBlockHeader(Stream,iBlockHeaders,BlockHeaderFirstBlock,StartingDeleteBlock,True,_Header) then exit;
     _intBlockIndex := (_Header.BlockNumber-BlockHeaderFirstBlock);
 
+    TLog.NewLog(ltInfo,ClassName,Format('Deleting Blockchain block %d',[StartingDeleteBlock]));
+
     p := FBlockHeadersFirstBytePosition[iBlockHeaders] + (Int64(_intBlockIndex) * Int64(CT_SizeOfBlockHeader));
 
     Stream.Position:=p;
@@ -686,6 +688,7 @@ function TFileStorage.LockBlockChainStream: TFileStream;
     FStreamFirstBlockNumber := 0;
     FStreamLastBlockNumber := -1;
     SetLength(FBlockHeadersFirstBytePosition,0);
+    Result := False;
     //
     if stream.Size<GetBlockHeaderFixedSize then begin
       if (stream.Size=0) then begin
@@ -693,9 +696,16 @@ function TFileStorage.LockBlockChainStream: TFileStream;
         exit;
       end else begin
         // Invalid stream!
-        Result := false;
-        errors := Format('Invalid stream size %d. Lower than minimum %d',[stream.Size, GetBlockHeaderFixedSize]);
-        exit;
+        if (ReadOnly) then begin
+          errors := Format('Invalid stream size %d. Lower than minimum %d',[stream.Size, GetBlockHeaderFixedSize]);
+          exit;
+        end else begin
+          // Clear it
+          TLog.NewLog(ltError,ClassName,Format('Invalid stream size %d. Lower than minimum %d - Initialized to 0',[stream.Size, GetBlockHeaderFixedSize]));
+          stream.size := 0;
+          Result := True;
+          Exit;
+        end;
       end;
     end;
     // Initialize it
@@ -720,9 +730,18 @@ function TFileStorage.LockBlockChainStream: TFileStream;
             FStreamFirstBlockNumber := bh.BlockNumber;
             FStreamLastBlockNumber := bh.BlockNumber;
             if (0<>bh.StreamBlockRelStartPos) then begin
-              errors := Format('Invalid first block start rel pos %d',[bh.StreamBlockRelStartPos]);
-              result := false;
-              exit;
+              errors := Format('Invalid BlockChain stream. First block start rel pos %d',[bh.StreamBlockRelStartPos]);
+              if (ReadOnly) then begin
+                Exit;
+              end else begin
+                FStreamFirstBlockNumber := 0;
+                FStreamLastBlockNumber := -1;
+                SetLength(FBlockHeadersFirstBytePosition,0);
+                stream.Size:=0; // Set size to 0, no data
+                TLog.NewLog(ltError,ClassName,Format('%s - Initialized to 0',[errors]));
+                Result := True;
+              end;
+              Exit;
             end;
             lastbh := bh;
           end else begin
@@ -730,12 +749,18 @@ function TFileStorage.LockBlockChainStream: TFileStream;
             if (bh.BlockNumber=0) then begin
               // This is an "empty" block. Check that ok
               If (bh.BlockNumber<>0) Or (bh.StreamBlockRelStartPos<>0) Or (bh.BlockSize<>0) then begin
-                errors := Format('Invalid empty block on block header. iPos=%d i=%d BlockNumber=%d relstart=%d size=%d - Last block:%d BlockNumber=%d relstart=%d size=%d',
-                [iPos,i,bh.BlockNumber,bh.StreamBlockRelStartPos,bh.BlockSize,
-                 FStreamLastBlockNumber,
-                 lastbh.BlockNumber,lastbh.StreamBlockRelStartPos,lastbh.BlockSize]);
-                result := false;
-                exit;
+                errors := Format('Invalid BlockChain stream not empty block on block header. iPos=%d i=%d BlockNumber=%d relstart=%d size=%d - Last block:%d BlockNumber=%d relstart=%d size=%d',
+                  [iPos,i,bh.BlockNumber,bh.StreamBlockRelStartPos,bh.BlockSize,
+                   FStreamLastBlockNumber,
+                   lastbh.BlockNumber,lastbh.StreamBlockRelStartPos,lastbh.BlockSize]);
+                if (ReadOnly) then begin
+                  Exit;
+                end else begin
+                  TLog.NewLog(lterror,ClassName,Format('%s - Initialized to %d',[errors,FStreamFirstBlockNumber]));
+                  DoDeleteBlockChainBlocks(FStreamLastBlockNumber+1);
+                  Result := True;
+                  Exit;
+                end;
               end;
               // Ok, inc blocknumber
               inc(lastbh.BlockNumber);
@@ -743,11 +768,17 @@ function TFileStorage.LockBlockChainStream: TFileStream;
               if (lastbh.BlockNumber+1<>bh.BlockNumber) or
                 ((lastbh.StreamBlockRelStartPos+lastbh.BlockSize<>bh.StreamBlockRelStartPos) And (i>0)) Or
                 ((0<>bh.StreamBlockRelStartPos) And (i=0)) then begin
-                errors := Format('Invalid check on block header. iPos=%d i=%d BlockNumber=%d relstart=%d size=%d - Last block:%d BlockNumber=%d relstart=%d size=%d',
+                errors := Format('Invalid BlockChain stream on block header. iPos=%d i=%d BlockNumber=%d relstart=%d size=%d - Last block:%d BlockNumber=%d relstart=%d size=%d',
                   [iPos,i,bh.BlockNumber,bh.StreamBlockRelStartPos,bh.BlockSize,FStreamLastBlockNumber,
                    lastbh.BlockNumber,lastbh.StreamBlockRelStartPos,lastbh.BlockSize]);
-                result := false;
-                exit;
+                If (ReadOnly) then begin
+                  Exit;
+                end else begin
+                  TLog.NewLog(lterror,ClassName,Format('%s - Initialized to %d',[errors,FStreamFirstBlockNumber]));
+                  DoDeleteBlockChainBlocks(FStreamLastBlockNumber+1);
+                  Result := True;
+                  Exit;
+                end;
               end else begin
                 FStreamLastBlockNumber := bh.BlockNumber;
                 lastbh := bh;
@@ -759,7 +790,7 @@ function TFileStorage.LockBlockChainStream: TFileStream;
         lastbh.StreamBlockRelStartPos:=0;
         lastbh.BlockSize:=0;
       end;
-      Result := true;
+      Result := True;
     Finally
       mem.Free;
     End;
@@ -792,6 +823,8 @@ begin
       If Not InitStreamInfo(FBlockChainStream,errors) then begin
         TLog.NewLog(lterror,ClassName,errors);
         raise Exception.Create('Error reading File: '+fn+#10+'Errors:'+#10+errors);
+      end else begin
+        TLog.NewLog(ltInfo,ClassName,Format('Loaded blockchain file: %s with blocks from %d to %d',[fn,FStreamFirstBlockNumber,FStreamLastBlockNumber]));
       end;
     end;
   Except