From 27fd97f6b578d94fb06fcdde779596dd90bd0738 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Mon, 3 Apr 2023 10:20:24 +1000 Subject: [PATCH] Use cached header for latest eth_getBlockByNumber (#5292) While syncing, it is possible that we access the cached header's number before the block itself has had chance to be imported. In other words there is a mismatch between cached blockNumber and non-cached blockHeader that is being retrieved for the RPC. Signed-off-by: Simon Dudley --- CHANGELOG.md | 2 +- .../jsonrpc/internal/methods/EthGetBlockByNumber.java | 4 +--- .../ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java | 10 ++-------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b1e9ea1539..18cd44ea4dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,8 @@ - Upgrade RocksDB version from 7.7.3 to 8.0.0. Besu Team [contributed](https://github.com/facebook/rocksdb/pull/11099) to this release to make disabling checksum verification work. ### Bug Fixes +- Fix eth_getBlockByNumber cache error for latest block when called during syncing [#5292](https://github.com/hyperledger/besu/pull/5292) - Fix QBFT and IBFT unable to propose blocks on London when zeroBaseFee is used [#5276](https://github.com/hyperledger/besu/pull/5276) - - Make QBFT validator smart contract mode work with london fork [#5249](https://github.com/hyperledger/besu/issues/5249) ### Download Links diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java index 12e9c847662..c1bdcc37dd2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; -import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Synchronizer; @@ -80,8 +79,7 @@ protected Object resultByBlockNumber( protected Object latestResult(final JsonRpcRequestContext request) { final long headBlockNumber = blockchainQueriesSupplier.get().headBlockNumber(); - Blockchain chain = blockchainQueriesSupplier.get().getBlockchain(); - BlockHeader headHeader = chain.getBlockHeader(headBlockNumber).orElse(null); + BlockHeader headHeader = blockchainQueriesSupplier.get().headBlockHeader(); Hash block = headHeader.getHash(); Hash stateRoot = headHeader.getStateRoot(); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index 1d258021448..db3e3b9a315 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -1063,10 +1063,7 @@ public void getBlockByNumberForLatest() throws Exception { final BlockWithMetadata blockWithMetadata = blockWithMetadata(block); when(blockchainQueries.headBlockNumber()).thenReturn(0L); - when(blockchainQueries.blockByNumber(eq(0L))).thenReturn(Optional.of(blockWithMetadata)); - when(blockchainQueries.getBlockchain()).thenReturn(blockchain); - when(blockchain.getBlockHeader(blockchainQueries.headBlockNumber())) - .thenReturn(Optional.of(block.getHeader())); + when(blockchainQueries.headBlockHeader()).thenReturn(block.getHeader()); WorldStateArchive state = mock(WorldStateArchive.class); when(state.isWorldStateAvailable(any(Hash.class), any(Hash.class))).thenReturn(true); when(blockchainQueries.getWorldStateArchive()).thenReturn(state); @@ -1097,11 +1094,8 @@ public void getBlockByNumberForPending() throws Exception { final Block block = gen.genesisBlock(); final BlockWithMetadata blockWithMetadata = blockWithMetadata(block); - when(blockchainQueries.headBlockNumber()).thenReturn(0L); when(blockchainQueries.blockByNumber(eq(0L))).thenReturn(Optional.of(blockWithMetadata)); - when(blockchainQueries.getBlockchain()).thenReturn(blockchain); - when(blockchain.getBlockHeader(blockchainQueries.headBlockNumber())) - .thenReturn(Optional.of(block.getHeader())); + when(blockchainQueries.headBlockHeader()).thenReturn(block.getHeader()); WorldStateArchive state = mock(WorldStateArchive.class); when(state.isWorldStateAvailable(any(Hash.class), any(Hash.class))).thenReturn(true); when(blockchainQueries.getWorldStateArchive()).thenReturn(state);