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

Import export trie log #6363

Merged
merged 51 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
16c0a49
Add x-trie-log subcommand for one-off backlog prune
siladu Nov 20, 2023
7dd4928
long -> int
siladu Nov 20, 2023
bf2b098
Removed banned method
gfukushima Dec 12, 2023
e67ae51
Preload process stream in parallel
gfukushima Dec 12, 2023
9b4e0c9
Drop unwanted trielogs and keep reatain layers only
gfukushima Dec 14, 2023
0b9fe83
Add output to user and cleanup refactor
gfukushima Dec 15, 2023
426848e
small tweak to display cf that had reference dropped by RocksDbSegmen…
gfukushima Dec 15, 2023
7401b59
spotless
gfukushima Dec 15, 2023
1b7fb72
Fix classes that changed package
gfukushima Dec 15, 2023
11e6b05
spotless
gfukushima Dec 15, 2023
f2d01e2
Code review
gfukushima Dec 15, 2023
04f1aaa
Only clear DB when we have the exact amount of trie logs we want in m…
gfukushima Dec 15, 2023
2f01c5a
Trielogs stream to and from file to avoid possibly OOM
gfukushima Dec 18, 2023
56e4c8e
Process trie logs in chunks to avoid OOM
gfukushima Dec 18, 2023
78561b0
save and read in batches to handle edge cases
gfukushima Dec 19, 2023
42c72cf
save and read files to/from database dir
gfukushima Dec 20, 2023
9961fc2
Merge branch 'main' into x-trie-log-subcommand-2
gfukushima Dec 20, 2023
9389540
add unit tests and PR review fixes
gfukushima Dec 21, 2023
e3d4fbc
Merge branch 'main' into x-trie-log-subcommand-2
gfukushima Dec 21, 2023
c7144fe
spdx
gfukushima Dec 21, 2023
20b0ba5
Fix unit tests directory creation and deletion
gfukushima Dec 21, 2023
586ab25
rename Xbonsai-trie-log-pruning-enabled to Xbonsai-limit-trie-logs-en…
gfukushima Jan 4, 2024
67e6f3d
Import and export trie log subcommands
gfukushima Jan 4, 2024
b9640e5
PR review
gfukushima Jan 4, 2024
3bc1878
spotless
gfukushima Jan 4, 2024
d47ddf5
fix path resolver and added unit tests
gfukushima Jan 7, 2024
999edb6
Merge branch 'main' into import-export-trie-log
gfukushima Jan 8, 2024
1699fe4
fix unit test
gfukushima Jan 8, 2024
e679cb3
Merge remote-tracking branch 'origin/import-export-trie-log' into imp…
gfukushima Jan 8, 2024
5d3b4f2
fix unit test
gfukushima Jan 8, 2024
f839b75
Merge branch 'main' into import-export-trie-log
gfukushima Jan 8, 2024
0caa4cf
Add import and export to list of subcommands under --x-trie-log
gfukushima Jan 8, 2024
2d5d31d
Merge remote-tracking branch 'origin/import-export-trie-log' into imp…
gfukushima Jan 8, 2024
37df23e
Remove static from setup method
gfukushima Jan 8, 2024
5ce1800
change option name and fix descriptions
gfukushima Jan 8, 2024
98423dc
Merge branch 'main' into import-export-trie-log
gfukushima Jan 8, 2024
cf3a5e6
Fix subcommands descriptions
gfukushima Jan 9, 2024
c759bba
Merge branch 'main' into import-export-trie-log
gfukushima Jan 9, 2024
5fb9413
Remove old flag and move commands const into Unstable
gfukushima Jan 12, 2024
087c54b
Allow list of block hashes to passed as well as a file to be generate…
gfukushima Jan 12, 2024
4b033a3
Merge remote-tracking branch 'origin/import-export-trie-log' into imp…
gfukushima Jan 12, 2024
3a89ac3
Allow list of block hashes to passed as well as a file to be generate…
gfukushima Jan 12, 2024
9be7d13
Fix broken test when replaced the old option
gfukushima Jan 12, 2024
75d1c3b
import and export using rlp
jframe Jan 19, 2024
5eb4cda
Merge branch 'main' into import-export-trie-log
jframe Jan 19, 2024
5425075
tests for exporting and importing multiple trielogs
jframe Jan 19, 2024
2de0b19
Merge branch 'import-export-trie-log' of github.com:gfukushima/besu i…
jframe Jan 19, 2024
248a776
Merge branch 'main' into import-export-trie-log
jframe Jan 19, 2024
55d653e
fix build
jframe Jan 19, 2024
c9d38f0
Merge branch 'main' into import-export-trie-log
jframe Jan 19, 2024
b9d7620
Merge branch 'main' into import-export-trie-log
jframe Jan 22, 2024
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,8 +42,6 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
private static final String BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD =
"--bonsai-historical-block-limit";



// Use Bonsai DB
@Option(
names = {DATA_STORAGE_FORMAT},
Expand All @@ -64,10 +62,12 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
private final DataStorageOptions.Unstable unstableOptions = new Unstable();

static class Unstable {
private static final String BONSAI_LIMIT_TRIE_LOGS_ENABLED = "--Xbonsai-limit-trie-logs-enabled";
private static final String BONSAI_LIMIT_TRIE_LOGS_ENABLED =
"--Xbonsai-limit-trie-logs-enabled";
private static final String BONSAI_TRIE_LOGS_RETENTION_THRESHOLD =
"--Xbonsai-trie-logs-retention-threshold";
private static final String BONSAI_TRIE_LOG_PRUNING_LIMIT = "--Xbonsai-trie-logs-pruning-limit";

@CommandLine.Option(
hidden = true,
names = {BONSAI_LIMIT_TRIE_LOGS_ENABLED},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.hyperledger.besu.cli.subcommands.storage;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Collections.singletonList;
import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH;

import org.hyperledger.besu.datatypes.Hash;
Expand Down Expand Up @@ -352,13 +351,9 @@ static void printCount(final PrintWriter out, final TrieLogCount count) {
}

static void importTrieLog(
final BonsaiWorldStateKeyValueStorage rootWorldStateStorage,
final Path dataDirectoryPath,
final Hash trieLogHash) {
final String trieLogFile =
dataDirectoryPath.resolve(DATABASE_PATH).resolve(trieLogHash.toString()).toString();
final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, final Path trieLogFilePath) {

var trieLog = readTrieLogsFromFile(trieLogFile);
var trieLog = readTrieLogsFromFile(trieLogFilePath.toString());

var updater = rootWorldStateStorage.updater();
trieLog.forEach((key, value) -> updater.getTrieLogStorageTransaction().put(key, value));
jframe marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -367,13 +362,12 @@ static void importTrieLog(

static void exportTrieLog(
final BonsaiWorldStateKeyValueStorage rootWorldStateStorage,
final Path dataDirectoryPath,
final Hash trieLogHash)
final List<Hash> trieLogHash,
final Path directoryPath)
throws IOException {
final String trieLogFile =
dataDirectoryPath.resolve(DATABASE_PATH).resolve(trieLogHash.toString()).toString();
final String trieLogFile = directoryPath.toString();

saveTrieLogsInFile(singletonList(trieLogHash), rootWorldStateStorage, trieLogFile);
saveTrieLogsInFile(trieLogHash, rootWorldStateStorage, trieLogFile);
}

record TrieLogCount(int total, int canonicalCount, int forkCount, int orphanCount) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.io.PrintWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
Expand Down Expand Up @@ -147,21 +148,38 @@ static class ExportTrieLog implements Runnable {

@CommandLine.Option(
names = "--trie-log-block-hash",
description = "The hash of the block you want to export the trie log of.",
description = "The hash of the block you want to import the trie log of",
siladu marked this conversation as resolved.
Show resolved Hide resolved
split = " {0,1}, {0,1}",
arity = "1..*")
private List<String> trieLogBlockHashList;

@CommandLine.Option(
names = "--trie-log-file-path",
description = "The hash of the block you want to import the trie log of",
arity = "1..1")
private String trieLogBlockHash;
private Path trieLogFilePath = null;

jframe marked this conversation as resolved.
Show resolved Hide resolved
@Override
public void run() {
if (trieLogFilePath == null) {
trieLogFilePath =
Paths.get(
TrieLogSubCommand.parentCommand
.parentCommand
.dataDir()
.resolve("trie-logs.bin")
.toAbsolutePath()
.toString());
}

TrieLogContext context = getTrieLogContext();
final Path dataDirectoryPath =
Paths.get(
TrieLogSubCommand.parentCommand.parentCommand.dataDir().toAbsolutePath().toString());

final List<Hash> listOfBlockHashes =
trieLogBlockHashList.stream().map(Hash::fromHexString).toList();

try {
TrieLogHelper.exportTrieLog(
context.rootWorldStateStorage(),
dataDirectoryPath,
Hash.fromHexString(trieLogBlockHash));
context.rootWorldStateStorage(), listOfBlockHashes, trieLogFilePath);
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand All @@ -184,19 +202,27 @@ static class ImportTrieLog implements Runnable {
private CommandLine.Model.CommandSpec spec; // Picocli injects reference to command spec

@CommandLine.Option(
names = "--trie-log-block-hash",
names = "--trie-log-file-path",
description = "The hash of the block you want to import the trie log of",
arity = "1..1")
private String trieLogBlockHash;
private Path trieLogFilePath = null;

@Override
public void run() {
if (trieLogFilePath == null) {
trieLogFilePath =
Paths.get(
TrieLogSubCommand.parentCommand
.parentCommand
.dataDir()
.resolve("trie-logs.bin")
.toAbsolutePath()
.toString());
}

TrieLogContext context = getTrieLogContext();
final Path dataDirectoryPath =
Paths.get(
TrieLogSubCommand.parentCommand.parentCommand.dataDir().toAbsolutePath().toString());
TrieLogHelper.importTrieLog(
context.rootWorldStateStorage(), dataDirectoryPath, Hash.fromHexString(trieLogBlockHash));

TrieLogHelper.importTrieLog(context.rootWorldStateStorage(), trieLogFilePath);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package org.hyperledger.besu.cli.subcommands.storage;

import static java.util.Collections.singletonList;
import static org.hyperledger.besu.ethereum.worldstate.DataStorageFormat.BONSAI;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand All @@ -39,7 +40,6 @@
import java.util.Optional;

import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -93,17 +93,6 @@ public void setup() throws IOException {
.getTrieLogStorageTransaction()
.put(blockHeader5.getHash().toArrayUnsafe(), Bytes.fromHexString("0x05").toArrayUnsafe());
updater.getTrieLogStorageTransaction().commit();

createDirectory();
}

static void createDirectory() throws IOException {
Files.createDirectories(dataDir.resolve("database"));
}

@AfterEach
void deleteDirectory() throws IOException {
Files.deleteIfExists(dataDir.resolve("database"));
}

void mockBlockchainBase() {
Expand All @@ -113,7 +102,8 @@ void mockBlockchainBase() {
}

@Test
public void prune() {
public void prune() throws IOException {
Files.createDirectories(dataDir.resolve("database"));

DataStorageConfiguration dataStorageConfiguration =
ImmutableDataStorageConfiguration.builder()
Expand Down Expand Up @@ -268,18 +258,20 @@ public void exceptionWhileSavingFileStopsPruneProcess() throws IOException {

@Test
public void exportedTrieMatchesDbTrieLog() throws IOException {
TrieLogHelper.exportTrieLog(inMemoryWorldState, dataDir, blockHeader1.getHash());
Path trieLogFile = dataDir.resolve("database").resolve(blockHeader1.getHash().toString());
TrieLogHelper.exportTrieLog(
inMemoryWorldState,
singletonList(blockHeader1.getHash()),
dataDir.resolve("trie-log-dump"));

var trieLog =
TrieLogHelper.readTrieLogsFromFile(trieLogFile.toString()).entrySet().stream()
TrieLogHelper.readTrieLogsFromFile(dataDir.resolve("trie-log-dump").toString())
.entrySet()
.stream()
.findFirst()
.get();

assertArrayEquals(trieLog.getKey(), blockHeader1.getHash().toArrayUnsafe());
assertArrayEquals(trieLog.getValue(), Bytes.fromHexString("0x01").toArrayUnsafe());

Files.delete(trieLogFile);
}

@Test
Expand All @@ -288,10 +280,12 @@ public void importedTrieLogMatchesDbTrieLog() throws IOException {
BonsaiWorldStateKeyValueStorage inMemoryWorldState2 =
new BonsaiWorldStateKeyValueStorage(tempStorageProvider, new NoOpMetricsSystem());

TrieLogHelper.exportTrieLog(inMemoryWorldState, dataDir, blockHeader1.getHash());
Path trieLogFile = dataDir.resolve("database").resolve(blockHeader1.getHash().toString());
TrieLogHelper.exportTrieLog(
inMemoryWorldState,
singletonList(blockHeader1.getHash()),
dataDir.resolve("trie-log-dump"));

var trieLog = TrieLogHelper.readTrieLogsFromFile(trieLogFile.toString());
var trieLog = TrieLogHelper.readTrieLogsFromFile(dataDir.resolve("trie-log-dump").toString());
var updater = inMemoryWorldState2.updater();

trieLog.forEach((k, v) -> updater.getTrieLogStorageTransaction().put(k, v));
Expand All @@ -301,7 +295,5 @@ public void importedTrieLogMatchesDbTrieLog() throws IOException {
assertArrayEquals(
inMemoryWorldState2.getTrieLog(blockHeader1.getHash()).get(),
Bytes.fromHexString("0x01").toArrayUnsafe());

Files.delete(trieLogFile);
}
}