Browse Source

fixed: Receive fast propagation block bug

PascalCoin 7 years ago
parent
commit
7696d87734
2 changed files with 23 additions and 6 deletions
  1. 7 1
      src/core/UBlockChain.pas
  2. 16 5
      src/core/UNetProtocol.pas

+ 7 - 1
src/core/UBlockChain.pas

@@ -901,6 +901,11 @@ Begin
       Result := op.DoOperation(FPreviousUpdatedBlocks, FSafeBoxTransaction, errors);
       Result := op.DoOperation(FPreviousUpdatedBlocks, FSafeBoxTransaction, errors);
     end else Result := true;
     end else Result := true;
     if Result then begin
     if Result then begin
+      if FIsOnlyOperationBlock then begin
+        // Clear fee values and put to False
+        FIsOnlyOperationBlock := False;
+        FOperationBlock.fee := 0;
+      end;
       FOperationsHashTree.AddOperationToHashTree(op);
       FOperationsHashTree.AddOperationToHashTree(op);
       FOperationBlock.fee := FOperationBlock.fee + op.OperationFee;
       FOperationBlock.fee := FOperationBlock.fee + op.OperationFee;
       FOperationBlock.operations_hash := FOperationsHashTree.HashTree;
       FOperationBlock.operations_hash := FOperationsHashTree.HashTree;
@@ -1980,7 +1985,8 @@ Var l : TList;
 begin
 begin
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
   Try
   Try
-    if not FindOrderedByOpReference(l,opReference,Result) then Result := -1;
+    if not FindOrderedByOpReference(l,opReference,Result) then Result := -1
+    else Result := PtrInt(FListOrderedByOpReference.Items[Result]);
   Finally
   Finally
     FHashTreeOperations.UnlockList;
     FHashTreeOperations.UnlockList;
   End;
   End;

+ 16 - 5
src/core/UNetProtocol.pas

@@ -3393,25 +3393,36 @@ begin
               if DataBuffer.Read(oprefcount,SizeOf(oprefcount))<>SizeOf(oprefcount) then Exit;
               if DataBuffer.Read(oprefcount,SizeOf(oprefcount))<>SizeOf(oprefcount) then Exit;
               if DataBuffer.Size - DataBuffer.Position < (oprefcount * SizeOf(TOpReference)) then Exit;
               if DataBuffer.Size - DataBuffer.Position < (oprefcount * SizeOf(TOpReference)) then Exit;
               SetLength(opReferencesArr,oprefcount);
               SetLength(opReferencesArr,oprefcount);
-              for i := 1 to oprefcount do begin
-                if DataBuffer.Read(opReference,SizeOf(opReference))<>SizeOf(opReference) then Exit;
-                opReferencesArr[High(opReferencesArr)] := opReference;
+              if (oprefcount>0) then begin
+                for i := 0 to Integer(Integer(oprefcount)-1) do begin
+                  if DataBuffer.Read(opReference,SizeOf(opReference))<>SizeOf(opReference) then Exit;
+                  opReferencesArr[i] := opReference;
+                end;
               end;
               end;
               DoDisconnect := False;
               DoDisconnect := False;
               // Try TNode locking process
               // Try TNode locking process
               If TNode.Node.TryLockNode(3000) then begin
               If TNode.Node.TryLockNode(3000) then begin
                 Try
                 Try
                   if (op.OperationBlock.block<>TNode.Node.Bank.BlocksCount) then Exit; // Meanwhile other threads have added it
                   if (op.OperationBlock.block<>TNode.Node.Bank.BlocksCount) then Exit; // Meanwhile other threads have added it
-                  // Fill not found operations:
+                  // Fill not included operations:
                   for i:=0 to High(opReferencesArr) do begin
                   for i:=0 to High(opReferencesArr) do begin
                     iNodeOpReference := TNode.Node.Operations.OperationsHashTree.IndexOfOpReference(opReferencesArr[i]);
                     iNodeOpReference := TNode.Node.Operations.OperationsHashTree.IndexOfOpReference(opReferencesArr[i]);
                     if iNodeOpReference<0 then begin
                     if iNodeOpReference<0 then begin
                       // Warning: Operation not found on mempool... cannot continue, must call block
                       // Warning: Operation not found on mempool... cannot continue, must call block
-                      TLog.NewLog(ltinfo,ClassName,Format('OpReference %d:%d not found on MemPool for new block %d at OpReference %d/%d',
+                      TLog.NewLog(ltError,ClassName,Format('OpReference %d:%d not found on MemPool for new block %d at OpReference %d/%d',
                         [TPCOperation.GetOpReferenceAccount(opReferencesArr[i]),TPCOperation.GetOpReferenceN_Operation(opReferencesArr[i]),
                         [TPCOperation.GetOpReferenceAccount(opReferencesArr[i]),TPCOperation.GetOpReferenceN_Operation(opReferencesArr[i]),
                         op.OperationBlock.block,i+1,Length(opReferencesArr)]));
                         op.OperationBlock.block,i+1,Length(opReferencesArr)]));
                       Send_GetBlocks(op.OperationBlock.block,1,oprefcount);
                       Send_GetBlocks(op.OperationBlock.block,1,oprefcount);
                       Exit;
                       Exit;
+                    end else begin
+                      // Add it!
+                      if Not (op.AddOperation(True,TNode.Node.Operations.Operation[iNodeOpReference],errors)) then begin
+                        TLog.NewLog(ltError,ClassName,Format('OpReference %d:%d (%d/%d) from MemPool invalid to be added at block %d - Error:%s',
+                          [TPCOperation.GetOpReferenceAccount(opReferencesArr[i]),TPCOperation.GetOpReferenceN_Operation(opReferencesArr[i]),
+                          i+1,Length(opReferencesArr),op.OperationBlock.block,errors]));
+                        Send_GetBlocks(op.OperationBlock.block,1,oprefcount);
+                        Exit;
+                      end;
                     end;
                     end;
                   end;
                   end;
                 Finally
                 Finally