Skip to content

Commit

Permalink
saving huge pile of code
Browse files Browse the repository at this point in the history
Signed-off-by: garyschulte <garyschulte@gmail.com>
  • Loading branch information
garyschulte committed Jul 12, 2023
1 parent 3f2a016 commit 779063c
Show file tree
Hide file tree
Showing 27 changed files with 384 additions and 286 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorage;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.SnappableKeyValueStorage;

import java.io.Closeable;
import java.util.List;

public interface StorageProvider extends Closeable {

Expand All @@ -39,9 +41,7 @@ BlockchainStorage createBlockchainStorage(

KeyValueStorage getStorageBySegmentIdentifier(SegmentIdentifier segment);

SnappableKeyValueStorage getSnappableStorageBySegmentIdentifier(SegmentIdentifier segment);
SegmentedKeyValueStorage getStorageBySegmentIdentifiers(List<SegmentIdentifier> segment);

boolean isWorldStateIterable();

boolean isWorldStateSnappable();
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,39 @@
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import org.hyperledger.besu.plugin.services.storage.SnappableKeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage;
import org.hyperledger.besu.services.kvstore.SegmentedKeyValueStorageAdapter;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class KeyValueStorageProvider implements StorageProvider {
private static final Logger LOG = LoggerFactory.getLogger(StorageProvider.class);

public static final boolean SEGMENT_ISOLATION_SUPPORTED = true;
public static final boolean SNAPSHOT_ISOLATION_UNSUPPORTED = false;

protected final Function<SegmentIdentifier, KeyValueStorage> storageCreator;
protected final Function<List<SegmentIdentifier>, SegmentedKeyValueStorage> segmentedStorageCreator;
private final KeyValueStorage worldStatePreimageStorage;
private final boolean isWorldStateIterable;
private final boolean isWorldStateSnappable;
protected final Map<SegmentIdentifier, KeyValueStorage> storageInstances = new HashMap<>();
protected final Map<List<SegmentIdentifier>, SegmentedKeyValueStorage> storageInstances = new HashMap<>();
private final ObservableMetricsSystem metricsSystem;

public KeyValueStorageProvider(
final Function<SegmentIdentifier, KeyValueStorage> storageCreator,
final Function<List<SegmentIdentifier>, SegmentedKeyValueStorage> segmentedStorageCreator,
final KeyValueStorage worldStatePreimageStorage,
final boolean segmentIsolationSupported,
final boolean storageSnapshotIsolationSupported,
final ObservableMetricsSystem metricsSystem) {
this.storageCreator = storageCreator;
this.segmentedStorageCreator = segmentedStorageCreator;
this.worldStatePreimageStorage = worldStatePreimageStorage;
this.isWorldStateIterable = segmentIsolationSupported;
this.isWorldStateSnappable = storageSnapshotIsolationSupported;
Expand Down Expand Up @@ -90,29 +97,35 @@ public WorldStatePreimageStorage createWorldStatePreimageStorage() {

@Override
public KeyValueStorage getStorageBySegmentIdentifier(final SegmentIdentifier segment) {
return storageInstances.computeIfAbsent(segment, storageCreator);
return new SegmentedKeyValueStorageAdapter(segment, storageInstances.computeIfAbsent(List.of(segment), segmentedStorageCreator));
}

@Override
public SnappableKeyValueStorage getSnappableStorageBySegmentIdentifier(
final SegmentIdentifier segment) {
return (SnappableKeyValueStorage) getStorageBySegmentIdentifier(segment);
public SegmentedKeyValueStorage getStorageBySegmentIdentifiers(final List<SegmentIdentifier> segments) {
return segmentedStorageCreator.apply(segments);
}

@Override
public boolean isWorldStateIterable() {
return isWorldStateIterable;
}

@Override
public boolean isWorldStateSnappable() {
return isWorldStateSnappable;
}

@Override
public void close() throws IOException {
for (final KeyValueStorage kvs : storageInstances.values()) {
kvs.close();
}
storageInstances.entrySet().stream()
.filter(storage -> storage instanceof AutoCloseable)
.forEach(
storage -> {
try {
storage.getValue().close();
} catch (final IOException e) {
LOG.atWarn()
.setMessage("Failed to close storage instance {}")
.addArgument(storage.getKey().stream()
.map(SegmentIdentifier::getName)
.collect(Collectors.joining(",")))
.setCause(e);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageFactory;
import org.hyperledger.besu.services.kvstore.LimitedInMemoryKeyValueStorage;

import java.util.List;

public class KeyValueStorageProviderBuilder {

private static final long DEFAULT_WORLD_STATE_PRE_IMAGE_CACHE_SIZE = 5_000L;
Expand Down Expand Up @@ -59,9 +61,10 @@ public KeyValueStorageProvider build() {
new LimitedInMemoryKeyValueStorage(DEFAULT_WORLD_STATE_PRE_IMAGE_CACHE_SIZE);

// this tickles init needed for isSegmentIsolationSupported
storageFactory.create(KeyValueSegmentIdentifier.BLOCKCHAIN, commonConfiguration, metricsSystem);
storageFactory.create(List.of(KeyValueSegmentIdentifier.BLOCKCHAIN), commonConfiguration, metricsSystem);

return new KeyValueStorageProvider(
segment -> storageFactory.create(segment, commonConfiguration, metricsSystem),
segments -> storageFactory.create(segments, commonConfiguration, metricsSystem),
worldStatePreImageStorage,
storageFactory.isSegmentIsolationSupported(),
storageFactory.isSnapshotIsolationSupported(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@
import org.hyperledger.besu.ethereum.worldstate.DefaultWorldStateArchive;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage;

public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider {

public InMemoryKeyValueStorageProvider() {
super(
segmentIdentifier -> new InMemoryKeyValueStorage(),
segmentIdentifiers -> new SegmentedInMemoryKeyValueStorage(),
new InMemoryKeyValueStorage(),
SEGMENT_ISOLATION_SUPPORTED,
SNAPSHOT_ISOLATION_UNSUPPORTED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
import org.hyperledger.besu.plugin.services.exception.StorageException;

import java.io.Closeable;
import java.util.List;

/** Factory for creating key-value storage instances. */
@Unstable
public interface KeyValueStorageFactory extends Closeable {
public interface KeyValueStorageFactory<S> extends Closeable {

/**
* Retrieves the identity of the key-value storage factory.
Expand Down Expand Up @@ -53,6 +54,24 @@ KeyValueStorage create(
SegmentIdentifier segment, BesuConfiguration configuration, MetricsSystem metricsSystem)
throws StorageException;

/**
* Creates a new segmented key-value storage instance, appropriate for the given segment.
*
* <p>New segments may be introduced in future releases and should result in a new empty
* key-space. Segments created with the identifier of an existing segment should have the same
* data as that existing segment.
*
* @param segments list of segments identifiers that comprise the created segmented storage
* will contain.
* @param configuration common configuration available to plugins, in a populated state.
* @param metricsSystem metrics component for recording key-value storage events.
* @return the storage instance reserved for the given segment.
* @exception StorageException problem encountered when creating storage for the segment.
*/
SegmentedKeyValueStorage<S> create(
List<SegmentIdentifier> segments, BesuConfiguration configuration, MetricsSystem metricsSystem)
throws StorageException;

/**
* Whether storage segment isolation is supported by the factory created instances.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

/** The interface Privacy key value storage factory. */
@Unstable
public interface PrivacyKeyValueStorageFactory extends KeyValueStorageFactory {
public interface PrivacyKeyValueStorageFactory<S> extends KeyValueStorageFactory<S> {
/**
* Retrieves the version of the key-value storage factory.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.services.kvstore;
package org.hyperledger.besu.plugin.services.storage;

import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;

import java.io.Closeable;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
Expand All @@ -40,6 +41,8 @@ public interface SegmentedKeyValueStorage<S> extends Closeable {
*/
S getSegmentIdentifierByName(SegmentIdentifier segment);

SegmentedKeyValueStorage<S> getComposedSegmentStorage(List<SegmentIdentifier> segments);

/**
* Get the value from the associated segment and key.
*
Expand Down Expand Up @@ -68,7 +71,7 @@ default boolean containsKey(final S segment, final byte[] key) throws StorageExc
* @return An object representing the transaction.
* @throws StorageException the storage exception
*/
Transaction<S> startTransaction() throws StorageException;
KeyValueStorageTransaction startTransaction() throws StorageException;

/**
* Returns a stream of all keys for the segment.
Expand Down Expand Up @@ -140,45 +143,4 @@ default boolean containsKey(final S segment, final byte[] key) throws StorageExc
* @return boolean indicating whether the underlying storage is closed.
*/
boolean isClosed();

/**
* Represents a set of changes to be committed atomically. A single transaction is not
* thread-safe, but multiple transactions can execute concurrently.
*
* @param <S> the segment identifier type
*/
interface Transaction<S> {

/**
* Add the given key-value pair to the set of updates to be committed.
*
* @param segment the database segment
* @param key The key to set / modify.
* @param value The value to be set.
*/
void put(S segment, byte[] key, byte[] value);

/**
* Schedules the given key to be deleted from storage.
*
* @param segment the database segment
* @param key The key to delete
*/
void remove(S segment, byte[] key);

/**
* Atomically commit the set of changes contained in this transaction to the underlying
* key-value storage from which this transaction was started. After committing, the transaction
* is no longer usable and will throw exceptions if modifications are attempted.
*
* @throws StorageException the storage exception
*/
void commit() throws StorageException;

/**
* Cancel this transaction. After rolling back, the transaction is no longer usable and will
* throw exceptions if modifications are attempted.
*/
void rollback();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.hyperledger.besu.plugin.services.storage;

public interface SnappableSegmentedKeyValueStorage<S> extends SegmentedKeyValueStorage<S> {
/**
* Take snapshot.
*
* @return the snapped key value storage
*/
SnappedSegmentedKeyValueStorage<S> takeSnapshot();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.hyperledger.besu.plugin.services.storage;

public interface SnappedSegmentedKeyValueStorage<S> extends SegmentedKeyValueStorage<S> {
/**
* Gets snapshot transaction.
*
* @return the snapshot transaction
*/
KeyValueStorageTransaction getSnapshotTransaction();

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageFactory;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.DatabaseMetadata;
import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBConfiguration;
import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBConfigurationBuilder;
Expand All @@ -46,7 +47,7 @@
import org.slf4j.LoggerFactory;

/** The Rocks db key value storage factory. */
public class RocksDBKeyValueStorageFactory implements KeyValueStorageFactory {
public class RocksDBKeyValueStorageFactory implements KeyValueStorageFactory<RocksDbSegmentIdentifier> {

private static final Logger LOG = LoggerFactory.getLogger(RocksDBKeyValueStorageFactory.class);
private static final int DEFAULT_VERSION = 1;
Expand Down Expand Up @@ -221,6 +222,12 @@ public KeyValueStorage create(
}
}

@Override
public SegmentedKeyValueStorage<RocksDbSegmentIdentifier> create(final List<SegmentIdentifier> segments, final BesuConfiguration configuration, final MetricsSystem metricsSystem) throws StorageException {
//TODO: write me
return null;
}

/**
* Storage path.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.plugin.services.storage.rocksdb.unsegmented;
package org.hyperledger.besu.plugin.services.storage.rocksdb;

import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.metrics.OperationTimer;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetrics;

import org.rocksdb.RocksDBException;
import org.rocksdb.Transaction;
Expand All @@ -41,7 +40,7 @@ public class RocksDBTransaction implements KeyValueStorageTransaction {
* @param options the options
* @param metrics the metrics
*/
RocksDBTransaction(
public RocksDBTransaction(
final Transaction innerTx, final WriteOptions options, final RocksDBMetrics metrics) {
this.innerTx = innerTx;
this.options = options;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@

import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBTransaction;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDbSegmentIdentifier;
import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBConfiguration;
import org.hyperledger.besu.services.kvstore.SegmentedKeyValueStorageTransactionTransitionValidatorDecorator;
import org.hyperledger.besu.services.kvstore.KeyValueStorageTransactionValidatorDecorator;

import java.util.List;

Expand Down Expand Up @@ -76,12 +78,12 @@ RocksDB getDB() {
* @throws StorageException the storage exception
*/
@Override
public Transaction<RocksDbSegmentIdentifier> startTransaction() throws StorageException {
public KeyValueStorageTransaction startTransaction() throws StorageException {
throwIfClosed();
final WriteOptions writeOptions = new WriteOptions();
writeOptions.setIgnoreMissingColumnFamilies(true);
return new SegmentedKeyValueStorageTransactionTransitionValidatorDecorator<>(
new RocksDbTransaction(db.beginTransaction(writeOptions), writeOptions), this.closed::get);
return new KeyValueStorageTransactionValidatorDecorator(
new RocksDBTransaction(db.beginTransaction(writeOptions), writeOptions, this.metrics), this.closed::get);
}

/**
Expand Down
Loading

0 comments on commit 779063c

Please sign in to comment.