Skip to content

Commit

Permalink
add Xchain-pruning-blocks-retained must be >= epochlength (#7963) (#8140
Browse files Browse the repository at this point in the history
)

Signed-off-by: philosup <[email protected]>
  • Loading branch information
philosup authored Feb 4, 2025
1 parent 90df5e5 commit b74a7f2
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 7 deletions.
38 changes: 31 additions & 7 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -1587,13 +1587,37 @@ private void validateRpcWsOptions() {
}

private void validateChainDataPruningParams() {
if (unstableChainPruningOptions.getChainDataPruningEnabled()
&& unstableChainPruningOptions.getChainDataPruningBlocksRetained()
< unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit()) {
throw new ParameterException(
this.commandLine,
"--Xchain-pruning-blocks-retained must be >= "
+ unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit());
Long chainDataPruningBlocksRetained =
unstableChainPruningOptions.getChainDataPruningBlocksRetained();
if (unstableChainPruningOptions.getChainDataPruningEnabled()) {
final GenesisConfigOptions genesisConfigOptions = readGenesisConfigOptions();
if (chainDataPruningBlocksRetained
< unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit()) {
throw new ParameterException(
this.commandLine,
"--Xchain-pruning-blocks-retained must be >= "
+ unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit());
} else if (genesisConfigOptions.isPoa()) {
Long epochLength = 0L;
String consensusMechanism = "";
if (genesisConfigOptions.isIbft2()) {
epochLength = genesisConfigOptions.getBftConfigOptions().getEpochLength();
consensusMechanism = "IBFT2";
} else if (genesisConfigOptions.isQbft()) {
epochLength = genesisConfigOptions.getQbftConfigOptions().getEpochLength();
consensusMechanism = "QBFT";
} else if (genesisConfigOptions.isClique()) {
epochLength = genesisConfigOptions.getCliqueConfigOptions().getEpochLength();
consensusMechanism = "Clique";
}
if (chainDataPruningBlocksRetained < epochLength) {
throw new ParameterException(
this.commandLine,
String.format(
"--Xchain-pruning-blocks-retained(%d) must be >= epochlength(%d) for %s",
chainDataPruningBlocksRetained, epochLength, consensusMechanism));
}
}
}
}

Expand Down
87 changes: 87 additions & 0 deletions besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2598,4 +2598,91 @@ void helpOutputShouldDisplayCorrectDefaultValues() {

assertThat(errorOutputString).isEmpty();
}

@Test
void chainPruningEnabledWithPOAShouldFailWhenChainPruningBlocksRetainedValueLessThanEpochLength()
throws IOException {
JsonObject genesis = GENESIS_VALID_JSON;

// for QBFT
genesis.getJsonObject("config").put("qbft", new JsonObject().put("epochlength", 25000));
final Path genesisFileQBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileQBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=7200",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("--Xchain-pruning-blocks-retained(7200) must be >= epochlength(25000) for QBFT");
commandErrorOutput.reset();

// for IBFT2
genesis.getJsonObject("config").put("ibft2", new JsonObject().put("epochlength", 20000));
genesis.getJsonObject("config").remove("qbft");
final Path genesisFileIBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileIBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=7200",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("--Xchain-pruning-blocks-retained(7200) must be >= epochlength(20000) for IBFT2");
commandErrorOutput.reset();

// for Clique
genesis.getJsonObject("config").put("clique", new JsonObject().put("epochlength", 10000));
genesis.getJsonObject("config").remove("ibft2");
final Path genesisFileClique = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileClique.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=7200",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
"--Xchain-pruning-blocks-retained(7200) must be >= epochlength(10000) for Clique");
}

@Test
void chainPruningEnabledWithPOA() throws IOException {
JsonObject genesis = GENESIS_VALID_JSON;
// for QBFT
genesis.getJsonObject("config").put("qbft", new JsonObject().put("epochlength", 25000));
final Path genesisFileForQBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileForQBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=25000",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();

// for IBFT2
genesis.getJsonObject("config").put("ibft2", new JsonObject().put("epochlength", 20000));
genesis.getJsonObject("config").remove("qbft");
final Path genesisFileIBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileIBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=20000",
"--version-compatibility-protection=false");

assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();

// for Clique
genesis.getJsonObject("config").put("clique", new JsonObject().put("epochlength", 10000));
genesis.getJsonObject("config").remove("ibft2");
final Path genesisFileClique = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileClique.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=10000",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
}

0 comments on commit b74a7f2

Please sign in to comment.