Browse Source

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 years ago
parent
commit
48088e4928
4 changed files with 56 additions and 17 deletions
  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:  
 ## 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
 ### 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
 - 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:  
 ## 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
 ### 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
 - 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_ChangeKeySigned            = 71;
   CT_OpSubtype_ChangeAccountInfo          = 81;
   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';
   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;
     If Not StreamReadBlockHeader(Stream,iBlockHeaders,BlockHeaderFirstBlock,StartingDeleteBlock,True,_Header) then exit;
     _intBlockIndex := (_Header.BlockNumber-BlockHeaderFirstBlock);
     _intBlockIndex := (_Header.BlockNumber-BlockHeaderFirstBlock);
 
 
+    TLog.NewLog(ltInfo,ClassName,Format('Deleting Blockchain block %d',[StartingDeleteBlock]));
+
     p := FBlockHeadersFirstBytePosition[iBlockHeaders] + (Int64(_intBlockIndex) * Int64(CT_SizeOfBlockHeader));
     p := FBlockHeadersFirstBytePosition[iBlockHeaders] + (Int64(_intBlockIndex) * Int64(CT_SizeOfBlockHeader));
 
 
     Stream.Position:=p;
     Stream.Position:=p;
@@ -686,6 +688,7 @@ function TFileStorage.LockBlockChainStream: TFileStream;
     FStreamFirstBlockNumber := 0;
     FStreamFirstBlockNumber := 0;
     FStreamLastBlockNumber := -1;
     FStreamLastBlockNumber := -1;
     SetLength(FBlockHeadersFirstBytePosition,0);
     SetLength(FBlockHeadersFirstBytePosition,0);
+    Result := False;
     //
     //
     if stream.Size<GetBlockHeaderFixedSize then begin
     if stream.Size<GetBlockHeaderFixedSize then begin
       if (stream.Size=0) then begin
       if (stream.Size=0) then begin
@@ -693,9 +696,16 @@ function TFileStorage.LockBlockChainStream: TFileStream;
         exit;
         exit;
       end else begin
       end else begin
         // Invalid stream!
         // 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;
     end;
     end;
     // Initialize it
     // Initialize it
@@ -720,9 +730,18 @@ function TFileStorage.LockBlockChainStream: TFileStream;
             FStreamFirstBlockNumber := bh.BlockNumber;
             FStreamFirstBlockNumber := bh.BlockNumber;
             FStreamLastBlockNumber := bh.BlockNumber;
             FStreamLastBlockNumber := bh.BlockNumber;
             if (0<>bh.StreamBlockRelStartPos) then begin
             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;
             end;
             lastbh := bh;
             lastbh := bh;
           end else begin
           end else begin
@@ -730,12 +749,18 @@ function TFileStorage.LockBlockChainStream: TFileStream;
             if (bh.BlockNumber=0) then begin
             if (bh.BlockNumber=0) then begin
               // This is an "empty" block. Check that ok
               // This is an "empty" block. Check that ok
               If (bh.BlockNumber<>0) Or (bh.StreamBlockRelStartPos<>0) Or (bh.BlockSize<>0) then begin
               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;
               end;
               // Ok, inc blocknumber
               // Ok, inc blocknumber
               inc(lastbh.BlockNumber);
               inc(lastbh.BlockNumber);
@@ -743,11 +768,17 @@ function TFileStorage.LockBlockChainStream: TFileStream;
               if (lastbh.BlockNumber+1<>bh.BlockNumber) or
               if (lastbh.BlockNumber+1<>bh.BlockNumber) or
                 ((lastbh.StreamBlockRelStartPos+lastbh.BlockSize<>bh.StreamBlockRelStartPos) And (i>0)) Or
                 ((lastbh.StreamBlockRelStartPos+lastbh.BlockSize<>bh.StreamBlockRelStartPos) And (i>0)) Or
                 ((0<>bh.StreamBlockRelStartPos) And (i=0)) then begin
                 ((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,
                   [iPos,i,bh.BlockNumber,bh.StreamBlockRelStartPos,bh.BlockSize,FStreamLastBlockNumber,
                    lastbh.BlockNumber,lastbh.StreamBlockRelStartPos,lastbh.BlockSize]);
                    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
               end else begin
                 FStreamLastBlockNumber := bh.BlockNumber;
                 FStreamLastBlockNumber := bh.BlockNumber;
                 lastbh := bh;
                 lastbh := bh;
@@ -759,7 +790,7 @@ function TFileStorage.LockBlockChainStream: TFileStream;
         lastbh.StreamBlockRelStartPos:=0;
         lastbh.StreamBlockRelStartPos:=0;
         lastbh.BlockSize:=0;
         lastbh.BlockSize:=0;
       end;
       end;
-      Result := true;
+      Result := True;
     Finally
     Finally
       mem.Free;
       mem.Free;
     End;
     End;
@@ -792,6 +823,8 @@ begin
       If Not InitStreamInfo(FBlockChainStream,errors) then begin
       If Not InitStreamInfo(FBlockChainStream,errors) then begin
         TLog.NewLog(lterror,ClassName,errors);
         TLog.NewLog(lterror,ClassName,errors);
         raise Exception.Create('Error reading File: '+fn+#10+'Errors:'+#10+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;
     end;
     end;
   Except
   Except