Skip to content

Commit 6e27fe3

Browse files
fab-10gfukushima
authored andcommitted
Database metadata refactor (besu-eth#6555)
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> Co-authored-by: Gabriel Fukushima <gabrielfukushima@gmail.com> Signed-off-by: amsmota <antonio.mota@citi.com>
1 parent 28bf551 commit 6e27fe3

File tree

79 files changed

+1461
-773
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1461
-773
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
## 24.2.1-SNAPSHOT
44

55
### Breaking Changes
6+
- RocksDB database metadata format has changed to be more expressive, the migration of an existing metadata file to the new format is automatic at startup. Before performing a downgrade to a previous version it is mandatory to revert to the original format using the subcommand `besu --data-path=/path/to/besu/datadir storage revert-metadata v2-to-v1`.
67

78
### Deprecations
89

910
### Additions and Improvements
1011
- Extend `Blockchain` service [#6592](https://github.com/hyperledger/besu/pull/6592)
12+
- RocksDB database metadata refactoring [#6555](https://github.com/hyperledger/besu/pull/6555)
1113

1214
### Bug fixes
1315

besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@
141141
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProviderBuilder;
142142
import org.hyperledger.besu.ethereum.trie.forest.pruner.PrunerConfiguration;
143143
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
144-
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
145144
import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract;
146145
import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract;
147146
import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract;
@@ -172,6 +171,7 @@
172171
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
173172
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
174173
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModule;
174+
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
175175
import org.hyperledger.besu.plugin.services.storage.PrivacyKeyValueStorageFactory;
176176
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBPlugin;
177177
import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelectorFactory;

besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import org.hyperledger.besu.cli.options.CLIOptions;
2626
import org.hyperledger.besu.cli.util.CommandLineUtils;
2727
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
28-
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
2928
import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration;
29+
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
3030

3131
import java.util.List;
3232

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Copyright Hyperledger Besu Contributors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*
13+
* SPDX-License-Identifier: Apache-2.0
14+
*/
15+
package org.hyperledger.besu.cli.subcommands.storage;
16+
17+
import org.hyperledger.besu.cli.util.VersionProvider;
18+
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
19+
20+
import java.io.File;
21+
import java.io.IOException;
22+
import java.nio.file.Path;
23+
import java.util.OptionalInt;
24+
25+
import com.fasterxml.jackson.annotation.JsonInclude;
26+
import com.fasterxml.jackson.databind.ObjectMapper;
27+
import com.fasterxml.jackson.databind.SerializationFeature;
28+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
29+
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
32+
import picocli.CommandLine;
33+
import picocli.CommandLine.Command;
34+
import picocli.CommandLine.ParentCommand;
35+
36+
/** The revert metadata to v1 subcommand. */
37+
@Command(
38+
name = "revert-metadata",
39+
description = "Revert database metadata to previous format",
40+
mixinStandardHelpOptions = true,
41+
versionProvider = VersionProvider.class,
42+
subcommands = RevertMetadataSubCommand.v2ToV1.class)
43+
public class RevertMetadataSubCommand implements Runnable {
44+
private static final Logger LOG = LoggerFactory.getLogger(RevertMetadataSubCommand.class);
45+
private static final String METADATA_FILENAME = "DATABASE_METADATA.json";
46+
private static final ObjectMapper MAPPER =
47+
new ObjectMapper()
48+
.registerModule(new Jdk8Module())
49+
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
50+
.enable(SerializationFeature.INDENT_OUTPUT);
51+
52+
@SuppressWarnings("unused")
53+
@ParentCommand
54+
private StorageSubCommand parentCommand;
55+
56+
@SuppressWarnings("unused")
57+
@CommandLine.Spec
58+
private CommandLine.Model.CommandSpec spec;
59+
60+
@Override
61+
public void run() {
62+
spec.commandLine().usage(System.out);
63+
}
64+
65+
@Command(
66+
name = "v2-to-v1",
67+
description = "Revert a database metadata v2 format to v1 format",
68+
mixinStandardHelpOptions = true,
69+
versionProvider = VersionProvider.class)
70+
static class v2ToV1 implements Runnable {
71+
72+
@SuppressWarnings("unused")
73+
@CommandLine.Spec
74+
private CommandLine.Model.CommandSpec spec;
75+
76+
@SuppressWarnings("unused")
77+
@ParentCommand
78+
private RevertMetadataSubCommand parentCommand;
79+
80+
@Override
81+
public void run() {
82+
83+
final Path dataDir = parentCommand.parentCommand.besuCommand.dataDir();
84+
85+
final File dbMetadata = dataDir.resolve(METADATA_FILENAME).toFile();
86+
if (!dbMetadata.exists()) {
87+
String errMsg =
88+
String.format(
89+
"Could not find database metadata file %s, check your data dir %s",
90+
dbMetadata, dataDir);
91+
LOG.error(errMsg);
92+
throw new IllegalArgumentException(errMsg);
93+
}
94+
try {
95+
final var root = MAPPER.readTree(dbMetadata);
96+
if (!root.has("v2")) {
97+
String errMsg =
98+
String.format("Database metadata file %s is not in v2 format", dbMetadata);
99+
LOG.error(errMsg);
100+
throw new IllegalArgumentException(errMsg);
101+
}
102+
103+
final var v2Obj = root.get("v2");
104+
if (!v2Obj.has("format")) {
105+
String errMsg =
106+
String.format(
107+
"Database metadata file %s is malformed, \"format\" field not found", dbMetadata);
108+
LOG.error(errMsg);
109+
throw new IllegalArgumentException(errMsg);
110+
}
111+
112+
final var formatField = v2Obj.get("format").asText();
113+
final OptionalInt maybePrivacyVersion =
114+
v2Obj.has("privacyVersion")
115+
? OptionalInt.of(v2Obj.get("privacyVersion").asInt())
116+
: OptionalInt.empty();
117+
118+
final DataStorageFormat dataStorageFormat = DataStorageFormat.valueOf(formatField);
119+
final int v1Version =
120+
switch (dataStorageFormat) {
121+
case FOREST -> 1;
122+
case BONSAI -> 2;
123+
};
124+
125+
@JsonSerialize
126+
record V1(int version, OptionalInt privacyVersion) {}
127+
128+
MAPPER.writeValue(dbMetadata, new V1(v1Version, maybePrivacyVersion));
129+
LOG.info("Successfully reverted database metadata from v2 to v1 in {}", dbMetadata);
130+
} catch (IOException ioe) {
131+
throw new RuntimeException(ioe);
132+
}
133+
}
134+
}
135+
}

besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/StorageSubCommand.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
subcommands = {
4949
StorageSubCommand.RevertVariablesStorage.class,
5050
RocksDbSubCommand.class,
51-
TrieLogSubCommand.class
51+
TrieLogSubCommand.class,
52+
RevertMetadataSubCommand.class
5253
})
5354
public class StorageSubCommand implements Runnable {
5455

besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
2929
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogPruner;
3030
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
31-
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
31+
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
3232

3333
import java.io.IOException;
3434
import java.io.PrintWriter;

besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@
9191
import org.hyperledger.besu.ethereum.trie.forest.pruner.Pruner;
9292
import org.hyperledger.besu.ethereum.trie.forest.pruner.PrunerConfiguration;
9393
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
94-
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
9594
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
9695
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
9796
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorage;
9897
import org.hyperledger.besu.evm.internal.EvmConfiguration;
9998
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
10099
import org.hyperledger.besu.plugin.services.MetricsSystem;
101100
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
101+
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
102102
import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelectorFactory;
103103
import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionValidatorFactory;
104104

besu/src/main/java/org/hyperledger/besu/services/BesuConfigurationImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.hyperledger.besu.ethereum.core.MiningParameters;
1919
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
2020
import org.hyperledger.besu.plugin.services.BesuConfiguration;
21+
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
2122

2223
import java.nio.file.Path;
2324

@@ -58,8 +59,8 @@ public Path getDataPath() {
5859
}
5960

6061
@Override
61-
public int getDatabaseVersion() {
62-
return dataStorageConfiguration.getDataStorageFormat().getDatabaseVersion();
62+
public DataStorageFormat getDatabaseFormat() {
63+
return dataStorageConfiguration.getDataStorageFormat();
6364
}
6465

6566
@Override

besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.GOERLI_DISCOVERY_URL;
3333
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_BOOTSTRAP_NODES;
3434
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_DISCOVERY_URL;
35-
import static org.hyperledger.besu.ethereum.worldstate.DataStorageFormat.BONSAI;
3635
import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER;
36+
import static org.hyperledger.besu.plugin.services.storage.DataStorageFormat.BONSAI;
3737
import static org.junit.Assume.assumeThat;
3838
import static org.mockito.ArgumentMatchers.any;
3939
import static org.mockito.ArgumentMatchers.contains;

besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
import org.hyperledger.besu.cli.options.AbstractCLIOptionsTest;
2222
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
23-
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
2423
import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration;
24+
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
2525

2626
import org.junit.jupiter.api.Test;
2727

0 commit comments

Comments
 (0)