From 1f72632e19c78010a42fb150ee9e1e84110099d9 Mon Sep 17 00:00:00 2001 From: Wetitpig Date: Wed, 22 Nov 2023 21:23:30 +0800 Subject: [PATCH] Return `address` from the `from` and `to` fields in a GraphQL (#6198) When the world state is not retrievable, instead of returning java.lang.reflect.InvocationTargetException in the from field and null in the to field in GraphQL, return an empty account with the address only. Signed-off-by: Wetitpig Signed-off-by: Danno Ferrin --- CHANGELOG.md | 1 + .../internal/pojoadapter/LogAdapter.java | 7 +-- .../pojoadapter/TransactionAdapter.java | 49 ++++++++++--------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cfc1c1804..7b365ac9c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Update OpenJDK latest Docker image to use Java 21 [#6189](https://github.com/hyperledger/besu/pull/6189) - Allow a transaction selection plugin to specify custom selection results [#6190](https://github.com/hyperledger/besu/pull/6190) - Add `rpc-gas-cap` to allow users to set gas limit to the RPC methods used to simulate transactions[#6156](https://github.com/hyperledger/besu/pull/6156) +- Fix the unavailability of `address` field when returning an `Account` entity on GraphQL in case of unreachable world state [#6198](https://github.com/hyperledger/besu/pull/6198) ### Bug fixes - Fix Docker image name clash between Besu and evmtool [#6194](https://github.com/hyperledger/besu/pull/6194) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java index 10357de0cc..6beab46fdc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata; @@ -63,9 +64,9 @@ public class LogAdapter extends AdapterBase { blockNumber = bn; } + final Address logger = logWithMetadata.getLogger(); return query - .getAndMapWorldState( - blockNumber, ws -> Optional.of(new AccountAdapter(ws.get(logWithMetadata.getLogger())))) - .get(); + .getAndMapWorldState(blockNumber, ws -> Optional.of(new AccountAdapter(ws.get(logger)))) + .orElse(new EmptyAccountAdapter(logger)); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java index 136249218c..f3ead13dad 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java @@ -82,35 +82,36 @@ public class TransactionAdapter extends AdapterBase { public AccountAdapter getFrom(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); - Long blockNumber = environment.getArgument("block"); - if (blockNumber == null) { - blockNumber = transactionWithMetadata.getBlockNumber().orElseGet(query::headBlockNumber); - } + final Long blockNumber = + Optional.ofNullable(environment.getArgument("block")) + .or(transactionWithMetadata::getBlockNumber) + .orElseGet(query::headBlockNumber); + + final Address addr = transactionWithMetadata.getTransaction().getSender(); return query .getAndMapWorldState( blockNumber, - mutableWorldState -> - Optional.of( - new AccountAdapter( - mutableWorldState.get( - transactionWithMetadata.getTransaction().getSender())))) - .get(); + mutableWorldState -> Optional.of(new AccountAdapter(mutableWorldState.get(addr)))) + .orElse(new EmptyAccountAdapter(addr)); } public Optional getTo(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); - Long blockNumber = environment.getArgument("block"); - if (blockNumber == null) { - blockNumber = transactionWithMetadata.getBlockNumber().orElseGet(query::headBlockNumber); - } + final Long blockNumber = + Optional.ofNullable(environment.getArgument("block")) + .or(transactionWithMetadata::getBlockNumber) + .orElseGet(query::headBlockNumber); - return query.getAndMapWorldState( - blockNumber, - ws -> - transactionWithMetadata - .getTransaction() - .getTo() - .map(address -> new AccountAdapter(address, ws.get(address)))); + return transactionWithMetadata + .getTransaction() + .getTo() + .flatMap( + address -> + query + .getAndMapWorldState( + blockNumber, + ws -> Optional.of(new AccountAdapter(address, ws.get(address)))) + .or(() -> Optional.of(new EmptyAccountAdapter(address)))); } public Wei getValue() { @@ -197,8 +198,10 @@ public class TransactionAdapter extends AdapterBase { return Optional.empty(); } final long blockNumber = bn.orElseGet(txBlockNumber::get); - return query.getAndMapWorldState( - blockNumber, ws -> Optional.of(new AccountAdapter(ws.get(addr.get())))); + return query + .getAndMapWorldState( + blockNumber, ws -> Optional.of(new AccountAdapter(ws.get(addr.get())))) + .or(() -> Optional.of(new EmptyAccountAdapter(addr.get()))); } } return Optional.empty();