diff --git a/src/Nethereum.JsonRpc.Client/RpcRequestResponseBatchItem.cs b/src/Nethereum.JsonRpc.Client/RpcRequestResponseBatchItem.cs index 305195eb6..a0e778708 100644 --- a/src/Nethereum.JsonRpc.Client/RpcRequestResponseBatchItem.cs +++ b/src/Nethereum.JsonRpc.Client/RpcRequestResponseBatchItem.cs @@ -34,7 +34,7 @@ public void DecodeResponse(RpcResponseMessage rpcResponse) catch { this.HasError = true; - this.RpcError = new RpcError(-1, "Invalid format excecption"); + this.RpcError = new RpcError(-1, "Invalid format exception"); } } } diff --git a/src/Nethereum.RPC/Eth/Blocks/EthGetBlockByHash.cs b/src/Nethereum.RPC/Eth/Blocks/EthGetBlockByHash.cs index bf26b9767..897f63612 100644 --- a/src/Nethereum.RPC/Eth/Blocks/EthGetBlockByHash.cs +++ b/src/Nethereum.RPC/Eth/Blocks/EthGetBlockByHash.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethereum.Hex.HexConvertors.Extensions; using Nethereum.JsonRpc.Client; @@ -82,6 +84,21 @@ public Task SendRequestAsync(string blockHash, object id return base.SendRequestAsync(id, blockHash.EnsureHexPrefix(), true); } +#if !DOTNET35 + public async Task> SendBatchRequestAsync(params string[] blockHashes) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < blockHashes.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(blockHashes[i], i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } +#endif + public RpcRequest BuildRequest(string blockHash, object id = null) { return base.BuildRequest(id, blockHash.EnsureHexPrefix(), true); @@ -166,6 +183,22 @@ public Task SendRequestAsync(string blockHash, objec return base.SendRequestAsync(id, blockHash.EnsureHexPrefix(), false); } + +#if !DOTNET35 + public async Task> SendBatchRequestAsync(params string[] blockHashes) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < blockHashes.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(blockHashes[i], i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } +#endif + public RpcRequest BuildRequest(string blockHash, object id = null) { if (blockHash == null) throw new ArgumentNullException(nameof(blockHash)); diff --git a/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsByNumber.cs b/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsByNumber.cs index 6c366f920..20af44851 100644 --- a/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsByNumber.cs +++ b/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsByNumber.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethereum.Hex.HexTypes; @@ -96,6 +98,21 @@ public Task SendRequestAsync(HexBigInteger number, object return base.SendRequestAsync(id, number, true); } +#if !DOTNET35 + public async Task> SendBatchRequestAsync(params HexBigInteger[] numbers) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < numbers.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(numbers[i], i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } +#endif + public RpcRequest BuildRequest(HexBigInteger number, object id = null) { if (number == null) throw new ArgumentNullException(nameof(number)); diff --git a/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsHashesByNumber.cs b/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsHashesByNumber.cs index 8494db56a..8f8c83462 100644 --- a/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsHashesByNumber.cs +++ b/src/Nethereum.RPC/Eth/Blocks/EthGetBlockWithTransactionsHashesByNumber.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethereum.Hex.HexTypes; @@ -96,6 +98,21 @@ public Task SendRequestAsync(BlockParameter blockPar return base.SendRequestAsync(id, blockParameter, false); } +#if !DOTNET35 + public async Task> SendBatchRequestAsync(params HexBigInteger[] numbers) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < numbers.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(numbers[i], i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } +#endif + public RpcRequest BuildRequest(HexBigInteger number, object id = null) { if (number == null) throw new ArgumentNullException(nameof(number)); diff --git a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByHash.cs b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByHash.cs index 032d85b2c..a5a9fc1f2 100644 --- a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByHash.cs +++ b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByHash.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -7,6 +8,9 @@ namespace Nethereum.RPC.Eth.Blocks public interface IEthGetBlockWithTransactionsByHash { RpcRequest BuildRequest(string blockHash, object id = null); +#if !DOTNET35 + Task> SendBatchRequestAsync(params string[] blockHashes); +#endif Task SendRequestAsync(string blockHash, object id = null); } } \ No newline at end of file diff --git a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByNumber.cs b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByNumber.cs index b4be6e923..b3c417e9e 100644 --- a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByNumber.cs +++ b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsByNumber.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.Hex.HexTypes; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -9,6 +10,10 @@ public interface IEthGetBlockWithTransactionsByNumber { RpcRequest BuildRequest(BlockParameter blockParameter, object id = null); RpcRequest BuildRequest(HexBigInteger number, object id = null); + +#if !DOTNET35 + Task> SendBatchRequestAsync(params HexBigInteger[] numbers); +#endif Task SendRequestAsync(BlockParameter blockParameter, object id = null); Task SendRequestAsync(HexBigInteger number, object id = null); } diff --git a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByHash.cs b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByHash.cs index 117c83f14..0ba778ab3 100644 --- a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByHash.cs +++ b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByHash.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -7,6 +8,9 @@ namespace Nethereum.RPC.Eth.Blocks public interface IEthGetBlockWithTransactionsHashesByHash { RpcRequest BuildRequest(string blockHash, object id = null); +#if !DOTNET35 + Task> SendBatchRequestAsync(params string[] blockHashes); +#endif Task SendRequestAsync(string blockHash, object id = null); } } \ No newline at end of file diff --git a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByNumber.cs b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByNumber.cs index b818a83b5..4711a3661 100644 --- a/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByNumber.cs +++ b/src/Nethereum.RPC/Eth/Blocks/IEthGetBlockWithTransactionsHashesByNumber.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.Hex.HexTypes; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -9,6 +10,9 @@ public interface IEthGetBlockWithTransactionsHashesByNumber { RpcRequest BuildRequest(BlockParameter blockParameter, object id = null); RpcRequest BuildRequest(HexBigInteger number, object id = null); +#if !DOTNET35 + Task> SendBatchRequestAsync(params HexBigInteger[] numbers); +#endif Task SendRequestAsync(BlockParameter blockParameter, object id = null); Task SendRequestAsync(HexBigInteger number, object id = null); } diff --git a/src/Nethereum.RPC/Eth/EthGetBalance.cs b/src/Nethereum.RPC/Eth/EthGetBalance.cs index 321542aa1..b205b77e5 100644 --- a/src/Nethereum.RPC/Eth/EthGetBalance.cs +++ b/src/Nethereum.RPC/Eth/EthGetBalance.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethereum.Hex.HexConvertors.Extensions; @@ -59,11 +61,32 @@ public Task SendRequestAsync(string address, object id = null) return base.SendRequestAsync(id, address.EnsureHexPrefix(), DefaultBlock); } +#if !DOTNET35 + public async Task> SendBatchRequestAsync(string[] addresses, BlockParameter block) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < addresses.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(addresses[i], block, i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } + + public Task> SendBatchRequestAsync(params string[] addresses) + { + return SendBatchRequestAsync(addresses, DefaultBlock); + } +#endif + public RpcRequest BuildRequest(string address, BlockParameter block, object id = null) { if (address == null) throw new ArgumentNullException(nameof(address)); if (block == null) throw new ArgumentNullException(nameof(block)); return base.BuildRequest(id, address.EnsureHexPrefix(), block); } + } } \ No newline at end of file diff --git a/src/Nethereum.RPC/Eth/IEthGetBalance.cs b/src/Nethereum.RPC/Eth/IEthGetBalance.cs index 066d7d05d..9242c12e1 100644 --- a/src/Nethereum.RPC/Eth/IEthGetBalance.cs +++ b/src/Nethereum.RPC/Eth/IEthGetBalance.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.Hex.HexTypes; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -10,6 +11,10 @@ public interface IEthGetBalance BlockParameter DefaultBlock { get; set; } RpcRequest BuildRequest(string address, BlockParameter block, object id = null); +#if !DOTNET35 + Task> SendBatchRequestAsync(string[] addresses, BlockParameter block); + Task> SendBatchRequestAsync(params string[] addresses); +#endif Task SendRequestAsync(string address, object id = null); Task SendRequestAsync(string address, BlockParameter block, object id = null); } diff --git a/src/Nethereum.RPC/Eth/Transactions/EthCall.cs b/src/Nethereum.RPC/Eth/Transactions/EthCall.cs index f8659d1ce..09e60cdf8 100644 --- a/src/Nethereum.RPC/Eth/Transactions/EthCall.cs +++ b/src/Nethereum.RPC/Eth/Transactions/EthCall.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethereum.JsonRpc.Client; @@ -54,6 +56,26 @@ public Task SendRequestAsync(CallInput callInput, object id = null) return base.SendRequestAsync(id, callInput, DefaultBlock); } +#if !DOTNET35 + public Task> SendBatchRequestAsync(params CallInput[] callInputs) + { + return SendBatchRequestAsync(callInputs, DefaultBlock); + } + + public async Task> SendBatchRequestAsync(CallInput[] callInputs, BlockParameter block) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < callInputs.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(callInputs[i], block, i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest).ConfigureAwait(false); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } +#endif + public RpcRequest BuildRequest(CallInput callInput, BlockParameter block, object id = null) { if (callInput == null) throw new ArgumentNullException(nameof(callInput)); diff --git a/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionByHash.cs b/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionByHash.cs index 78b2496f2..b8e12178e 100644 --- a/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionByHash.cs +++ b/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionByHash.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethereum.Hex.HexConvertors.Extensions; @@ -61,6 +63,21 @@ public Task SendRequestAsync(string hashTransaction, object id = nu return base.SendRequestAsync(id, hashTransaction.EnsureHexPrefix()); } +#if !DOTNET35 + public async Task> SendBatchRequestAsync(string[] transactionHashes) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < transactionHashes.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(transactionHashes[i], i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } +#endif + public RpcRequest BuildRequest(string hashTransaction, object id = null) { return base.BuildRequest(id, hashTransaction.EnsureHexPrefix()); diff --git a/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionReceipt.cs b/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionReceipt.cs index 8c70645ad..548ba3e30 100644 --- a/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionReceipt.cs +++ b/src/Nethereum.RPC/Eth/Transactions/EthGetTransactionReceipt.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Nethereum.Hex.HexConvertors.Extensions; @@ -60,6 +62,21 @@ public Task SendRequestAsync(string transactionHash, object return base.SendRequestAsync(id, transactionHash.EnsureHexPrefix()); } +#if !DOTNET35 + public async Task> SendBatchRequestAsync(string[] transactionHashes) + { + var batchRequest = new RpcRequestResponseBatch(); + for (int i = 0; i < transactionHashes.Length; i++) + { + batchRequest.BatchItems.Add(new RpcRequestResponseBatchItem(this, BuildRequest(transactionHashes[i], i))); + } + + var response = await Client.SendBatchRequestAsync(batchRequest); + return response.BatchItems.Select(x => ((RpcRequestResponseBatchItem)x).Response).ToList(); + + } +#endif + public RpcRequest BuildRequest(string transactionHash, object id = null) { if (transactionHash == null) throw new ArgumentNullException(nameof(transactionHash)); diff --git a/src/Nethereum.RPC/Eth/Transactions/IEthCall.cs b/src/Nethereum.RPC/Eth/Transactions/IEthCall.cs index 03afc301d..b91f9169b 100644 --- a/src/Nethereum.RPC/Eth/Transactions/IEthCall.cs +++ b/src/Nethereum.RPC/Eth/Transactions/IEthCall.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -9,6 +10,10 @@ public interface IEthCall BlockParameter DefaultBlock { get; set; } RpcRequest BuildRequest(CallInput callInput, BlockParameter block, object id = null); +#if !DOTNET35 + Task> SendBatchRequestAsync(params CallInput[] callInputs); + Task> SendBatchRequestAsync(CallInput[] callInputs, BlockParameter block); +#endif Task SendRequestAsync(CallInput callInput, object id = null); Task SendRequestAsync(CallInput callInput, BlockParameter block, object id = null); } diff --git a/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionByHash.cs b/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionByHash.cs index 48acbcfa7..351b4872b 100644 --- a/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionByHash.cs +++ b/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionByHash.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -7,6 +8,9 @@ namespace Nethereum.RPC.Eth.Transactions public interface IEthGetTransactionByHash { RpcRequest BuildRequest(string hashTransaction, object id = null); +#if !DOTNET35 + Task> SendBatchRequestAsync(string[] transactionHashes); +#endif Task SendRequestAsync(string hashTransaction, object id = null); } } \ No newline at end of file diff --git a/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionReceipt.cs b/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionReceipt.cs index e8feddf56..7ca641e94 100644 --- a/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionReceipt.cs +++ b/src/Nethereum.RPC/Eth/Transactions/IEthGetTransactionReceipt.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Nethereum.JsonRpc.Client; using Nethereum.RPC.Eth.DTOs; @@ -7,6 +8,9 @@ namespace Nethereum.RPC.Eth.Transactions public interface IEthGetTransactionReceipt { RpcRequest BuildRequest(string transactionHash, object id = null); +#if !DOTNET35 + Task> SendBatchRequestAsync(string[] transactionHashes); +#endif Task SendRequestAsync(string transactionHash, object id = null); } } \ No newline at end of file diff --git a/tests/Nethereum.Accounts.IntegrationTests/BatchTests.cs b/tests/Nethereum.Accounts.IntegrationTests/BatchTests.cs index 06b42acaf..0662f3f34 100644 --- a/tests/Nethereum.Accounts.IntegrationTests/BatchTests.cs +++ b/tests/Nethereum.Accounts.IntegrationTests/BatchTests.cs @@ -5,6 +5,7 @@ using Nethereum.RPC.Eth.Blocks; using Nethereum.XUnitEthereumClients; using Xunit; +using System.Linq; namespace Nethereum.Accounts.IntegrationTests { @@ -18,8 +19,9 @@ public BatchTests(EthereumClientIntegrationFixture ethereumClientIntegrationFixt { _ethereumClientIntegrationFixture = ethereumClientIntegrationFixture; } + [Fact] - public async void ShoulBatchGetBalances() + public async void ShouldBatchGetBalances() { var web3 = _ethereumClientIntegrationFixture.GetWeb3(); @@ -33,9 +35,44 @@ public async void ShoulBatchGetBalances() Assert.Equal(batchItem1.Response.Value, batchItem2.Response.Value); } + [Fact] + public async void ShouldBatchGetBalancesRpc() + { + var web3 = _ethereumClientIntegrationFixture.GetWeb3(); + var balances = await web3.Eth.GetBalance.SendBatchRequestAsync(EthereumClientIntegrationFixture.AccountAddress, EthereumClientIntegrationFixture.AccountAddress); + Assert.Equal(balances[0], balances[1]); + } + + [Fact] + public async void ShouldBatchGetBlocksWithTransactionHashesRpc() + { + var web3 = _ethereumClientIntegrationFixture.GetInfuraWeb3(InfuraNetwork.Mainnet); + var blocks = await web3.Eth.Blocks.GetBlockWithTransactionsHashesByNumber.SendBatchRequestAsync( + new HexBigInteger(1000000), new HexBigInteger(1000001), new HexBigInteger(1000002)); + Assert.Equal(3, blocks.Count); + } + + [Fact] + public async void ShouldBatchGetBlocksWithTransactionsRpc() + { + var web3 = _ethereumClientIntegrationFixture.GetInfuraWeb3(InfuraNetwork.Mainnet); + var blocks = await web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendBatchRequestAsync( + new HexBigInteger(1000000), new HexBigInteger(1000001), new HexBigInteger(1000002)); + Assert.Equal(3, blocks.Count); + } + + [Fact] + public async void ShouldBatchGetTransactionReceiptsRpc() + { + var web3 = _ethereumClientIntegrationFixture.GetInfuraWeb3(InfuraNetwork.Mainnet); + var block = await web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync( + new HexBigInteger(1000000)); + var receipts = await web3.Eth.Transactions.GetTransactionReceipt.SendBatchRequestAsync(block.Transactions.Select(x => x.TransactionHash).ToArray()); + Assert.Equal(2, receipts.Count); + } [Fact] - public async void ShoulBatchGetBlocks() + public async void ShouldBatchGetBlocks() { var web3 = _ethereumClientIntegrationFixture.GetInfuraWeb3(InfuraNetwork.Mainnet);