Browse Source

Build 1.5.2.2

Miner server with a 10 jobs buffer and sending job with new timestamp to
allow best practices
PascalCoin 8 years ago
parent
commit
0cbc58d2fb
3 changed files with 51 additions and 16 deletions
  1. 1 1
      Units/PascalCoin/UConst.pas
  2. 4 1
      Units/PascalCoin/UNetProtocol.pas
  3. 46 14
      Units/PascalCoin/UPoolMining.pas

+ 1 - 1
Units/PascalCoin/UConst.pas

@@ -99,7 +99,7 @@ Const
   CT_Op_Changekey = $02;
   CT_Op_Changekey = $02;
   CT_Op_Recover = $03;
   CT_Op_Recover = $03;
 
 
-  CT_ClientAppVersion : AnsiString = {$IFDEF PRODUCTION}'1.5.2.1'{$ELSE}{$IFDEF TESTNET}'TESTNET 1.5.2.1'{$ELSE}{$ENDIF}{$ENDIF};
+  CT_ClientAppVersion : AnsiString = {$IFDEF PRODUCTION}'1.5.2.2'{$ELSE}{$IFDEF TESTNET}'TESTNET 1.5.2.2'{$ELSE}{$ENDIF}{$ENDIF};
 
 
   CT_Discover_IPs =  'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin2.ddns.net;pascalcoin1.dynamic-dns.net;pascalcoin1.dns1.us';
   CT_Discover_IPs =  'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin2.ddns.net;pascalcoin1.dynamic-dns.net;pascalcoin1.dns1.us';
 
 

+ 4 - 1
Units/PascalCoin/UNetProtocol.pas

@@ -1509,9 +1509,11 @@ begin
         sleep(10);
         sleep(10);
         DebugStep := 'Assigning old client';
         DebugStep := 'Assigning old client';
         n.SetClient( NetTcpIpClientClass.Create(Nil) );
         n.SetClient( NetTcpIpClientClass.Create(Nil) );
+        DebugStep := 'Finalizing connection';
         n.FinalizeConnection;
         n.FinalizeConnection;
-      Finally
+        sleep(500); // Delay - Sleep time before destroying (1.5.3)
         DebugStep := 'Freeing NetServerClient';
         DebugStep := 'Freeing NetServerClient';
+      Finally
         n.Free;
         n.Free;
       End;
       End;
     End;
     End;
@@ -3220,6 +3222,7 @@ begin
       finally
       finally
         FNetData.NetConnections.UnlockList;
         FNetData.NetConnections.UnlockList;
       end;
       end;
+      sleep(500); // Delay - Sleep time before destroying (1.5.3)
       if l_to_del.Count>0 then begin
       if l_to_del.Count>0 then begin
         TLog.NewLog(ltDebug,ClassName,'Destroying NetClients: '+inttostr(l_to_del.Count));
         TLog.NewLog(ltDebug,ClassName,'Destroying NetClients: '+inttostr(l_to_del.Count));
         for i := 0 to l_to_del.Count - 1 do begin
         for i := 0 to l_to_del.Count - 1 do begin

+ 46 - 14
Units/PascalCoin/UPoolMining.pas

@@ -495,16 +495,19 @@ end;
 { TPoolMiningServer }
 { TPoolMiningServer }
 
 
 Const CT_WAIT_SECONDS_BEFORE_SEND_NEW_JOB = 10;
 Const CT_WAIT_SECONDS_BEFORE_SEND_NEW_JOB = 10;
+  CT_MAX_SECONDS_BETWEEN_JOBS = 30; // 1.5.3 Will send new job to miner (with updated timestamp)
+  CT_MAX_BUFFER_JOBS = 10; // 1.5.3 Will buffer last 10 jobs sent to miner
 
 
 Type
 Type
   TPoolJob = Record
   TPoolJob = Record
     OperationsComp : TPCOperationsComp;
     OperationsComp : TPCOperationsComp;
     SentDateTime : TDateTime;
     SentDateTime : TDateTime;
+    SentMinTimestamp : Cardinal;
   End;
   End;
   PPoolJob = ^TPoolJob;
   PPoolJob = ^TPoolJob;
 
 
 procedure TPoolMiningServer.CaptureNewJobAndSendToMiners;
 procedure TPoolMiningServer.CaptureNewJobAndSendToMiners;
-Var P : PPoolJob;
+Var P, PToDelete : PPoolJob;
   i : Integer;
   i : Integer;
   l : TList;
   l : TList;
   doAdd : Boolean;
   doAdd : Boolean;
@@ -513,6 +516,7 @@ Var P : PPoolJob;
 begin
 begin
   if Not Active then exit;
   if Not Active then exit;
   doAdd := false;
   doAdd := false;
+  P := Nil;
   l := FPoolJobs.LockList;
   l := FPoolJobs.LockList;
   Try
   Try
     if l.count=0 then doAdd := true
     if l.count=0 then doAdd := true
@@ -520,21 +524,37 @@ begin
       P := l[l.Count-1];
       P := l[l.Count-1];
       if (FNodeNotifyEvents.Node.Operations.OperationsHashTree.HashTree<>P^.OperationsComp.OperationsHashTree.HashTree) then begin
       if (FNodeNotifyEvents.Node.Operations.OperationsHashTree.HashTree<>P^.OperationsComp.OperationsHashTree.HashTree) then begin
         doAdd := (P^.SentDateTime + EncodeTime(0,0,CT_WAIT_SECONDS_BEFORE_SEND_NEW_JOB,0)) < Now;
         doAdd := (P^.SentDateTime + EncodeTime(0,0,CT_WAIT_SECONDS_BEFORE_SEND_NEW_JOB,0)) < Now;
+      end else begin
+        // No new operations waiting to be sent, but to prevent "old time mining", we will send new job with time:
+        doAdd := ((P^.SentDateTime + EncodeTime(0,0,CT_MAX_SECONDS_BETWEEN_JOBS,0)) < Now);
       end;
       end;
     end;
     end;
-    P := Nil;
     if doAdd then begin
     if doAdd then begin
       New(P);
       New(P);
       P^.SentDateTime := now;
       P^.SentDateTime := now;
+      P^.SentMinTimestamp := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
+      if (P^.SentMinTimestamp<FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.timestamp) then begin
+        P^.SentMinTimestamp := FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.timestamp;
+      end;
       P^.OperationsComp := TPCOperationsComp.Create(Nil);
       P^.OperationsComp := TPCOperationsComp.Create(Nil);
       P^.OperationsComp.CopyFrom(FNodeNotifyEvents.Node.Operations);
       P^.OperationsComp.CopyFrom(FNodeNotifyEvents.Node.Operations);
       P^.OperationsComp.AccountKey := FMinerAccountKey;
       P^.OperationsComp.AccountKey := FMinerAccountKey;
       P^.OperationsComp.BlockPayload := FMinerPayload;
       P^.OperationsComp.BlockPayload := FMinerPayload;
+      P^.OperationsComp.timestamp := P^.SentMinTimestamp; // Best practices 1.5.3
       OpB := P^.OperationsComp.OperationBlock;
       OpB := P^.OperationsComp.OperationBlock;
       if (OpB.block<>0) And (OpB.block <> (FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.block+1)) then begin
       if (OpB.block<>0) And (OpB.block <> (FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.block+1)) then begin
         raise Exception.Create('ERROR DEV 20170228-1');
         raise Exception.Create('ERROR DEV 20170228-1');
       end;
       end;
-      l.Add(P);
+      i := l.Add(P);
+      TLog.NewLog(ltDebug,ClassName,'Added new job '+IntToStr(i+1)+'/'+IntToStr(l.Count));
+    end;
+    // Clean buffer jobs
+    while (l.Count>CT_MAX_BUFFER_JOBS) do begin
+      PToDelete := l[0]; // Index 0 is oldest sent job
+      l.Delete(0);
+      PToDelete^.OperationsComp.free;
+      Dispose(PToDelete);
+      TLog.NewLog(ltDebug,ClassName,'Deleted Job 1 from buffer, now count:'+inttostr(l.Count));
     end;
     end;
   Finally
   Finally
     FPoolJobs.UnlockList;
     FPoolJobs.UnlockList;
@@ -667,7 +687,7 @@ end;
 function TPoolMiningServer.MinerSubmit(Client: TJSONRPCTcpIpClient; params: TPCJSONObject; const id : Variant): Boolean;
 function TPoolMiningServer.MinerSubmit(Client: TJSONRPCTcpIpClient; params: TPCJSONObject; const id : Variant): Boolean;
 Var s : String;
 Var s : String;
   nbOperations : TPCOperationsComp;
   nbOperations : TPCOperationsComp;
-  errors : AnsiString;
+  errors, sJobInfo : AnsiString;
   nba : TBlockAccount;
   nba : TBlockAccount;
   json : TPCJSONObject;
   json : TPCJSONObject;
   p1,p2,p3 : TRawBytes;
   p1,p2,p3 : TRawBytes;
@@ -688,6 +708,7 @@ begin
     If calculated PoW does not match valid PoW then error
     If calculated PoW does not match valid PoW then error
     If all ok... congrats!!! }
     If all ok... congrats!!! }
   Result := false;
   Result := false;
+  sJobInfo := '';
   // Must chek on previous sent jobs
   // Must chek on previous sent jobs
   nbOperations := Nil;
   nbOperations := Nil;
   Try
   Try
@@ -709,14 +730,19 @@ begin
       while (i>=0) And (Not Assigned(nbOperations)) do begin
       while (i>=0) And (Not Assigned(nbOperations)) do begin
         P := l[i];
         P := l[i];
         P^.OperationsComp.BlockPayload := _payload;
         P^.OperationsComp.BlockPayload := _payload;
-        P^.OperationsComp.timestamp := _timestamp;
-        P^.OperationsComp.nonce := _nOnce;
-        if (P^.OperationsComp.OperationBlock.proof_of_work<=_targetPoW) then begin
-          // Candidate!
-          nbOperations := TPCOperationsComp.Create(Nil);
-          nbOperations.bank := FNodeNotifyEvents.Node.Bank;
-          nbOperations.CopyFrom(P^.OperationsComp);
-          nbOperations.AccountKey := MinerAccountKey;
+        // Best practices: Only will accept a solution if timestamp >= sent timestamp for this job (1.5.3)
+        If (P^.SentMinTimestamp<=_timestamp) then begin
+          P^.OperationsComp.timestamp := _timestamp;
+          P^.OperationsComp.nonce := _nOnce;
+          if (P^.OperationsComp.OperationBlock.proof_of_work<=_targetPoW) then begin
+            // Candidate!
+            nbOperations := TPCOperationsComp.Create(Nil);
+            nbOperations.bank := FNodeNotifyEvents.Node.Bank;
+            nbOperations.CopyFrom(P^.OperationsComp);
+            nbOperations.AccountKey := MinerAccountKey;
+            sJobInfo := 'Miner job '+IntToStr(i+1)+'/'+IntToStr(l.Count);
+            TLog.NewLog(ltInfo,ClassName,sJobInfo+' - Found a solution for block '+IntToStr(nbOperations.OperationBlock.block));
+          end;
         end;
         end;
         dec(i);
         dec(i);
       end;
       end;
@@ -740,10 +766,10 @@ begin
         end;
         end;
         if Assigned(FOnMiningServerNewBlockFound) then FOnMiningServerNewBlockFound(Self);
         if Assigned(FOnMiningServerNewBlockFound) then FOnMiningServerNewBlockFound(Self);
       end else begin
       end else begin
-        Client.SendJSONRPCErrorResponse(id,'Error: '+errors+' payload:'+nbOperations.BlockPayload+' timestamp:'+InttoStr(nbOperations.timestamp)+' nonce:'+IntToStr(nbOperations.nonce));
+        Client.SendJSONRPCErrorResponse(id,'Error: '+errors+' executing '+sJobInfo+' payload:'+nbOperations.BlockPayload+' timestamp:'+InttoStr(nbOperations.timestamp)+' nonce:'+IntToStr(nbOperations.nonce));
       end;
       end;
     end else begin
     end else begin
-      Client.SendJSONRPCErrorResponse(id,'Error: No valid job found with these values! payload:'+_payload+' timestamp:'+InttoStr(_timestamp)+' nonce:'+IntToStr(_nonce));
+      Client.SendJSONRPCErrorResponse(id,'Error: No valid job found with these values! (Perhaps prior block job or old job) payload:'+_payload+' timestamp:'+InttoStr(_timestamp)+' nonce:'+IntToStr(_nonce));
     end;
     end;
   Finally
   Finally
     if Assigned(nbOperations) then nbOperations.Free;
     if Assigned(nbOperations) then nbOperations.Free;
@@ -809,10 +835,15 @@ begin
         TLog.NewLog(ltInfo,ClassName,'Creating new job for miner');
         TLog.NewLog(ltInfo,ClassName,'Creating new job for miner');
         New(P);
         New(P);
         P^.SentDateTime := now;
         P^.SentDateTime := now;
+        P^.SentMinTimestamp := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
+        if (P^.SentMinTimestamp<FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.timestamp) then begin
+          P^.SentMinTimestamp := FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.timestamp;
+        end;
         P^.OperationsComp := TPCOperationsComp.Create(Nil);
         P^.OperationsComp := TPCOperationsComp.Create(Nil);
         P^.OperationsComp.CopyFrom(FNodeNotifyEvents.Node.Operations);
         P^.OperationsComp.CopyFrom(FNodeNotifyEvents.Node.Operations);
         P^.OperationsComp.AccountKey := FMinerAccountKey;
         P^.OperationsComp.AccountKey := FMinerAccountKey;
         P^.OperationsComp.BlockPayload := FMinerPayload;
         P^.OperationsComp.BlockPayload := FMinerPayload;
+        P^.OperationsComp.timestamp := P^.SentMinTimestamp; // Best practices 1.5.3
         if (P^.OperationsComp.OperationBlock.block<>0) And (P^.OperationsComp.OperationBlock.block <> (FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.block+1)) then begin
         if (P^.OperationsComp.OperationBlock.block<>0) And (P^.OperationsComp.OperationBlock.block <> (FNodeNotifyEvents.Node.Bank.LastBlockFound.OperationBlock.block+1)) then begin
           raise Exception.Create('ERROR DEV 20170228-2');
           raise Exception.Create('ERROR DEV 20170228-2');
         end;
         end;
@@ -829,6 +860,7 @@ begin
   Finally
   Finally
     FPoolJobs.UnlockList;
     FPoolJobs.UnlockList;
   End;
   End;
+
   params := TPCJSONObject.Create;
   params := TPCJSONObject.Create;
   Try
   Try
     if Not Active then exit;
     if Not Active then exit;