add Xchain-pruning-blocks-retained must be >= epochlength (#7963) (#8140)

Signed-off-by: philosup <philosup@gmail.com>
This commit is contained in:
phillip Yun
2025-02-04 19:19:45 +09:00
committed by GitHub
parent 90df5e5564
commit b74a7f2133
2 changed files with 118 additions and 7 deletions

View File

@@ -1587,13 +1587,37 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
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));
}
}
}
}

View File

@@ -2598,4 +2598,91 @@ public class BesuCommandTest extends CommandTestAbstract {
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();
}
}