From 16774cb40fee65cad0cdc471b621a57d4eb219cc Mon Sep 17 00:00:00 2001 From: shemnon Date: Thu, 16 May 2019 19:31:22 -0600 Subject: [PATCH] [PAN-2705] helpful graphql error when an account doesn't exist When we are asking for an account at an address that does not exist the error message should state that the account doesn't exist. --- .../graphqlrpc/GraphQLDataFetchers.java | 22 ++++++++++++++----- .../EthGraphQLRpcHttpBySpecTest.java | 2 ++ ..._getBalance_invalidAccountBlockNumber.json | 22 +++++++++++++++++++ .../eth_getBalance_invalidAccountLatest.json | 22 +++++++++++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountBlockNumber.json create mode 100644 ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountLatest.json diff --git a/ethereum/graphqlrpc/src/main/java/tech/pegasys/pantheon/ethereum/graphqlrpc/GraphQLDataFetchers.java b/ethereum/graphqlrpc/src/main/java/tech/pegasys/pantheon/ethereum/graphqlrpc/GraphQLDataFetchers.java index 6c9e78dcf5..e70f4f3dbf 100644 --- a/ethereum/graphqlrpc/src/main/java/tech/pegasys/pantheon/ethereum/graphqlrpc/GraphQLDataFetchers.java +++ b/ethereum/graphqlrpc/src/main/java/tech/pegasys/pantheon/ethereum/graphqlrpc/GraphQLDataFetchers.java @@ -12,7 +12,10 @@ */ package tech.pegasys.pantheon.ethereum.graphqlrpc; +import static com.google.common.base.Preconditions.checkArgument; + import tech.pegasys.pantheon.ethereum.blockcreation.MiningCoordinator; +import tech.pegasys.pantheon.ethereum.core.Account; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.ethereum.core.SyncStatus; @@ -163,7 +166,9 @@ DataFetcher> getAccountDataFetcher() { if (bn != null) { final Optional ws = blockchainQuery.getWorldState(bn); if (ws.isPresent()) { - return Optional.of(new AccountAdapter(ws.get().get(addr))); + final Account account = ws.get().get(addr); + checkArgument(account != null, "Account with address %s does not exist", addr); + return Optional.of(new AccountAdapter(account)); } else if (bn > blockchainQuery.getBlockchain().getChainHeadBlockNumber()) { // block is past chainhead throw new GraphQLRpcException(GraphQLRpcError.INVALID_PARAMS); @@ -171,11 +176,18 @@ DataFetcher> getAccountDataFetcher() { // we don't have that block throw new GraphQLRpcException(GraphQLRpcError.CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE); } + } else { + // return account on latest block + final long latestBn = blockchainQuery.latestBlock().get().getHeader().getNumber(); + final Optional ows = blockchainQuery.getWorldState(latestBn); + return ows.flatMap( + ws -> { + Account account = ws.get(addr); + checkArgument(account != null, "Account with address %s does not exist", addr); + return Optional.ofNullable(account); + }) + .map(AccountAdapter::new); } - // return account on latest block - final long latestBn = blockchainQuery.latestBlock().get().getHeader().getNumber(); - final Optional ows = blockchainQuery.getWorldState(latestBn); - return ows.flatMap(ws -> Optional.ofNullable(ws.get(addr))).map(AccountAdapter::new); }; } diff --git a/ethereum/graphqlrpc/src/test/java/tech/pegasys/pantheon/ethereum/graphqlrpc/EthGraphQLRpcHttpBySpecTest.java b/ethereum/graphqlrpc/src/test/java/tech/pegasys/pantheon/ethereum/graphqlrpc/EthGraphQLRpcHttpBySpecTest.java index 61e1f4c251..279de001a3 100644 --- a/ethereum/graphqlrpc/src/test/java/tech/pegasys/pantheon/ethereum/graphqlrpc/EthGraphQLRpcHttpBySpecTest.java +++ b/ethereum/graphqlrpc/src/test/java/tech/pegasys/pantheon/ethereum/graphqlrpc/EthGraphQLRpcHttpBySpecTest.java @@ -72,6 +72,8 @@ public static Collection specs() { specs.add("eth_call_BlockLatest"); specs.add("eth_getBalance_latest"); specs.add("eth_getBalance_0x19"); + specs.add("eth_getBalance_invalidAccountBlockNumber"); + specs.add("eth_getBalance_invalidAccountLatest"); specs.add("eth_gasPrice"); specs.add("eth_getTransactionReceipt"); diff --git a/ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountBlockNumber.json b/ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountBlockNumber.json new file mode 100644 index 0000000000..b1aa916085 --- /dev/null +++ b/ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountBlockNumber.json @@ -0,0 +1,22 @@ +{ + "request": "{account(blockNumber:\"0x19\", address: \"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef\") { balance } }", + "response": { + "data": null, + "errors": [ + { + "message": "Exception while fetching data (/account) : Account with address 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef does not exist", + "locations": [ + { + "line": 1, + "column": 2 + } + ], + "path": [ + "account" + ] + } + ] + }, + "statusCode": 400 +} + diff --git a/ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountLatest.json b/ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountLatest.json new file mode 100644 index 0000000000..80b2d654a2 --- /dev/null +++ b/ethereum/graphqlrpc/src/test/resources/tech/pegasys/pantheon/ethereum/graphqlrpc/eth_getBalance_invalidAccountLatest.json @@ -0,0 +1,22 @@ +{ + "request": "{account(address: \"0xdeaff00ddeaff00ddeaff00ddeaff00ddeaff00d\") { balance } }", + "response": { + "data": null, + "errors": [ + { + "message": "Exception while fetching data (/account) : Account with address 0xdeaff00ddeaff00ddeaff00ddeaff00ddeaff00d does not exist", + "locations": [ + { + "line": 1, + "column": 2 + } + ], + "path": [ + "account" + ] + } + ] + }, + "statusCode": 400 +} +