diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProvider.java index 944f668cd6..3f05323e2e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProvider.java @@ -37,8 +37,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; +import com.google.common.base.Suppliers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,17 +49,17 @@ public class KeyValueStorageProvider implements StorageProvider { protected final Function, SegmentedKeyValueStorage> segmentedStorageCreator; - private final KeyValueStorage worldStatePreimageStorage; + private final Supplier preimageStorageSupplier; protected final Map, SegmentedKeyValueStorage> storageInstances = new HashMap<>(); private final ObservableMetricsSystem metricsSystem; public KeyValueStorageProvider( final Function, SegmentedKeyValueStorage> segmentedStorageCreator, - final KeyValueStorage worldStatePreimageStorage, + final Supplier worldStatePreimageStorage, final ObservableMetricsSystem metricsSystem) { this.segmentedStorageCreator = segmentedStorageCreator; - this.worldStatePreimageStorage = worldStatePreimageStorage; + this.preimageStorageSupplier = Suppliers.memoize(worldStatePreimageStorage::get); this.metricsSystem = metricsSystem; } @@ -99,7 +101,7 @@ public class KeyValueStorageProvider implements StorageProvider { @Override public WorldStatePreimageStorage createWorldStatePreimageStorage() { - return new WorldStatePreimageKeyValueStorage(worldStatePreimageStorage); + return new WorldStatePreimageKeyValueStorage(preimageStorageSupplier.get()); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProviderBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProviderBuilder.java index 2c4ab8bcf7..11f8bded3a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProviderBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProviderBuilder.java @@ -23,8 +23,7 @@ import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; import org.hyperledger.besu.plugin.services.storage.KeyValueStorageFactory; import org.hyperledger.besu.services.kvstore.LimitedInMemoryKeyValueStorage; -import java.util.ArrayList; -import java.util.EnumSet; +import java.util.function.Supplier; public class KeyValueStorageProviderBuilder { @@ -58,22 +57,19 @@ public class KeyValueStorageProviderBuilder { "Cannot build a storage provider without the plugin common configuration."); checkNotNull(metricsSystem, "Cannot build a storage provider without a metrics system."); - // TODO: unhack this storage pre-init hack, maybe a memoized supplier - storageFactory.create( - new ArrayList<>(EnumSet.allOf(KeyValueSegmentIdentifier.class)), - commonConfiguration, - metricsSystem); - - final KeyValueStorage worldStatePreImageStorage = + final Supplier preimageStorageSupplier = commonConfiguration.getDataStorageConfiguration().getHashPreImageStorageEnabled() - ? storageFactory.create( - KeyValueSegmentIdentifier.HASH_PREIMAGE_STORE, commonConfiguration, metricsSystem) - : new LimitedInMemoryKeyValueStorage(DEFAULT_WORLD_STATE_PRE_IMAGE_CACHE_SIZE); + ? () -> + storageFactory.create( + KeyValueSegmentIdentifier.HASH_PREIMAGE_STORE, + commonConfiguration, + metricsSystem) + : () -> new LimitedInMemoryKeyValueStorage(DEFAULT_WORLD_STATE_PRE_IMAGE_CACHE_SIZE); ; return new KeyValueStorageProvider( segments -> storageFactory.create(segments, commonConfiguration, metricsSystem), - worldStatePreImageStorage, + preimageStorageSupplier, (ObservableMetricsSystem) metricsSystem); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/WorldStatePreimageKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/WorldStatePreimageKeyValueStorage.java index b312e23c0c..8824b3ef82 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/WorldStatePreimageKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/WorldStatePreimageKeyValueStorage.java @@ -49,11 +49,6 @@ public class WorldStatePreimageKeyValueStorage implements WorldStatePreimageStor .map(val -> Address.wrap(Bytes.wrap(val))); } - @Override - public boolean canSupportStreaming() { - return keyValueStorage.isPersistent(); - } - @Override public Updater updater() { return new Updater(keyValueStorage.startTransaction()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/GenesisWorldStateProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/GenesisWorldStateProvider.java index 78bcb417e3..5bb23d7b01 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/GenesisWorldStateProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/common/GenesisWorldStateProvider.java @@ -64,7 +64,7 @@ public class GenesisWorldStateProvider { new BonsaiWorldStateKeyValueStorage( new KeyValueStorageProvider( segmentIdentifiers -> new SegmentedInMemoryKeyValueStorage(), - new InMemoryKeyValueStorage(), + () -> new InMemoryKeyValueStorage(), new NoOpMetricsSystem()), new NoOpMetricsSystem(), DataStorageConfiguration.DEFAULT_BONSAI_CONFIG); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java index c1d32e14ab..a74ef1bf14 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java @@ -432,11 +432,6 @@ public class BonsaiWorldState extends DiffBasedWorldState { .map(UInt256::fromBytes); } - @Override - public Stream streamAccounts(final Bytes32 startKeyHash, final int limit) { - return worldStateKeyValueStorage.streamAccounts(this, startKeyHash, limit); - } - @Override public UInt256 getPriorStorageValue(final Address address, final UInt256 storageKey) { return getStorageValue(address, storageKey); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java index eb94eadc05..3aed9f5172 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java @@ -180,7 +180,7 @@ public abstract class DiffBasedWorldStateKeyValueStorage public NavigableMap storageEntriesFrom( final Hash addressHash, final Bytes32 startKeyHash, final int limit) { - if (preImageProxy != null && preImageProxy.canSupportStreaming()) { + if (preImageProxy != null) { return streamFlatStorages(addressHash, startKeyHash, UInt256.MAX_VALUE, limit) .entrySet() // map back to slot keys using preImage provider: @@ -201,28 +201,23 @@ public abstract class DiffBasedWorldStateKeyValueStorage public Stream streamAccounts( final DiffBasedWorldView context, final Bytes32 startKeyHash, final int limit) { - if (preImageProxy.canSupportStreaming()) { - return streamFlatAccounts(startKeyHash, UInt256.MAX_VALUE, limit) - .entrySet() - // map back to addresses using preImage provider: - .stream() - .map( - entry -> - preImageProxy - .getAccountTrieKeyPreimage(entry.getKey()) - .map( - address -> - new WorldState.StreamableAccount( - Optional.of(address), - BonsaiAccount.fromRLP( - context, address, entry.getValue(), false)))) - .filter(Optional::isPresent) - .map(Optional::get) - .filter(acct -> context.updater().getAccount(acct.getAddress().orElse(null)) != null) - .sorted(Comparator.comparing(account -> account.getAddress().orElse(Address.ZERO))); - } else { - throw new RuntimeException("Not configured to support enumerating accounts"); - } + return streamFlatAccounts(startKeyHash, UInt256.MAX_VALUE, limit) + .entrySet() + // map back to addresses using preImage provider: + .stream() + .map( + entry -> + preImageProxy + .getAccountTrieKeyPreimage(entry.getKey()) + .map( + address -> + new WorldState.StreamableAccount( + Optional.of(address), + BonsaiAccount.fromRLP(context, address, entry.getValue(), false)))) + .filter(Optional::isPresent) + .map(Optional::get) + .filter(acct -> context.updater().getAccount(acct.getAddress().orElse(null)) != null) + .sorted(Comparator.comparing(account -> account.getAddress().orElse(Address.ZERO))); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/NoOpTrieLogManager.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/NoOpTrieLogManager.java index edea97f4e9..8c8c2acbfc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/NoOpTrieLogManager.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/NoOpTrieLogManager.java @@ -29,7 +29,7 @@ public class NoOpTrieLogManager extends TrieLogManager { } @Override - public synchronized Optional saveTrieLog( + public synchronized void saveTrieLog( final DiffBasedWorldStateUpdateAccumulator localUpdater, final Hash forWorldStateRootHash, final BlockHeader forBlockHeader, @@ -37,7 +37,6 @@ public class NoOpTrieLogManager extends TrieLogManager { // notify trie log added observers, synchronously TrieLog trieLog = trieLogFactory.create(localUpdater, forBlockHeader); trieLogObservers.forEach(o -> o.onTrieLogAdded(new TrieLogAddedEvent(trieLog))); - return Optional.of(trieLog); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogManager.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogManager.java index 04e12867a0..70d45f546d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogManager.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogManager.java @@ -60,7 +60,7 @@ public class TrieLogManager { this.trieLogFactory = setupTrieLogFactory(pluginContext); } - public synchronized Optional saveTrieLog( + public synchronized void saveTrieLog( final DiffBasedWorldStateUpdateAccumulator localUpdater, final Hash forWorldStateRootHash, final BlockHeader forBlockHeader, @@ -80,7 +80,6 @@ public class TrieLogManager { trieLogObservers.forEach(o -> o.onTrieLogAdded(new TrieLogAddedEvent(trieLog))); success = true; - return Optional.of(trieLog); } finally { if (success) { stateUpdater.commit(); @@ -89,7 +88,6 @@ public class TrieLogManager { } } } - return Optional.empty(); } private TrieLog prepareTrieLog( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java index 46c226afa9..c3925ebdf9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java @@ -160,6 +160,33 @@ public abstract class DiffBasedWorldState final DiffBasedWorldStateKeyValueStorage.Updater stateUpdater = worldStateKeyValueStorage.updater(); Runnable saveTrieLog = () -> {}; + Runnable savePreimages = + () -> { + var preImageUpdater = worldStateKeyValueStorage.getPreimageStorage().updater(); + localCopy + .getAccountsToUpdate() + // log.getAccountChanges() + .keySet() + .forEach(acct -> preImageUpdater.putAccountTrieKeyPreimage(acct.addressHash(), acct)); + localCopy.getStorageToUpdate().values().stream() + .flatMap(z -> z.keySet().stream()) + .filter( + z -> { + // TODO: we should add logic here to prevent writing + // common slot keys + return z.getSlotKey().isPresent(); + }) + .distinct() + .forEach( + slot -> { + preImageUpdater.putStorageTrieKeyPreimage( + slot.getSlotHash(), slot.getSlotKey().get()); + }); + // prob need to override this in a bonsai implementation that simply defers to the trielog + // tx/commit + preImageUpdater.commit(); + }; + try { final Hash calculatedRootHash; @@ -183,40 +210,11 @@ public abstract class DiffBasedWorldState verifyWorldStateRoot(calculatedRootHash, blockHeader); saveTrieLog = () -> { - var trieLog = - trieLogManager.saveTrieLog(localCopy, calculatedRootHash, blockHeader, this); + trieLogManager.saveTrieLog(localCopy, calculatedRootHash, blockHeader, this); // not save a frozen state in the cache if (!worldStateConfig.isFrozen()) { cachedWorldStorageManager.addCachedLayer(blockHeader, calculatedRootHash, this); } - - // TODO: maybe move this, make conditional so we don't affect performance - // if we are not tracking preimages. using the trielog probably is going to get us - // duplicates - // because we will get updates in addition to creates :frown: - if (trieLog.isPresent()) { - var log = trieLog.get(); - var preImageUpdater = worldStateKeyValueStorage.getPreimageStorage().updater(); - log.getAccountChanges() - .keySet() - .forEach( - acct -> - preImageUpdater.putAccountTrieKeyPreimage(acct.addressHash(), acct)); - localCopy.getStorageToUpdate().values().stream() - .flatMap(z -> z.keySet().stream()) - .filter( - z -> { - // TODO: we should add logic here to prevent writing - // common slot keys - return z.getSlotKey().isPresent(); - }) - .distinct() - .forEach( - slot -> { - preImageUpdater.putStorageTrieKeyPreimage( - slot.getSlotHash(), slot.getSlotKey().get()); - }); - } }; stateUpdater @@ -238,6 +236,9 @@ public abstract class DiffBasedWorldState stateUpdater.commit(); accumulator.reset(); saveTrieLog.run(); + // TODO: maybe move this, make conditional so we don't affect performance + // if we are not tracking preimages. + savePreimages.run(); } else { stateUpdater.rollback(); accumulator.reset(); @@ -323,8 +324,9 @@ public abstract class DiffBasedWorldState } @Override - public abstract Stream streamAccounts( - final Bytes32 startKeyHash, final int limit); + public Stream streamAccounts(final Bytes32 startKeyHash, final int limit) { + return worldStateKeyValueStorage.streamAccounts(this, startKeyHash, limit); + } @Override public UInt256 getPriorStorageValue(final Address address, final UInt256 storageKey) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/WorldStatePreimageStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/WorldStatePreimageStorage.java index a48aa47c79..fde6572aa8 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/WorldStatePreimageStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/WorldStatePreimageStorage.java @@ -28,14 +28,6 @@ public interface WorldStatePreimageStorage { Optional
getAccountTrieKeyPreimage(Bytes32 trieKey); - /** - * This method indicates whether this Pre-Image store is "complete", meaning it has all of the - * hash preimages for all entries in the state trie. - * - * @return boolean indicating whether the pre-image store is complete or not - */ - boolean canSupportStreaming(); - Updater updater(); interface Updater { diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java index aa32ee2b05..3d75d0968e 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java @@ -37,7 +37,9 @@ import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; +import org.hyperledger.besu.services.kvstore.LimitedInMemoryKeyValueStorage; import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage; import java.util.Optional; @@ -47,7 +49,7 @@ public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider { public InMemoryKeyValueStorageProvider() { super( segmentIdentifiers -> new SegmentedInMemoryKeyValueStorage(), - new InMemoryKeyValueStorage(), + InMemoryKeyValueStorageProvider::get, new NoOpMetricsSystem()); } @@ -126,4 +128,8 @@ public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider { public static VariablesStorage createInMemoryVariablesStorage() { return new VariablesKeyValueStorage(new InMemoryKeyValueStorage()); } + + private static KeyValueStorage get() { + return new LimitedInMemoryKeyValueStorage(4000); + } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProviderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProviderTest.java index 87cc16c23c..75a2adb6b9 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProviderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProviderTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.storage.StorageProvider; +import org.hyperledger.besu.ethereum.storage.keyvalue.WorldStatePreimageKeyValueStorage; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedWorldStorageManager; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; @@ -57,6 +58,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; @@ -73,6 +75,10 @@ class BonsaiWorldStateProviderTest { @Mock StorageProvider storageProvider; @Mock SegmentedKeyValueStorage segmentedKeyValueStorage; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + WorldStatePreimageKeyValueStorage preimageStorage; + @Mock KeyValueStorage trieLogStorage; @Mock SegmentedKeyValueStorageTransaction segmentedKeyValueStorageTransaction; BonsaiWorldStateProvider bonsaiWorldStateArchive; @@ -82,8 +88,10 @@ class BonsaiWorldStateProviderTest { @BeforeEach public void setUp() { + when(storageProvider.getStorageBySegmentIdentifiers(anyList())) .thenReturn(segmentedKeyValueStorage); + when(storageProvider.createWorldStatePreimageStorage()).thenReturn(preimageStorage); when(segmentedKeyValueStorage.startTransaction()) .thenReturn(segmentedKeyValueStorageTransaction); when(storageProvider.getStorageBySegmentIdentifier(any())).thenReturn(trieLogStorage); diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java index 771ae4672a..6fc7532d0c 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java @@ -75,7 +75,6 @@ public class BlockchainReferenceTestCaseSpec { final MutableWorldState worldState = worldStateArchive.getMutable(); final WorldUpdater updater = worldState.updater(); - for (final Map.Entry entry : accounts.entrySet()) { ReferenceTestWorldState.insertAccount( updater, Address.fromHexString(entry.getKey()), entry.getValue()); diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BonsaiReferenceTestWorldState.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BonsaiReferenceTestWorldState.java index d476ea8fd6..fa8c0daf89 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BonsaiReferenceTestWorldState.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BonsaiReferenceTestWorldState.java @@ -235,6 +235,8 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState updater, Address.fromHexString(entry.getKey()), entry.getValue()); } updater.commit(); + // persist in order to save preimages + worldState.persist(null); return worldState; } @@ -248,7 +250,7 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState } @Override - public synchronized Optional saveTrieLog( + public synchronized void saveTrieLog( final DiffBasedWorldStateUpdateAccumulator localUpdater, final Hash forWorldStateRootHash, final BlockHeader forBlockHeader, @@ -257,7 +259,6 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState TrieLog trieLog = trieLogFactory.create(localUpdater, forBlockHeader); trieLogCache.put(forBlockHeader.getHash(), trieLogFactory.serialize(trieLog)); trieLogObservers.forEach(o -> o.onTrieLogAdded(new TrieLogAddedEvent(trieLog))); - return Optional.of(trieLog); } @Override