Browse Source

Changes for new build protections

Protection for nodes sending bad TOperationBlock info. Also removed not
core units (UCommon, Generics ...)
PascalCoin 7 years ago
parent
commit
72e6ad716d
2 changed files with 98 additions and 62 deletions
  1. 52 12
      src/core/UNetProtocol.pas
  2. 46 50
      src/core/UNode.pas

+ 52 - 12
src/core/UNetProtocol.pas

@@ -26,7 +26,7 @@ Uses
   {LCLIntf, LCLType, LMessages,}
   {LCLIntf, LCLType, LMessages,}
 {$ENDIF}
 {$ENDIF}
   UBlockChain, Classes, SysUtils, UAccounts, UThread,
   UBlockChain, Classes, SysUtils, UAccounts, UThread,
-  UCrypto, UTCPIP, SyncObjs, UCommon;
+  UCrypto, UTCPIP, SyncObjs, UBaseTypes;
 
 
 {$I config.inc}
 {$I config.inc}
 
 
@@ -240,7 +240,7 @@ Type
     FRegisteredRequests : TPCThreadList;
     FRegisteredRequests : TPCThreadList;
     FIsDiscoveringServers : Boolean;
     FIsDiscoveringServers : Boolean;
     FIsGettingNewBlockChainFromClient : Boolean;
     FIsGettingNewBlockChainFromClient : Boolean;
-    FOnConnectivityChanged : TNotifyManyEvent;
+    FOnConnectivityChanged : TNotifyEventToMany;
     FOnNetConnectionsUpdated: TNotifyEvent;
     FOnNetConnectionsUpdated: TNotifyEvent;
     FOnNodeServersUpdated: TNotifyEvent;
     FOnNodeServersUpdated: TNotifyEvent;
     FOnBlackListUpdated: TNotifyEvent;
     FOnBlackListUpdated: TNotifyEvent;
@@ -299,7 +299,7 @@ Type
     Property IsGettingNewBlockChainFromClient : Boolean read FIsGettingNewBlockChainFromClient;
     Property IsGettingNewBlockChainFromClient : Boolean read FIsGettingNewBlockChainFromClient;
     Property MaxRemoteOperationBlock : TOperationBlock read FMaxRemoteOperationBlock;
     Property MaxRemoteOperationBlock : TOperationBlock read FMaxRemoteOperationBlock;
     Property NodePrivateKey : TECPrivateKey read FNodePrivateKey;
     Property NodePrivateKey : TECPrivateKey read FNodePrivateKey;
-    property OnConnectivityChanged : TNotifyManyEvent read FOnConnectivityChanged;
+    property OnConnectivityChanged : TNotifyEventToMany read FOnConnectivityChanged;
     Property OnNetConnectionsUpdated : TNotifyEvent read FOnNetConnectionsUpdated write FOnNetConnectionsUpdated;
     Property OnNetConnectionsUpdated : TNotifyEvent read FOnNetConnectionsUpdated write FOnNetConnectionsUpdated;
     Property OnNodeServersUpdated : TNotifyEvent read FOnNodeServersUpdated write FOnNodeServersUpdated;
     Property OnNodeServersUpdated : TNotifyEvent read FOnNodeServersUpdated write FOnNodeServersUpdated;
     Property OnBlackListUpdated : TNotifyEvent read FOnBlackListUpdated write FOnBlackListUpdated;
     Property OnBlackListUpdated : TNotifyEvent read FOnBlackListUpdated write FOnBlackListUpdated;
@@ -1111,6 +1111,7 @@ begin
   SetLength(FFixedServers,0);
   SetLength(FFixedServers,0);
   FMaxRemoteOperationBlock := CT_OperationBlock_NUL;
   FMaxRemoteOperationBlock := CT_OperationBlock_NUL;
   FNetStatistics := CT_TNetStatistics_NUL;
   FNetStatistics := CT_TNetStatistics_NUL;
+  FOnConnectivityChanged := TNotifyEventToMany.Create;
   FOnStatisticsChanged := Nil;
   FOnStatisticsChanged := Nil;
   FOnNetConnectionsUpdated := Nil;
   FOnNetConnectionsUpdated := Nil;
   FOnNodeServersUpdated := Nil;
   FOnNodeServersUpdated := Nil;
@@ -1138,6 +1139,7 @@ Var l : TList;
   tdc : TThreadDiscoverConnection;
   tdc : TThreadDiscoverConnection;
 begin
 begin
   TLog.NewLog(ltInfo,ClassName,'TNetData.Destroy START');
   TLog.NewLog(ltInfo,ClassName,'TNetData.Destroy START');
+  FreeAndNil(FOnConnectivityChanged);
   FOnStatisticsChanged := Nil;
   FOnStatisticsChanged := Nil;
   FOnNetConnectionsUpdated := Nil;
   FOnNetConnectionsUpdated := Nil;
   FOnNodeServersUpdated := Nil;
   FOnNodeServersUpdated := Nil;
@@ -1385,7 +1387,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
   Var SendData,ReceiveData : TMemoryStream;
   Var SendData,ReceiveData : TMemoryStream;
     headerdata : TNetHeaderData;
     headerdata : TNetHeaderData;
     op : TPCOperationsComp;
     op : TPCOperationsComp;
-    request_id,opcount,i : Cardinal;
+    request_id,opcount,i, last_n_block : Cardinal;
     errors : AnsiString;
     errors : AnsiString;
     noperation : Integer;
     noperation : Integer;
   begin
   begin
@@ -1409,14 +1411,24 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
       if Connection.DoSendAndWaitForResponse(noperation,request_id,SendData,ReceiveData,MaxWaitMilliseconds,headerdata) then begin
       if Connection.DoSendAndWaitForResponse(noperation,request_id,SendData,ReceiveData,MaxWaitMilliseconds,headerdata) then begin
         if HeaderData.is_error then exit;
         if HeaderData.is_error then exit;
         if ReceiveData.Read(opcount,4)<4 then exit; // Error in data
         if ReceiveData.Read(opcount,4)<4 then exit; // Error in data
-        i := 0;
+        i := 0; last_n_block := 0;
         while (i<opcount) do begin
         while (i<opcount) do begin
           // decode data
           // decode data
           op := TPCOperationsComp.Create(AssignToBank);
           op := TPCOperationsComp.Create(AssignToBank);
           If op.LoadBlockFromStream(ReceiveData,errors) then begin
           If op.LoadBlockFromStream(ReceiveData,errors) then begin
-            BlocksList.Add(op);
+            // Build 2.1.7 Protection for invalid block number
+            If ((i>0) And (last_n_block>=op.OperationBlock.block)) Or
+               ((Not OnlyOperationBlock) And
+                 ( ((i=0) And (op.OperationBlock.block=block_start))
+                   Or
+                   ((i>0) And (op.OperationBlock.block=last_n_block+1)) ) ) then begin
+              Connection.DisconnectInvalidClient(false,Format('Invalid block sequence received last:%d received:%d',[last_n_block,op.OperationBlock.block]));
+              op.free;
+              break;
+            end else BlocksList.Add(op);
+            last_n_block := op.OperationBlock.block;
           end else begin
           end else begin
-            TLog.NewLog(lterror,CT_LogSender,Format('Error reading OperationBlock from received stream %d/%d: %s',[i+1,opcount,errors]));
+            Connection.DisconnectInvalidClient(false,Format('Error reading OperationBlock from received stream %d/%d: %s',[i+1,opcount,errors]));
             op.free;
             op.free;
             break;
             break;
           end;
           end;
@@ -1440,8 +1452,12 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     BlocksList := TList.Create;
     BlocksList := TList.Create;
     try
     try
       Result := Do_GetOperationsBlock(TNode.Node.Bank,block,block,MaxWaitMilliseconds,True,BlocksList);
       Result := Do_GetOperationsBlock(TNode.Node.Bank,block,block,MaxWaitMilliseconds,True,BlocksList);
+      // Build 2.1.7 - Included protection agains not good block received
       if (Result) And (BlocksList.Count=1) then begin
       if (Result) And (BlocksList.Count=1) then begin
         OperationBlock := TPCOperationsComp(BlocksList[0]).OperationBlock;
         OperationBlock := TPCOperationsComp(BlocksList[0]).OperationBlock;
+        If OperationBlock.block<>block then Result := False;
+      end else begin
+        Result := False;
       end;
       end;
     finally
     finally
       for i := 0 to BlocksList.Count - 1 do TPCOperationsComp(BlocksList[i]).Free;
       for i := 0 to BlocksList.Count - 1 do TPCOperationsComp(BlocksList[i]).Free;
@@ -1455,6 +1471,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     auxBlock, sbBlock : TOperationBlock;
     auxBlock, sbBlock : TOperationBlock;
     distinctmax,distinctmin : Cardinal;
     distinctmax,distinctmin : Cardinal;
     BlocksList : TList;
     BlocksList : TList;
+    errors : AnsiString;
   Begin
   Begin
     Result := false;
     Result := false;
     OperationBlock := CT_OperationBlock_NUL;
     OperationBlock := CT_OperationBlock_NUL;
@@ -1472,6 +1489,12 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
             Connection.DisconnectInvalidClient(false,'Invalid response... '+inttostr(min)+'<'+inttostr(auxBlock.block)+'<'+inttostr(max)+' ant:'+inttostr(ant_nblock));
             Connection.DisconnectInvalidClient(false,'Invalid response... '+inttostr(min)+'<'+inttostr(auxBlock.block)+'<'+inttostr(max)+' ant:'+inttostr(ant_nblock));
             exit;
             exit;
           end;
           end;
+          // New Build 2.1.7 - Check valid operationblock
+          If Not TPCSafeBox.IsValidOperationBlock(auxBlock,errors) then begin
+            Connection.DisconnectInvalidClient(false,'Received invalid operation block searching '+TPCOperationsComp.OperationBlockToText(auxBlock)+' errors: '+errors);
+            Exit;
+          end;
+
           ant_nblock := auxBlock.block;
           ant_nblock := auxBlock.block;
           //
           //
           sbBlock := TNode.Node.Bank.SafeBox.Block(auxBlock.block).blockchainInfo;
           sbBlock := TNode.Node.Bank.SafeBox.Block(auxBlock.block).blockchainInfo;
@@ -1543,7 +1566,12 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
             try
             try
               OpComp.SaveBlockToStream(false,ms);
               OpComp.SaveBlockToStream(false,ms);
               ms.Position := 0;
               ms.Position := 0;
-              OpExecute.LoadBlockFromStream(ms,errors);
+              If not OpExecute.LoadBlockFromStream(ms,errors) then begin
+                Connection.DisconnectInvalidClient(false,'Invalid block stream received for block '+IntToStr(Bank.BlocksCount)+' errors: '+errors );
+                finished := true;
+                IsAScam := true;
+                break;
+              end;
               if Bank.AddNewBlockChainBlock(OpExecute,TNetData.NetData.NetworkAdjustedTime.GetMaxAllowedTimestampForNewBlock,newBlock,errors) then begin
               if Bank.AddNewBlockChainBlock(OpExecute,TNetData.NetData.NetworkAdjustedTime.GetMaxAllowedTimestampForNewBlock,newBlock,errors) then begin
                 inc(i);
                 inc(i);
               end else begin
               end else begin
@@ -1702,6 +1730,11 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
       Connection.DisconnectInvalidClient(false,Format('Cannot obtain operation block %d for downloading safebox',[_blockcount]));
       Connection.DisconnectInvalidClient(false,Format('Cannot obtain operation block %d for downloading safebox',[_blockcount]));
       exit;
       exit;
     end;
     end;
+    // New Build 2.1.7 - Check valid operationblock
+    If Not TPCSafeBox.IsValidOperationBlock(op,errors) then begin
+      Connection.DisconnectInvalidClient(false,'Invalid operation block at DownloadSafeBox '+TPCOperationsComp.OperationBlockToText(op)+' errors: '+errors);
+      Exit;
+    end;
     receiveData := TMemoryStream.Create;
     receiveData := TMemoryStream.Create;
     try
     try
       SetLength(chunks,0);
       SetLength(chunks,0);
@@ -1772,6 +1805,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
 
 
 var rid : Cardinal;
 var rid : Cardinal;
   my_op, client_op : TOperationBlock;
   my_op, client_op : TOperationBlock;
+  errors : AnsiString;
 begin
 begin
   // Protection against discovering servers...
   // Protection against discovering servers...
   if FIsDiscoveringServers then begin
   if FIsDiscoveringServers then begin
@@ -1805,6 +1839,11 @@ begin
       // Disabled at Build 1.0.6 >  Connection.DisconnectInvalidClient(false,'Cannot receive information about my block ('+inttostr(my_op.block)+')... Invalid client. Disconnecting');
       // Disabled at Build 1.0.6 >  Connection.DisconnectInvalidClient(false,'Cannot receive information about my block ('+inttostr(my_op.block)+')... Invalid client. Disconnecting');
       Exit;
       Exit;
     end;
     end;
+    // New Build 2.1.7 - Check valid operationblock
+    If Not TPCSafeBox.IsValidOperationBlock(client_op,errors) then begin
+      Connection.DisconnectInvalidClient(false,'Received invalid operation block '+TPCOperationsComp.OperationBlockToText(client_op)+' errors: '+errors);
+      Exit;
+    end;
 
 
     if (NOT TPCOperationsComp.EqualsOperationBlock(my_op,client_op)) then begin
     if (NOT TPCOperationsComp.EqualsOperationBlock(my_op,client_op)) then begin
       TLog.NewLog(ltinfo,CT_LogSender,'My blockchain is not equal... received: '+TPCOperationsComp.OperationBlockToText(client_op)+' My: '+TPCOperationsComp.OperationBlockToText(my_op));
       TLog.NewLog(ltinfo,CT_LogSender,'My blockchain is not equal... received: '+TPCOperationsComp.OperationBlockToText(client_op)+' My: '+TPCOperationsComp.OperationBlockToText(my_op));
@@ -1910,14 +1949,14 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TNetData.NotifyConnectivityChanged;
+procedure TNetData.NotifyBlackListUpdated;
 begin
 begin
-  FOnConnectivityChanged.Invoke(Self);
+  FNetDataNotifyEventsThread.FNotifyOnBlackListUpdated := true;
 end;
 end;
 
 
-procedure TNetData.NotifyBlackListUpdated;
+procedure TNetData.NotifyConnectivityChanged;
 begin
 begin
-  FNetDataNotifyEventsThread.FNotifyOnBlackListUpdated := true;
+  FOnConnectivityChanged.Invoke(Self);
 end;
 end;
 
 
 procedure TNetData.NotifyNetConnectionUpdated;
 procedure TNetData.NotifyNetConnectionUpdated;
@@ -1998,6 +2037,7 @@ end;
 procedure TNetData.SetNetConnectionsActive(const Value: Boolean);
 procedure TNetData.SetNetConnectionsActive(const Value: Boolean);
 begin
 begin
   FNetConnectionsActive := Value;
   FNetConnectionsActive := Value;
+  NotifyConnectivityChanged;
   if FNetConnectionsActive then DiscoverServers
   if FNetConnectionsActive then DiscoverServers
   else DisconnectClients;
   else DisconnectClients;
 end;
 end;

+ 46 - 50
src/core/UNode.pas

@@ -30,7 +30,7 @@ unit UNode;
 interface
 interface
 
 
 uses
 uses
-  Classes, UBlockChain, UNetProtocol, UAccounts, UCrypto, UThread, Generics.Collections, SyncObjs, ULog;
+  Classes, UBlockChain, UNetProtocol, UAccounts, UCrypto, UThread, SyncObjs, ULog;
 
 
 {$I config.inc}
 {$I config.inc}
 
 
@@ -45,7 +45,7 @@ Type
     FNodeLog : TLog;
     FNodeLog : TLog;
     FLockNodeOperations : TPCCriticalSection;
     FLockNodeOperations : TPCCriticalSection;
     FOperationSequenceLock : TPCCriticalSection;
     FOperationSequenceLock : TPCCriticalSection;
-    FNotifyList : Classes.TList;
+    FNotifyList : TList;
     FBank : TPCBank;
     FBank : TPCBank;
     FOperations : TPCOperationsComp;
     FOperations : TPCOperationsComp;
     FNetServer : TNetServer;
     FNetServer : TNetServer;
@@ -80,7 +80,7 @@ Type
     //
     //
     Procedure NotifyBlocksChanged;
     Procedure NotifyBlocksChanged;
     //
     //
-    procedure GetStoredOperationsFromAccount(const OperationsResume: TOperationsResumeList; account_number: Cardinal; MaxDepth, StartOperation, EndOperation : Integer); overload;
+    procedure GetStoredOperationsFromAccount(const OperationsResume: TOperationsResumeList; account_number: Cardinal; MaxDepth, StartOperation, EndOperation : Integer);
     Function FindOperation(Const OperationComp : TPCOperationsComp; Const OperationHash : TRawBytes; var block : Cardinal; var operation_block_index : Integer) : Boolean;
     Function FindOperation(Const OperationComp : TPCOperationsComp; Const OperationHash : TRawBytes; var block : Cardinal; var operation_block_index : Integer) : Boolean;
     Function FindOperationExt(Const OperationComp : TPCOperationsComp; Const OperationHash : TRawBytes; var block : Cardinal; var operation_block_index : Integer) : TSearchOperationResult;
     Function FindOperationExt(Const OperationComp : TPCOperationsComp; Const OperationHash : TRawBytes; var block : Cardinal; var operation_block_index : Integer) : TSearchOperationResult;
     Function FindNOperation(block, account, n_operation : Cardinal; var OpResume : TOperationResume) : TSearchOperationResult;
     Function FindNOperation(block, account, n_operation : Cardinal; var OpResume : TOperationResume) : TSearchOperationResult;
@@ -94,7 +94,7 @@ Type
     Procedure DisableNewBlocks;
     Procedure DisableNewBlocks;
     Procedure EnableNewBlocks;
     Procedure EnableNewBlocks;
     Property NodeLogFilename : AnsiString read GetNodeLogFilename write SetNodeLogFilename;
     Property NodeLogFilename : AnsiString read GetNodeLogFilename write SetNodeLogFilename;
-    Property OperationSequenceLock : TPCCriticalSection read FOperationSequenceLock;   // TODO - refactor out, put in URPC directly (since only client)
+    Property OperationSequenceLock : TPCCriticalSection read FOperationSequenceLock;
   End;
   End;
 
 
   TNodeNotifyEvents = Class;
   TNodeNotifyEvents = Class;
@@ -139,6 +139,7 @@ Type
     FNewBlockOperations : TPCOperationsComp;
     FNewBlockOperations : TPCOperationsComp;
   protected
   protected
     procedure BCExecute; override;
     procedure BCExecute; override;
+  public
     Constructor Create(NetConnection : TNetConnection; MakeACopyOfNewBlockOperations: TPCOperationsComp; MakeACopyOfSanitizedOperationsHashTree : TOperationsHashTree);
     Constructor Create(NetConnection : TNetConnection; MakeACopyOfNewBlockOperations: TPCOperationsComp; MakeACopyOfSanitizedOperationsHashTree : TOperationsHashTree);
     destructor Destroy; override;
     destructor Destroy; override;
   End;
   End;
@@ -147,13 +148,14 @@ Type
     FNetConnection : TNetConnection;
     FNetConnection : TNetConnection;
   protected
   protected
     procedure BCExecute; override;
     procedure BCExecute; override;
+  public
     Constructor Create(NetConnection : TNetConnection; MakeACopyOfOperationsHashTree : TOperationsHashTree);
     Constructor Create(NetConnection : TNetConnection; MakeACopyOfOperationsHashTree : TOperationsHashTree);
     destructor Destroy; override;
     destructor Destroy; override;
   End;
   End;
 
 
 implementation
 implementation
 
 
-Uses UOpTransaction, SysUtils,  UConst, UTime, UAutoScope, UCommon;
+Uses UOpTransaction, SysUtils,  UConst, UTime;
 
 
 var _Node : TNode;
 var _Node : TNode;
 
 
@@ -161,11 +163,9 @@ var _Node : TNode;
 
 
 function TNode.AddNewBlockChain(SenderConnection: TNetConnection; NewBlockOperations: TPCOperationsComp;
 function TNode.AddNewBlockChain(SenderConnection: TNetConnection; NewBlockOperations: TPCOperationsComp;
   var newBlockAccount: TBlockAccount; var errors: AnsiString): Boolean;
   var newBlockAccount: TBlockAccount; var errors: AnsiString): Boolean;
-Var i,j : Integer;
+Var i,j,maxResend : Integer;
   nc : TNetConnection;
   nc : TNetConnection;
-  ms : TMemoryStream;
   s : String;
   s : String;
-  errors2 : AnsiString;
   OpBlock : TOperationBlock;
   OpBlock : TOperationBlock;
   opsht : TOperationsHashTree;
   opsht : TOperationsHashTree;
   minBlockResend : Cardinal;
   minBlockResend : Cardinal;
@@ -198,38 +198,26 @@ begin
       errors := 'Duplicated block';
       errors := 'Duplicated block';
       exit;
       exit;
     end;
     end;
-    ms := TMemoryStream.Create;
-    try
-      FOperations.SaveBlockToStream(false,ms);
-      Result := Bank.AddNewBlockChainBlock(NewBlockOperations,TNetData.NetData.NetworkAdjustedTime.GetMaxAllowedTimestampForNewBlock,newBlockAccount,errors);
-      if Result then begin
-        if Assigned(SenderConnection) then begin
-          FNodeLog.NotifyNewLog(ltupdate,SenderConnection.ClassName,Format(';%d;%s;%s;;%d;%d;%d;%s',[OpBlock.block,SenderConnection.ClientRemoteAddr,OpBlock.block_payload,
-            OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
-        end else begin
-          FNodeLog.NotifyNewLog(ltupdate,ClassName,Format(';%d;%s;%s;;%d;%d;%d;%s',[OpBlock.block,'NIL',OpBlock.block_payload,
-            OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
-        end;
+    // Improvement TNode speed 2.1.6
+    // Does not need to save a FOperations backup because is Sanitized by "TNode.OnBankNewBlock"
+    Result := Bank.AddNewBlockChainBlock(NewBlockOperations,TNetData.NetData.NetworkAdjustedTime.GetMaxAllowedTimestampForNewBlock,newBlockAccount,errors);
+    if Result then begin
+      if Assigned(SenderConnection) then begin
+        FNodeLog.NotifyNewLog(ltupdate,SenderConnection.ClassName,Format(';%d;%s;%s;;%d;%d;%d;%s',[OpBlock.block,SenderConnection.ClientRemoteAddr,OpBlock.block_payload,
+          OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
       end else begin
       end else begin
-        if Assigned(SenderConnection) then begin
-          FNodeLog.NotifyNewLog(lterror,SenderConnection.ClassName,Format(';%d;%s;%s;%s;%d;%d;%d;%s',[OpBlock.block,SenderConnection.ClientRemoteAddr,OpBlock.block_payload,errors,
-            OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
-        end else begin
-          FNodeLog.NotifyNewLog(lterror,ClassName,Format(';%d;%s;%s;%s;%d;%d;%d;%s',[OpBlock.block,'NIL',OpBlock.block_payload,errors,
-            OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
-        end;
+        FNodeLog.NotifyNewLog(ltupdate,ClassName,Format(';%d;%s;%s;;%d;%d;%d;%s',[OpBlock.block,'NIL',OpBlock.block_payload,
+          OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
       end;
       end;
-      FOperations.Clear(true);
-      ms.Position:=0;
-      If Not FOperations.LoadBlockFromStream(ms,errors2) then begin
-        TLog.NewLog(lterror,Classname,'Error recovering operations to sanitize: '+errors2);
-        if Result then errors := errors2
-        else errors := errors +' - '+errors2;
+    end else begin
+      if Assigned(SenderConnection) then begin
+        FNodeLog.NotifyNewLog(lterror,SenderConnection.ClassName,Format(';%d;%s;%s;%s;%d;%d;%d;%s',[OpBlock.block,SenderConnection.ClientRemoteAddr,OpBlock.block_payload,errors,
+          OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
+      end else begin
+        FNodeLog.NotifyNewLog(lterror,ClassName,Format(';%d;%s;%s;%s;%d;%d;%d;%s',[OpBlock.block,'NIL',OpBlock.block_payload,errors,
+          OpBlock.timestamp,UnivDateTimeToUnix(DateTime2UnivDateTime(Now)),UnivDateTimeToUnix(DateTime2UnivDateTime(Now)) - OpBlock.timestamp,IntToHex(OpBlock.compact_target,8)]));
       end;
       end;
-    finally
-      ms.Free;
     end;
     end;
-    FOperations.SanitizeOperations;
     if Result then begin
     if Result then begin
       opsht := TOperationsHashTree.Create;
       opsht := TOperationsHashTree.Create;
       Try
       Try
@@ -237,7 +225,9 @@ begin
         If (Bank.LastBlockFound.OperationBlock.block>j) then
         If (Bank.LastBlockFound.OperationBlock.block>j) then
           minBlockResend:=Bank.LastBlockFound.OperationBlock.block - j
           minBlockResend:=Bank.LastBlockFound.OperationBlock.block - j
         else minBlockResend:=1;
         else minBlockResend:=1;
-        for i := 0 to FOperations.Count - 1 do begin
+        maxResend := CT_MaxResendMemPoolOperations;
+        i := 0;
+        While (opsht.OperationsCount<maxResend) And (i<FOperations.Count) do begin
           resendOp := FOperations.Operation[i];
           resendOp := FOperations.Operation[i];
           j := FSentOperations.GetTag(resendOp.Sha256);
           j := FSentOperations.GetTag(resendOp.Sha256);
           if (j=0) Or (j<=minBlockResend) then begin
           if (j=0) Or (j<=minBlockResend) then begin
@@ -247,14 +237,19 @@ begin
             FSentOperations.SetTag(resendOp.Sha256,FOperations.OperationBlock.block); // Set tag new value
             FSentOperations.SetTag(resendOp.Sha256,FOperations.OperationBlock.block); // Set tag new value
             FSentOperations.Add(FOperations.Operation[i].Sha256,Bank.LastBlockFound.OperationBlock.block);
             FSentOperations.Add(FOperations.Operation[i].Sha256,Bank.LastBlockFound.OperationBlock.block);
           end else begin
           end else begin
-            TLog.NewLog(ltInfo,ClassName,'Sanitized operation not included to resend (j:'+IntToStr(j)+'>'+inttostr(minBlockResend)+') ('+inttostr(i+1)+'/'+inttostr(FOperations.Count)+'): '+FOperations.Operation[i].ToString);
+            {$IFDEF HIGHLOG}TLog.NewLog(ltInfo,ClassName,'Sanitized operation not included to resend (j:'+IntToStr(j)+'>'+inttostr(minBlockResend)+') ('+inttostr(i+1)+'/'+inttostr(FOperations.Count)+'): '+FOperations.Operation[i].ToString);{$ENDIF}
           end;
           end;
+          inc(i);
         end;
         end;
-        if opsht.OperationsCount>0 then begin
-          TLog.NewLog(ltinfo,classname,'Resending '+IntToStr(opsht.OperationsCount)+' operations for new block');
-          for i := 0 to opsht.OperationsCount - 1 do begin
-            TLog.NewLog(ltInfo,ClassName,'Resending ('+inttostr(i+1)+'/'+inttostr(opsht.OperationsCount)+'): '+opsht.GetOperation(i).ToString);
-          end;
+        If FOperations.Count>0 then begin
+          TLog.NewLog(ltinfo,classname,Format('Resending %d operations for new block (Buffer Pending Operations:%d)',[opsht.OperationsCount,FOperations.Count]));
+          {$IFDEF HIGHLOG}
+          if opsht.OperationsCount>0 then begin
+            for i := 0 to opsht.OperationsCount - 1 do begin
+              TLog.NewLog(ltInfo,ClassName,'Resending ('+inttostr(i+1)+'/'+inttostr(opsht.OperationsCount)+'): '+opsht.GetOperation(i).ToString);
+            end;
+          end
+          {$ENDIF}
         end;
         end;
         // Clean sent operations buffer
         // Clean sent operations buffer
         j := 0;
         j := 0;
@@ -504,7 +499,7 @@ begin
   FNetServer := TNetServer.Create;
   FNetServer := TNetServer.Create;
   FOperations := TPCOperationsComp.Create(Self);
   FOperations := TPCOperationsComp.Create(Self);
   FOperations.bank := FBank;
   FOperations.bank := FBank;
-  FNotifyList := Classes.TList.Create;
+  FNotifyList := TList.Create;
   {$IFDEF BufferOfFutureOperations}
   {$IFDEF BufferOfFutureOperations}
   FBufferAuxWaitingOperations := TOperationsHashTree.Create;
   FBufferAuxWaitingOperations := TOperationsHashTree.Create;
   {$ENDIF}
   {$ENDIF}
@@ -706,14 +701,14 @@ procedure TNode.GetStoredOperationsFromAccount(const OperationsResume: TOperatio
   var opc : TPCOperationsComp;
   var opc : TPCOperationsComp;
     op : TPCOperation;
     op : TPCOperation;
     OPR : TOperationResume;
     OPR : TOperationResume;
-    l : Classes.TList;
+    l : TList;
     i : Integer;
     i : Integer;
     last_block_number, next_block_number : Integer;
     last_block_number, next_block_number : Integer;
   begin
   begin
     if (act_depth<=0) then exit;
     if (act_depth<=0) then exit;
     opc := TPCOperationsComp.Create(Nil);
     opc := TPCOperationsComp.Create(Nil);
     Try
     Try
-      l := Classes.TList.Create;
+      l := TList.Create;
       try
       try
         last_block_number := block_number+1;
         last_block_number := block_number+1;
         while (last_block_number>block_number) And (act_depth>0)
         while (last_block_number>block_number) And (act_depth>0)
@@ -751,13 +746,12 @@ procedure TNode.GetStoredOperationsFromAccount(const OperationsResume: TOperatio
             OPR := CT_TOperationResume_NUL;
             OPR := CT_TOperationResume_NUL;
             OPR.valid := true;
             OPR.valid := true;
             OPR.Block := block_number;
             OPR.Block := block_number;
-            OPR.NOpInsideBlock:=-1;
             OPR.time := opc.OperationBlock.timestamp;
             OPR.time := opc.OperationBlock.timestamp;
             OPR.AffectedAccount := account_number;
             OPR.AffectedAccount := account_number;
             OPR.Amount := opc.OperationBlock.reward;
             OPR.Amount := opc.OperationBlock.reward;
             OPR.Fee := opc.OperationBlock.fee;
             OPR.Fee := opc.OperationBlock.fee;
             OPR.Balance := last_balance;
             OPR.Balance := last_balance;
-            OPR.OperationTxt := 'Miner reward';
+            OPR.OperationTxt := 'Blockchain reward';
             if (nOpsCounter>=StartOperation) And (nOpsCounter<=EndOperation) then begin
             if (nOpsCounter>=StartOperation) And (nOpsCounter<=EndOperation) then begin
               OperationsResume.Add(OPR);
               OperationsResume.Add(OPR);
             end;
             end;
@@ -1200,8 +1194,9 @@ begin
   FSanitizedOperationsHashTree.CopyFromHashTree(MakeACopyOfSanitizedOperationsHashTree);
   FSanitizedOperationsHashTree.CopyFromHashTree(MakeACopyOfSanitizedOperationsHashTree);
   FNewBlockOperations := TPCOperationsComp.Create(Nil);
   FNewBlockOperations := TPCOperationsComp.Create(Nil);
   FNewBlockOperations.CopyFrom(MakeACopyOfNewBlockOperations);
   FNewBlockOperations.CopyFrom(MakeACopyOfNewBlockOperations);
-  Inherited Create(false);
+  Inherited Create(True);
   FreeOnTerminate := true;
   FreeOnTerminate := true;
+  Suspended:=False;
 end;
 end;
 
 
 destructor TThreadNodeNotifyNewBlock.Destroy;
 destructor TThreadNodeNotifyNewBlock.Destroy;
@@ -1230,8 +1225,9 @@ constructor TThreadNodeNotifyOperations.Create(NetConnection: TNetConnection; Ma
 begin
 begin
   FNetConnection := NetConnection;
   FNetConnection := NetConnection;
   FNetConnection.AddOperationsToBufferForSend(MakeACopyOfOperationsHashTree);
   FNetConnection.AddOperationsToBufferForSend(MakeACopyOfOperationsHashTree);
-  Inherited Create(false);
+  Inherited Create(True);
   FreeOnTerminate := true;
   FreeOnTerminate := true;
+  Suspended:=False;
 end;
 end;
 
 
 destructor TThreadNodeNotifyOperations.Destroy;
 destructor TThreadNodeNotifyOperations.Destroy;