Browse Source

Some race-condition protection on api calls

PascalCoin 4 years ago
parent
commit
49c63661f2
1 changed files with 24 additions and 9 deletions
  1. 24 9
      src/core/URPC.pas

+ 24 - 9
src/core/URPC.pas

@@ -3719,7 +3719,7 @@ begin
     {$IFDEF Use_OpenSSL}
     {$IFDEF Use_OpenSSL}
     GetResultObject.GetAsVariant('openssl').Value := IntToHex(OpenSSLVersion,8);
     GetResultObject.GetAsVariant('openssl').Value := IntToHex(OpenSSLVersion,8);
     {$ENDIF}
     {$ENDIF}
-    nsaarr := TNetData.NetData.NodeServersAddresses.GetValidNodeServers(true,20);
+    nsaarr := TNetData.NetData.NodeServersAddresses.GetValidNodeServers(true,10);
     for i := low(nsaarr) to High(nsaarr) do begin
     for i := low(nsaarr) to High(nsaarr) do begin
       jso := GetResultObject.GetAsArray('nodeservers').GetAsObject(i);
       jso := GetResultObject.GetAsArray('nodeservers').GetAsObject(i);
       jso.GetAsVariant('ip').Value := nsaarr[i].ip;
       jso.GetAsVariant('ip').Value := nsaarr[i].ip;
@@ -3836,7 +3836,12 @@ begin
       ErrorNum := CT_RPC_ErrNum_NotAllowedCall;
       ErrorNum := CT_RPC_ErrNum_NotAllowedCall;
       Exit;
       Exit;
     end;
     end;
-    jsonresponse.GetAsVariant('result').Value := _RPCServer.WalletKeys.LockWallet;
+    FNode.OperationSequenceLock.Acquire;  // Use lock to prevent N_Operation race-condition on concurrent invocations
+    try
+      jsonresponse.GetAsVariant('result').Value := _RPCServer.WalletKeys.LockWallet;
+    finally
+      FNode.OperationSequenceLock.Release;
+    end;
     Result := true;
     Result := true;
   end else if (method='unlock') then begin
   end else if (method='unlock') then begin
     // Unlocks the Wallet with "pwd" password
     // Unlocks the Wallet with "pwd" password
@@ -3851,11 +3856,16 @@ begin
       ErrorDesc := 'Need param "pwd"';
       ErrorDesc := 'Need param "pwd"';
       exit;
       exit;
     end;
     end;
-    If Not _RPCServer.WalletKeys.IsValidPassword then begin
-      _RPCServer.WalletKeys.WalletPassword:=params.AsString('pwd','');
+    FNode.OperationSequenceLock.Acquire;  // Use lock to prevent N_Operation race-condition on concurrent invocations
+    try
+      If Not _RPCServer.WalletKeys.IsValidPassword then begin
+        _RPCServer.WalletKeys.WalletPassword:=params.AsString('pwd','');
+      end;
+      jsonresponse.GetAsVariant('result').Value := _RPCServer.WalletKeys.IsValidPassword;
+      Result := true;
+    finally
+      FNode.OperationSequenceLock.Release;
     end;
     end;
-    jsonresponse.GetAsVariant('result').Value := _RPCServer.WalletKeys.IsValidPassword;
-    Result := true;
   end else if (method='setwalletpassword') then begin
   end else if (method='setwalletpassword') then begin
     // Changes the Wallet password with "pwd" param
     // Changes the Wallet password with "pwd" param
     // Must be unlocked first
     // Must be unlocked first
@@ -3876,9 +3886,14 @@ begin
       ErrorDesc := 'Need param "pwd"';
       ErrorDesc := 'Need param "pwd"';
       exit;
       exit;
     end;
     end;
-    _RPCServer.WalletKeys.WalletPassword:=params.AsString('pwd','');
-    jsonresponse.GetAsVariant('result').Value := _RPCServer.WalletKeys.IsValidPassword;
-    Result := true;
+    FNode.OperationSequenceLock.Acquire;  // Use lock to prevent N_Operation race-condition on concurrent invocations
+    try
+      _RPCServer.WalletKeys.WalletPassword:=params.AsString('pwd','');
+      jsonresponse.GetAsVariant('result').Value := _RPCServer.WalletKeys.IsValidPassword;
+      Result := true;
+    finally
+      FNode.OperationSequenceLock.Release;
+    end;
   end else if (method='stopnode') then begin
   end else if (method='stopnode') then begin
     // Stops communications to other nodes
     // Stops communications to other nodes
     if (Not _RPCServer.AllowUsePrivateKeys) then begin
     if (Not _RPCServer.AllowUsePrivateKeys) then begin