Ver código fonte

Fixed race-condition bug on sendto

PascalCoin 4 anos atrás
pai
commit
71294d485c
2 arquivos alterados com 29 adições e 28 exclusões
  1. 24 23
      src/core/UPCRPCSend.pas
  2. 5 5
      src/core/URPC.pas

+ 24 - 23
src/core/UPCRPCSend.pas

@@ -137,32 +137,33 @@ begin
     exit;
   end;
 
-  if Not TPascalCoinJSONComp.CaptureAccountNumber(AInputParams,'sender',ASender.Node,LSender.account,AErrorDesc) then begin
-    AErrorNum := CT_RPC_ErrNum_InvalidAccount;
-    Exit;
-  end else LSender := ASender.Node.GetMempoolAccount(LSender.account);
-
-  LTarget := CT_Account_NUL;
-  if Not TPascalCoinJSONComp.CaptureEPASA(AInputParams,'target',ASender.Node, LTargetEPASA, LTarget.account, LTargetKey, LTargetRequiresPurchase, AErrorDesc) then begin
-    AErrorNum := CT_RPC_ErrNum_InvalidAccount;
-    Exit;
-  end else LTarget := ASender.Node.GetMempoolAccount(LTarget.account);
-
-  if Not TPascalCoinJSONComp.OverridePayloadParams(AInputParams, LTargetEPASA) then begin
-    AErrorNum := CT_RPC_ErrNum_AmbiguousPayload;
-    AErrorDesc := 'Target EPASA payload conflicts with argument payload.';
-    Exit;
-  end;
-
-  LAmount := TPascalCoinJSONComp.ToPascalCoins(AInputParams.AsDouble('amount',0));
-  LFee := TPascalCoinJSONComp.ToPascalCoins(AInputParams.AsDouble('fee',0));
-  LRawPayload := TCrypto.HexaToRaw(AInputParams.AsString('payload',''));
-  LPayload_method := AInputParams.AsString('payload_method','dest');
-  LEncodePwd := AInputParams.AsString('pwd','');
-
   // Do new operation
   ASender.Node.OperationSequenceLock.Acquire;  // Use lock to prevent N_Operation race-condition on concurrent sends
   try
+
+    if Not TPascalCoinJSONComp.CaptureAccountNumber(AInputParams,'sender',ASender.Node,LSender.account,AErrorDesc) then begin
+      AErrorNum := CT_RPC_ErrNum_InvalidAccount;
+      Exit;
+    end else LSender := ASender.Node.GetMempoolAccount(LSender.account);
+
+    LTarget := CT_Account_NUL;
+    if Not TPascalCoinJSONComp.CaptureEPASA(AInputParams,'target',ASender.Node, LTargetEPASA, LTarget.account, LTargetKey, LTargetRequiresPurchase, AErrorDesc) then begin
+      AErrorNum := CT_RPC_ErrNum_InvalidAccount;
+      Exit;
+    end else LTarget := ASender.Node.GetMempoolAccount(LTarget.account);
+
+    if Not TPascalCoinJSONComp.OverridePayloadParams(AInputParams, LTargetEPASA) then begin
+      AErrorNum := CT_RPC_ErrNum_AmbiguousPayload;
+      AErrorDesc := 'Target EPASA payload conflicts with argument payload.';
+      Exit;
+    end;
+
+    LAmount := TPascalCoinJSONComp.ToPascalCoins(AInputParams.AsDouble('amount',0));
+    LFee := TPascalCoinJSONComp.ToPascalCoins(AInputParams.AsDouble('fee',0));
+    LRawPayload := TCrypto.HexaToRaw(AInputParams.AsString('payload',''));
+    LPayload_method := AInputParams.AsString('payload_method','dest');
+    LEncodePwd := AInputParams.AsString('pwd','');
+
     // Create operation
     if LTargetRequiresPurchase then begin
       // Buy Account

+ 5 - 5
src/core/URPC.pas

@@ -105,7 +105,7 @@ Type
     Function GetLogFileName : String;
     procedure SetValidIPs(const Value: String);  protected
     Function IsValidClientIP(Const clientIp : String; clientPort : Word) : Boolean;
-    Procedure AddRPCLog(Const Sender : String; Const Message : String);
+    Procedure AddRPCLog(Const Sender : String; ACallsCounter : Int64; Const Message : String);
     Function GetNewCallCounter : Int64;
   public
     Constructor Create;
@@ -813,10 +813,10 @@ end;
 
 { TRPCServer }
 
-Procedure TRPCServer.AddRPCLog(Const Sender : String; Const Message : String);
+Procedure TRPCServer.AddRPCLog(Const Sender : String; ACallsCounter : Int64; Const Message : String);
 Begin
   If Not Assigned(FRPCLog) then exit;
-  FRPCLog.NotifyNewLog(ltinfo,Sender+' '+Inttostr(FCallsCounter),Message);
+  FRPCLog.NotifyNewLog(ltinfo,Sender+' '+Inttostr(ACallsCounter),Message);
 end;
 
 Function TRPCServer.GetLogFileName : String;
@@ -1014,7 +1014,7 @@ begin
   // IP Protection
   If (Not _RPCServer.IsValidClientIP(FSock.GetRemoteSinIP,FSock.GetRemoteSinPort)) then begin
     TLog.NewLog(lterror,Classname,FSock.GetRemoteSinIP+':'+inttostr(FSock.GetRemoteSinPort)+' INVALID IP');
-    _RPCServer.AddRPCLog(FSock.GetRemoteSinIP+':'+InttoStr(FSock.GetRemoteSinPort),' INVALID IP');
+    _RPCServer.AddRPCLog(FSock.GetRemoteSinIP+':'+InttoStr(FSock.GetRemoteSinPort),callcounter,' INVALID IP');
     exit;
   end;
   errNum := CT_RPC_ErrNum_InternalError;
@@ -1138,7 +1138,7 @@ begin
           FSock.SendString(jsonresponsetxt);
         end;
       end;
-      _RPCServer.AddRPCLog(FSock.GetRemoteSinIP+':'+InttoStr(FSock.GetRemoteSinPort),'Method:'+methodName+' Params:'+paramsTxt+' '+Inttostr(errNum)+':'+errDesc+' Time:'+FormatFloat('0.000',(TPlatform.GetElapsedMilliseconds(tc)/1000)));
+      _RPCServer.AddRPCLog(FSock.GetRemoteSinIP+':'+InttoStr(FSock.GetRemoteSinPort),callcounter,'Method:'+methodName+' Params:'+paramsTxt+' '+Inttostr(errNum)+':'+errDesc+' Time:'+FormatFloat('0.000',(TPlatform.GetElapsedMilliseconds(tc)/1000)));
     finally
       jsonresponse.free;
       Headers.Free;