Browse Source

Merge pull request #53 from PascalCoinDev/master

Release 5.6 proposal
Albert Molina 3 years ago
parent
commit
3e6aa172ac
4 changed files with 51 additions and 17 deletions
  1. 13 5
      src/core/UBlockChain.pas
  2. 2 2
      src/core/UConst.pas
  3. 30 9
      src/core/UNetProtocol.pas
  4. 6 1
      src/core/UPoolMining.pas

+ 13 - 5
src/core/UBlockChain.pas

@@ -337,6 +337,7 @@ Type
     FTotalAmount : Int64;
     FTotalFee : Int64;
     FMax0feeOperationsBySigner : Integer;
+    FHasOpRecoverOperations : Boolean;
     function InternalCanAddOperationToHashTree(lockedThreadList : TList<Pointer>; op : TPCOperation) : Boolean;
     function InternalAddOperationToHashTree(list : TList<Pointer>; op : TPCOperation; CalcNewHashTree : Boolean) : Boolean;
     Function FindOrderedByOpReference(lockedThreadList : TList<Pointer>; const Value: TOpReference; var Index: Integer): Boolean;
@@ -367,7 +368,7 @@ Type
     Property OnChanged : TNotifyEvent read FOnChanged write FOnChanged;
     Property Max0feeOperationsBySigner : Integer Read FMax0feeOperationsBySigner write SetMax0feeOperationsBySigner;
     procedure MarkVerifiedECDSASignatures(operationsHashTreeToMark : TOperationsHashTree);
-
+    Property HasOpRecoverOperations : Boolean read FHasOpRecoverOperations;
     // Will add all operations of the HashTree to then end of AList without removing previous objects
     function GetOperationsList(AList : TList<TPCOperation>; AAddOnlyOperationsWithoutNotVerifiedSignature : Boolean) : Integer;
   End;
@@ -432,7 +433,7 @@ Type
     function LoadBlockFromStream(Stream: TStream; var errors: String): Boolean;
     //
     Function GetMinerRewardPseudoOperation : TOperationResume;
-    Function AddMinerRecover(LRecoverAccounts: TAccountList) : Boolean;
+    Function AddMinerRecover(LRecoverAccounts: TAccountList; const ANewAccountKey : TAccountKey) : Boolean;
     Function ValidateOperationBlock(var errors : String) : Boolean;
     Property IsOnlyOperationBlock : Boolean read FIsOnlyOperationBlock;
     Procedure Lock;
@@ -2117,12 +2118,13 @@ begin
    Result.OperationTxt := 'Miner reward';
 end;
 
-function TPCOperationsComp.AddMinerRecover(LRecoverAccounts: TAccountList): Boolean;
+function TPCOperationsComp.AddMinerRecover(LRecoverAccounts: TAccountList; const ANewAccountKey : TAccountKey): Boolean;
 var
   LAccount: TAccount;
   LOpRecoverFounds: TOpRecoverFounds;
   i: Integer;
   errors: string;
+  LmaxFee : UInt64;
 begin
   Self.Lock;
   errors := '';
@@ -2130,12 +2132,14 @@ begin
   try
     for i:=0 to LRecoverAccounts.Count-1 do begin
       LAccount := LRecoverAccounts[i];
+      LmaxFee := LAccount.balance;
+      if LMaxFee>CT_MaxTransactionFee then LMaxFee := CT_MaxTransactionFee;
       LOpRecoverFounds := TOpRecoverFounds.Create(
         Self.OperationBlock.protocol_version,
         LAccount.account,
         LAccount.n_operation+1,
-        LAccount.balance,
-        Self.AccountKey
+        LmaxFee,
+        ANewAccountKey
       );
       try
         if not(
@@ -2146,6 +2150,7 @@ begin
           )
         ) then begin
           // if it fails then it number of operations could be maxed out, not a problem
+          TLog.NewLog(lterror,ClassName,Format('Cannot add OpRecover %d/%d %s error %s',[i+1,LRecoverAccounts.Count,LOpRecoverFounds.ToString,errors]));
           Break;
         end;
       finally
@@ -2332,6 +2337,7 @@ begin
       FListOrderedByAccountsData.Clear;
       FListOrderedByOpReference.Clear;
       FHashTree:=Nil;
+      FHasOpRecoverOperations := False;
     End;
     If Assigned(FOnChanged) then FOnChanged(Self);
   finally
@@ -2387,6 +2393,7 @@ begin
   FHashTree := Nil;
   FMax0feeOperationsBySigner := -1; // Unlimited by default
   FHashTreeOperations := TPCThreadList<Pointer>.Create('TOperationsHashTree_HashTreeOperations');
+  FHasOpRecoverOperations := False;
 end;
 
 procedure TOperationsHashTree.Delete(index: Integer);
@@ -2617,6 +2624,7 @@ begin
     Result := False;
     Exit;
   end else Result := True; // Will add:
+    if (op is TOpRecoverFounds) then FHasOpRecoverOperations := True;
     New(P);
     if Not _PCOperationsStorage.FindPCOperationAndIncCounterIfFound(op) then begin
       msCopy := TMemoryStream.Create;

+ 2 - 2
src/core/UConst.pas

@@ -135,7 +135,7 @@ Const
   CT_NetProtocol_Version: Word = 12;
   // IMPORTANT NOTE!!!
   // NetProtocol_Available MUST BE always >= NetProtocol_version
-  CT_NetProtocol_Available: Word = {$IFDEF PRODUCTION}13{$ELSE}13{$ENDIF};
+  CT_NetProtocol_Available: Word = {$IFDEF PRODUCTION}14{$ELSE}14{$ENDIF};
 
   CT_MaxAccountOperationsPerBlockWithoutFee = 1;
 
@@ -198,7 +198,7 @@ Const
   CT_OpSubtype_Data_Signer                = 103;
   CT_OpSubtype_Data_Receiver              = 104;
 
-  CT_ClientAppVersion : String = {$IFDEF PRODUCTION}'5.5'{$ELSE}{$IFDEF TESTNET}'TESTNET 5.5'{$ELSE}{$ENDIF}{$ENDIF};
+  CT_ClientAppVersion : String = {$IFDEF PRODUCTION}'5.6'{$ELSE}{$IFDEF TESTNET}'TESTNET 5.6'{$ELSE}{$ENDIF}{$ENDIF};
 
   CT_Discover_IPs = {$IFDEF PRODUCTION}'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'
                     {$ELSE}'pascaltestnet1.dynamic-dns.net;pascaltestnet2.dynamic-dns.net;pascaltestnet1.dns1.us;pascaltestnet2.dns1.us'{$ENDIF};

+ 30 - 9
src/core/UNetProtocol.pas

@@ -164,7 +164,8 @@ Type
     Function LockList : TList<Pointer>;
     Procedure UnlockList;
     procedure ResetConnectAttempts;
-    function IsBlackListed(const ip: String): Boolean;
+    function IsBlackListed(const ip: String; out AReason : string): Boolean; overload;
+    function IsBlackListed(const ip: String): Boolean; overload;
     function GetNodeServerAddress(const ip : String; port:Word; CanAdd : Boolean; var nodeServerAddress : TNodeServerAddress) : Boolean;
     procedure SetNodeServerAddress(const nodeServerAddress : TNodeServerAddress);
     Procedure UpdateNetConnection(netConnection : TNetConnection);
@@ -512,7 +513,7 @@ implementation
 
 uses
   UConst, ULog, UNode, UTime, UPCEncryption, UChunk,
-  UPCOperationsBlockValidator, UPCOperationsSignatureValidator,
+  UPCOperationsBlockValidator, UPCOperationsSignatureValidator, UOpTransaction,
   UPCTemporalFileStream;
 
 Const
@@ -821,11 +822,12 @@ begin
   end;
 end;
 
-function TOrderedServerAddressListTS.IsBlackListed(const ip: String): Boolean;
+function TOrderedServerAddressListTS.IsBlackListed(const ip: String; out AReason : string): Boolean;
 Var i : Integer;
   P : PNodeServerAddress;
 begin
   Result := false;
+  AReason := '';
   FCritical.Acquire;
   Try
     SecuredFindByIp(ip,0,i);
@@ -835,6 +837,7 @@ begin
       if Not SameStr(P^.ip,ip) then exit;
       if P^.is_blacklisted then begin
         Result := Not P^.its_myself;
+        AReason := P^.BlackListText;
       end;
       inc(i);
     end;
@@ -843,6 +846,12 @@ begin
   End;
 end;
 
+function TOrderedServerAddressListTS.IsBlackListed(const ip: String): Boolean;
+var LReason : String;
+begin
+  Result := IsBlackListed(ip,LReason);
+end;
+
 function TOrderedServerAddressListTS.LockList: TList<Pointer>;
 begin
   FCritical.Acquire;
@@ -2417,7 +2426,7 @@ end;
 
 procedure TNetServer.OnNewIncommingConnection(Sender : TObject; Client : TNetTcpIpClient);
 Var n : TNetServerClient;
-  DebugStep : String;
+  DebugStep, LReason : String;
   tc : TTickCount;
 begin
   DebugStep := '';
@@ -2433,10 +2442,10 @@ begin
       TNetData.NetData.IncStatistics(1,1,0,0,0,0);
       TNetData.NetData.NodeServersAddresses.CleanBlackList(False);
       DebugStep := 'Checking blacklisted';
-      if (TNetData.NetData.NodeServersAddresses.IsBlackListed(Client.RemoteHost)) then begin
+      if (TNetData.NetData.NodeServersAddresses.IsBlackListed(Client.RemoteHost,LReason)) then begin
         // Invalid!
         TLog.NewLog(ltinfo,Classname,'Refusing Blacklist ip: '+Client.ClientRemoteAddr);
-        n.SendError(ntp_autosend,CT_NetOp_Error, 0,CT_NetError_IPBlackListed,'Your IP is blacklisted:'+Client.ClientRemoteAddr);
+        n.SendError(ntp_autosend,CT_NetOp_Error, 0,CT_NetError_IPBlackListed,'Your IP is blacklisted:'+Client.ClientRemoteAddr+' '+LReason);
         // Wait some time before close connection
         sleep(5000);
       end else begin
@@ -3925,8 +3934,13 @@ var operationsComp : TPCOperationsComp;
     If Not TAccountComp.EqualOperationBlocks(operationsComp.OperationBlock,original_OperationBlock) then begin
       // This can happen when a OpReference in my MEMPOOL is different to an OpReference in the miner, causing different OperationsHash value
       // This means a possible double spend found
-      TLog.NewLog(lterror,ClassName,Format('Constructed a distinct FAST PROPAGATION block with my mempool operations. Received: %s Constructed: %s',
+      if Not operationsComp.OperationsHashTree.HasOpRecoverOperations then begin
+        TLog.NewLog(lterror,ClassName,Format('Constructed a distinct FAST PROPAGATION block with my mempool operations. Received: %s Constructed: %s',
         [TPCOperationsComp.OperationBlockToText(original_OperationBlock),TPCOperationsComp.OperationBlockToText(operationsComp.OperationBlock)]));
+      end else begin
+        TLog.NewLog(lterror,ClassName,Format('Constructed a distinct FAST PROPAGATION block with my mempool operations. Posible double-spend attempt. Received: %s Constructed: %s',
+        [TPCOperationsComp.OperationBlockToText(original_OperationBlock),TPCOperationsComp.OperationBlockToText(operationsComp.OperationBlock)]));
+      end;
       if Not TPCSafeBox.IsValidOperationBlock(original_OperationBlock,errors) then begin
         // This means a scammer!
         DoDisconnect := True;
@@ -4637,8 +4651,12 @@ begin
     data := TMemoryStream.Create;
     try
       request_id := TNetData.NetData.NewRequestId;
-      // Will send a FAST PROPAGATION BLOCK as described at PIP-0015
-      netOp := CT_NetOp_NewBlock_Fast_Propagation;
+      if (NewBlock.OperationsHashTree.HasOpRecoverOperations) then begin
+        netOp := CT_NetOp_NewBlock;
+      end else begin
+        // Will send a FAST PROPAGATION BLOCK as described at PIP-0015
+        netOp := CT_NetOp_NewBlock_Fast_Propagation;
+      end;
       NewBlock.SaveBlockToStream(netOp = CT_NetOp_NewBlock_Fast_Propagation,data); // Will save all only if not FAST PROPAGATION
       // Send Aggregated Hashsrate based on network protocol available version
       if FNetProtocolVersion.protocol_available>=CT_MIN_NetProtocol_Use_Aggregated_Hashrate then begin
@@ -4658,6 +4676,9 @@ begin
             data.Write(opRef,SizeOf(opRef));
           end;
         end;
+        TLog.NewLog(ltdebug,ClassName,Format('Sending NEW FAST PROPAGATION BLOCK %d with %d operations in %d bytes to %s',[NewBlock.OperationBlock.block,c,data.Size,ClientRemoteAddr]));
+      end else begin
+        TLog.NewLog(ltdebug,ClassName,Format('Sending NEW BLOCK %d with %d operations in %d bytes to %s',[NewBlock.OperationBlock.block,NewBlock.Count,data.Size,ClientRemoteAddr]));
       end;
       Send(ntp_autosend,netOp,0,request_id,data);
     finally

+ 6 - 1
src/core/UPoolMining.pas

@@ -790,6 +790,11 @@ var tree : TOperationsHashTree;
     if checkDuplicate then begin
       if tree.IndexOfOperation(Op)>=0 then exit;
     end;
+    if (Op is TOpRecoverFounds) then begin
+      if Not TAccountComp.EqualAccountKeys( TOpRecoverFounds(Op).Data.new_accountkey , FMinerAccountKey ) then begin
+        TLog.NewLog(lterror,ClassName,'Adding a OpRecoverFounds operation from another public key: '+Op.ToString);
+      end;
+    end;
     tree.AddOperationToHashTree(Op);
   End;
 Var i,j : Integer;
@@ -976,7 +981,7 @@ begin
           if Not LAccOrd.Next(LIndexKey) then Break;
           Inc(LRecIndex);
         end;
-        nbOperations.AddMinerRecover(LRecoverAccounts);
+        nbOperations.AddMinerRecover(LRecoverAccounts,FMinerAccountKey);
       end;
     end;
   finally