Add BlockHash to WorldStateArchive query (#1732)

Bonsai tries will require storing state by block hash rather than by
state root.  To accommodate both forest mode and bonsai mode all state
queries will pass in both the block hash and state root.  This also
permits parallel forest/bonsai modes for private state with bonsai
public state.

Signed-off-by: Danno Ferrin <danno.ferrin@gmail.com>
pull/1753/head
Danno Ferrin 4 years ago committed by GitHub
parent ac82a075a2
commit fdc1c2d4bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      besu/src/main/java/org/hyperledger/besu/chainimport/JsonBlockImporter.java
  2. 2
      besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java
  3. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java
  4. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockReplay.java
  5. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
  6. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java
  7. 2
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracerTest.java
  8. 17
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesTest.java
  9. 2
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
  10. 2
      ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java
  11. 26
      ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java
  12. 19
      ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/worldstate/PrunerIntegrationTest.java
  13. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
  14. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiWorldStateArchive.java
  15. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/OnChainPrivacyPrecompiledContract.java
  16. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java
  17. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/ChainHeadPrivateNonceProvider.java
  18. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java
  19. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateRehydration.java
  20. 7
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionSimulator.java
  21. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateWorldStateReader.java
  22. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateStorageMigration.java
  23. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java
  24. 10
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DefaultWorldStateArchive.java
  25. 12
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/WorldStateArchive.java
  26. 2
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TestCodeExecutor.java
  27. 9
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java
  28. 5
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java
  29. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/OnChainPrivacyPrecompiledContractTest.java
  30. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java
  31. 9
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/ChainHeadPrivateNonceProviderTest.java
  32. 9
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/PrivateWorldStateReaderTest.java
  33. 11
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateStorageMigrationTest.java
  34. 6
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java
  35. 6
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java
  36. 12
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/MarkSweepPrunerTest.java
  37. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManager.java
  38. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
  39. 17
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManagerTest.java
  40. 12
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderTest.java
  41. 2
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java

@ -84,7 +84,7 @@ public class JsonBlockImporter {
controller
.getProtocolContext()
.getWorldStateArchive()
.get(parentHeader.getStateRoot())
.get(parentHeader.getStateRoot(), parentHeader.getHash())
.get();
final List<Transaction> transactions =
blockData.streamTransactions(worldState).collect(Collectors.toList());

@ -125,7 +125,7 @@ public class BesuEventsImplTest {
.thenReturn(ValidationResult.valid());
when(mockTransactionValidator.validateForSender(any(), any(), any()))
.thenReturn(ValidationResult.valid());
when(mockWorldStateArchive.get(any())).thenReturn(Optional.of(mockWorldState));
when(mockWorldStateArchive.get(any(), any())).thenReturn(Optional.of(mockWorldState));
blockBroadcaster = new BlockBroadcaster(mockEthContext);
syncState = new SyncState(blockchain, mockEthPeers);

@ -68,7 +68,7 @@ public class EthEstimateGas implements JsonRpcMethod {
}
if (!blockchainQueries
.getWorldStateArchive()
.isWorldStateAvailable(blockHeader.getStateRoot())) {
.isWorldStateAvailable(blockHeader.getStateRoot(), blockHeader.getHash())) {
return errorResponse(requestContext, JsonRpcError.WORLD_STATE_UNAVAILABLE);
}

@ -146,7 +146,7 @@ public class BlockReplay {
return Optional.empty();
}
final MutableWorldState mutableWorldState =
worldStateArchive.getMutable(previous.getStateRoot()).orElse(null);
worldStateArchive.getMutable(previous.getStateRoot(), previous.getHash()).orElse(null);
if (mutableWorldState == null) {
return Optional.empty();
}

@ -730,7 +730,9 @@ public class BlockchainQueries {
*/
public Optional<MutableWorldState> getWorldState(final long blockNumber) {
final Optional<BlockHeader> header = blockchain.getBlockHeader(blockNumber);
return header.map(BlockHeader::getStateRoot).flatMap(worldStateArchive::getMutable);
return header.flatMap(
blockHeader ->
worldStateArchive.getMutable(blockHeader.getStateRoot(), blockHeader.getHash()));
}
public Optional<Long> gasPrice() {

@ -76,7 +76,7 @@ public class EthEstimateGasTest {
when(blockchain.getBlockHeader(eq(1L))).thenReturn(Optional.of(blockHeader));
when(blockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE);
when(blockHeader.getNumber()).thenReturn(1L);
when(worldStateArchive.isWorldStateAvailable(any())).thenReturn(true);
when(worldStateArchive.isWorldStateAvailable(any(), any())).thenReturn(true);
method = new EthEstimateGas(blockchainQueries, transactionSimulator);
}
@ -223,7 +223,7 @@ public class EthEstimateGasTest {
@Test
public void shouldReturnErrorWhenWorldStateIsNotAvailable() {
when(worldStateArchive.isWorldStateAvailable(any())).thenReturn(false);
when(worldStateArchive.isWorldStateAvailable(any(), any())).thenReturn(false);
final JsonRpcRequestContext request =
ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO));
mockTransientProcessorResultGasEstimate(1L, false, false);

@ -110,7 +110,7 @@ public class TransactionTracerTest {
when(blockHeader.getHash()).thenReturn(blockHash);
when(blockHeader.getParentHash()).thenReturn(previousBlockHash);
when(previousBlockHeader.getStateRoot()).thenReturn(Hash.ZERO);
when(worldStateArchive.getMutable(Hash.ZERO)).thenReturn(Optional.of(mutableWorldState));
when(worldStateArchive.getMutable(Hash.ZERO, null)).thenReturn(Optional.of(mutableWorldState));
when(protocolSchedule.getByBlockNumber(12)).thenReturn(protocolSpec);
when(protocolSpec.getTransactionProcessor()).thenReturn(transactionProcessor);
when(protocolSpec.getMiningBeneficiaryCalculator()).thenReturn(BlockHeader::getCoinbase);

@ -204,8 +204,10 @@ public class BlockchainQueriesTest {
final BlockchainWithData data = setupBlockchain(3, addresses, storageKeys);
final BlockchainQueries queries = data.blockchainQueries;
final Hash latestStateRoot0 = data.blockData.get(2).block.getHeader().getStateRoot();
final WorldState worldState0 = data.worldStateArchive.get(latestStateRoot0).get();
final BlockHeader blockHeader0 = data.blockData.get(2).block.getHeader();
final Hash latestStateRoot0 = blockHeader0.getStateRoot();
final WorldState worldState0 =
data.worldStateArchive.get(latestStateRoot0, blockHeader0.getHash()).get();
addresses.forEach(
address ->
storageKeys.forEach(
@ -215,8 +217,10 @@ public class BlockchainQueriesTest {
assertThat(result).contains(actualAccount0.getStorageValue(storageKey));
}));
final Hash latestStateRoot1 = data.blockData.get(1).block.getHeader().getStateRoot();
final WorldState worldState1 = data.worldStateArchive.get(latestStateRoot1).get();
final BlockHeader header1 = data.blockData.get(1).block.getHeader();
final Hash latestStateRoot1 = header1.getStateRoot();
final WorldState worldState1 =
data.worldStateArchive.get(latestStateRoot1, header1.getHash()).get();
addresses.forEach(
address ->
storageKeys.forEach(
@ -236,8 +240,9 @@ public class BlockchainQueriesTest {
for (int i = 0; i < blockCount; i++) {
final long curBlockNumber = i;
final Hash stateRoot = data.blockData.get(i).block.getHeader().getStateRoot();
final WorldState worldState = data.worldStateArchive.get(stateRoot).get();
final BlockHeader header = data.blockData.get(i).block.getHeader();
final Hash stateRoot = header.getStateRoot();
final WorldState worldState = data.worldStateArchive.get(stateRoot, header.getHash()).get();
assertThat(addresses).isNotEmpty();
addresses.forEach(

@ -240,7 +240,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
final MutableWorldState worldState =
protocolContext
.getWorldStateArchive()
.getMutable(parentStateRoot)
.getMutable(parentStateRoot, parentHeader.getHash())
.orElseThrow(
() -> {
LOG.info("Unable to create block because world state is not available");

@ -147,7 +147,7 @@ public class PrivacyPrecompiledContractIntegrationTest {
final MutableWorldState mutableWorldState = mock(MutableWorldState.class);
when(mutableWorldState.updater()).thenReturn(mock(WorldUpdater.class));
when(worldStateArchive.getMutable()).thenReturn(mutableWorldState);
when(worldStateArchive.getMutable(any())).thenReturn(Optional.of(mutableWorldState));
when(worldStateArchive.getMutable(any(), any())).thenReturn(Optional.of(mutableWorldState));
privateStateStorage = mock(PrivateStateStorage.class);
final PrivateStateStorage.Updater storageUpdater = mock(PrivateStateStorage.Updater.class);

@ -21,6 +21,7 @@ import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.Account;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
@ -86,16 +87,19 @@ public class TraceTransactionIntegrationTest {
.value(Wei.ZERO)
.signAndBuild(keyPair);
final BlockHeader genesisBlockHeader = genesisBlock.getHeader();
final MutableWorldState worldState =
worldStateArchive.getMutable(genesisBlock.getHeader().getStateRoot()).get();
worldStateArchive
.getMutable(genesisBlockHeader.getStateRoot(), genesisBlockHeader.getHash())
.get();
final WorldUpdater createTransactionUpdater = worldState.updater();
TransactionProcessingResult result =
transactionProcessor.processTransaction(
blockchain,
createTransactionUpdater,
genesisBlock.getHeader(),
genesisBlockHeader,
createTransaction,
genesisBlock.getHeader().getCoinbase(),
genesisBlockHeader.getCoinbase(),
blockHashLookup,
false,
TransactionValidationParams.blockReplay());
@ -125,9 +129,9 @@ public class TraceTransactionIntegrationTest {
transactionProcessor.processTransaction(
blockchain,
storeUpdater,
genesisBlock.getHeader(),
genesisBlockHeader,
executeTransaction,
genesisBlock.getHeader().getCoinbase(),
genesisBlockHeader.getCoinbase(),
tracer,
blockHashLookup,
false);
@ -159,14 +163,18 @@ public class TraceTransactionIntegrationTest {
final Transaction transaction =
Transaction.readFrom(
new BytesValueRLPInput(Bytes.fromHexString(CONTRACT_CREATION_TX), false));
BlockHeader genesisBlockHeader = genesisBlock.getHeader();
transactionProcessor.processTransaction(
blockchain,
worldStateArchive.getMutable(genesisBlock.getHeader().getStateRoot()).get().updater(),
genesisBlock.getHeader(),
worldStateArchive
.getMutable(genesisBlockHeader.getStateRoot(), genesisBlockHeader.getHash())
.get()
.updater(),
genesisBlockHeader,
transaction,
genesisBlock.getHeader().getCoinbase(),
genesisBlockHeader.getCoinbase(),
tracer,
new BlockHashLookup(genesisBlock.getHeader(), blockchain),
new BlockHashLookup(genesisBlockHeader, blockchain),
false);
final int expectedDepth = 0; // Reference impl returned 1. Why the difference?

@ -137,9 +137,11 @@ public class PrunerIntegrationTest {
// Assert that blocks from mark point onward are still accessible
for (int i = fullyMarkedBlockNum; i <= blockchain.getChainHeadBlockNumber(); i++) {
final Hash stateRoot = blockchain.getBlockHeader(i).get().getStateRoot();
assertThat(worldStateArchive.get(stateRoot)).isPresent();
final WorldState markedState = worldStateArchive.get(stateRoot).get();
final BlockHeader blockHeader = blockchain.getBlockHeader(i).get();
final Hash stateRoot = blockHeader.getStateRoot();
assertThat(worldStateArchive.get(stateRoot, blockHeader.getHash())).isPresent();
final WorldState markedState =
worldStateArchive.get(stateRoot, blockHeader.getHash()).get();
// Traverse accounts and make sure all are accessible
final int expectedAccounts = accountsPerBlock * i;
final long accounts =
@ -155,7 +157,8 @@ public class PrunerIntegrationTest {
for (int i = 0; i < fullyMarkedBlockNum; i++) {
final BlockHeader curHeader = blockchain.getBlockHeader(i).get();
if (!curHeader.getStateRoot().equals(Hash.EMPTY_TRIE_HASH)) {
assertThat(worldStateArchive.get(curHeader.getStateRoot())).isEmpty();
assertThat(worldStateArchive.get(curHeader.getStateRoot(), curHeader.getHash()))
.isEmpty();
}
}
@ -172,8 +175,10 @@ public class PrunerIntegrationTest {
private void generateBlockchainData(final int numBlocks, final int numAccounts) {
Block parentBlock = blockchain.getChainHeadBlock();
for (int i = 0; i < numBlocks; i++) {
final BlockHeader parentHeader = parentBlock.getHeader();
final Hash parentHash = parentBlock.getHash();
final MutableWorldState worldState =
worldStateArchive.getMutable(parentBlock.getHeader().getStateRoot()).get();
worldStateArchive.getMutable(parentHeader.getStateRoot(), parentHash).get();
gen.createRandomContractAccountsWithNonEmptyStorage(worldState, numAccounts);
final Hash stateRoot = worldState.rootHash();
@ -181,8 +186,8 @@ public class PrunerIntegrationTest {
gen.block(
BlockOptions.create()
.setStateRoot(stateRoot)
.setBlockNumber(parentBlock.getHeader().getNumber() + 1L)
.setParentHash(parentBlock.getHash()));
.setBlockNumber(parentHeader.getNumber() + 1L)
.setParentHash(parentHash));
final List<TransactionReceipt> receipts = gen.receipts(block);
blockchain.appendBlock(block, receipts);
parentBlock = block;

@ -83,7 +83,9 @@ public class MainnetBlockValidator implements BlockValidator {
final MutableBlockchain blockchain = context.getBlockchain();
final Optional<MutableWorldState> maybeWorldState =
context.getWorldStateArchive().getMutable(parentHeader.getStateRoot());
context
.getWorldStateArchive()
.getMutable(parentHeader.getStateRoot(), parentHeader.getHash());
if (!maybeWorldState.isPresent()) {
LOG.debug(
"Unable to process block {} because parent world state {} is not available",

@ -53,7 +53,7 @@ public class BonsaiWorldStateArchive implements WorldStateArchive {
}
@Override
public Optional<WorldState> get(final Hash rootHash) {
public Optional<WorldState> get(final Hash rootHash, final Hash blockHash) {
if (layeredWorldStates.containsKey(rootHash)) {
return Optional.of(layeredWorldStates.get(rootHash));
} else if (rootHash.equals(persistedState.rootHash())) {
@ -68,13 +68,13 @@ public class BonsaiWorldStateArchive implements WorldStateArchive {
}
@Override
public boolean isWorldStateAvailable(final Hash rootHash) {
public boolean isWorldStateAvailable(final Hash rootHash, final Hash blockHash) {
return layeredWorldStates.containsKey(rootHash)
|| persistedState.rootHash().equals(rootHash) /* || check disk storage */;
}
@Override
public Optional<MutableWorldState> getMutable(final Hash rootHash) {
public Optional<MutableWorldState> getMutable(final Hash rootHash, final Hash blockHash) {
if (rootHash.equals(persistedState.rootHash())) {
return Optional.of(persistedState);
} else {

@ -147,7 +147,7 @@ public class OnChainPrivacyPrecompiledContract extends PrivacyPrecompiledContrac
privateStateRootResolver.resolveLastStateRoot(privacyGroupId, privateMetadataUpdater);
final MutableWorldState disposablePrivateState =
privateWorldStateArchive.getMutable(lastRootHash).get();
privateWorldStateArchive.getMutable(lastRootHash, null).get();
final WorldUpdater privateWorldStateUpdater = disposablePrivateState.updater();
@ -398,7 +398,7 @@ public class OnChainPrivacyPrecompiledContract extends PrivacyPrecompiledContrac
// privateTransactionProcessor.processTransaction(...) commits the state if the process was
// successful before it returns
final MutableWorldState localMutableState =
privateWorldStateArchive.getMutable(disposablePrivateState.rootHash()).get();
privateWorldStateArchive.getMutable(disposablePrivateState.rootHash(), null).get();
final WorldUpdater updater = localMutableState.updater();
return privateTransactionProcessor.processTransaction(

@ -158,7 +158,7 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
privateStateRootResolver.resolveLastStateRoot(privacyGroupId, privateMetadataUpdater);
final MutableWorldState disposablePrivateState =
privateWorldStateArchive.getMutable(lastRootHash).get();
privateWorldStateArchive.getMutable(lastRootHash, null).get();
final WorldUpdater privateWorldStateUpdater = disposablePrivateState.updater();

@ -40,10 +40,11 @@ public class ChainHeadPrivateNonceProvider implements PrivateNonceProvider {
@Override
public long getNonce(final Address sender, final Bytes32 privacyGroupId) {
final BlockHeader chainHeadHeader = blockchain.getChainHeadHeader();
Hash chainHeadHash = chainHeadHeader.getHash();
final Hash stateRoot =
privateStateRootResolver.resolveLastStateRoot(privacyGroupId, chainHeadHeader.getHash());
privateStateRootResolver.resolveLastStateRoot(privacyGroupId, chainHeadHash);
return privateWorldStateArchive
.get(stateRoot)
.get(stateRoot, chainHeadHash)
.map(
privateWorldState -> {
final Account account = privateWorldState.get(sender);

@ -121,7 +121,7 @@ public class PrivateGroupRehydrationBlockProcessor {
privateStateRootResolver.resolveLastStateRoot(privacyGroupId, metadataUpdater);
final MutableWorldState disposablePrivateState =
privateWorldStateArchive.getMutable(lastRootHash).get();
privateWorldStateArchive.getMutable(lastRootHash, null).get();
final WorldUpdater privateStateUpdater = disposablePrivateState.updater();
maybeInjectDefaultManagementAndProxy(
lastRootHash, disposablePrivateState, privateStateUpdater);

@ -150,8 +150,9 @@ public class PrivateStateRehydration {
final MutableWorldState publicWorldState =
blockchain
.getBlockHeader(blockHeader.getParentHash())
.map(BlockHeader::getStateRoot)
.flatMap(publicWorldStateArchive::getMutable)
.flatMap(
header ->
publicWorldStateArchive.getMutable(header.getStateRoot(), header.getHash()))
.orElseThrow(RuntimeException::new);
privateGroupRehydrationBlockProcessor.processBlock(

@ -94,7 +94,7 @@ public class PrivateTransactionSimulator {
}
final MutableWorldState publicWorldState =
worldStateArchive.getMutable(header.getStateRoot()).orElse(null);
worldStateArchive.getMutable(header.getStateRoot(), header.getHash()).orElse(null);
if (publicWorldState == null) {
return Optional.empty();
}
@ -105,7 +105,10 @@ public class PrivateTransactionSimulator {
privateStateRootResolver.resolveLastStateRoot(privacyGroupId, header.getHash());
final MutableWorldState disposablePrivateState =
privacyParameters.getPrivateWorldStateArchive().getMutable(lastRootHash).get();
privacyParameters
.getPrivateWorldStateArchive()
.getMutable(lastRootHash, header.getHash())
.get();
final PrivateTransaction transaction =
getPrivateTransaction(callParams, header, privacyGroupId, disposablePrivateState);

@ -50,7 +50,7 @@ public class PrivateWorldStateReader {
Bytes32.wrap(Bytes.fromBase64String(privacyGroupId)), blockHash);
return privateWorldStateArchive
.get(latestStateRoot)
.get(latestStateRoot, blockHash)
.flatMap(worldState -> Optional.ofNullable(worldState.get(contractAddress)))
.flatMap(account -> Optional.ofNullable(account.getCode()));
}

@ -100,8 +100,9 @@ public class PrivateStorageMigration {
final MutableWorldState publicWorldState =
blockchain
.getBlockHeader(blockHeader.getParentHash())
.map(BlockHeader::getStateRoot)
.flatMap(publicWorldStateArchive::getMutable)
.flatMap(
header ->
publicWorldStateArchive.getMutable(header.getStateRoot(), header.getHash()))
.orElseThrow(PrivateStorageMigrationException::new);
final List<Transaction> transactionsToProcess =

@ -113,7 +113,7 @@ public class TransactionSimulator {
return Optional.empty();
}
final MutableWorldState worldState =
worldStateArchive.getMutable(header.getStateRoot()).orElse(null);
worldStateArchive.getMutable(header.getStateRoot(), header.getHash()).orElse(null);
if (worldState == null) {
return Optional.empty();
}
@ -179,7 +179,7 @@ public class TransactionSimulator {
}
final MutableWorldState worldState =
worldStateArchive.getMutable(header.getStateRoot()).orElse(null);
worldStateArchive.getMutable(header.getStateRoot(), header.getHash()).orElse(null);
if (worldState == null) {
return Optional.empty();
}

@ -44,17 +44,17 @@ public class DefaultWorldStateArchive implements WorldStateArchive {
}
@Override
public Optional<WorldState> get(final Hash rootHash) {
return getMutable(rootHash).map(state -> state);
public Optional<WorldState> get(final Hash rootHash, final Hash blockHash) {
return getMutable(rootHash, blockHash).map(state -> state);
}
@Override
public boolean isWorldStateAvailable(final Hash rootHash) {
public boolean isWorldStateAvailable(final Hash rootHash, final Hash blockHash) {
return worldStateStorage.isWorldStateAvailable(rootHash);
}
@Override
public Optional<MutableWorldState> getMutable(final Hash rootHash) {
public Optional<MutableWorldState> getMutable(final Hash rootHash, final Hash blockHash) {
if (!worldStateStorage.isWorldStateAvailable(rootHash)) {
return Optional.empty();
}
@ -63,7 +63,7 @@ public class DefaultWorldStateArchive implements WorldStateArchive {
@Override
public MutableWorldState getMutable() {
return getMutable(EMPTY_ROOT_HASH).get();
return getMutable(EMPTY_ROOT_HASH, null).get();
}
@Override

@ -30,18 +30,16 @@ import org.apache.tuweni.units.bigints.UInt256;
public interface WorldStateArchive {
Hash EMPTY_ROOT_HASH = Hash.wrap(MerklePatriciaTrie.EMPTY_TRIE_NODE_HASH);
Optional<WorldState> get(final Hash rootHash);
Optional<WorldState> get(Hash rootHash, Hash blockHash);
boolean isWorldStateAvailable(final Hash rootHash);
boolean isWorldStateAvailable(Hash rootHash, Hash blockHash);
Optional<MutableWorldState> getMutable(final Hash rootHash);
Optional<MutableWorldState> getMutable(Hash rootHash, Hash blockHash);
MutableWorldState getMutable();
Optional<Bytes> getNodeData(final Hash hash);
Optional<Bytes> getNodeData(Hash hash);
Optional<WorldStateProof> getAccountProof(
final Hash worldStateRoot,
final Address accountAddress,
final List<UInt256> accountStorageKeys);
Hash worldStateRoot, Address accountAddress, List<UInt256> accountStorageKeys);
}

@ -101,6 +101,6 @@ public class TestCodeExecutor {
accountSetup.accept(senderAccount);
worldState.commit();
initialWorldState.persist(null);
return stateArchive.getMutable(initialWorldState.rootHash()).get().updater();
return stateArchive.getMutable(initialWorldState.rootHash(), null).get().updater();
}
}

@ -115,7 +115,8 @@ public class MainnetBlockValidatorTest {
eq(protocolContext),
eq(HeaderValidationMode.DETACHED_ONLY)))
.thenReturn(true);
when(worldStateArchive.getMutable(any(Hash.class))).thenReturn(Optional.empty());
when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class)))
.thenReturn(Optional.empty());
assertThat(badBlockManager.getBadBlocks().size()).isEqualTo(0);
mainnetBlockValidator.validateAndProcessBlock(
@ -136,7 +137,7 @@ public class MainnetBlockValidatorTest {
eq(protocolContext),
eq(HeaderValidationMode.DETACHED_ONLY)))
.thenReturn(true);
when(worldStateArchive.getMutable(any(Hash.class)))
when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class)))
.thenReturn(Optional.of(mock(MutableWorldState.class)));
when(blockProcessor.processBlock(eq(blockchain), any(MutableWorldState.class), eq(badBlock)))
.thenReturn(
@ -171,7 +172,7 @@ public class MainnetBlockValidatorTest {
eq(protocolContext),
eq(HeaderValidationMode.DETACHED_ONLY)))
.thenReturn(true);
when(worldStateArchive.getMutable(any(Hash.class)))
when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class)))
.thenReturn(Optional.of(mock(MutableWorldState.class)));
when(blockProcessor.processBlock(eq(blockchain), any(MutableWorldState.class), eq(badBlock)))
.thenReturn(
@ -206,7 +207,7 @@ public class MainnetBlockValidatorTest {
eq(protocolContext),
eq(HeaderValidationMode.DETACHED_ONLY)))
.thenReturn(true);
when(worldStateArchive.getMutable(any(Hash.class)))
when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class)))
.thenReturn(Optional.of(mock(MutableWorldState.class)));
when(blockProcessor.processBlock(eq(blockchain), any(MutableWorldState.class), eq(badBlock)))
.thenReturn(

@ -150,9 +150,10 @@ public class PrivacyBlockProcessorTest {
when(blockchain.getBlockHeader(any())).thenReturn(Optional.of(firstBlock.getHeader()));
final ProtocolSpec protocolSpec = mockProtocolSpec();
when(protocolSchedule.getByBlockNumber(anyLong())).thenReturn(protocolSpec);
when(publicWorldStateArchive.getMutable(any())).thenReturn(Optional.of(mutableWorldState));
when(publicWorldStateArchive.getMutable(any(), any()))
.thenReturn(Optional.of(mutableWorldState));
final MutableWorldState mockPrivateStateArchive = mockPrivateStateArchive();
when(privateWorldStateArchive.getMutable(any()))
when(privateWorldStateArchive.getMutable(any(), any()))
.thenReturn(Optional.of(mockPrivateStateArchive));
final PrivacyGroupHeadBlockMap expected =

@ -107,7 +107,7 @@ public class OnChainPrivacyPrecompiledContractTest {
final MutableWorldState mutableWorldState = mock(MutableWorldState.class);
when(mutableWorldState.updater()).thenReturn(mock(WorldUpdater.class));
when(worldStateArchive.getMutable()).thenReturn(mutableWorldState);
when(worldStateArchive.getMutable(any())).thenReturn(Optional.of(mutableWorldState));
when(worldStateArchive.getMutable(any(), any())).thenReturn(Optional.of(mutableWorldState));
final PrivateStateStorage.Updater storageUpdater = mock(PrivateStateStorage.Updater.class);
when(privateStateStorage.getPrivacyGroupHeadBlockMap(any()))

@ -110,7 +110,7 @@ public class PrivacyPrecompiledContractTest {
final MutableWorldState mutableWorldState = mock(MutableWorldState.class);
when(mutableWorldState.updater()).thenReturn(mock(WorldUpdater.class));
when(worldStateArchive.getMutable()).thenReturn(mutableWorldState);
when(worldStateArchive.getMutable(any())).thenReturn(Optional.of(mutableWorldState));
when(worldStateArchive.getMutable(any(), any())).thenReturn(Optional.of(mutableWorldState));
when(privateMetadataUpdater.getPrivacyGroupHeadBlockMap())
.thenReturn(PrivacyGroupHeadBlockMap.empty());

@ -67,7 +67,8 @@ public class ChainHeadPrivateNonceProviderTest {
public void determineNonceForPrivacyGroupRequestWhenPrivateStateDoesNotExist() {
when(privateStateRootResolver.resolveLastStateRoot(any(Bytes32.class), any(Hash.class)))
.thenReturn(Hash.ZERO);
when(privateWorldStateArchive.get(any(Hash.class))).thenReturn(Optional.empty());
when(privateWorldStateArchive.get(any(Hash.class), any(Hash.class)))
.thenReturn(Optional.empty());
final long nonce = privateNonceProvider.getNonce(ADDRESS, PRIVACY_GROUP_ID);
@ -80,7 +81,8 @@ public class ChainHeadPrivateNonceProviderTest {
when(worldState.get(any(Address.class))).thenReturn(account);
when(privateStateRootResolver.resolveLastStateRoot(any(Bytes32.class), any(Hash.class)))
.thenReturn(Hash.ZERO);
when(privateWorldStateArchive.get(any(Hash.class))).thenReturn(Optional.of(worldState));
when(privateWorldStateArchive.get(any(Hash.class), any(Hash.class)))
.thenReturn(Optional.of(worldState));
final long nonce = privateNonceProvider.getNonce(ADDRESS, PRIVACY_GROUP_ID);
@ -91,7 +93,8 @@ public class ChainHeadPrivateNonceProviderTest {
public void determineNonceForPrivacyGroupRequestWhenAccountDoesNotExist() {
when(privateStateRootResolver.resolveLastStateRoot(any(Bytes32.class), any(Hash.class)))
.thenReturn(Hash.ZERO);
when(privateWorldStateArchive.get(any(Hash.class))).thenReturn(Optional.of(worldState));
when(privateWorldStateArchive.get(any(Hash.class), any(Hash.class)))
.thenReturn(Optional.of(worldState));
when(account.getNonce()).thenReturn(4L);
final long nonce = privateNonceProvider.getNonce(ADDRESS, PRIVACY_GROUP_ID);

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture.generatePrivateBlockMetadata;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@ -81,7 +82,7 @@ public class PrivateWorldStateReaderTest {
when(privateStateRootResolver.resolveLastStateRoot(eq(privacyGroupBytes), eq(blockHash)))
.thenReturn(stateRootHash);
when(privateWorldStateArchive.get(eq(stateRootHash))).thenReturn(Optional.empty());
when(privateWorldStateArchive.get(eq(stateRootHash), any())).thenReturn(Optional.empty());
final Optional<Bytes> maybecontractCode =
privateWorldStateReader.getContractCode(PRIVACY_GROUP_ID, blockHash, contractAddress);
@ -96,7 +97,7 @@ public class PrivateWorldStateReaderTest {
when(privateStateRootResolver.resolveLastStateRoot(eq(privacyGroupBytes), eq(blockHash)))
.thenReturn(stateRootHash);
when(privateWorldStateArchive.get(eq(stateRootHash)))
when(privateWorldStateArchive.get(eq(stateRootHash), any()))
.thenReturn(Optional.of(privateWorldState));
when(privateWorldState.get(eq(contractAddress))).thenReturn(null);
@ -113,7 +114,7 @@ public class PrivateWorldStateReaderTest {
when(privateStateRootResolver.resolveLastStateRoot(eq(privacyGroupBytes), eq(blockHash)))
.thenReturn(stateRootHash);
when(privateWorldStateArchive.get(eq(stateRootHash)))
when(privateWorldStateArchive.get(eq(stateRootHash), any()))
.thenReturn(Optional.of(privateWorldState));
when(privateWorldState.get(eq(contractAddress))).thenReturn(contractAccount);
when(contractAccount.getCode()).thenReturn(null);
@ -128,7 +129,7 @@ public class PrivateWorldStateReaderTest {
public void existingAccountWithCodeReturnsExpectedBytes() {
when(privateStateRootResolver.resolveLastStateRoot(eq(PRIVACY_GROUP_ID_BYTES), eq(blockHash)))
.thenReturn(stateRootHash);
when(privateWorldStateArchive.get(eq(stateRootHash)))
when(privateWorldStateArchive.get(eq(stateRootHash), any()))
.thenReturn(Optional.of(privateWorldState));
when(privateWorldState.get(eq(contractAddress))).thenReturn(contractAccount);
when(contractAccount.getCode()).thenReturn(contractCode);

@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
@ -297,11 +298,13 @@ public class PrivateStorageMigrationTest {
}
private void mockBlockInBlockchain(final Block block) {
when(blockchain.getBlockByNumber(block.getHeader().getNumber())).thenReturn(Optional.of(block));
when(blockchain.getBlockHeader(block.getHash())).thenReturn(Optional.of(block.getHeader()));
when(blockchain.getBlockBody(block.getHash())).thenReturn(Optional.of(block.getBody()));
final BlockHeader blockHeader = block.getHeader();
final Hash blockHash = block.getHash();
when(blockchain.getBlockByNumber(blockHeader.getNumber())).thenReturn(Optional.of(block));
when(blockchain.getBlockHeader(blockHash)).thenReturn(Optional.of(blockHeader));
when(blockchain.getBlockBody(blockHash)).thenReturn(Optional.of(block.getBody()));
when(publicWorldStateArchive.getMutable(block.getHeader().getStateRoot()))
when(publicWorldStateArchive.getMutable(blockHeader.getStateRoot(), blockHash))
.thenReturn(Optional.of(publicMutableWorldState));
}

@ -409,19 +409,19 @@ public class TransactionSimulatorTest {
final Hash stateRoot, final Address address, final long nonce) {
final Account account = mock(Account.class);
when(account.getNonce()).thenReturn(nonce);
when(worldStateArchive.getMutable(eq(stateRoot))).thenReturn(Optional.of(worldState));
when(worldStateArchive.getMutable(eq(stateRoot), any())).thenReturn(Optional.of(worldState));
when(worldState.get(eq(address))).thenReturn(account);
}
private void mockWorldStateForAbsentAccount(final Hash stateRoot) {
when(worldStateArchive.getMutable(eq(stateRoot))).thenReturn(Optional.of(worldState));
when(worldStateArchive.getMutable(eq(stateRoot), any())).thenReturn(Optional.of(worldState));
when(worldState.get(any())).thenReturn(null);
}
private MutableAccount mockWorldUpdaterForAccount(final Hash stateRoot, final Address address) {
final EvmAccount account = mock(EvmAccount.class);
final MutableAccount mutableAccount = mock(MutableAccount.class);
when(worldStateArchive.getMutable(eq(stateRoot))).thenReturn(Optional.of(worldState));
when(worldStateArchive.getMutable(eq(stateRoot), any())).thenReturn(Optional.of(worldState));
when(worldState.updater()).thenReturn(worldUpdater);
when(worldUpdater.getOrCreate(eq(address))).thenReturn(account);
when(account.getMutable()).thenReturn(mutableAccount);

@ -90,9 +90,11 @@ public class BlockchainReferenceTestTools {
}
public static void executeTest(final BlockchainReferenceTestCaseSpec spec) {
final MutableWorldState worldState =
spec.getWorldStateArchive().getMutable(spec.getGenesisBlockHeader().getStateRoot()).get();
final BlockHeader genesisBlockHeader = spec.getGenesisBlockHeader();
final MutableWorldState worldState =
spec.getWorldStateArchive()
.getMutable(genesisBlockHeader.getStateRoot(), genesisBlockHeader.getHash())
.get();
assertThat(worldState.rootHash()).isEqualTo(genesisBlockHeader.getStateRoot());
final ProtocolSchedule schedule =

@ -87,8 +87,9 @@ public class MarkSweepPrunerTest {
pruner.sweepBefore(markBlock.getNumber());
// Assert that the block we marked is still present and all accounts are accessible
assertThat(worldStateArchive.get(markBlock.getStateRoot())).isPresent();
final WorldState markedState = worldStateArchive.get(markBlock.getStateRoot()).get();
assertThat(worldStateArchive.get(markBlock.getStateRoot(), markBlock.getHash())).isPresent();
final WorldState markedState =
worldStateArchive.get(markBlock.getStateRoot(), markBlock.getHash()).get();
// Traverse accounts and make sure all are accessible
final int expectedAccounts = numAccounts * markBlockNumber;
final long accounts = markedState.streamAccounts(Bytes32.ZERO, expectedAccounts * 2).count();
@ -104,7 +105,7 @@ public class MarkSweepPrunerTest {
if (curHeader.getNumber() == markBlock.getNumber()) {
continue;
}
assertThat(worldStateArchive.get(curHeader.getStateRoot())).isEmpty();
assertThat(worldStateArchive.get(curHeader.getStateRoot(), curHeader.getHash())).isEmpty();
}
// Check that storage contains only the values we expect
@ -189,8 +190,9 @@ public class MarkSweepPrunerTest {
private void generateBlockchainData(final int numBlocks, final int numAccounts) {
Block parentBlock = blockchain.getChainHeadBlock();
for (int i = 0; i < numBlocks; i++) {
final BlockHeader parentHeader = parentBlock.getHeader();
final MutableWorldState worldState =
worldStateArchive.getMutable(parentBlock.getHeader().getStateRoot()).get();
worldStateArchive.getMutable(parentHeader.getStateRoot(), parentHeader.getHash()).get();
gen.createRandomContractAccountsWithNonEmptyStorage(worldState, numAccounts);
final Hash stateRoot = worldState.rootHash();
@ -198,7 +200,7 @@ public class MarkSweepPrunerTest {
gen.block(
BlockOptions.create()
.setStateRoot(stateRoot)
.setBlockNumber(parentBlock.getHeader().getNumber() + 1L)
.setBlockNumber(parentHeader.getNumber() + 1L)
.setParentHash(parentBlock.getHash()));
final List<TransactionReceipt> receipts = gen.receipts(block);
blockchain.appendBlock(block, receipts);

@ -56,7 +56,7 @@ class FullSyncTargetManager extends SyncTargetManager {
final BlockHeader commonAncestor = syncTarget.commonAncestor();
if (protocolContext
.getWorldStateArchive()
.isWorldStateAvailable(commonAncestor.getStateRoot())) {
.isWorldStateAvailable(commonAncestor.getStateRoot(), commonAncestor.getHash())) {
return Optional.of(syncTarget);
} else {
LOG.warn(

@ -251,7 +251,7 @@ public class TransactionPool implements BlockAddedObserver {
return protocolContext
.getWorldStateArchive()
.get(chainHeadBlockHeader.getStateRoot())
.get(chainHeadBlockHeader.getStateRoot(), chainHeadBlockHeader.getHash())
.map(
worldState -> {
final Account senderAccount = worldState.get(transaction.getSender());

@ -21,6 +21,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture;
@ -90,7 +91,9 @@ public class FullSyncTargetManagerTest {
@Test
public void findSyncTarget_withHeightEstimates() {
when(localWorldState.isWorldStateAvailable(localBlockchain.getChainHeadHeader().getStateRoot()))
final BlockHeader chainHeadHeader = localBlockchain.getChainHeadHeader();
when(localWorldState.isWorldStateAvailable(
chainHeadHeader.getStateRoot(), chainHeadHeader.getHash()))
.thenReturn(true);
final RespondingEthPeer bestPeer =
EthProtocolManagerTestUtil.createPeer(ethProtocolManager, Difficulty.MAX_VALUE, 4);
@ -105,7 +108,9 @@ public class FullSyncTargetManagerTest {
@Test
public void findSyncTarget_noHeightEstimates() {
when(localWorldState.isWorldStateAvailable(localBlockchain.getChainHeadHeader().getStateRoot()))
final BlockHeader chainHeadHeader = localBlockchain.getChainHeadHeader();
when(localWorldState.isWorldStateAvailable(
chainHeadHeader.getStateRoot(), chainHeadHeader.getHash()))
.thenReturn(true);
final RespondingEthPeer bestPeer =
EthProtocolManagerTestUtil.createPeer(ethProtocolManager, Difficulty.MAX_VALUE, 0);
@ -118,7 +123,9 @@ public class FullSyncTargetManagerTest {
@Test
public void shouldDisconnectPeerIfWorldStateIsUnavailableForCommonAncestor() {
when(localWorldState.isWorldStateAvailable(localBlockchain.getChainHeadHeader().getStateRoot()))
final BlockHeader chainHeadHeader = localBlockchain.getChainHeadHeader();
when(localWorldState.isWorldStateAvailable(
chainHeadHeader.getStateRoot(), chainHeadHeader.getHash()))
.thenReturn(false);
final RespondingEthPeer bestPeer =
EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 20);
@ -133,7 +140,9 @@ public class FullSyncTargetManagerTest {
@Test
public void shouldAllowSyncTargetWhenIfWorldStateIsAvailableForCommonAncestor() {
when(localWorldState.isWorldStateAvailable(localBlockchain.getChainHeadHeader().getStateRoot()))
final BlockHeader chainHeadHeader = localBlockchain.getChainHeadHeader();
when(localWorldState.isWorldStateAvailable(
chainHeadHeader.getStateRoot(), chainHeadHeader.getHash()))
.thenReturn(true);
final RespondingEthPeer bestPeer =
EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 20);

@ -266,7 +266,7 @@ public class WorldStateDownloaderTest {
// Check that all expected account data was downloaded
final WorldStateArchive localWorldStateArchive =
new DefaultWorldStateArchive(localStorage, createPreimageStorage());
final WorldState localWorldState = localWorldStateArchive.get(stateRoot).get();
final WorldState localWorldState = localWorldStateArchive.get(stateRoot, null).get();
assertThat(result).isDone();
assertAccountsMatch(localWorldState, accounts);
}
@ -335,7 +335,7 @@ public class WorldStateDownloaderTest {
// Check that all expected account data was downloaded
final WorldStateArchive localWorldStateArchive =
new DefaultWorldStateArchive(localStorage, createPreimageStorage());
final WorldState localWorldState = localWorldStateArchive.get(stateRoot).get();
final WorldState localWorldState = localWorldStateArchive.get(stateRoot, null).get();
assertThat(result).isDone();
assertAccountsMatch(localWorldState, accounts);
}
@ -501,7 +501,7 @@ public class WorldStateDownloaderTest {
// Check that all expected account data was downloaded
final WorldStateArchive localWorldStateArchive =
new DefaultWorldStateArchive(localStorage, createPreimageStorage());
final WorldState localWorldState = localWorldStateArchive.get(stateRoot).get();
final WorldState localWorldState = localWorldStateArchive.get(stateRoot, null).get();
assertThat(result).isDone();
assertAccountsMatch(localWorldState, accounts);
}
@ -600,7 +600,7 @@ public class WorldStateDownloaderTest {
// Check that all expected account data was downloaded
final WorldStateArchive localWorldStateArchive =
new DefaultWorldStateArchive(localStorage, createPreimageStorage());
final WorldState localWorldState = localWorldStateArchive.get(stateRoot).get();
final WorldState localWorldState = localWorldStateArchive.get(stateRoot, null).get();
assertThat(result).isDone();
assertAccountsMatch(localWorldState, accounts);
}
@ -732,7 +732,7 @@ public class WorldStateDownloaderTest {
assertThat(result).isDone();
final WorldStateArchive localWorldStateArchive =
new DefaultWorldStateArchive(localStorage, createPreimageStorage());
final WorldState localWorldState = localWorldStateArchive.get(stateRoot).get();
final WorldState localWorldState = localWorldStateArchive.get(stateRoot, null).get();
assertAccountsMatch(localWorldState, accounts);
}
@ -875,7 +875,7 @@ public class WorldStateDownloaderTest {
}
// Check that all expected account data was downloaded
final WorldState localWorldState = localWorldStateArchive.get(stateRoot).get();
final WorldState localWorldState = localWorldStateArchive.get(stateRoot, null).get();
assertThat(result).isDone();
assertAccountsMatch(localWorldState, accounts);

@ -166,7 +166,7 @@ public class TransactionPoolFactoryTest {
.thenReturn(ValidationResult.valid());
when(transactionValidator.validateForSender(any(), any(), any()))
.thenReturn(ValidationResult.valid());
when(worldStateArchive.get(any())).thenReturn(Optional.of(worldState));
when(worldStateArchive.get(any(), any())).thenReturn(Optional.of(worldState));
final TransactionPool pool =
TransactionPoolFactory.createTransactionPool(

Loading…
Cancel
Save