Skip to content

Commit

Permalink
fix parent world state is not available issue on bonsai (#4069)
Browse files Browse the repository at this point in the history
Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
  • Loading branch information
matkt committed Jul 7, 2022
1 parent 4d8ef07 commit 49e4fd8
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

### Additions and Improvements

### Bug Fixes
- Fixed a trie log layer issue on bonsai during reorg [#4069](https://github.com/hyperledger/besu/pull/4069)

## 22.7.0-RC1

### Additions and Improvements
- Do not require a minimum block height when downloading headers or blocks [#3911](https://github.com/hyperledger/besu/pull/3911)
- When on PoS the head can be only be updated by ForkchoiceUpdate [#3994](https://github.com/hyperledger/besu/pull/3994)
- Version information available in metrics [#3997](https://github.com/hyperledger/besu/pull/3997)
- Add TTD and DNS to Sepolia config [#4024](https://github.com/hyperledger/besu/pull/4024)
- Add terminal block hash and number to Ropsten genesis file [#4026](https://github.com/hyperledger/besu/pull/4026)
- Return `type` with value `0x0` when serializing legacy transactions [#4027](https://github.com/hyperledger/besu/pull/4027)
- Ignore `ForkchoiceUpdate` if `newHead` is an ancestor of the chain head [#4055](https://github.com/hyperledger/besu/pull/4055)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,17 @@ public void persist(final BlockHeader blockHeader) {
// then persist the TrieLog for that transition.
// If specified but not a direct descendant simply store the new block hash.
if (blockHeader != null) {
final TrieLogLayer trieLog =
prepareTrieLog(blockHeader, localUpdater, newWorldStateRootHash);
persistTrieLog(blockHeader, newWorldStateRootHash, trieLog, stateUpdater);
// do not overwrite a trielog layer that already exists in the database.
// if it's only in memory we need to save it
// for example, like that in case of reorg we don't replace a trielog layer
if (worldStateStorage.getTrieLog(blockHeader.getHash()).isEmpty()) {
final TrieLogLayer trieLog =
prepareTrieLog(blockHeader, localUpdater, newWorldStateRootHash);
persistTrieLog(blockHeader, newWorldStateRootHash, trieLog, stateUpdater);
}
stateUpdater
.getTrieBranchStorageTransaction()
.put(WORLD_BLOCK_HASH_KEY, blockHeader.getHash().toArrayUnsafe());
worldStateBlockHash = blockHeader.getHash();
} else {
stateUpdater.getTrieBranchStorageTransaction().remove(WORLD_BLOCK_HASH_KEY);
Expand Down Expand Up @@ -310,9 +318,6 @@ private void persistTrieLog(
"Persisting trie log for block hash {} and world state root {}",
blockHeader::toLogString,
worldStateRootHash::toHexString);
stateUpdater
.getTrieBranchStorageTransaction()
.put(WORLD_BLOCK_HASH_KEY, blockHeader.getHash().toArrayUnsafe());
final BytesValueRLPOutput rlpLog = new BytesValueRLPOutput();
trieLog.writeTo(rlpLog);
stateUpdater
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -200,4 +201,52 @@ public void testGetMutableWithStorageConsistencyToRollbackAndRollForwardTheState
verify(updater, times(1)).rollBack(any());
verify(updater, times(1)).rollForward(any());
}

@SuppressWarnings({"unchecked"})
@Test
public void testGetMutableWithRollbackNotOverrideTrieLogLayer() {
final KeyValueStorageTransaction keyValueStorageTransaction =
mock(KeyValueStorageTransaction.class);
when(keyValueStorage.startTransaction()).thenReturn(keyValueStorageTransaction);
final BlockHeader genesis = blockBuilder.number(0).buildHeader();
final BlockHeader blockHeaderChainA =
blockBuilder.number(1).timestamp(1).parentHash(genesis.getHash()).buildHeader();
final BlockHeader blockHeaderChainB =
blockBuilder.number(1).timestamp(2).parentHash(genesis.getHash()).buildHeader();

final Map<Bytes32, BonsaiLayeredWorldState> layeredWorldStatesByHash = mock(HashMap.class);
when(layeredWorldStatesByHash.containsKey(any(Bytes32.class))).thenReturn(true);
when(layeredWorldStatesByHash.get(eq(blockHeaderChainA.getHash())))
.thenReturn(mock(BonsaiLayeredWorldState.class, Answers.RETURNS_MOCKS));
when(layeredWorldStatesByHash.get(eq(blockHeaderChainB.getHash())))
.thenReturn(mock(BonsaiLayeredWorldState.class, Answers.RETURNS_MOCKS));

bonsaiWorldStateArchive =
spy(new BonsaiWorldStateArchive(storageProvider, blockchain, 12, layeredWorldStatesByHash));
var updater = spy(bonsaiWorldStateArchive.getUpdater());
when(bonsaiWorldStateArchive.getUpdater()).thenReturn(updater);

// initial persisted state hash key
when(blockchain.getBlockHeader(eq(Hash.ZERO))).thenReturn(Optional.of(blockHeaderChainA));
// fake trie log layer
final BytesValueRLPOutput rlpLogBlockB = new BytesValueRLPOutput();
final TrieLogLayer trieLogLayerBlockB = new TrieLogLayer();
trieLogLayerBlockB.setBlockHash(blockHeaderChainB.getHash());
trieLogLayerBlockB.writeTo(rlpLogBlockB);
when(keyValueStorage.get(blockHeaderChainB.getHash().toArrayUnsafe()))
.thenReturn(Optional.of(rlpLogBlockB.encoded().toArrayUnsafe()));

when(blockchain.getBlockHeader(eq(blockHeaderChainB.getHash())))
.thenReturn(Optional.of(blockHeaderChainB));
when(blockchain.getBlockHeader(eq(genesis.getHash()))).thenReturn(Optional.of(genesis));

assertThat(bonsaiWorldStateArchive.getMutable(null, blockHeaderChainB.getHash()))
.containsInstanceOf(BonsaiPersistedWorldState.class);

// verify is not persisting if already present
verify(keyValueStorageTransaction, never())
.put(eq(blockHeaderChainA.getHash().toArrayUnsafe()), any());
verify(keyValueStorageTransaction, never())
.put(eq(blockHeaderChainB.getHash().toArrayUnsafe()), any());
}
}

0 comments on commit 49e4fd8

Please sign in to comment.