From 11c85e53811a8c31b040cad7121fbaa2874b3553 Mon Sep 17 00:00:00 2001 From: Wetitpig Date: Wed, 22 Nov 2023 09:17:29 +0800 Subject: [PATCH 1/5] [#6182] Return address from getFrom and getTo methods 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 --- .../pojoadapter/TransactionAdapter.java | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) 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 136249218c0..1fb3234f956 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,37 @@ public Optional getIndex() { 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 senderAddress = transactionWithMetadata.getTransaction().getSender(); return query .getAndMapWorldState( blockNumber, mutableWorldState -> - Optional.of( - new AccountAdapter( - mutableWorldState.get( - transactionWithMetadata.getTransaction().getSender())))) - .get(); + Optional.of(new AccountAdapter(mutableWorldState.get(senderAddress)))) + .orElse(new EmptyAccountAdapter(senderAddress)); } 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() { From f39692e37eca569edb27e794dfadff180ec6e7c1 Mon Sep 17 00:00:00 2001 From: Wetitpig Date: Wed, 22 Nov 2023 09:20:10 +0800 Subject: [PATCH 2/5] Same philosophy for LogAdapter Signed-off-by: Wetitpig --- .../api/graphql/internal/pojoadapter/LogAdapter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 10357de0cca..6beab46fdc8 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 AccountAdapter getAccount(final DataFetchingEnvironment environment) { 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)); } } From b0f47f66bdab8effe7b1ac7970898e494258165f Mon Sep 17 00:00:00 2001 From: Wetitpig Date: Wed, 22 Nov 2023 11:50:08 +0800 Subject: [PATCH 3/5] Update CHANGELOG.md Because it affects the behaviour of all GraphQL requests. Signed-off-by: Wetitpig --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cfc1c18045..06d1a2c212b 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` in `from` and `to` fields of a `Transaction` and `account` field in `Log` 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) From 1c7fe2e1dbd8f37e734586e38954dd401b828d07 Mon Sep 17 00:00:00 2001 From: Wetitpig Date: Wed, 22 Nov 2023 16:09:58 +0800 Subject: [PATCH 4/5] Also fix for createdContract Signed-off-by: Wetitpig --- CHANGELOG.md | 2 +- .../internal/pojoadapter/TransactionAdapter.java | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06d1a2c212b..7b365ac9c9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +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` in `from` and `to` fields of a `Transaction` and `account` field in `Log` on GraphQL in case of unreachable world state [#6198](https://github.com/hyperledger/besu/pull/6198) +- 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/TransactionAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java index 1fb3234f956..1c55dacce86 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 @@ -87,13 +87,12 @@ public AccountAdapter getFrom(final DataFetchingEnvironment environment) { .or(() -> transactionWithMetadata.getBlockNumber()) .orElseGet(query::headBlockNumber); - final Address senderAddress = transactionWithMetadata.getTransaction().getSender(); + final Address addr = transactionWithMetadata.getTransaction().getSender(); return query .getAndMapWorldState( blockNumber, - mutableWorldState -> - Optional.of(new AccountAdapter(mutableWorldState.get(senderAddress)))) - .orElse(new EmptyAccountAdapter(senderAddress)); + mutableWorldState -> Optional.of(new AccountAdapter(mutableWorldState.get(addr)))) + .orElse(new EmptyAccountAdapter(addr)); } public Optional getTo(final DataFetchingEnvironment environment) { @@ -199,8 +198,10 @@ public Optional getCreatedContract(final DataFetchingEnvironment 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(); From 514fd13996d27166150a4da34b8c93afcf9eebd8 Mon Sep 17 00:00:00 2001 From: Wetitpig Date: Wed, 22 Nov 2023 17:01:02 +0800 Subject: [PATCH 5/5] Refactor lambda Signed-off-by: Wetitpig --- .../api/graphql/internal/pojoadapter/TransactionAdapter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 1c55dacce86..f3ead13dadb 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 @@ -84,7 +84,7 @@ public AccountAdapter getFrom(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final Long blockNumber = Optional.ofNullable(environment.getArgument("block")) - .or(() -> transactionWithMetadata.getBlockNumber()) + .or(transactionWithMetadata::getBlockNumber) .orElseGet(query::headBlockNumber); final Address addr = transactionWithMetadata.getTransaction().getSender(); @@ -99,7 +99,7 @@ public Optional getTo(final DataFetchingEnvironment environment) final BlockchainQueries query = getBlockchainQueries(environment); final Long blockNumber = Optional.ofNullable(environment.getArgument("block")) - .or(() -> transactionWithMetadata.getBlockNumber()) + .or(transactionWithMetadata::getBlockNumber) .orElseGet(query::headBlockNumber); return transactionWithMetadata