From 7b516213ff84747d00051b657cdc215b3bf3c92c Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Wed, 14 Oct 2020 19:30:29 -0700 Subject: [PATCH] Pure async RpcClient (#335) * compiling, some stuff stubbed out * more tests working * MakeTxContext * mistake in GetBlock/GetBlockHeader * rework TransactionManager to be closer to original * more unit tests (2 still failing) * remove assertEx * Add ThrowsAsync comment * ReturnsAsync * fixed last remaining test issues * minor TXManager cleanup * formatting * move tx contruction to MakeTransaction * discards * Async Suffixes (PR feedback) * GetCommitteeAsync * add custom magic support to tx manager * fix format * add magic param comment * CR Feedback * Clean enter Co-authored-by: Harry Co-authored-by: Shargon --- src/RpcClient/ContractClient.cs | 27 +- src/RpcClient/Nep5API.cs | 68 +++-- src/RpcClient/PolicyAPI.cs | 23 +- src/RpcClient/RpcClient.cs | 279 ++++++++++-------- src/RpcClient/TransactionManager.cs | 89 +++--- src/RpcClient/TransactionManagerFactory.cs | 57 ++++ src/RpcClient/WalletAPI.cs | 57 ++-- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 94 +++--- .../UT_ContractClient.cs | 9 +- tests/Neo.Network.RPC.Tests/UT_Nep5API.cs | 29 +- tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs | 17 +- tests/Neo.Network.RPC.Tests/UT_RpcClient.cs | 248 ++++++++-------- tests/Neo.Network.RPC.Tests/UT_RpcModels.cs | 32 +- .../UT_TransactionManager.cs | 77 +++-- tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs | 43 +-- 15 files changed, 633 insertions(+), 516 deletions(-) create mode 100644 src/RpcClient/TransactionManagerFactory.cs diff --git a/src/RpcClient/ContractClient.cs b/src/RpcClient/ContractClient.cs index 0aa3aff3b..a6ffb8f28 100644 --- a/src/RpcClient/ContractClient.cs +++ b/src/RpcClient/ContractClient.cs @@ -1,3 +1,5 @@ +using System; +using System.Threading.Tasks; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; @@ -13,14 +15,21 @@ namespace Neo.Network.RPC public class ContractClient { protected readonly RpcClient rpcClient; + protected readonly uint? magic; + /// /// ContractClient Constructor /// /// the RPC client to call NEO RPC methods - public ContractClient(RpcClient rpc) + /// + /// the network Magic value to use when signing transactions. + /// Defaults to ProtocolSettings.Default.Magic if not specified. + /// + public ContractClient(RpcClient rpc, uint? magic = null) { rpcClient = rpc; + this.magic = magic; } /// @@ -30,10 +39,10 @@ public ContractClient(RpcClient rpc) /// contract operation /// operation arguments /// - public RpcInvokeResult TestInvoke(UInt160 scriptHash, string operation, params object[] args) + public Task TestInvokeAsync(UInt160 scriptHash, string operation, params object[] args) { byte[] script = scriptHash.MakeScript(operation, args); - return rpcClient.InvokeScript(script); + return rpcClient.InvokeScriptAsync(script); } /// @@ -43,7 +52,7 @@ public RpcInvokeResult TestInvoke(UInt160 scriptHash, string operation, params o /// contract manifest /// sender KeyPair /// - public Transaction CreateDeployContractTx(byte[] contractScript, ContractManifest manifest, KeyPair key) + public async Task CreateDeployContractTxAsync(byte[] contractScript, ContractManifest manifest, KeyPair key) { byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) @@ -54,13 +63,11 @@ public Transaction CreateDeployContractTx(byte[] contractScript, ContractManifes UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; - Transaction tx = new TransactionManager(rpcClient) - .MakeTransaction(script, signers) + TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); + TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); + return await manager .AddSignature(key) - .Sign() - .Tx; - - return tx; + .SignAsync().ConfigureAwait(false); } } } diff --git a/src/RpcClient/Nep5API.cs b/src/RpcClient/Nep5API.cs index c700d5c68..59cadd67e 100644 --- a/src/RpcClient/Nep5API.cs +++ b/src/RpcClient/Nep5API.cs @@ -7,6 +7,7 @@ using System; using System.Linq; using System.Numerics; +using System.Threading.Tasks; using static Neo.Helper; namespace Neo.Network.RPC @@ -28,9 +29,10 @@ public Nep5API(RpcClient rpcClient) : base(rpcClient) { } /// contract script hash /// account script hash /// - public BigInteger BalanceOf(UInt160 scriptHash, UInt160 account) + public async Task BalanceOfAsync(UInt160 scriptHash, UInt160 account) { - BigInteger balance = TestInvoke(scriptHash, "balanceOf", account).Stack.Single().GetInteger(); + var result = await TestInvokeAsync(scriptHash, "balanceOf", account).ConfigureAwait(false); + BigInteger balance = result.Stack.Single().GetInteger(); return balance; } @@ -39,9 +41,10 @@ public BigInteger BalanceOf(UInt160 scriptHash, UInt160 account) /// /// contract script hash /// - public string Name(UInt160 scriptHash) + public async Task NameAsync(UInt160 scriptHash) { - return TestInvoke(scriptHash, "name").Stack.Single().GetString(); + var result = await TestInvokeAsync(scriptHash, "name").ConfigureAwait(false); + return result.Stack.Single().GetString(); } /// @@ -49,9 +52,10 @@ public string Name(UInt160 scriptHash) /// /// contract script hash /// - public string Symbol(UInt160 scriptHash) + public async Task SymbolAsync(UInt160 scriptHash) { - return TestInvoke(scriptHash, "symbol").Stack.Single().GetString(); + var result = await TestInvokeAsync(scriptHash, "symbol").ConfigureAwait(false); + return result.Stack.Single().GetString(); } /// @@ -59,9 +63,10 @@ public string Symbol(UInt160 scriptHash) /// /// contract script hash /// - public byte Decimals(UInt160 scriptHash) + public async Task DecimalsAsync(UInt160 scriptHash) { - return (byte)TestInvoke(scriptHash, "decimals").Stack.Single().GetInteger(); + var result = await TestInvokeAsync(scriptHash, "decimals").ConfigureAwait(false); + return (byte)result.Stack.Single().GetInteger(); } /// @@ -69,9 +74,10 @@ public byte Decimals(UInt160 scriptHash) /// /// contract script hash /// - public BigInteger TotalSupply(UInt160 scriptHash) + public async Task TotalSupplyAsync(UInt160 scriptHash) { - return TestInvoke(scriptHash, "totalSupply").Stack.Single().GetInteger(); + var result = await TestInvokeAsync(scriptHash, "totalSupply").ConfigureAwait(false); + return result.Stack.Single().GetInteger(); } /// @@ -79,21 +85,23 @@ public BigInteger TotalSupply(UInt160 scriptHash) /// /// contract script hash /// - public RpcNep5TokenInfo GetTokenInfo(UInt160 scriptHash) + public async Task GetTokenInfoAsync(UInt160 scriptHash) { - byte[] script = Concat(scriptHash.MakeScript("name"), + byte[] script = Concat( + scriptHash.MakeScript("name"), scriptHash.MakeScript("symbol"), scriptHash.MakeScript("decimals"), scriptHash.MakeScript("totalSupply")); - var result = rpcClient.InvokeScript(script).Stack; + var result = await rpcClient.InvokeScriptAsync(script).ConfigureAwait(false); + var stack = result.Stack; return new RpcNep5TokenInfo { - Name = result[0].GetString(), - Symbol = result[1].GetString(), - Decimals = (byte)result[2].GetInteger(), - TotalSupply = result[3].GetInteger() + Name = stack[0].GetString(), + Symbol = stack[1].GetString(), + Decimals = (byte)stack[2].GetInteger(), + TotalSupply = stack[3].GetInteger() }; } @@ -105,19 +113,18 @@ public RpcNep5TokenInfo GetTokenInfo(UInt160 scriptHash) /// to account script hash /// transfer amount /// - public Transaction CreateTransferTx(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount) + public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount) { var sender = Contract.CreateSignatureRedeemScript(fromKey.PublicKey).ToScriptHash(); Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; byte[] script = scriptHash.MakeScript("transfer", sender, to, amount); - Transaction tx = new TransactionManager(rpcClient) - .MakeTransaction(script, signers) - .AddSignature(fromKey) - .Sign() - .Tx; - return tx; + TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); + TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); + return await manager + .AddSignature(fromKey) + .SignAsync().ConfigureAwait(false); } /// @@ -130,7 +137,7 @@ public Transaction CreateTransferTx(UInt160 scriptHash, KeyPair fromKey, UInt160 /// to account /// transfer amount /// - public Transaction CreateTransferTx(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] fromKeys, UInt160 to, BigInteger amount) + public async Task CreateTransferTxAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] fromKeys, UInt160 to, BigInteger amount) { if (m > fromKeys.Length) throw new ArgumentException($"Need at least {m} KeyPairs for signing!"); @@ -138,13 +145,12 @@ public Transaction CreateTransferTx(UInt160 scriptHash, int m, ECPoint[] pubKeys Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; byte[] script = scriptHash.MakeScript("transfer", sender, to, amount); - Transaction tx = new TransactionManager(rpcClient) - .MakeTransaction(script, signers) - .AddMultiSig(fromKeys, m, pubKeys) - .Sign() - .Tx; - return tx; + TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); + TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); + return await manager + .AddMultiSig(fromKeys, m, pubKeys) + .SignAsync().ConfigureAwait(false); } } } diff --git a/src/RpcClient/PolicyAPI.cs b/src/RpcClient/PolicyAPI.cs index 073b105b3..540f945da 100644 --- a/src/RpcClient/PolicyAPI.cs +++ b/src/RpcClient/PolicyAPI.cs @@ -1,6 +1,7 @@ using Neo.SmartContract.Native; using Neo.VM; using System.Linq; +using System.Threading.Tasks; namespace Neo.Network.RPC { @@ -21,37 +22,41 @@ public PolicyAPI(RpcClient rpcClient) : base(rpcClient) { } /// Get Max Transactions Count Per Block /// /// - public uint GetMaxTransactionsPerBlock() + public async Task GetMaxTransactionsPerBlockAsync() { - return (uint)TestInvoke(scriptHash, "getMaxTransactionsPerBlock").Stack.Single().GetInteger(); + var result = await TestInvokeAsync(scriptHash, "getMaxTransactionsPerBlock").ConfigureAwait(false); + return (uint)result.Stack.Single().GetInteger(); } /// /// Get Max Block Size /// /// - public uint GetMaxBlockSize() + public async Task GetMaxBlockSizeAsync() { - return (uint)TestInvoke(scriptHash, "getMaxBlockSize").Stack.Single().GetInteger(); + var result = await TestInvokeAsync(scriptHash, "getMaxBlockSize").ConfigureAwait(false); + return (uint)result.Stack.Single().GetInteger(); } /// /// Get Network Fee Per Byte /// /// - public long GetFeePerByte() + public async Task GetFeePerByteAsync() { - return (long)TestInvoke(scriptHash, "getFeePerByte").Stack.Single().GetInteger(); + var result = await TestInvokeAsync(scriptHash, "getFeePerByte").ConfigureAwait(false); + return (long)result.Stack.Single().GetInteger(); } /// /// Get Ploicy Blocked Accounts /// /// - public UInt160[] GetBlockedAccounts() + public async Task GetBlockedAccountsAsync() { - var result = (VM.Types.Array)TestInvoke(scriptHash, "getBlockedAccounts").Stack.Single(); - return result.Select(p => new UInt160(p.GetSpan().ToArray())).ToArray(); + var result = await TestInvokeAsync(scriptHash, "getBlockedAccounts").ConfigureAwait(false); + var array = (VM.Types.Array)result.Stack.Single(); + return array.Select(p => new UInt160(p.GetSpan().ToArray())).ToArray(); } } } diff --git a/src/RpcClient/RpcClient.cs b/src/RpcClient/RpcClient.cs index d6f3411c7..6d81f9b86 100644 --- a/src/RpcClient/RpcClient.cs +++ b/src/RpcClient/RpcClient.cs @@ -20,11 +20,13 @@ namespace Neo.Network.RPC /// public class RpcClient : IDisposable { - private HttpClient httpClient; + private readonly HttpClient httpClient; + private readonly string baseAddress; public RpcClient(string url, string rpcUser = default, string rpcPass = default) { - httpClient = new HttpClient() { BaseAddress = new Uri(url) }; + httpClient = new HttpClient(); + baseAddress = url; if (!string.IsNullOrEmpty(rpcUser) && !string.IsNullOrEmpty(rpcPass)) { string token = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{rpcUser}:{rpcPass}")); @@ -32,9 +34,10 @@ public RpcClient(string url, string rpcUser = default, string rpcPass = default) } } - public RpcClient(HttpClient client) + public RpcClient(HttpClient client, string url) { httpClient = client; + baseAddress = url; } #region IDisposable Support @@ -46,10 +49,9 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - httpClient?.Dispose(); + httpClient.Dispose(); } - httpClient = null; disposedValue = true; } } @@ -62,8 +64,10 @@ public void Dispose() public async Task SendAsync(RpcRequest request) { + if (disposedValue) throw new ObjectDisposedException(nameof(RpcClient)); + var requestJson = request.ToJson().ToString(); - using var result = await httpClient.PostAsync(httpClient.BaseAddress, new StringContent(requestJson, Encoding.UTF8)); + using var result = await httpClient.PostAsync(baseAddress, new StringContent(requestJson, Encoding.UTF8)).ConfigureAwait(false); var content = await result.Content.ReadAsStringAsync(); var response = RpcResponse.FromJson(JObject.Parse(content)); response.RawResponse = content; @@ -76,19 +80,7 @@ public async Task SendAsync(RpcRequest request) return response; } - public RpcResponse Send(RpcRequest request) - { - try - { - return SendAsync(request).Result; - } - catch (AggregateException ex) - { - throw ex.GetBaseException(); - } - } - - public virtual JObject RpcSend(string method, params JObject[] paraArgs) + public virtual async Task RpcSendAsync(string method, params JObject[] paraArgs) { var request = new RpcRequest { @@ -97,7 +89,9 @@ public virtual JObject RpcSend(string method, params JObject[] paraArgs) Method = method, Params = paraArgs }; - return Send(request).Result; + + var response = await SendAsync(request).ConfigureAwait(false); + return response.Result; } #region Blockchain @@ -105,82 +99,84 @@ public virtual JObject RpcSend(string method, params JObject[] paraArgs) /// /// Returns the hash of the tallest block in the main chain. /// - public string GetBestBlockHash() + public async Task GetBestBlockHashAsync() { - return RpcSend("getbestblockhash").AsString(); + var result = await RpcSendAsync("getbestblockhash").ConfigureAwait(false); + return result.AsString(); } /// /// Returns the hash of the tallest block in the main chain. /// The serialized information of the block is returned, represented by a hexadecimal string. /// - public string GetBlockHex(string hashOrIndex) + public async Task GetBlockHexAsync(string hashOrIndex) { - if (int.TryParse(hashOrIndex, out int index)) - { - return RpcSend("getblock", index).AsString(); - } - return RpcSend("getblock", hashOrIndex).AsString(); + var result = int.TryParse(hashOrIndex, out int index) + ? await RpcSendAsync("getblock", index).ConfigureAwait(false) + : await RpcSendAsync("getblock", hashOrIndex).ConfigureAwait(false); + return result.AsString(); } /// /// Returns the hash of the tallest block in the main chain. /// - public RpcBlock GetBlock(string hashOrIndex) + public async Task GetBlockAsync(string hashOrIndex) { - if (int.TryParse(hashOrIndex, out int index)) - { - return RpcBlock.FromJson(RpcSend("getblock", index, true)); - } - return RpcBlock.FromJson(RpcSend("getblock", hashOrIndex, true)); + var result = int.TryParse(hashOrIndex, out int index) + ? await RpcSendAsync("getblock", index, true).ConfigureAwait(false) + : await RpcSendAsync("getblock", hashOrIndex, true).ConfigureAwait(false); + + return RpcBlock.FromJson(result); } /// /// Gets the number of blocks in the main chain. /// - public uint GetBlockCount() + public async Task GetBlockCountAsync() { - return (uint)RpcSend("getblockcount").AsNumber(); + var result = await RpcSendAsync("getblockcount").ConfigureAwait(false); + return (uint)result.AsNumber(); } /// /// Returns the hash value of the corresponding block, based on the specified index. /// - public string GetBlockHash(int index) + public async Task GetBlockHashAsync(int index) { - return RpcSend("getblockhash", index).AsString(); + var result = await RpcSendAsync("getblockhash", index).ConfigureAwait(false); + return result.AsString(); } /// /// Returns the corresponding block header information according to the specified script hash. /// - public string GetBlockHeaderHex(string hashOrIndex) + public async Task GetBlockHeaderHexAsync(string hashOrIndex) { - if (int.TryParse(hashOrIndex, out int index)) - { - return RpcSend("getblockheader", index).AsString(); - } - return RpcSend("getblockheader", hashOrIndex).AsString(); + var result = int.TryParse(hashOrIndex, out int index) + ? await RpcSendAsync("getblockheader", index).ConfigureAwait(false) + : await RpcSendAsync("getblockheader", hashOrIndex).ConfigureAwait(false); + return result.AsString(); } /// /// Returns the corresponding block header information according to the specified script hash. /// - public RpcBlockHeader GetBlockHeader(string hashOrIndex) + public async Task GetBlockHeaderAsync(string hashOrIndex) { - if (int.TryParse(hashOrIndex, out int index)) - { - return RpcBlockHeader.FromJson(RpcSend("getblockheader", index, true)); - } - return RpcBlockHeader.FromJson(RpcSend("getblockheader", hashOrIndex, true)); + var result = int.TryParse(hashOrIndex, out int index) + ? await RpcSendAsync("getblockheader", index, true).ConfigureAwait(false) + : await RpcSendAsync("getblockheader", hashOrIndex, true).ConfigureAwait(false); + + return RpcBlockHeader.FromJson(result); } /// /// Queries contract information, according to the contract script hash. /// - public ContractState GetContractState(string hash) + public async Task GetContractStateAsync(string hash) { - return ContractStateFromJson(RpcSend("getcontractstate", hash)); + var result = await RpcSendAsync("getcontractstate", hash).ConfigureAwait(false); + return ContractStateFromJson(result); } public static ContractState ContractStateFromJson(JObject json) @@ -196,35 +192,39 @@ public static ContractState ContractStateFromJson(JObject json) /// /// Obtains the list of unconfirmed transactions in memory. /// - public string[] GetRawMempool() + public async Task GetRawMempoolAsync() { - return ((JArray)RpcSend("getrawmempool")).Select(p => p.AsString()).ToArray(); + var result = await RpcSendAsync("getrawmempool").ConfigureAwait(false); + return ((JArray)result).Select(p => p.AsString()).ToArray(); } /// /// Obtains the list of unconfirmed transactions in memory. /// shouldGetUnverified = true /// - public RpcRawMemPool GetRawMempoolBoth() + public async Task GetRawMempoolBothAsync() { - return RpcRawMemPool.FromJson(RpcSend("getrawmempool", true)); + var result = await RpcSendAsync("getrawmempool", true).ConfigureAwait(false); + return RpcRawMemPool.FromJson(result); } /// /// Returns the corresponding transaction information, based on the specified hash value. /// - public string GetRawTransactionHex(string txHash) + public async Task GetRawTransactionHexAsync(string txHash) { - return RpcSend("getrawtransaction", txHash).AsString(); + var result = await RpcSendAsync("getrawtransaction", txHash).ConfigureAwait(false); + return result.AsString(); } /// /// Returns the corresponding transaction information, based on the specified hash value. /// verbose = true /// - public RpcTransaction GetRawTransaction(string txHash) + public async Task GetRawTransactionAsync(string txHash) { - return RpcTransaction.FromJson(RpcSend("getrawtransaction", txHash, true)); + var result = await RpcSendAsync("getrawtransaction", txHash, true).ConfigureAwait(false); + return RpcTransaction.FromJson(result); } /// @@ -232,47 +232,49 @@ public RpcTransaction GetRawTransaction(string txHash) /// /// Transaction /// NetworkFee - public long CalculateNetworkFee(Transaction tx) + public async Task CalculateNetworkFeeAsync(Transaction tx) { - var json = RpcSend("calculatenetworkfee", Convert.ToBase64String(tx.ToArray())); + var json = await RpcSendAsync("calculatenetworkfee", Convert.ToBase64String(tx.ToArray())) + .ConfigureAwait(false); return (long)json["networkfee"].AsNumber(); } /// /// Returns the stored value, according to the contract script hash (or Id) and the stored key. /// - public string GetStorage(string scriptHashOrId, string key) + public async Task GetStorageAsync(string scriptHashOrId, string key) { - if (int.TryParse(scriptHashOrId, out int id)) - { - return RpcSend("getstorage", id, key).AsString(); - } - - return RpcSend("getstorage", scriptHashOrId, key).AsString(); + var result = int.TryParse(scriptHashOrId, out int id) + ? await RpcSendAsync("getstorage", id, key).ConfigureAwait(false) + : await RpcSendAsync("getstorage", scriptHashOrId, key).ConfigureAwait(false); + return result.AsString(); } /// /// Returns the block index in which the transaction is found. /// - public uint GetTransactionHeight(string txHash) + public async Task GetTransactionHeightAsync(string txHash) { - return uint.Parse(RpcSend("gettransactionheight", txHash).AsString()); + var result = await RpcSendAsync("gettransactionheight", txHash).ConfigureAwait(false); + return uint.Parse(result.AsString()); } /// /// Returns the next NEO consensus nodes information and voting status. /// - public RpcValidator[] GetNextBlockValidators() + public async Task GetNextBlockValidatorsAsync() { - return ((JArray)RpcSend("getnextblockvalidators")).Select(p => RpcValidator.FromJson(p)).ToArray(); + var result = await RpcSendAsync("getnextblockvalidators").ConfigureAwait(false); + return ((JArray)result).Select(p => RpcValidator.FromJson(p)).ToArray(); } /// /// Returns the current NEO committee members. /// - public string[] GetCommittee() + public async Task GetCommitteeAsync() { - return ((JArray)RpcSend("getcommittee")).Select(p => p.AsString()).ToArray(); + var result = await RpcSendAsync("getcommittee").ConfigureAwait(false); + return ((JArray)result).Select(p => p.AsString()).ToArray(); } #endregion Blockchain @@ -282,49 +284,54 @@ public string[] GetCommittee() /// /// Gets the current number of connections for the node. /// - public int GetConnectionCount() + public async Task GetConnectionCountAsync() { - return (int)RpcSend("getconnectioncount").AsNumber(); + var result = await RpcSendAsync("getconnectioncount").ConfigureAwait(false); + return (int)result.AsNumber(); } /// /// Gets the list of nodes that the node is currently connected/disconnected from. /// - public RpcPeers GetPeers() + public async Task GetPeersAsync() { - return RpcPeers.FromJson(RpcSend("getpeers")); + var result = await RpcSendAsync("getpeers").ConfigureAwait(false); + return RpcPeers.FromJson(result); } /// /// Returns the version information about the queried node. /// - public RpcVersion GetVersion() + public async Task GetVersionAsync() { - return RpcVersion.FromJson(RpcSend("getversion")); + var result = await RpcSendAsync("getversion").ConfigureAwait(false); + return RpcVersion.FromJson(result); } /// /// Broadcasts a serialized transaction over the NEO network. /// - public UInt256 SendRawTransaction(byte[] rawTransaction) + public async Task SendRawTransactionAsync(byte[] rawTransaction) { - return UInt256.Parse(RpcSend("sendrawtransaction", rawTransaction.ToHexString())["hash"].AsString()); + var result = await RpcSendAsync("sendrawtransaction", rawTransaction.ToHexString()).ConfigureAwait(false); + return UInt256.Parse(result["hash"].AsString()); } /// /// Broadcasts a transaction over the NEO network. /// - public UInt256 SendRawTransaction(Transaction transaction) + public Task SendRawTransactionAsync(Transaction transaction) { - return SendRawTransaction(transaction.ToArray()); + return SendRawTransactionAsync(transaction.ToArray()); } /// /// Broadcasts a serialized block over the NEO network. /// - public UInt256 SubmitBlock(byte[] block) + public async Task SubmitBlockAsync(byte[] block) { - return UInt256.Parse(RpcSend("submitblock", block.ToHexString())["hash"].AsString()); + var result = await RpcSendAsync("submitblock", block.ToHexString()).ConfigureAwait(false); + return UInt256.Parse(result["hash"].AsString()); } #endregion Node @@ -335,33 +342,36 @@ public UInt256 SubmitBlock(byte[] block) /// Returns the result after calling a smart contract at scripthash with the given operation and parameters. /// This RPC call does not affect the blockchain in any way. /// - public RpcInvokeResult InvokeFunction(string scriptHash, string operation, RpcStack[] stacks, params Signer[] signer) + public async Task InvokeFunctionAsync(string scriptHash, string operation, RpcStack[] stacks, params Signer[] signer) { List parameters = new List { scriptHash.AsScriptHash(), operation, stacks.Select(p => p.ToJson()).ToArray() }; if (signer.Length > 0) { parameters.Add(signer.Select(p => (JObject)p.ToJson()).ToArray()); } - return RpcInvokeResult.FromJson(RpcSend("invokefunction", parameters.ToArray())); + var result = await RpcSendAsync("invokefunction", parameters.ToArray()).ConfigureAwait(false); + return RpcInvokeResult.FromJson(result); } /// /// Returns the result after passing a script through the VM. /// This RPC call does not affect the blockchain in any way. /// - public RpcInvokeResult InvokeScript(byte[] script, params Signer[] signers) + public async Task InvokeScriptAsync(byte[] script, params Signer[] signers) { List parameters = new List { script.ToHexString() }; if (signers.Length > 0) { parameters.Add(signers.Select(p => p.ToJson()).ToArray()); } - return RpcInvokeResult.FromJson(RpcSend("invokescript", parameters.ToArray())); + var result = await RpcSendAsync("invokescript", parameters.ToArray()).ConfigureAwait(false); + return RpcInvokeResult.FromJson(result); } - public RpcUnclaimedGas GetUnclaimedGas(string address) + public async Task GetUnclaimedGasAsync(string address) { - return RpcUnclaimedGas.FromJson(RpcSend("getunclaimedgas", address.AsScriptHash())); + var result = await RpcSendAsync("getunclaimedgas", address.AsScriptHash()).ConfigureAwait(false); + return RpcUnclaimedGas.FromJson(result); } #endregion SmartContract @@ -371,17 +381,19 @@ public RpcUnclaimedGas GetUnclaimedGas(string address) /// /// Returns a list of plugins loaded by the node. /// - public RpcPlugin[] ListPlugins() + public async Task ListPluginsAsync() { - return ((JArray)RpcSend("listplugins")).Select(p => RpcPlugin.FromJson(p)).ToArray(); + var result = await RpcSendAsync("listplugins").ConfigureAwait(false); + return ((JArray)result).Select(p => RpcPlugin.FromJson(p)).ToArray(); } /// /// Verifies that the address is a correct NEO address. /// - public RpcValidateAddressResult ValidateAddress(string address) + public async Task ValidateAddressAsync(string address) { - return RpcValidateAddressResult.FromJson(RpcSend("validateaddress", address)); + var result = await RpcSendAsync("validateaddress", address).ConfigureAwait(false); + return RpcValidateAddressResult.FromJson(result); } #endregion Utilities @@ -391,25 +403,28 @@ public RpcValidateAddressResult ValidateAddress(string address) /// /// Close the wallet opened by RPC. /// - public bool CloseWallet() + public async Task CloseWalletAsync() { - return RpcSend("closewallet").AsBoolean(); + var result = await RpcSendAsync("closewallet").ConfigureAwait(false); + return result.AsBoolean(); } /// /// Exports the private key of the specified address. /// - public string DumpPrivKey(string address) + public async Task DumpPrivKeyAsync(string address) { - return RpcSend("dumpprivkey", address).AsString(); + var result = await RpcSendAsync("dumpprivkey", address).ConfigureAwait(false); + return result.AsString(); } /// /// Creates a new account in the wallet opened by RPC. /// - public string GetNewAddress() + public async Task GetNewAddressAsync() { - return RpcSend("getnewaddress").AsString(); + var result = await RpcSendAsync("getnewaddress").ConfigureAwait(false); + return result.AsString(); } /// @@ -417,60 +432,66 @@ public string GetNewAddress() /// This method applies to assets that conform to NEP-5 standards. /// /// new address as string - public BigDecimal GetWalletBalance(string assetId) + public async Task GetWalletBalanceAsync(string assetId) { - byte decimals = new Nep5API(this).Decimals(UInt160.Parse(assetId.AsScriptHash())); - BigInteger balance = BigInteger.Parse(RpcSend("getwalletbalance", assetId)["balance"].AsString()); + byte decimals = await new Nep5API(this).DecimalsAsync(UInt160.Parse(assetId.AsScriptHash())).ConfigureAwait(false); + var result = await RpcSendAsync("getwalletbalance", assetId).ConfigureAwait(false); + BigInteger balance = BigInteger.Parse(result["balance"].AsString()); return new BigDecimal(balance, decimals); } /// /// Gets the amount of unclaimed GAS in the wallet. /// - public BigInteger GetWalletUnclaimedGas() + public async Task GetWalletUnclaimedGasAsync() { - return BigInteger.Parse(RpcSend("getwalletunclaimedgas").AsString()); + var result = await RpcSendAsync("getwalletunclaimedgas").ConfigureAwait(false); + return BigInteger.Parse(result.AsString()); } /// /// Imports the private key to the wallet. /// - public RpcAccount ImportPrivKey(string wif) + public async Task ImportPrivKeyAsync(string wif) { - return RpcAccount.FromJson(RpcSend("importprivkey", wif)); + var result = await RpcSendAsync("importprivkey", wif).ConfigureAwait(false); + return RpcAccount.FromJson(result); } /// /// Lists all the accounts in the current wallet. /// - public List ListAddress() + public async Task> ListAddressAsync() { - return ((JArray)RpcSend("listaddress")).Select(p => RpcAccount.FromJson(p)).ToList(); + var result = await RpcSendAsync("listaddress").ConfigureAwait(false); + return ((JArray)result).Select(p => RpcAccount.FromJson(p)).ToList(); } /// /// Open wallet file in the provider's machine. /// By default, this method is disabled by RpcServer config.json. /// - public bool OpenWallet(string path, string password) + public async Task OpenWalletAsync(string path, string password) { - return RpcSend("openwallet", path, password).AsBoolean(); + var result = await RpcSendAsync("openwallet", path, password).ConfigureAwait(false); + return result.AsBoolean(); } /// /// Transfer from the specified address to the destination address. /// /// This function returns Signed Transaction JSON if successful, ContractParametersContext JSON if signing failed. - public JObject SendFrom(string assetId, string fromAddress, string toAddress, string amount) + public async Task SendFromAsync(string assetId, string fromAddress, string toAddress, string amount) { - return RpcSend("sendfrom", assetId.AsScriptHash(), fromAddress.AsScriptHash(), toAddress.AsScriptHash(), amount); + return await RpcSendAsync("sendfrom", assetId.AsScriptHash(), fromAddress.AsScriptHash(), + toAddress.AsScriptHash(), amount).ConfigureAwait(false); } /// /// Bulk transfer order, and you can specify a sender address. /// /// This function returns Signed Transaction JSON if successful, ContractParametersContext JSON if signing failed. - public JObject SendMany(string fromAddress, IEnumerable outputs) + public async Task SendManyAsync(string fromAddress, IEnumerable outputs) { var parameters = new List(); if (!string.IsNullOrEmpty(fromAddress)) @@ -479,16 +500,17 @@ public JObject SendMany(string fromAddress, IEnumerable outputs) } parameters.Add(outputs.Select(p => p.ToJson()).ToArray()); - return RpcSend("sendmany", paraArgs: parameters.ToArray()); + return await RpcSendAsync("sendmany", paraArgs: parameters.ToArray()).ConfigureAwait(false); } /// /// Transfer asset from the wallet to the destination address. /// /// This function returns Signed Transaction JSON if successful, ContractParametersContext JSON if signing failed. - public JObject SendToAddress(string assetId, string address, string amount) + public async Task SendToAddressAsync(string assetId, string address, string amount) { - return RpcSend("sendtoaddress", assetId.AsScriptHash(), address.AsScriptHash(), amount); + return await RpcSendAsync("sendtoaddress", assetId.AsScriptHash(), address.AsScriptHash(), amount) + .ConfigureAwait(false); } #endregion Wallet @@ -499,9 +521,10 @@ public JObject SendToAddress(string assetId, string address, string amount) /// Returns the contract log based on the specified txHash. The complete contract logs are stored under the ApplicationLogs directory. /// This method is provided by the plugin ApplicationLogs. /// - public RpcApplicationLog GetApplicationLog(string txHash) + public async Task GetApplicationLogAsync(string txHash) { - return RpcApplicationLog.FromJson(RpcSend("getapplicationlog", txHash)); + var result = await RpcSendAsync("getapplicationlog", txHash).ConfigureAwait(false); + return RpcApplicationLog.FromJson(result); } /// @@ -511,20 +534,24 @@ public RpcApplicationLog GetApplicationLog(string txHash) /// The address to query the transaction information. /// The start block Timestamp, default to seven days before UtcNow /// The end block Timestamp, default to UtcNow - public RpcNep5Transfers GetNep5Transfers(string address, ulong? startTimestamp = default, ulong? endTimestamp = default) + public async Task GetNep5TransfersAsync(string address, ulong? startTimestamp = default, ulong? endTimestamp = default) { startTimestamp ??= 0; endTimestamp ??= DateTime.UtcNow.ToTimestampMS(); - return RpcNep5Transfers.FromJson(RpcSend("getnep5transfers", address.AsScriptHash(), startTimestamp, endTimestamp)); + var result = await RpcSendAsync("getnep5transfers", address.AsScriptHash(), startTimestamp, endTimestamp) + .ConfigureAwait(false); + return RpcNep5Transfers.FromJson(result); } /// /// Returns the balance of all NEP-5 assets in the specified address. /// This method is provided by the plugin RpcNep5Tracker. /// - public RpcNep5Balances GetNep5Balances(string address) + public async Task GetNep5BalancesAsync(string address) { - return RpcNep5Balances.FromJson(RpcSend("getnep5balances", address.AsScriptHash())); + var result = await RpcSendAsync("getnep5balances", address.AsScriptHash()) + .ConfigureAwait(false); + return RpcNep5Balances.FromJson(result); } #endregion Plugins diff --git a/src/RpcClient/TransactionManager.cs b/src/RpcClient/TransactionManager.cs index ac38818de..7e35e25f0 100644 --- a/src/RpcClient/TransactionManager.cs +++ b/src/RpcClient/TransactionManager.cs @@ -1,12 +1,13 @@ using Neo.Cryptography.ECC; +using Neo.IO; using Neo.Network.P2P.Payloads; -using Neo.Network.RPC.Models; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.Wallets; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace Neo.Network.RPC { @@ -15,65 +16,56 @@ namespace Neo.Network.RPC /// public class TransactionManager { + private class SignItem { public Contract Contract; public HashSet KeyPairs; } + private readonly RpcClient rpcClient; - private readonly PolicyAPI policyAPI; - private readonly Nep5API nep5API; - private class SignItem { public Contract Contract; public HashSet KeyPairs; } + /// + /// protocol settings Magic value to use for hashing transactions. + /// + private readonly uint magic; /// /// The Transaction context to manage the witnesses /// - private ContractParametersContext context; + private readonly ContractParametersContext context; /// /// This container stores the keys for sign the transaction /// - private List signStore; + private readonly List signStore = new List(); /// - /// The Transaction managed by this class + /// The Transaction managed by this instance /// - public Transaction Tx { get; private set; } + private readonly Transaction tx; + + public Transaction Tx => tx; /// /// TransactionManager Constructor /// - /// the RPC client to call NEO RPC API - /// the account script hash of sender - public TransactionManager(RpcClient rpc) + /// the transaction to manage. Typically buildt + /// the RPC client to call NEO RPC API + /// + /// the network Magic value to use when signing transactions. + /// Defaults to ProtocolSettings.Default.Magic if not specified. + /// + public TransactionManager(Transaction tx, RpcClient rpcClient, uint magic) { - rpcClient = rpc; - policyAPI = new PolicyAPI(rpc); - nep5API = new Nep5API(rpc); + this.tx = tx; + this.context = new ContractParametersContext(tx); + this.rpcClient = rpcClient; + this.magic = magic; } /// - /// Create an unsigned Transaction object with given parameters. + /// Helper function for one-off TransactionManager creation /// - /// Transaction Script - /// Transaction Attributes - /// - public TransactionManager MakeTransaction(byte[] script, Signer[] signers = null, TransactionAttribute[] attributes = null) + public static Task MakeTransactionAsync(RpcClient rpcClient, byte[] script, Signer[] signers = null, TransactionAttribute[] attributes = null, uint? magic = null) { - var random = new Random(); - uint height = rpcClient.GetBlockCount() - 1; - Tx = new Transaction - { - Version = 0, - Nonce = (uint)random.Next(), - Script = script, - Signers = signers, - ValidUntilBlock = height + Transaction.MaxValidUntilBlockIncrement, - Attributes = attributes ?? Array.Empty(), - }; - - RpcInvokeResult result = rpcClient.InvokeScript(script, signers); - Tx.SystemFee = long.Parse(result.GasConsumed); - context = new ContractParametersContext(Tx); - signStore = new List(); - - return this; + var factory = new TransactionManagerFactory(rpcClient, magic); + return factory.MakeTransactionAsync(script, signers, attributes); } /// @@ -109,9 +101,10 @@ public TransactionManager AddMultiSig(KeyPair key, int m, params ECPoint[] publi /// The Public Keys construct the multiple signature contract public TransactionManager AddMultiSig(KeyPair[] keys, int m, params ECPoint[] publicKeys) { - foreach (var key in keys) + Contract contract = Contract.CreateMultiSigContract(m, publicKeys); + for (int i = 0; i < keys.Length; i++) { - AddMultiSig(key, m, publicKeys); + AddSignItem(contract, keys[i]); } return this; } @@ -162,7 +155,7 @@ public TransactionManager AddWitness(UInt160 scriptHash, params object[] paramet /// /// Verify Witness count and add witnesses /// - public TransactionManager Sign() + public async Task SignAsync() { // Calculate NetworkFee Tx.Witnesses = Tx.GetScriptHashesForVerifying(null).Select(u => new Witness() @@ -170,23 +163,25 @@ public TransactionManager Sign() InvocationScript = Array.Empty(), VerificationScript = GetVerificationScript(u) }).ToArray(); - Tx.NetworkFee = rpcClient.CalculateNetworkFee(Tx); + Tx.NetworkFee = await rpcClient.CalculateNetworkFeeAsync(Tx).ConfigureAwait(false); Tx.Witnesses = null; - var gasBalance = nep5API.BalanceOf(NativeContract.GAS.Hash, Tx.Sender); + var gasBalance = await new Nep5API(rpcClient).BalanceOfAsync(NativeContract.GAS.Hash, Tx.Sender).ConfigureAwait(false); if (gasBalance < Tx.SystemFee + Tx.NetworkFee) throw new InvalidOperationException($"Insufficient GAS in address: {Tx.Sender.ToAddress()}"); // Sign with signStore - foreach (var item in signStore) - foreach (var key in item.KeyPairs) + for (int i = 0; i < signStore.Count; i++) + { + foreach (var key in signStore[i].KeyPairs) { - byte[] signature = Tx.Sign(key); - if (!context.AddSignature(item.Contract, key.PublicKey, signature)) + byte[] signature = Tx.Sign(key, magic); + if (!context.AddSignature(signStore[i].Contract, key.PublicKey, signature)) { throw new Exception("AddSignature failed!"); } } + } // Verify witness count if (!context.Completed) @@ -194,7 +189,7 @@ public TransactionManager Sign() throw new Exception($"Please add signature or witness first!"); } Tx.Witnesses = context.GetWitnesses(); - return this; + return Tx; } private byte[] GetVerificationScript(UInt160 hash) diff --git a/src/RpcClient/TransactionManagerFactory.cs b/src/RpcClient/TransactionManagerFactory.cs new file mode 100644 index 000000000..0f7277a2c --- /dev/null +++ b/src/RpcClient/TransactionManagerFactory.cs @@ -0,0 +1,57 @@ +using Neo.Network.P2P.Payloads; +using Neo.Network.RPC.Models; +using System; +using System.Threading.Tasks; + +namespace Neo.Network.RPC +{ + public class TransactionManagerFactory + { + private readonly RpcClient rpcClient; + + /// + /// protocol settings Magic value to use for hashing transactions. + /// defaults to ProtocolSettings.Default.Magic if unspecified + /// + private readonly uint magic; + + /// + /// TransactionManagerFactory Constructor + /// + /// the RPC client to call NEO RPC API + /// + /// the network Magic value to use when signing transactions. + /// Defaults to ProtocolSettings.Default.Magic if not specified. + /// + public TransactionManagerFactory(RpcClient rpcClient, uint? magic = null) + { + this.rpcClient = rpcClient; + this.magic = magic ?? ProtocolSettings.Default.Magic; + } + + /// + /// Create an unsigned Transaction object with given parameters. + /// + /// Transaction Script + /// Transaction Attributes + /// + public async Task MakeTransactionAsync(byte[] script, Signer[] signers = null, TransactionAttribute[] attributes = null) + { + uint blockCount = await rpcClient.GetBlockCountAsync().ConfigureAwait(false) - 1; + RpcInvokeResult invokeResult = await rpcClient.InvokeScriptAsync(script, signers).ConfigureAwait(false); + + var tx = new Transaction + { + Version = 0, + Nonce = (uint)new Random().Next(), + Script = script, + Signers = signers ?? Array.Empty(), + ValidUntilBlock = blockCount - 1 + Transaction.MaxValidUntilBlockIncrement, + SystemFee = long.Parse(invokeResult.GasConsumed), + Attributes = attributes ?? Array.Empty(), + }; + + return new TransactionManager(tx, rpcClient, magic); + } + } +} diff --git a/src/RpcClient/WalletAPI.cs b/src/RpcClient/WalletAPI.cs index 014aba6ec..b4cef3c55 100644 --- a/src/RpcClient/WalletAPI.cs +++ b/src/RpcClient/WalletAPI.cs @@ -37,10 +37,10 @@ public WalletAPI(RpcClient rpc) /// address, scripthash or public key string /// Example: address ("Ncm9TEzrp8SSer6Wa3UCSLTRnqzwVhCfuE"), scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") /// - public decimal GetUnclaimedGas(string account) + public Task GetUnclaimedGasAsync(string account) { UInt160 accountHash = Utility.GetScriptHash(account); - return GetUnclaimedGas(accountHash); + return GetUnclaimedGasAsync(accountHash); } /// @@ -48,11 +48,12 @@ public decimal GetUnclaimedGas(string account) /// /// account scripthash /// - public decimal GetUnclaimedGas(UInt160 account) + public async Task GetUnclaimedGasAsync(UInt160 account) { UInt160 scriptHash = NativeContract.NEO.Hash; - BigInteger balance = nep5API.TestInvoke(scriptHash, "unclaimedGas", account, rpcClient.GetBlockCount() - 1) - .Stack.Single().GetInteger(); + var blockCount = await rpcClient.GetBlockCountAsync().ConfigureAwait(false); + var result = await nep5API.TestInvokeAsync(scriptHash, "unclaimedGas", account, blockCount - 1).ConfigureAwait(false); + BigInteger balance = result.Stack.Single().GetInteger(); return ((decimal)balance) / (long)NativeContract.GAS.Factor; } @@ -62,9 +63,9 @@ public decimal GetUnclaimedGas(UInt160 account) /// address, scripthash or public key string /// Example: address ("Ncm9TEzrp8SSer6Wa3UCSLTRnqzwVhCfuE"), scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") /// - public uint GetNeoBalance(string account) + public async Task GetNeoBalanceAsync(string account) { - BigInteger balance = GetTokenBalance(NativeContract.NEO.Hash.ToString(), account); + BigInteger balance = await GetTokenBalanceAsync(NativeContract.NEO.Hash.ToString(), account).ConfigureAwait(false); return (uint)balance; } @@ -74,9 +75,9 @@ public uint GetNeoBalance(string account) /// address, scripthash or public key string /// Example: address ("Ncm9TEzrp8SSer6Wa3UCSLTRnqzwVhCfuE"), scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") /// - public decimal GetGasBalance(string account) + public async Task GetGasBalanceAsync(string account) { - BigInteger balance = GetTokenBalance(NativeContract.GAS.Hash.ToString(), account); + BigInteger balance = await GetTokenBalanceAsync(NativeContract.GAS.Hash.ToString(), account).ConfigureAwait(false); return ((decimal)balance) / (long)NativeContract.GAS.Factor; } @@ -87,11 +88,11 @@ public decimal GetGasBalance(string account) /// address, scripthash or public key string /// Example: address ("Ncm9TEzrp8SSer6Wa3UCSLTRnqzwVhCfuE"), scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8"), public key ("02f9ec1fd0a98796cf75b586772a4ddd41a0af07a1dbdf86a7238f74fb72503575") /// - public BigInteger GetTokenBalance(string tokenHash, string account) + public Task GetTokenBalanceAsync(string tokenHash, string account) { UInt160 scriptHash = Utility.GetScriptHash(tokenHash); UInt160 accountHash = Utility.GetScriptHash(account); - return nep5API.BalanceOf(scriptHash, accountHash); + return nep5API.BalanceOfAsync(scriptHash, accountHash); } /// @@ -101,10 +102,10 @@ public BigInteger GetTokenBalance(string tokenHash, string account) /// wif or private key /// Example: WIF ("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"), PrivateKey ("450d6c2a04b5b470339a745427bae6828400cf048400837d73c415063835e005") /// The transaction sended - public Transaction ClaimGas(string key) + public Task ClaimGasAsync(string key) { KeyPair keyPair = Utility.GetKeyPair(key); - return ClaimGas(keyPair); + return ClaimGasAsync(keyPair); } /// @@ -113,12 +114,12 @@ public Transaction ClaimGas(string key) /// /// keyPair /// The transaction sended - public Transaction ClaimGas(KeyPair keyPair) + public async Task ClaimGasAsync(KeyPair keyPair) { UInt160 toHash = Contract.CreateSignatureRedeemScript(keyPair.PublicKey).ToScriptHash(); - BigInteger balance = nep5API.BalanceOf(NativeContract.NEO.Hash, toHash); - Transaction transaction = nep5API.CreateTransferTx(NativeContract.NEO.Hash, keyPair, toHash, balance); - rpcClient.SendRawTransaction(transaction); + BigInteger balance = await nep5API.BalanceOfAsync(NativeContract.NEO.Hash, toHash).ConfigureAwait(false); + Transaction transaction = await nep5API.CreateTransferTxAsync(NativeContract.NEO.Hash, keyPair, toHash, balance).ConfigureAwait(false); + await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } @@ -131,15 +132,15 @@ public Transaction ClaimGas(KeyPair keyPair) /// address or account script hash /// token amount /// - public Transaction Transfer(string tokenHash, string fromKey, string toAddress, decimal amount) + public async Task TransferAsync(string tokenHash, string fromKey, string toAddress, decimal amount) { UInt160 scriptHash = Utility.GetScriptHash(tokenHash); - var decimals = nep5API.Decimals(scriptHash); + var decimals = await nep5API.DecimalsAsync(scriptHash).ConfigureAwait(false); KeyPair from = Utility.GetKeyPair(fromKey); UInt160 to = Utility.GetScriptHash(toAddress); BigInteger amountInteger = amount.ToBigInteger(decimals); - return Transfer(scriptHash, from, to, amountInteger); + return await TransferAsync(scriptHash, from, to, amountInteger).ConfigureAwait(false); } /// @@ -150,10 +151,10 @@ public Transaction Transfer(string tokenHash, string fromKey, string toAddress, /// to account script hash /// transfer amount /// - public Transaction Transfer(UInt160 scriptHash, KeyPair from, UInt160 to, BigInteger amountInteger) + public async Task TransferAsync(UInt160 scriptHash, KeyPair from, UInt160 to, BigInteger amountInteger) { - Transaction transaction = nep5API.CreateTransferTx(scriptHash, from, to, amountInteger); - rpcClient.SendRawTransaction(transaction); + Transaction transaction = await nep5API.CreateTransferTxAsync(scriptHash, from, to, amountInteger).ConfigureAwait(false); + await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } @@ -167,10 +168,10 @@ public Transaction Transfer(UInt160 scriptHash, KeyPair from, UInt160 to, BigInt /// to account /// transfer amount /// - public Transaction Transfer(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] keys, UInt160 to, BigInteger amountInteger) + public async Task TransferAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] keys, UInt160 to, BigInteger amountInteger) { - Transaction transaction = nep5API.CreateTransferTx(scriptHash, m, pubKeys, keys, to, amountInteger); - rpcClient.SendRawTransaction(transaction); + Transaction transaction = await nep5API.CreateTransferTxAsync(scriptHash, m, pubKeys, keys, to, amountInteger).ConfigureAwait(false); + await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } @@ -180,7 +181,7 @@ public Transaction Transfer(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPai /// the transaction to observe /// TimeoutException throws after "timeout" seconds /// the Transaction state, including vmState and blockhash - public async Task WaitTransaction(Transaction transaction, int timeout = 60) + public async Task WaitTransactionAsync(Transaction transaction, int timeout = 60) { DateTime deadline = DateTime.UtcNow.AddSeconds(timeout); RpcTransaction rpcTx = null; @@ -193,7 +194,7 @@ public async Task WaitTransaction(Transaction transaction, int t try { - rpcTx = rpcClient.GetRawTransaction(transaction.Hash.ToString()); + rpcTx = await rpcClient.GetRawTransactionAsync(transaction.Hash.ToString()).ConfigureAwait(false); if (rpcTx == null || rpcTx.Confirmations == null) { await Task.Delay((int)Blockchain.MillisecondsPerBlock / 2); diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 845741690..f1a7b9e07 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -1,6 +1,6 @@ [ { - "Name": "sendrawtransactionerror", + "Name": "sendrawtransactionasyncerror", "Request": { "jsonrpc": "2.0", "method": "sendrawtransaction", @@ -18,7 +18,7 @@ } }, { - "Name": "getbestblockhash", + "Name": "getbestblockhashasync", "Request": { "jsonrpc": "2.0", "method": "getbestblockhash", @@ -32,7 +32,7 @@ } }, { - "Name": "getblockhex", + "Name": "getblockhexasync", "Request": { "jsonrpc": "2.0", "method": "getblock", @@ -46,7 +46,7 @@ } }, { - "Name": "getblockhex", + "Name": "getblockhexasync", "Request": { "jsonrpc": "2.0", "method": "getblock", @@ -60,7 +60,7 @@ } }, { - "Name": "getblock", + "Name": "getblockasync", "Request": { "jsonrpc": "2.0", "method": "getblock", @@ -121,7 +121,7 @@ } }, { - "Name": "getblock", + "Name": "getblockasync", "Request": { "jsonrpc": "2.0", "method": "getblock", @@ -182,7 +182,7 @@ } }, { - "Name": "getblockcount", + "Name": "getblockcountasync", "Request": { "jsonrpc": "2.0", "method": "getblockcount", @@ -196,7 +196,7 @@ } }, { - "Name": "getblockhash", + "Name": "getblockhashasync", "Request": { "jsonrpc": "2.0", "method": "getblockhash", @@ -210,7 +210,7 @@ } }, { - "Name": "getblockheaderhex", + "Name": "getblockheaderhexasync", "Request": { "jsonrpc": "2.0", "method": "getblockheader", @@ -224,7 +224,7 @@ } }, { - "Name": "getblockheaderhex", + "Name": "getblockheaderhexasync", "Request": { "jsonrpc": "2.0", "method": "getblockheader", @@ -238,7 +238,7 @@ } }, { - "Name": "getblockheader", + "Name": "getblockheaderasync", "Request": { "jsonrpc": "2.0", "method": "getblockheader", @@ -269,7 +269,7 @@ } }, { - "Name": "getblockheader", + "Name": "getblockheaderasync", "Request": { "jsonrpc": "2.0", "method": "getblockheader", @@ -300,7 +300,7 @@ } }, { - "Name": "getblocksysfee", + "Name": "getblocksysfeeasync", "Request": { "jsonrpc": "2.0", "method": "getblocksysfee", @@ -314,7 +314,7 @@ } }, { - "Name": "getcontractstate", + "Name": "getcontractstateasync", "Request": { "jsonrpc": "2.0", "method": "getcontractstate", @@ -458,7 +458,7 @@ } }, { - "Name": "getrawmempool", + "Name": "getrawmempoolasync", "Request": { "jsonrpc": "2.0", "method": "getrawmempool", @@ -472,7 +472,7 @@ } }, { - "Name": "getrawmempoolboth", + "Name": "getrawmempoolbothasync", "Request": { "jsonrpc": "2.0", "method": "getrawmempool", @@ -490,7 +490,7 @@ } }, { - "Name": "getrawtransactionhex", + "Name": "getrawtransactionhexasync", "Request": { "jsonrpc": "2.0", "method": "getrawtransaction", @@ -504,7 +504,7 @@ } }, { - "Name": "getrawtransaction", + "Name": "getrawtransactionasync", "Request": { "jsonrpc": "2.0", "method": "getrawtransaction", @@ -545,7 +545,7 @@ } }, { - "Name": "getstorage", + "Name": "getstorageasync", "Request": { "jsonrpc": "2.0", "method": "getstorage", @@ -559,7 +559,7 @@ } }, { - "Name": "getstorage", + "Name": "getstorageasync", "Request": { "jsonrpc": "2.0", "method": "getstorage", @@ -573,7 +573,7 @@ } }, { - "Name": "gettransactionheight", + "Name": "gettransactionheightasync", "Request": { "jsonrpc": "2.0", "method": "gettransactionheight", @@ -587,7 +587,7 @@ } }, { - "Name": "getnextblockvalidators", + "Name": "getnextblockvalidatorsasync", "Request": { "jsonrpc": "2.0", "method": "getnextblockvalidators", @@ -609,7 +609,7 @@ { - "Name": "getconnectioncount", + "Name": "getconnectioncountasync", "Request": { "jsonrpc": "2.0", "method": "getconnectioncount", @@ -623,7 +623,7 @@ } }, { - "Name": "getpeers", + "Name": "getpeersasync", "Request": { "jsonrpc": "2.0", "method": "getpeers", @@ -655,7 +655,7 @@ } }, { - "Name": "getversion", + "Name": "getversionasync", "Request": { "jsonrpc": "2.0", "method": "getversion", @@ -674,7 +674,7 @@ } }, { - "Name": "sendrawtransaction", + "Name": "sendrawtransactionasync", "Request": { "jsonrpc": "2.0", "method": "sendrawtransaction", @@ -690,7 +690,7 @@ } }, { - "Name": "submitblock", + "Name": "submitblockasync", "Request": { "jsonrpc": "2.0", "method": "submitblock", @@ -708,7 +708,7 @@ { - "Name": "invokefunction", + "Name": "invokefunctionasync", "Request": { "jsonrpc": "2.0", "method": "invokefunction", @@ -742,7 +742,7 @@ } }, { - "Name": "invokescript", + "Name": "invokescriptasync", "Request": { "jsonrpc": "2.0", "method": "invokescript", @@ -822,7 +822,7 @@ }, { - "Name": "getunclaimedgas", + "Name": "getunclaimedgasasync", "Request": { "jsonrpc": "2.0", "method": "getunclaimedgas", @@ -840,7 +840,7 @@ }, { - "Name": "listplugins", + "Name": "listpluginsasync", "Request": { "jsonrpc": "2.0", "method": "listplugins", @@ -881,7 +881,7 @@ } }, { - "Name": "validateaddress", + "Name": "validateaddressasync", "Request": { "jsonrpc": "2.0", "method": "validateaddress", @@ -900,7 +900,7 @@ { - "Name": "closewallet", + "Name": "closewalletasync", "Request": { "jsonrpc": "2.0", "method": "closewallet", @@ -914,7 +914,7 @@ } }, { - "Name": "dumpprivkey", + "Name": "dumpprivkeyasync", "Request": { "jsonrpc": "2.0", "method": "dumpprivkey", @@ -928,7 +928,7 @@ } }, { - "Name": "invokescript", + "Name": "invokescriptasync", "Request": { "jsonrpc": "2.0", "method": "invokescript", @@ -953,7 +953,7 @@ } }, { - "Name": "getnewaddress", + "Name": "getnewaddressasync", "Request": { "jsonrpc": "2.0", "method": "getnewaddress", @@ -967,7 +967,7 @@ } }, { - "Name": "getwalletbalance", + "Name": "getwalletbalanceasync", "Request": { "jsonrpc": "2.0", "method": "getwalletbalance", @@ -983,7 +983,7 @@ } }, { - "Name": "getwalletunclaimedgas", + "Name": "getwalletunclaimedgasasync", "Request": { "jsonrpc": "2.0", "method": "getwalletunclaimedgas", @@ -997,7 +997,7 @@ } }, { - "Name": "importprivkey", + "Name": "importprivkeyasync", "Request": { "jsonrpc": "2.0", "method": "importprivkey", @@ -1016,7 +1016,7 @@ } }, { - "Name": "listaddress", + "Name": "listaddressasync", "Request": { "jsonrpc": "2.0", "method": "listaddress", @@ -1043,7 +1043,7 @@ } }, { - "Name": "openwallet", + "Name": "openwalletasync", "Request": { "jsonrpc": "2.0", "method": "openwallet", @@ -1057,7 +1057,7 @@ } }, { - "Name": "sendfrom", + "Name": "sendfromasync", "Request": { "jsonrpc": "2.0", "method": "sendfrom", @@ -1094,7 +1094,7 @@ } }, { - "Name": "sendmany", + "Name": "sendmanyasync", "Request": { "jsonrpc": "2.0", "method": "sendmany", @@ -1153,7 +1153,7 @@ } }, { - "Name": "sendtoaddress", + "Name": "sendtoaddressasync", "Request": { "jsonrpc": "2.0", "method": "sendtoaddress", @@ -1196,7 +1196,7 @@ { - "Name": "getapplicationlog", + "Name": "getapplicationlogasync", "Request": { "jsonrpc": "2.0", "method": "getapplicationlog", @@ -1359,7 +1359,7 @@ } }, { - "Name": "getnep5transfers", + "Name": "getnep5transfersasync", "Request": { "jsonrpc": "2.0", "method": "getnep5transfers", @@ -1406,7 +1406,7 @@ } }, { - "Name": "getnep5balances", + "Name": "getnep5balancesasync", "Request": { "jsonrpc": "2.0", "method": "getnep5balances", diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index dfdbf9990..2a120fad4 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Neo.SmartContract; @@ -24,19 +25,19 @@ public void TestSetup() } [TestMethod] - public void TestInvoke() + public async Task TestInvoke() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.ByteArray, Value = "00e057eb481b".HexToBytes() }); ContractClient contractClient = new ContractClient(rpcClientMock.Object); - var result = contractClient.TestInvoke(NativeContract.GAS.Hash, "balanceOf", UInt160.Zero); + var result = await contractClient.TestInvokeAsync(NativeContract.GAS.Hash, "balanceOf", UInt160.Zero); Assert.AreEqual(30000000000000L, (long)result.Stack[0].GetInteger()); } [TestMethod] - public void TestDeployContract() + public async Task TestDeployContract() { byte[] script; var manifest = new ContractManifest() @@ -64,7 +65,7 @@ public void TestDeployContract() UT_TransactionManager.MockInvokeScript(rpcClientMock, script, new ContractParameter()); ContractClient contractClient = new ContractClient(rpcClientMock.Object); - var result = contractClient.CreateDeployContractTx(new byte[1], manifest, keyPair1); + var result = await contractClient.CreateDeployContractTxAsync(new byte[1], manifest, keyPair1); Assert.IsNotNull(result); } diff --git a/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs b/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs index 8454d4afa..12f0142c9 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs @@ -6,6 +6,7 @@ using Neo.Wallets; using System.Linq; using System.Numerics; +using System.Threading.Tasks; namespace Neo.Network.RPC.Tests { @@ -27,57 +28,57 @@ public void TestSetup() } [TestMethod] - public void TestBalanceOf() + public async Task TestBalanceOf() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(10000) }); - var balance = nep5API.BalanceOf(NativeContract.GAS.Hash, UInt160.Zero); + var balance = await nep5API.BalanceOfAsync(NativeContract.GAS.Hash, UInt160.Zero); Assert.AreEqual(10000, (int)balance); } [TestMethod] - public void TestGetName() + public async Task TestGetName() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("name"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Name }); - var result = nep5API.Name(NativeContract.GAS.Hash); + var result = await nep5API.NameAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Name, result); } [TestMethod] - public void TestGetSymbol() + public async Task TestGetSymbol() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("symbol"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol }); - var result = nep5API.Symbol(NativeContract.GAS.Hash); + var result = await nep5API.SymbolAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Symbol, result); } [TestMethod] - public void TestGetDecimals() + public async Task TestGetDecimals() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("decimals"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }); - var result = nep5API.Decimals(NativeContract.GAS.Hash); + var result = await nep5API.DecimalsAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Decimals, result); } [TestMethod] - public void TestGetTotalSupply() + public async Task TestGetTotalSupply() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("totalSupply"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - var result = nep5API.TotalSupply(NativeContract.GAS.Hash); + var result = await nep5API.TotalSupplyAsync(NativeContract.GAS.Hash); Assert.AreEqual(1_00000000, (int)result); } [TestMethod] - public void TestGetTokenInfo() + public async Task TestGetTokenInfo() { UInt160 scriptHash = NativeContract.GAS.Hash; byte[] testScript = scriptHash.MakeScript("name") @@ -91,7 +92,7 @@ public void TestGetTokenInfo() new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - var result = nep5API.GetTokenInfo(NativeContract.GAS.Hash); + var result = await nep5API.GetTokenInfoAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Name, result.Name); Assert.AreEqual(NativeContract.GAS.Symbol, result.Symbol); Assert.AreEqual(8, (int)result.Decimals); @@ -99,12 +100,12 @@ public void TestGetTokenInfo() } [TestMethod] - public void TestTransfer() + public async Task TestTransfer() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000)); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter()); - var result = nep5API.CreateTransferTx(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); + var result = await nep5API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); Assert.IsNotNull(result); } } diff --git a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs index b6a8bdd01..546e250e1 100644 --- a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs @@ -5,6 +5,7 @@ using Neo.VM; using Neo.Wallets; using System.Numerics; +using System.Threading.Tasks; namespace Neo.Network.RPC.Tests { @@ -26,42 +27,42 @@ public void TestSetup() } [TestMethod] - public void TestGetMaxTransactionsPerBlock() + public async Task TestGetMaxTransactionsPerBlock() { byte[] testScript = NativeContract.Policy.Hash.MakeScript("getMaxTransactionsPerBlock"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(512) }); - var result = policyAPI.GetMaxTransactionsPerBlock(); + var result = await policyAPI.GetMaxTransactionsPerBlockAsync(); Assert.AreEqual(512u, result); } [TestMethod] - public void TestGetMaxBlockSize() + public async Task TestGetMaxBlockSize() { byte[] testScript = NativeContract.Policy.Hash.MakeScript("getMaxBlockSize"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1024u * 256u) }); - var result = policyAPI.GetMaxBlockSize(); + var result = await policyAPI.GetMaxBlockSizeAsync(); Assert.AreEqual(1024u * 256u, result); } [TestMethod] - public void TestGetFeePerByte() + public async Task TestGetFeePerByte() { byte[] testScript = NativeContract.Policy.Hash.MakeScript("getFeePerByte"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1000) }); - var result = policyAPI.GetFeePerByte(); + var result = await policyAPI.GetFeePerByteAsync(); Assert.AreEqual(1000L, result); } [TestMethod] - public void TestGetBlockedAccounts() + public async Task TestGetBlockedAccounts() { byte[] testScript = NativeContract.Policy.Hash.MakeScript("getBlockedAccounts"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Array, Value = new[] { new ContractParameter { Type = ContractParameterType.Hash160, Value = UInt160.Zero } } }); - var result = policyAPI.GetBlockedAccounts(); + var result = await policyAPI.GetBlockedAccountsAsync(); Assert.AreEqual(UInt160.Zero, result[0]); } } diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs index 1c4287d91..dd38fd9fe 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs @@ -27,12 +27,8 @@ public void TestSetup() handlerMock = new Mock(MockBehavior.Strict); // use real http client with mocked handler here - var httpClient = new HttpClient(handlerMock.Object) - { - BaseAddress = new Uri("http://seed1.neo.org:10331"), - }; - - rpc = new RpcClient(httpClient); + var httpClient = new HttpClient(handlerMock.Object); + rpc = new RpcClient(httpClient, "http://seed1.neo.org:10331"); foreach (var test in TestUtils.RpcTestCases) { MockResponse(test.Request, test.Response); @@ -58,12 +54,12 @@ private void MockResponse(RpcRequest request, RpcResponse response) } [TestMethod] - public void TestErrorResponse() + public async Task TestErrorResponse() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == (nameof(rpc.SendRawTransaction) + "error").ToLower()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == (nameof(rpc.SendRawTransactionAsync) + "error").ToLower()); try { - var result = rpc.SendRawTransaction(test.Request.Params[0].AsString().HexToBytes().AsSerializable()); + var result = await rpc.SendRawTransactionAsync(test.Request.Params[0].AsString().HexToBytes().AsSerializable()); } catch (RpcException ex) { @@ -91,137 +87,137 @@ public void TestConstructorWithBasicAuth() #region Blockchain [TestMethod] - public void TestGetBestBlockHash() + public async Task TestGetBestBlockHash() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetBestBlockHash).ToLower()); - var result = rpc.GetBestBlockHash(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetBestBlockHashAsync).ToLower()); + var result = await rpc.GetBestBlockHashAsync(); Assert.AreEqual(test.Response.Result.AsString(), result); } [TestMethod] - public void TestGetBlockHex() + public async Task TestGetBlockHex() { - var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlockHex).ToLower()); + var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlockHexAsync).ToLower()); foreach (var test in tests) { - var result = rpc.GetBlockHex(test.Request.Params[0].AsString()); + var result = await rpc.GetBlockHexAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.AsString(), result); } } [TestMethod] - public void TestGetBlock() + public async Task TestGetBlock() { - var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlock).ToLower()); + var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlockAsync).ToLower()); foreach (var test in tests) { - var result = rpc.GetBlock(test.Request.Params[0].AsString()); + var result = await rpc.GetBlockAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.AsString(), result.ToJson().ToString()); } } [TestMethod] - public void TestGetBlockCount() + public async Task TestGetBlockCount() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetBlockCount).ToLower()); - var result = rpc.GetBlockCount(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetBlockCountAsync).ToLower()); + var result = await rpc.GetBlockCountAsync(); Assert.AreEqual(test.Response.Result.AsString(), result.ToString()); } [TestMethod] - public void TestGetBlockHash() + public async Task TestGetBlockHash() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetBlockHash).ToLower()); - var result = rpc.GetBlockHash((int)test.Request.Params[0].AsNumber()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetBlockHashAsync).ToLower()); + var result = await rpc.GetBlockHashAsync((int)test.Request.Params[0].AsNumber()); Assert.AreEqual(test.Response.Result.AsString(), result.ToString()); } [TestMethod] - public void TestGetBlockHeaderHex() + public async Task TestGetBlockHeaderHex() { - var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlockHeaderHex).ToLower()); + var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlockHeaderHexAsync).ToLower()); foreach (var test in tests) { - var result = rpc.GetBlockHeaderHex(test.Request.Params[0].AsString()); + var result = await rpc.GetBlockHeaderHexAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.AsString(), result); } } [TestMethod] - public void TestGetBlockHeader() + public async Task TestGetBlockHeader() { - var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlockHeader).ToLower()); + var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetBlockHeaderAsync).ToLower()); foreach (var test in tests) { - var result = rpc.GetBlockHeader(test.Request.Params[0].AsString()); + var result = await rpc.GetBlockHeaderAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } } [TestMethod] - public void TestGetContractState() + public async Task TestGetContractState() { - var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetContractState).ToLower()); + var tests = TestUtils.RpcTestCases.Where(p => p.Name == nameof(rpc.GetContractStateAsync).ToLower()); foreach (var test in tests) { - var result = rpc.GetContractState(test.Request.Params[0].AsString()); + var result = await rpc.GetContractStateAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } } [TestMethod] - public void TestGetRawMempool() + public async Task TestGetRawMempool() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawMempool).ToLower()); - var result = rpc.GetRawMempool(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawMempoolAsync).ToLower()); + var result = await rpc.GetRawMempoolAsync(); Assert.AreEqual(test.Response.Result.ToString(), ((JArray)result.Select(p => (JObject)p).ToArray()).ToString()); } [TestMethod] - public void TestGetRawMempoolBoth() + public async Task TestGetRawMempoolBoth() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawMempoolBoth).ToLower()); - var result = rpc.GetRawMempoolBoth(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawMempoolBothAsync).ToLower()); + var result = await rpc.GetRawMempoolBothAsync(); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod] - public void TestGetRawTransactionHex() + public async Task TestGetRawTransactionHex() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawTransactionHex).ToLower()); - var result = rpc.GetRawTransactionHex(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawTransactionHexAsync).ToLower()); + var result = await rpc.GetRawTransactionHexAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.AsString(), result); } [TestMethod] - public void TestGetRawTransaction() + public async Task TestGetRawTransaction() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawTransaction).ToLower()); - var result = rpc.GetRawTransaction(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetRawTransactionAsync).ToLower()); + var result = await rpc.GetRawTransactionAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod] - public void TestGetStorage() + public async Task TestGetStorage() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetStorage).ToLower()); - var result = rpc.GetStorage(test.Request.Params[0].AsString(), test.Request.Params[1].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetStorageAsync).ToLower()); + var result = await rpc.GetStorageAsync(test.Request.Params[0].AsString(), test.Request.Params[1].AsString()); Assert.AreEqual(test.Response.Result.AsString(), result); } [TestMethod] - public void TestGetTransactionHeight() + public async Task TestGetTransactionHeight() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetTransactionHeight).ToLower()); - var result = rpc.GetTransactionHeight(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetTransactionHeightAsync).ToLower()); + var result = await rpc.GetTransactionHeightAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToString()); } [TestMethod] - public void TestGetNextBlockValidators() + public async Task TestGetNextBlockValidators() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNextBlockValidators).ToLower()); - var result = rpc.GetNextBlockValidators(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNextBlockValidatorsAsync).ToLower()); + var result = await rpc.GetNextBlockValidatorsAsync(); Assert.AreEqual(test.Response.Result.ToString(), ((JArray)result.Select(p => p.ToJson()).ToArray()).ToString()); } @@ -230,43 +226,43 @@ public void TestGetNextBlockValidators() #region Node [TestMethod] - public void TestGetConnectionCount() + public async Task TestGetConnectionCount() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetConnectionCount).ToLower()); - var result = rpc.GetConnectionCount(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetConnectionCountAsync).ToLower()); + var result = await rpc.GetConnectionCountAsync(); Assert.AreEqual(test.Response.Result.ToString(), result.ToString()); } [TestMethod] - public void TestGetPeers() + public async Task TestGetPeers() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetPeers).ToLower()); - var result = rpc.GetPeers(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetPeersAsync).ToLower()); + var result = await rpc.GetPeersAsync(); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod] - public void TestGetVersion() + public async Task TestGetVersion() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetVersion).ToLower()); - var result = rpc.GetVersion(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetVersionAsync).ToLower()); + var result = await rpc.GetVersionAsync(); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod] - public void TestSendRawTransaction() + public async Task TestSendRawTransaction() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendRawTransaction).ToLower()); - var result = rpc.SendRawTransaction(test.Request.Params[0].AsString().HexToBytes().AsSerializable()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendRawTransactionAsync).ToLower()); + var result = await rpc.SendRawTransactionAsync(test.Request.Params[0].AsString().HexToBytes().AsSerializable()); Assert.AreEqual(test.Response.Result["hash"].AsString(), result.ToString()); } [TestMethod] - public void TestSubmitBlock() + public async Task TestSubmitBlock() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SubmitBlock).ToLower()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SubmitBlockAsync).ToLower()); var block = TestUtils.GetBlock(2).Hash; - var result = rpc.SubmitBlock(test.Request.Params[0].AsString().HexToBytes()); + var result = await rpc.SubmitBlockAsync(test.Request.Params[0].AsString().HexToBytes()); Assert.AreEqual(test.Response.Result["hash"].AsString(), result.ToString()); } @@ -275,27 +271,27 @@ public void TestSubmitBlock() #region SmartContract [TestMethod] - public void TestInvokeFunction() + public async Task TestInvokeFunction() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.InvokeFunction).ToLower()); - var result = rpc.InvokeFunction(test.Request.Params[0].AsString(), test.Request.Params[1].AsString(), + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.InvokeFunctionAsync).ToLower()); + var result = await rpc.InvokeFunctionAsync(test.Request.Params[0].AsString(), test.Request.Params[1].AsString(), ((JArray)test.Request.Params[2]).Select(p => RpcStack.FromJson(p)).ToArray()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod] - public void TestInvokeScript() + public async Task TestInvokeScript() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.InvokeScript).ToLower()); - var result = rpc.InvokeScript(test.Request.Params[0].AsString().HexToBytes()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.InvokeScriptAsync).ToLower()); + var result = await rpc.InvokeScriptAsync(test.Request.Params[0].AsString().HexToBytes()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod] - public void TestGetUnclaimedGas() + public async Task TestGetUnclaimedGas() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetUnclaimedGas).ToLower()); - var result = rpc.GetUnclaimedGas(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetUnclaimedGasAsync).ToLower()); + var result = await rpc.GetUnclaimedGasAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result["unclaimed"].AsString(), result.Unclaimed.ToString()); } @@ -304,18 +300,18 @@ public void TestGetUnclaimedGas() #region Utilities [TestMethod] - public void TestListPlugins() + public async Task TestListPlugins() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ListPlugins).ToLower()); - var result = rpc.ListPlugins(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ListPluginsAsync).ToLower()); + var result = await rpc.ListPluginsAsync(); Assert.AreEqual(test.Response.Result.ToString(), ((JArray)result.Select(p => p.ToJson()).ToArray()).ToString()); } [TestMethod] - public void TestValidateAddress() + public async Task TestValidateAddress() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ValidateAddress).ToLower()); - var result = rpc.ValidateAddress(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ValidateAddressAsync).ToLower()); + var result = await rpc.ValidateAddressAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } @@ -324,91 +320,91 @@ public void TestValidateAddress() #region Wallet [TestMethod] - public void TestCloseWallet() + public async Task TestCloseWallet() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.CloseWallet).ToLower()); - var result = rpc.CloseWallet(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.CloseWalletAsync).ToLower()); + var result = await rpc.CloseWalletAsync(); Assert.AreEqual(test.Response.Result.AsBoolean(), result); } [TestMethod] - public void TestDumpPrivKey() + public async Task TestDumpPrivKey() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.DumpPrivKey).ToLower()); - var result = rpc.DumpPrivKey(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.DumpPrivKeyAsync).ToLower()); + var result = await rpc.DumpPrivKeyAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.AsString(), result); } [TestMethod] - public void TestGetNewAddress() + public async Task TestGetNewAddress() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNewAddress).ToLower()); - var result = rpc.GetNewAddress(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNewAddressAsync).ToLower()); + var result = await rpc.GetNewAddressAsync(); Assert.AreEqual(test.Response.Result.AsString(), result); } [TestMethod] - public void TestGetWalletBalance() + public async Task TestGetWalletBalance() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetWalletBalance).ToLower()); - var result = rpc.GetWalletBalance(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetWalletBalanceAsync).ToLower()); + var result = await rpc.GetWalletBalanceAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result["balance"].AsString(), result.Value.ToString()); } [TestMethod] - public void TestGetWalletUnclaimedGas() + public async Task TestGetWalletUnclaimedGas() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetWalletUnclaimedGas).ToLower()); - var result = rpc.GetWalletUnclaimedGas(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetWalletUnclaimedGasAsync).ToLower()); + var result = await rpc.GetWalletUnclaimedGasAsync(); Assert.AreEqual(test.Response.Result.AsString(), result.ToString()); } [TestMethod] - public void TestImportPrivKey() + public async Task TestImportPrivKey() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ImportPrivKey).ToLower()); - var result = rpc.ImportPrivKey(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ImportPrivKeyAsync).ToLower()); + var result = await rpc.ImportPrivKeyAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod] - public void TestListAddress() + public async Task TestListAddress() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ListAddress).ToLower()); - var result = rpc.ListAddress(); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.ListAddressAsync).ToLower()); + var result = await rpc.ListAddressAsync(); Assert.AreEqual(test.Response.Result.ToString(), ((JArray)result.Select(p => p.ToJson()).ToArray()).ToString()); } [TestMethod] - public void TestOpenWallet() + public async Task TestOpenWallet() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.OpenWallet).ToLower()); - var result = rpc.OpenWallet(test.Request.Params[0].AsString(), test.Request.Params[1].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.OpenWalletAsync).ToLower()); + var result = await rpc.OpenWalletAsync(test.Request.Params[0].AsString(), test.Request.Params[1].AsString()); Assert.AreEqual(test.Response.Result.AsBoolean(), result); } [TestMethod] - public void TestSendFrom() + public async Task TestSendFrom() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendFrom).ToLower()); - var result = rpc.SendFrom(test.Request.Params[0].AsString(), test.Request.Params[1].AsString(), + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendFromAsync).ToLower()); + var result = await rpc.SendFromAsync(test.Request.Params[0].AsString(), test.Request.Params[1].AsString(), test.Request.Params[2].AsString(), test.Request.Params[3].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToString()); } [TestMethod] - public void TestSendMany() + public async Task TestSendMany() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendMany).ToLower()); - var result = rpc.SendMany(test.Request.Params[0].AsString(), ((JArray)test.Request.Params[1]).Select(p => RpcTransferOut.FromJson(p))); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendManyAsync).ToLower()); + var result = await rpc.SendManyAsync(test.Request.Params[0].AsString(), ((JArray)test.Request.Params[1]).Select(p => RpcTransferOut.FromJson(p))); Assert.AreEqual(test.Response.Result.ToString(), result.ToString()); } [TestMethod] - public void TestSendToAddress() + public async Task TestSendToAddress() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendToAddress).ToLower()); - var result = rpc.SendToAddress(test.Request.Params[0].AsString(), test.Request.Params[1].AsString(), test.Request.Params[2].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.SendToAddressAsync).ToLower()); + var result = await rpc.SendToAddressAsync(test.Request.Params[0].AsString(), test.Request.Params[1].AsString(), test.Request.Params[2].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToString()); } @@ -417,27 +413,27 @@ public void TestSendToAddress() #region Plugins [TestMethod()] - public void GetApplicationLogTest() + public async Task GetApplicationLogTest() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetApplicationLog).ToLower()); - var result = rpc.GetApplicationLog(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetApplicationLogAsync).ToLower()); + var result = await rpc.GetApplicationLogAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod()] - public void GetNep5TransfersTest() + public async Task GetNep5TransfersTest() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5Transfers).ToLower()); - var result = rpc.GetNep5Transfers(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5TransfersAsync).ToLower()); + var result = await rpc.GetNep5TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod()] - public void GetNep5BalancesTest() + public async Task GetNep5BalancesTest() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5Balances).ToLower()); - var result = rpc.GetNep5Balances(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5BalancesAsync).ToLower()); + var result = await rpc.GetNep5BalancesAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs b/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs index 559e1f748..04613dbc1 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs @@ -11,7 +11,7 @@ public class UT_RpcModels [TestMethod()] public void TestRpcAccount() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.ImportPrivKey).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.ImportPrivKeyAsync).ToLower()).Response.Result; var item = RpcAccount.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -19,7 +19,7 @@ public void TestRpcAccount() [TestMethod()] public void TestRpcApplicationLog() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetApplicationLog).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetApplicationLogAsync).ToLower()).Response.Result; var item = RpcApplicationLog.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -27,7 +27,7 @@ public void TestRpcApplicationLog() [TestMethod()] public void TestRpcBlock() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetBlock).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetBlockAsync).ToLower()).Response.Result; var item = RpcBlock.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -35,7 +35,7 @@ public void TestRpcBlock() [TestMethod()] public void TestRpcBlockHeader() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetBlockHeader).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetBlockHeaderAsync).ToLower()).Response.Result; var item = RpcBlockHeader.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -43,7 +43,7 @@ public void TestRpcBlockHeader() [TestMethod()] public void TestGetContractState() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetContractState).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetContractStateAsync).ToLower()).Response.Result; var item = RpcContractState.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -51,7 +51,7 @@ public void TestGetContractState() [TestMethod()] public void TestRpcInvokeResult() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.InvokeFunction).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.InvokeFunctionAsync).ToLower()).Response.Result; var item = RpcInvokeResult.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -59,7 +59,7 @@ public void TestRpcInvokeResult() [TestMethod()] public void TestRpcNep5Balances() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5Balances).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5BalancesAsync).ToLower()).Response.Result; var item = RpcNep5Balances.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -67,7 +67,7 @@ public void TestRpcNep5Balances() [TestMethod()] public void TestRpcNep5Transfers() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5Transfers).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5TransfersAsync).ToLower()).Response.Result; var item = RpcNep5Transfers.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -75,7 +75,7 @@ public void TestRpcNep5Transfers() [TestMethod()] public void TestRpcPeers() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetPeers).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetPeersAsync).ToLower()).Response.Result; var item = RpcPeers.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -83,7 +83,7 @@ public void TestRpcPeers() [TestMethod()] public void TestRpcPlugin() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.ListPlugins).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.ListPluginsAsync).ToLower()).Response.Result; var item = ((JArray)json).Select(p => RpcPlugin.FromJson(p)); Assert.AreEqual(json.ToString(), ((JArray)item.Select(p => p.ToJson()).ToArray()).ToString()); } @@ -91,7 +91,7 @@ public void TestRpcPlugin() [TestMethod()] public void TestRpcRawMemPool() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetRawMempoolBoth).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetRawMempoolBothAsync).ToLower()).Response.Result; var item = RpcRawMemPool.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -99,7 +99,7 @@ public void TestRpcRawMemPool() [TestMethod()] public void TestRpcTransaction() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetRawTransaction).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetRawTransactionAsync).ToLower()).Response.Result; var item = RpcTransaction.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -107,7 +107,7 @@ public void TestRpcTransaction() [TestMethod()] public void TestRpcTransferOut() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.SendMany).ToLower()).Request.Params[1]; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.SendManyAsync).ToLower()).Request.Params[1]; var item = ((JArray)json).Select(p => RpcTransferOut.FromJson(p)); Assert.AreEqual(json.ToString(), ((JArray)item.Select(p => p.ToJson()).ToArray()).ToString()); } @@ -115,7 +115,7 @@ public void TestRpcTransferOut() [TestMethod()] public void TestRpcValidateAddressResult() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.ValidateAddress).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.ValidateAddressAsync).ToLower()).Response.Result; var item = RpcValidateAddressResult.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } @@ -123,7 +123,7 @@ public void TestRpcValidateAddressResult() [TestMethod()] public void TestRpcValidator() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNextBlockValidators).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNextBlockValidatorsAsync).ToLower()).Response.Result; var item = ((JArray)json).Select(p => RpcValidator.FromJson(p)); Assert.AreEqual(json.ToString(), ((JArray)item.Select(p => p.ToJson()).ToArray()).ToString()); } @@ -131,7 +131,7 @@ public void TestRpcValidator() [TestMethod()] public void TestRpcVersion() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetVersion).ToLower()).Response.Result; + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetVersionAsync).ToLower()).Response.Result; var item = RpcVersion.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index a9802fec0..c5d8a1d4b 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -14,6 +14,7 @@ using System; using System.Linq; using System.Numerics; +using System.Threading.Tasks; namespace Neo.Network.RPC.Tests { @@ -44,13 +45,13 @@ public static Mock MockRpcClient(UInt160 sender, byte[] script) var mockRpc = new Mock(MockBehavior.Strict, "http://seed1.neo.org:10331", null, null); // MockHeight - mockRpc.Setup(p => p.RpcSend("getblockcount")).Returns(100).Verifiable(); + mockRpc.Setup(p => p.RpcSendAsync("getblockcount")).ReturnsAsync(100).Verifiable(); // calculatenetworkfee var networkfee = new JObject(); networkfee["networkfee"] = 100000000; - mockRpc.Setup(p => p.RpcSend("calculatenetworkfee", It.Is(u => true))) - .Returns(networkfee) + mockRpc.Setup(p => p.RpcSendAsync("calculatenetworkfee", It.Is(u => true))) + .ReturnsAsync(networkfee) .Verifiable(); // MockGasBalance @@ -77,13 +78,13 @@ public static Mock MockMultiSig(UInt160 multiHash, byte[] script) var mockRpc = new Mock(MockBehavior.Strict, "http://seed1.neo.org:10331", null, null); // MockHeight - mockRpc.Setup(p => p.RpcSend("getblockcount")).Returns(100).Verifiable(); + mockRpc.Setup(p => p.RpcSendAsync("getblockcount")).ReturnsAsync(100).Verifiable(); // calculatenetworkfee var networkfee = new JObject(); networkfee["networkfee"] = 100000000; - mockRpc.Setup(p => p.RpcSend("calculatenetworkfee", It.Is(u => true))) - .Returns(networkfee) + mockRpc.Setup(p => p.RpcSendAsync("calculatenetworkfee", It.Is(u => true))) + .ReturnsAsync(networkfee) .Verifiable(); // MockGasBalance @@ -115,16 +116,14 @@ public static void MockInvokeScript(Mock mockClient, byte[] script, p State = VMState.HALT }; - mockClient.Setup(p => p.RpcSend("invokescript", It.Is(j => j[0].AsString() == script.ToHexString()))) - .Returns(result.ToJson()) + mockClient.Setup(p => p.RpcSendAsync("invokescript", It.Is(j => j[0].AsString() == script.ToHexString()))) + .ReturnsAsync(result.ToJson()) .Verifiable(); } [TestMethod] - public void TestMakeTransaction() + public async Task TestMakeTransaction() { - txManager = new TransactionManager(rpcClientMock.Object); - Signer[] signers = new Signer[1] { new Signer @@ -135,17 +134,15 @@ public void TestMakeTransaction() }; byte[] script = new byte[1]; - txManager.MakeTransaction(script, signers); + txManager = await TransactionManager.MakeTransactionAsync(rpcClientMock.Object, script, signers); var tx = txManager.Tx; Assert.AreEqual(WitnessScope.Global, tx.Signers[0].Scopes); } [TestMethod] - public void TestSign() + public async Task TestSign() { - txManager = new TransactionManager(rpcClientMock.Object); - Signer[] signers = new Signer[1] { new Signer @@ -156,9 +153,10 @@ public void TestSign() }; byte[] script = new byte[1]; - txManager.MakeTransaction(script, signers) + txManager = await TransactionManager.MakeTransactionAsync(rpcClientMock.Object, script, signers); + await txManager .AddSignature(keyPair1) - .Sign(); + .SignAsync(); // get signature from Witnesses var tx = txManager.Tx; @@ -170,18 +168,40 @@ public void TestSign() Assert.AreEqual(100, tx.SystemFee); // duplicate sign should not add new witness - txManager.AddSignature(keyPair1).Sign(); + await txManager.AddSignature(keyPair1).SignAsync(); Assert.AreEqual(1, txManager.Tx.Witnesses.Length); // throw exception when the KeyPair is wrong - Assert.ThrowsException(() => txManager.AddSignature(keyPair2).Sign()); + await ThrowsAsync(async () => await txManager.AddSignature(keyPair2).SignAsync()); } - [TestMethod] - public void TestSignMulti() + // https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/november/async-programming-unit-testing-asynchronous-code#testing-exceptions + static async Task ThrowsAsync(Func action, bool allowDerivedTypes = true) + where TException : Exception { - txManager = new TransactionManager(multiSigMock.Object); + try + { + await action(); + } + catch (Exception ex) + { + if (allowDerivedTypes && !(ex is TException)) + throw new Exception("Delegate threw exception of type " + + ex.GetType().Name + ", but " + typeof(TException).Name + + " or a derived type was expected.", ex); + if (!allowDerivedTypes && ex.GetType() != typeof(TException)) + throw new Exception("Delegate threw exception of type " + + ex.GetType().Name + ", but " + typeof(TException).Name + + " was expected.", ex); + return (TException)ex; + } + throw new Exception("Delegate did not throw expected exception " + + typeof(TException).Name + "."); + } + [TestMethod] + public async Task TestSignMulti() + { // Cosigner needs multi signature Signer[] signers = new Signer[1] { @@ -193,17 +213,16 @@ public void TestSignMulti() }; byte[] script = new byte[1]; - txManager.MakeTransaction(script, signers) + txManager = await TransactionManager.MakeTransactionAsync(multiSigMock.Object, script, signers); + await txManager .AddMultiSig(keyPair1, 2, keyPair1.PublicKey, keyPair2.PublicKey) .AddMultiSig(keyPair2, 2, keyPair1.PublicKey, keyPair2.PublicKey) - .Sign(); + .SignAsync(); } [TestMethod] - public void TestAddWitness() + public async Task TestAddWitness() { - txManager = new TransactionManager(rpcClientMock.Object); - // Cosigner as contract scripthash Signer[] signers = new Signer[2] { @@ -220,10 +239,10 @@ public void TestAddWitness() }; byte[] script = new byte[1]; - txManager.MakeTransaction(script, signers); + txManager = await TransactionManager.MakeTransactionAsync(rpcClientMock.Object, script, signers); txManager.AddWitness(UInt160.Zero); txManager.AddSignature(keyPair1); - txManager.Sign(); + await txManager.SignAsync(); var tx = txManager.Tx; Assert.AreEqual(2, tx.Witnesses.Length); diff --git a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs index 37a0cc181..ebfbcb51b 100644 --- a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs @@ -8,6 +8,7 @@ using Neo.VM; using Neo.Wallets; using System.Numerics; +using System.Threading.Tasks; namespace Neo.Network.RPC.Tests { @@ -33,47 +34,47 @@ public void TestSetup() } [TestMethod] - public void TestGetUnclaimedGas() + public async Task TestGetUnclaimedGas() { byte[] testScript = NativeContract.NEO.Hash.MakeScript("unclaimedGas", sender, 99); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); - var balance = walletAPI.GetUnclaimedGas(address1); + var balance = await walletAPI.GetUnclaimedGasAsync(address1); Assert.AreEqual(1.1m, balance); } [TestMethod] - public void TestGetNeoBalance() + public async Task TestGetNeoBalance() { byte[] testScript = NativeContract.NEO.Hash.MakeScript("balanceOf", sender); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - var balance = walletAPI.GetNeoBalance(address1); + var balance = await walletAPI.GetNeoBalanceAsync(address1); Assert.AreEqual(1_00000000u, balance); } [TestMethod] - public void TestGetGasBalance() + public async Task TestGetGasBalance() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", sender); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); - var balance = walletAPI.GetGasBalance(address1); + var balance = await walletAPI.GetGasBalanceAsync(address1); Assert.AreEqual(1.1m, balance); } [TestMethod] - public void TestGetTokenBalance() + public async Task TestGetTokenBalance() { byte[] testScript = UInt160.Zero.MakeScript("balanceOf", sender); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); - var balance = walletAPI.GetTokenBalance(UInt160.Zero.ToString(), address1); + var balance = await walletAPI.GetTokenBalanceAsync(UInt160.Zero.ToString(), address1); Assert.AreEqual(1_10000000, balance); } [TestMethod] - public void TestClaimGas() + public async Task TestClaimGas() { byte[] balanceScript = NativeContract.NEO.Hash.MakeScript("balanceOf", sender); UT_TransactionManager.MockInvokeScript(rpcClientMock, balanceScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); @@ -83,14 +84,14 @@ public void TestClaimGas() var json = new JObject(); json["hash"] = UInt256.Zero.ToString(); - rpcClientMock.Setup(p => p.RpcSend("sendrawtransaction", It.IsAny())).Returns(json); + rpcClientMock.Setup(p => p.RpcSendAsync("sendrawtransaction", It.IsAny())).ReturnsAsync(json); - var tranaction = walletAPI.ClaimGas(keyPair1.Export()); + var tranaction = await walletAPI.ClaimGasAsync(keyPair1.Export()); Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); } [TestMethod] - public void TestTransfer() + public async Task TestTransfer() { byte[] decimalsScript = NativeContract.GAS.Hash.MakeScript("decimals"); UT_TransactionManager.MockInvokeScript(rpcClientMock, decimalsScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(8) }); @@ -100,14 +101,14 @@ public void TestTransfer() var json = new JObject(); json["hash"] = UInt256.Zero.ToString(); - rpcClientMock.Setup(p => p.RpcSend("sendrawtransaction", It.IsAny())).Returns(json); + rpcClientMock.Setup(p => p.RpcSendAsync("sendrawtransaction", It.IsAny())).ReturnsAsync(json); - var tranaction = walletAPI.Transfer(NativeContract.GAS.Hash.ToString(), keyPair1.Export(), UInt160.Zero.ToAddress(), 100); + var tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash.ToString(), keyPair1.Export(), UInt160.Zero.ToAddress(), 100); Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); } [TestMethod] - public void TestTransferfromMultiSigAccount() + public async Task TestTransferfromMultiSigAccount() { byte[] balanceScript = NativeContract.GAS.Hash.MakeScript("balanceOf", multiSender); var balanceResult = new ContractParameter() { Type = ContractParameterType.Integer, Value = BigInteger.Parse("10000000000000000") }; @@ -122,20 +123,20 @@ public void TestTransferfromMultiSigAccount() var json = new JObject(); json["hash"] = UInt256.Zero.ToString(); - rpcClientMock.Setup(p => p.RpcSend("sendrawtransaction", It.IsAny())).Returns(json); + rpcClientMock.Setup(p => p.RpcSendAsync("sendrawtransaction", It.IsAny())).ReturnsAsync(json); - var tranaction = walletAPI.Transfer(NativeContract.GAS.Hash, 1, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100); + var tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash, 1, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100); Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); } [TestMethod] - public void TestWaitTransaction() + public async Task TestWaitTransaction() { Transaction transaction = TestUtils.GetTransaction(); - rpcClientMock.Setup(p => p.RpcSend("getrawtransaction", It.Is(j => j[0].AsString() == transaction.Hash.ToString()))) - .Returns(new RpcTransaction { Transaction = transaction, VMState = VMState.HALT, BlockHash = UInt256.Zero, BlockTime = 100, Confirmations = 1 }.ToJson()); + rpcClientMock.Setup(p => p.RpcSendAsync("getrawtransaction", It.Is(j => j[0].AsString() == transaction.Hash.ToString()))) + .ReturnsAsync(new RpcTransaction { Transaction = transaction, VMState = VMState.HALT, BlockHash = UInt256.Zero, BlockTime = 100, Confirmations = 1 }.ToJson()); - var tx = walletAPI.WaitTransaction(transaction).Result; + var tx = await walletAPI.WaitTransactionAsync(transaction); Assert.AreEqual(VMState.HALT, tx.VMState); Assert.AreEqual(UInt256.Zero, tx.BlockHash); }