public async Task <IActionResult> Search(uint blockHeight, string address) { // This could be stripped out to somewhere else but for such a small application I think it's fine here. if (!string.IsNullOrWhiteSpace(address) && !address.IsValidHex()) { return(BadRequest("Address was in an invalid format.")); } string hexBlockHeight = blockHeight.UIntToHexString(); JsonRpcBlockResponseResult blockResponse = await this.jsonRpcClient.GetBlockByHeightAsync(hexBlockHeight); SearchResultViewModel model = SearchResultViewModel.FromBlockResponse(blockResponse); // If address wasn't filled in, assume user wants the whole block. if (string.IsNullOrWhiteSpace(address)) { return(Ok(model)); } // Assume that the jsonrpc results are lower case. model.Transactions = model.Transactions.Where(x => x.From == address || x.To == address); return(Ok(model)); }
public static SearchResultViewModel FromBlockResponse(JsonRpcBlockResponseResult apiBlockResponse) { return(new SearchResultViewModel { BlockHash = apiBlockResponse.Hash, BlockNumber = apiBlockResponse.Number.HexToUint(), Transactions = apiBlockResponse.Transactions.Select(x => TransactionViewModel.FromTransactionResponse(x)) }); }
public async Task FiltersTransactionsForAddress() { var jsonRpcMock = new Mock <IJsonRpcClient>(); var jsonRpcResponse = new JsonRpcBlockResponseResult { Hash = BlockHash, Number = BlockNumber, Transactions = new List <JsonRpcTransactionResponse> { new JsonRpcTransactionResponse { BlockNumber = BlockNumber, BlockHash = BlockHash, Hash = TxHash1, From = Addr1, To = Addr3, Value = Value, Gas = Gas }, new JsonRpcTransactionResponse { BlockNumber = BlockNumber, BlockHash = BlockHash, Hash = TxHash2, From = Addr1, To = Addr2, Value = Value, Gas = Gas }, new JsonRpcTransactionResponse { BlockNumber = BlockNumber, BlockHash = BlockHash, Hash = TxHash3, From = Addr3, To = Addr2, Value = Value, Gas = Gas } } }; jsonRpcMock.Setup(x => x.GetBlockByHeightAsync(BlockNumber, true)) .Returns(Task.FromResult(jsonRpcResponse)); var controller = new EthereumController(jsonRpcMock.Object); var result = (OkObjectResult)await controller.Search(7, Addr3); var returnedJson = (SearchResultViewModel)result.Value; Assert.Equal(2, returnedJson.Transactions.Count()); }
public async Task GetBlockByHashIsCorrectAsync() { const string knownBlockHeightHex = "0x8B99C9"; const string knownBlockHash = "0x6dbde4b224013c46537231c548bd6ff8e2a2c927c435993d351866d505c523f1"; const int knownBlockTxCount = 232; JsonRpcBlockResponseResult response = await this.client.GetBlockByHeightAsync(knownBlockHeightHex); Assert.Equal(knownBlockHash, response.Hash); Assert.Equal(knownBlockTxCount, response.Transactions.Count); }
public async Task GetRandomBlocksSuccessFully() { // Not deterministic but just checks that generally, we can get blocks without errors. var random = new Random(); for (int i = 0; i < 100; i++) { uint blockNum = (uint)random.Next(100, 9_000_000); string blockNumHex = blockNum.UIntToHexString(); JsonRpcBlockResponseResult response = await this.client.GetBlockByHeightAsync(blockNumHex); Assert.NotNull(response); Thread.Sleep(1_000); // Haven't checked if there is an API limit. } }