Skip to content

Commit

Permalink
Promote segmented storage (hyperledger#5700)
Browse files Browse the repository at this point in the history
promote segmented storage to plugin-api, implement SegmentedInMemoryKeyValueStorage
Signed-off-by: garyschulte <garyschulte@gmail.com>
  • Loading branch information
garyschulte committed Aug 28, 2023
1 parent 4a071b2 commit be5c0e2
Show file tree
Hide file tree
Showing 52 changed files with 1,398 additions and 1,117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,7 @@ public BesuController build() {

Optional<Pruner> maybePruner = Optional.empty();
if (isPruningEnabled) {
if (!storageProvider.isWorldStateIterable()) {
LOG.warn(
"Cannot enable pruning with current database version. Disabling. Resync to get the latest database version or disable pruning explicitly on the command line to remove this warning.");
} else if (dataStorageConfiguration.getDataStorageFormat().equals(DataStorageFormat.BONSAI)) {
if (dataStorageConfiguration.getDataStorageFormat().equals(DataStorageFormat.BONSAI)) {
LOG.warn(
"Cannot enable pruning with Bonsai data storage format. Disabling. Change the data storage format or disable pruning explicitly on the command line to remove this warning.");
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModule;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageFactory;
import org.hyperledger.besu.plugin.services.storage.PrivacyKeyValueStorageFactory;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.PrivacyPluginServiceImpl;
Expand Down Expand Up @@ -312,7 +313,7 @@ public void initMocks() throws Exception {
.when(securityModuleService.getByName(eq("localfile")))
.thenReturn(Optional.of(() -> securityModule));
lenient()
.when(rocksDBSPrivacyStorageFactory.create(any(), any(), any()))
.when(rocksDBSPrivacyStorageFactory.create(any(SegmentIdentifier.class), any(), any()))
.thenReturn(new InMemoryKeyValueStorage());

lenient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@
import static org.hyperledger.besu.ethereum.core.VariablesStorageHelper.getSampleVariableValues;
import static org.hyperledger.besu.ethereum.core.VariablesStorageHelper.populateBlockchainStorage;
import static org.hyperledger.besu.ethereum.core.VariablesStorageHelper.populateVariablesStorage;
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.BLOCKCHAIN;
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.VARIABLES;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import org.hyperledger.besu.cli.CommandTestAbstract;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage;
import org.hyperledger.besu.services.kvstore.SegmentedKeyValueStorageAdapter;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -58,13 +63,14 @@ public void storageRevertVariablesSubCommandExists() {

@Test
public void revertVariables() {
final var kvVariables = new InMemoryKeyValueStorage();
final var kvBlockchain = new InMemoryKeyValueStorage();
when(rocksDBStorageFactory.create(eq(KeyValueSegmentIdentifier.VARIABLES), any(), any()))
.thenReturn(kvVariables);
when(rocksDBStorageFactory.create(eq(KeyValueSegmentIdentifier.BLOCKCHAIN), any(), any()))
.thenReturn(kvBlockchain);

final var kvVariablesSeg = new SegmentedInMemoryKeyValueStorage();
final var kvVariables = new SegmentedKeyValueStorageAdapter(VARIABLES, kvVariablesSeg);
final var kvBlockchainSeg = new SegmentedInMemoryKeyValueStorage();
final var kvBlockchain = new SegmentedKeyValueStorageAdapter(BLOCKCHAIN, kvBlockchainSeg);
when(rocksDBStorageFactory.create(eq(List.of(VARIABLES)), any(), any()))
.thenReturn(kvVariablesSeg);
when(rocksDBStorageFactory.create(eq(List.of(BLOCKCHAIN)), any(), any()))
.thenReturn(kvBlockchainSeg);
final var variableValues = getSampleVariableValues();
assertNoVariablesInStorage(kvBlockchain);
populateVariablesStorage(kvVariables, variableValues);
Expand All @@ -77,12 +83,14 @@ public void revertVariables() {

@Test
public void revertVariablesWhenSomeVariablesDoNotExist() {
final var kvVariables = new InMemoryKeyValueStorage();
final var kvBlockchain = new InMemoryKeyValueStorage();
when(rocksDBStorageFactory.create(eq(KeyValueSegmentIdentifier.VARIABLES), any(), any()))
.thenReturn(kvVariables);
when(rocksDBStorageFactory.create(eq(KeyValueSegmentIdentifier.BLOCKCHAIN), any(), any()))
.thenReturn(kvBlockchain);
final var kvVariablesSeg = new SegmentedInMemoryKeyValueStorage();
final var kvVariables = new SegmentedKeyValueStorageAdapter(VARIABLES, kvVariablesSeg);
final var kvBlockchainSeg = new SegmentedInMemoryKeyValueStorage();
final var kvBlockchain = new SegmentedKeyValueStorageAdapter(BLOCKCHAIN, kvBlockchainSeg);
when(rocksDBStorageFactory.create(eq(List.of(VARIABLES)), any(), any()))
.thenReturn(kvVariablesSeg);
when(rocksDBStorageFactory.create(eq(List.of(BLOCKCHAIN)), any(), any()))
.thenReturn(kvBlockchainSeg);

final var variableValues = getSampleVariableValues();
variableValues.remove(FINALIZED_BLOCK_HASH);
Expand All @@ -100,10 +108,8 @@ public void revertVariablesWhenSomeVariablesDoNotExist() {
public void doesNothingWhenVariablesAlreadyReverted() {
final var kvVariables = new InMemoryKeyValueStorage();
final var kvBlockchain = new InMemoryKeyValueStorage();
when(rocksDBStorageFactory.create(eq(KeyValueSegmentIdentifier.VARIABLES), any(), any()))
.thenReturn(kvVariables);
when(rocksDBStorageFactory.create(eq(KeyValueSegmentIdentifier.BLOCKCHAIN), any(), any()))
.thenReturn(kvBlockchain);
when(rocksDBStorageFactory.create(eq(VARIABLES), any(), any())).thenReturn(kvVariables);
when(rocksDBStorageFactory.create(eq(BLOCKCHAIN), any(), any())).thenReturn(kvBlockchain);

final var variableValues = getSampleVariableValues();
assertNoVariablesInStorage(kvVariables);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ public void setup() {
when(storageProvider.createWorldStateStorage(DataStorageFormat.FOREST))
.thenReturn(worldStateStorage);
when(storageProvider.createWorldStatePreimageStorage()).thenReturn(worldStatePreimageStorage);
when(storageProvider.isWorldStateIterable()).thenReturn(true);

when(worldStateStorage.isWorldStateAvailable(any(), any())).thenReturn(true);
when(worldStatePreimageStorage.updater())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@

import java.util.Collection;

import org.mockito.quality.Strictness;

public class BftContextBuilder {

public static BftContext setupContextWithValidators(final Collection<Address> validators) {
final BftContext bftContext = mock(BftContext.class, withSettings().lenient());
final BftContext bftContext =
mock(BftContext.class, withSettings().strictness(Strictness.LENIENT));
final ValidatorProvider mockValidatorProvider =
mock(ValidatorProvider.class, withSettings().lenient());
mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
final BftBlockInterface mockBftBlockInterface =
mock(BftBlockInterface.class, withSettings().lenient());
mock(BftBlockInterface.class, withSettings().strictness(Strictness.LENIENT));
when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider);
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.getBlockInterface()).thenReturn(mockBftBlockInterface);
Expand All @@ -48,11 +51,11 @@ public static <T extends BftContext> T setupContextWithBftExtraData(
final Class<T> contextClazz,
final Collection<Address> validators,
final BftExtraData bftExtraData) {
final T bftContext = mock(contextClazz, withSettings().lenient());
final T bftContext = mock(contextClazz, withSettings().strictness(Strictness.LENIENT));
final ValidatorProvider mockValidatorProvider =
mock(ValidatorProvider.class, withSettings().lenient());
mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
final BftBlockInterface mockBftBlockInterface =
mock(BftBlockInterface.class, withSettings().lenient());
mock(BftBlockInterface.class, withSettings().strictness(Strictness.LENIENT));
when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider);
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.getBlockInterface()).thenReturn(mockBftBlockInterface);
Expand All @@ -70,9 +73,9 @@ public static <T extends BftContext> T setupContextWithBftExtraDataEncoder(
final Class<T> contextClazz,
final Collection<Address> validators,
final BftExtraDataCodec bftExtraDataCodec) {
final T bftContext = mock(contextClazz, withSettings().lenient());
final T bftContext = mock(contextClazz, withSettings().strictness(Strictness.LENIENT));
final ValidatorProvider mockValidatorProvider =
mock(ValidatorProvider.class, withSettings().lenient());
mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT));
when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider);
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.getBlockInterface()).thenReturn(new BftBlockInterface(bftExtraDataCodec));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBConfigurationBuilder;
import org.hyperledger.besu.plugin.services.storage.rocksdb.segmented.OptimisticRocksDBColumnarKeyValueStorage;
import org.hyperledger.besu.services.kvstore.SnappableSegmentedKeyValueStorageAdapter;
import org.hyperledger.besu.services.kvstore.SegmentedKeyValueStorageAdapter;

import java.io.IOException;
import java.nio.file.Files;
Expand Down Expand Up @@ -70,7 +70,7 @@ public static OperationBenchmarkHelper create() throws IOException {
RocksDBMetricsFactory.PUBLIC_ROCKS_DB_METRICS);

final KeyValueStorage keyValueStorage =
new SnappableSegmentedKeyValueStorageAdapter<>(
new SegmentedKeyValueStorageAdapter(
KeyValueSegmentIdentifier.BLOCKCHAIN, optimisticRocksDBColumnarKeyValueStorage);

final ExecutionContextTestFixture executionContext =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,13 @@ public class BonsaiSnapshotWorldStateKeyValueStorage extends BonsaiWorldStateKey

public BonsaiSnapshotWorldStateKeyValueStorage(
final BonsaiWorldStateKeyValueStorage parentWorldStateStorage,
final SnappedKeyValueStorage accountStorage,
final SnappedKeyValueStorage codeStorage,
final SnappedKeyValueStorage storageStorage,
final SnappedKeyValueStorage trieBranchStorage,
final SnappedKeyValueStorage segmentedWorldStateStorage,
final KeyValueStorage trieLogStorage,
final ObservableMetricsSystem metricsSystem) {
super(
parentWorldStateStorage.flatDbMode,
parentWorldStateStorage.flatDbReaderStrategy,
accountStorage,
codeStorage,
storageStorage,
trieBranchStorage,
segmentedWorldStateStorage,
trieLogStorage,
metricsSystem);
this.parentWorldStateStorage = parentWorldStateStorage;
Expand All @@ -66,10 +60,7 @@ public BonsaiSnapshotWorldStateKeyValueStorage(
final ObservableMetricsSystem metricsSystem) {
this(
worldStateStorage,
((SnappableKeyValueStorage) worldStateStorage.accountStorage).takeSnapshot(),
((SnappableKeyValueStorage) worldStateStorage.codeStorage).takeSnapshot(),
((SnappableKeyValueStorage) worldStateStorage.storageStorage).takeSnapshot(),
((SnappableKeyValueStorage) worldStateStorage.trieBranchStorage).takeSnapshot(),
((SnappableKeyValueStorage) worldStateStorage.composedWorldStateStorage).takeSnapshot(),
worldStateStorage.trieLogStorage,
metricsSystem);
}
Expand All @@ -85,10 +76,7 @@ private boolean isClosedGet() {
@Override
public BonsaiUpdater updater() {
return new Updater(
((SnappedKeyValueStorage) accountStorage).getSnapshotTransaction(),
((SnappedKeyValueStorage) codeStorage).getSnapshotTransaction(),
((SnappedKeyValueStorage) storageStorage).getSnapshotTransaction(),
((SnappedKeyValueStorage) trieBranchStorage).getSnapshotTransaction(),
((SnappedKeyValueStorage) composedWorldStateStorage).getSnapshotTransaction(),
trieLogStorage.startTransaction());
}

Expand Down Expand Up @@ -223,10 +211,7 @@ protected synchronized void doClose() throws Exception {
subscribers.forEach(BonsaiStorageSubscriber::onCloseStorage);

// close all of the SnappedKeyValueStorages:
accountStorage.close();
codeStorage.close();
storageStorage.close();
trieBranchStorage.close();
composedWorldStateStorage.close();

// unsubscribe the parent worldstate
parentWorldStateStorage.unSubscribe(subscribeParentId);
Expand Down
Loading

0 comments on commit be5c0e2

Please sign in to comment.