Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blobdb for static data #5475

Merged
merged 31 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ab4020e
Introduce variables storage
fab-10 May 18, 2023
2e8d64a
Enabling BlobDB for column families with static data
fab-10 May 19, 2023
9d8aaec
Merge branch 'main' into blobdb-for-static-data
fab-10 May 19, 2023
03e4cd1
Merge branch 'main' into blobdb-for-static-data
fab-10 May 23, 2023
489d4fd
Merge branch 'main' into variables-storage
fab-10 May 26, 2023
5c0d58f
Little opt
fab-10 May 26, 2023
87ef810
Merge branch 'main' into variables-storage
fab-10 May 29, 2023
e35b825
Revert variables storage subcommand
fab-10 May 29, 2023
a36da27
Merge branch 'main' into variables-storage
fab-10 May 30, 2023
b880e2e
Merge branch 'main' into variables-storage
fab-10 Jun 1, 2023
10b918e
Fix migrate and revert
fab-10 Jun 1, 2023
62dc6f4
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 1, 2023
8cac30b
Merge branch 'main' into variables-storage
fab-10 Jun 5, 2023
fb3dd58
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 5, 2023
8da7a37
Log migration and revert activity
fab-10 Jun 6, 2023
ebc581b
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 6, 2023
227a926
Revert unwanted change
fab-10 Jun 6, 2023
d74f336
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 6, 2023
4b504cb
Add javadoc
fab-10 Jun 6, 2023
b512350
Unit tests
fab-10 Jun 6, 2023
7a07221
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 6, 2023
2276f62
Unit tests
fab-10 Jun 6, 2023
7185b63
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 6, 2023
85b0aeb
Update CHANGELOG
fab-10 Jun 6, 2023
eb5ea18
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 6, 2023
c6fa6bd
Update CHANGELOG
fab-10 Jun 6, 2023
5a99f7b
Merge branch 'main' into variables-storage
fab-10 Jun 7, 2023
86c27d0
Deprecate variables in blockchain
fab-10 Jun 7, 2023
7864159
Ignore unnecessary stubbing
fab-10 Jun 7, 2023
4b1b7d9
Merge branch 'variables-storage' into blobdb-for-static-data
fab-10 Jun 7, 2023
df41fec
Merge branch 'main' into blobdb-for-static-data
fab-10 Jun 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.chain.VariablesStorage;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
Expand Down Expand Up @@ -547,11 +548,14 @@ public BesuController build() {

final ProtocolSchedule protocolSchedule = createProtocolSchedule();
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);

final VariablesStorage variablesStorage = storageProvider.createVariablesStorage();

final WorldStateStorage worldStateStorage =
storageProvider.createWorldStateStorage(dataStorageConfiguration.getDataStorageFormat());

final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule);
storageProvider.createBlockchainStorage(protocolSchedule, variablesStorage);

final MutableBlockchain blockchain =
DefaultBlockchain.createMutable(
Expand Down
15 changes: 8 additions & 7 deletions besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
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.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -163,7 +164,7 @@ public void enodeUrlShouldHaveAdvertisedHostWhenDiscoveryDisabled() {
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(vertx)
.dataDir(dataDir.getRoot())
.storageProvider(mock(KeyValueStorageProvider.class))
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl())
.build();
runner.startEthereumMainLoop();
Expand Down Expand Up @@ -223,7 +224,7 @@ public void movingAcrossProtocolSpecsUpdatesNodeRecord() {
inMemoryBlockchain.appendBlock(block, gen.receipts(block));
assertThat(
storageProvider
.getStorageBySegmentIdentifier(BLOCKCHAIN)
.getStorageBySegmentIdentifier(VARIABLES)
.get("local-enr-seqno".getBytes(StandardCharsets.UTF_8))
.map(Bytes::of)
.map(NodeRecordFactory.DEFAULT::fromBytes)
Expand Down Expand Up @@ -265,7 +266,7 @@ public void whenEngineApiAddedListensOnDefaultPort() {
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
.dataDir(dataDir.getRoot())
.storageProvider(mock(KeyValueStorageProvider.class))
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class))
.build();
Expand Down Expand Up @@ -307,7 +308,7 @@ public void whenEngineApiAddedWebSocketReadyOnSamePort() {
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
.dataDir(dataDir.getRoot())
.storageProvider(mock(KeyValueStorageProvider.class))
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class))
.build();
Expand Down Expand Up @@ -348,7 +349,7 @@ public void whenEngineApiAddedEthSubscribeAvailable() {
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
.dataDir(dataDir.getRoot())
.storageProvider(mock(KeyValueStorageProvider.class))
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class))
.build();
Expand Down Expand Up @@ -390,7 +391,7 @@ public void noEngineApiNoServiceForMethods() {
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
.dataDir(dataDir.getRoot())
.storageProvider(mock(KeyValueStorageProvider.class))
.storageProvider(mock(KeyValueStorageProvider.class, RETURNS_DEEP_STUBS))
.rpcEndpointService(new RpcEndpointServiceImpl())
.besuPluginContext(mock(BesuPluginContextImpl.class))
.networkingConfiguration(NetworkingConfiguration.create())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration;
Expand Down Expand Up @@ -114,10 +115,12 @@ public void setup() {
when(ethashConfigOptions.getFixedDifficulty()).thenReturn(OptionalLong.empty());
when(storageProvider.getStorageBySegmentIdentifier(any()))
.thenReturn(new InMemoryKeyValueStorage());
when(storageProvider.createBlockchainStorage(any()))
when(storageProvider.createBlockchainStorage(any(), any()))
.thenReturn(
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(), new MainnetBlockHeaderFunctions()));
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()));
when(synchronizerConfiguration.getDownloaderParallelism()).thenReturn(1);
when(synchronizerConfiguration.getTransactionsParallelism()).thenReturn(1);
when(synchronizerConfiguration.getComputationParallelism()).thenReturn(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
Expand Down Expand Up @@ -119,10 +120,12 @@ public void setup() {
when(genesisConfigOptions.getThanosBlockNumber()).thenReturn(OptionalLong.empty());
when(genesisConfigOptions.getTerminalBlockHash()).thenReturn(Optional.of(Hash.ZERO));
when(genesisConfigOptions.getTerminalBlockNumber()).thenReturn(OptionalLong.of(1L));
when(storageProvider.createBlockchainStorage(any()))
when(storageProvider.createBlockchainStorage(any(), any()))
.thenReturn(
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(), new MainnetBlockHeaderFunctions()));
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()));
when(storageProvider.getStorageBySegmentIdentifier(any()))
.thenReturn(new InMemoryKeyValueStorage());
when(synchronizerConfiguration.getDownloaderParallelism()).thenReturn(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorage;
Expand Down Expand Up @@ -103,10 +104,12 @@ public void setup() {
when(genesisConfigFile.getConfigOptions(any())).thenReturn(genesisConfigOptions);
when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
when(storageProvider.createBlockchainStorage(any()))
when(storageProvider.createBlockchainStorage(any(), any()))
.thenReturn(
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(), new MainnetBlockHeaderFunctions()));
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()));
when(storageProvider.createWorldStateStorage(DataStorageFormat.FOREST))
.thenReturn(worldStateStorage);
when(worldStateStorage.isWorldStateAvailable(any(), any())).thenReturn(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.data.AddedBlockContext;
Expand Down Expand Up @@ -114,7 +115,9 @@ public void setUp() {
DefaultBlockchain.createMutable(
gen.genesisBlock(),
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(), new MainnetBlockHeaderFunctions()),
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()),
new NoOpMetricsSystem(),
0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;

Expand All @@ -60,7 +61,9 @@ public class NewBlockHeadersSubscriptionServiceTest {
private final BlockDataGenerator gen = new BlockDataGenerator();
private final BlockchainStorage blockchainStorage =
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(), new MainnetBlockHeaderFunctions());
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions());
private final Block genesisBlock = gen.genesisBlock();
private final MutableBlockchain blockchain =
DefaultBlockchain.createMutable(genesisBlock, blockchainStorage, new NoOpMetricsSystem(), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static OperationBenchmarkHelper create() throws IOException {
RocksDBMetricsFactory.PUBLIC_ROCKS_DB_METRICS);

final ExecutionContextTestFixture executionContext =
ExecutionContextTestFixture.builder().keyValueStorage(keyValueStorage).build();
ExecutionContextTestFixture.builder().blockchainKeyValueStorage(keyValueStorage).build();
final MutableBlockchain blockchain = executionContext.getBlockchain();

for (int i = 1; i < 256; i++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.chain;

import static java.nio.charset.StandardCharsets.UTF_8;

import org.hyperledger.besu.datatypes.Hash;

import java.util.Collection;
import java.util.Optional;

import org.apache.tuweni.bytes.Bytes;

public interface VariablesStorage {
enum Keys {
CHAIN_HEAD_HASH("chainHeadHash"),
FORK_HEADS("forkHeads"),
FINALIZED_BLOCK_HASH("finalizedBlockHash"),
SAFE_BLOCK_HASH("safeBlockHash"),
SEQ_NO_STORE("local-enr-seqno");

private final String name;

Keys(final String name) {
this.name = name;
}

public byte[] toByteArray() {
return name.getBytes(UTF_8);
}

public Bytes getBytes() {
return Bytes.wrap(toByteArray());
}
}

Optional<Hash> getChainHead();

Collection<Hash> getForkHeads();

Optional<Hash> getFinalized();

Optional<Hash> getSafeBlock();

Optional<Bytes> getLocalEnrSeqno();

Updater updater();

interface Updater {

void setChainHead(Hash blockHash);

void setForkHeads(Collection<Hash> forkHeadHashes);

void setFinalized(Hash blockHash);

void setSafeBlock(Hash blockHash);

void setLocalEnrSeqno(Bytes nodeRecord);

void commit();

void rollback();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.storage;

import org.hyperledger.besu.ethereum.chain.BlockchainStorage;
import org.hyperledger.besu.ethereum.chain.VariablesStorage;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
Expand All @@ -27,7 +28,10 @@

public interface StorageProvider extends Closeable {

BlockchainStorage createBlockchainStorage(ProtocolSchedule protocolSchedule);
VariablesStorage createVariablesStorage();

BlockchainStorage createBlockchainStorage(
ProtocolSchedule protocolSchedule, VariablesStorage variablesStorage);

WorldStateStorage createWorldStateStorage(DataStorageFormat dataStorageFormat);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.bouncycastle.util.Arrays;

public enum KeyValueSegmentIdentifier implements SegmentIdentifier {
BLOCKCHAIN(new byte[] {1}),
BLOCKCHAIN(new byte[] {1}, true),
WORLD_STATE(new byte[] {2}, new int[] {0, 1}),
PRIVATE_TRANSACTIONS(new byte[] {3}),
PRIVATE_STATE(new byte[] {4}),
Expand All @@ -28,11 +28,11 @@ public enum KeyValueSegmentIdentifier implements SegmentIdentifier {
CODE_STORAGE(new byte[] {7}, new int[] {2}),
ACCOUNT_STORAGE_STORAGE(new byte[] {8}, new int[] {2}),
TRIE_BRANCH_STORAGE(new byte[] {9}, new int[] {2}),
TRIE_LOG_STORAGE(new byte[] {10}, new int[] {2}),
TRIE_LOG_STORAGE(new byte[] {10}, new int[] {2}, true),
VARIABLES(new byte[] {11}), // formerly GOQUORUM_PRIVATE_WORLD_STATE

// previously supported GoQuorum private states
// no longer used but need to be retained for db backward compatibility
GOQUORUM_PRIVATE_WORLD_STATE(new byte[] {11}),
GOQUORUM_PRIVATE_STORAGE(new byte[] {12}),

BACKWARD_SYNC_HEADERS(new byte[] {13}),
Expand All @@ -44,14 +44,25 @@ public enum KeyValueSegmentIdentifier implements SegmentIdentifier {

private final byte[] id;
private final int[] versionList;
private final boolean containsStaticData;

KeyValueSegmentIdentifier(final byte[] id) {
this(id, new int[] {0, 1, 2});
}

KeyValueSegmentIdentifier(final byte[] id, final boolean containsStaticData) {
this(id, new int[] {0, 1, 2}, containsStaticData);
}

KeyValueSegmentIdentifier(final byte[] id, final int[] versionList) {
this(id, versionList, false);
}

KeyValueSegmentIdentifier(
final byte[] id, final int[] versionList, final boolean containsStaticData) {
this.id = id;
this.versionList = versionList;
this.containsStaticData = containsStaticData;
}

@Override
Expand All @@ -64,6 +75,11 @@ public byte[] getId() {
return id;
}

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

@Override
public boolean includeInDatabaseVersion(final int version) {
return Arrays.contains(versionList, version);
Expand Down
Loading