Skip to content

Commit

Permalink
Acceptance test for Clique when configured to not create empty blocks (
Browse files Browse the repository at this point in the history
…hyperledger#6191)


Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
  • Loading branch information
fab-10 authored Nov 23, 2023
1 parent 4326002 commit be5cc68
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationFactory;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationFactory.CliqueOptions;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.pki.PkiKeystoreConfigurationFactory;

import java.io.File;
Expand Down Expand Up @@ -368,14 +369,30 @@ public BesuNode createNodeWithNoDiscovery(final String name) throws IOException
}

public BesuNode createCliqueNode(final String name) throws IOException {
return createCliqueNode(name, CliqueOptions.DEFAULT);
}

public BesuNode createCliqueNode(final String name, final CliqueOptions cliqueOptions)
throws IOException {
return createCliqueNodeWithExtraCliOptions(name, cliqueOptions, List.of());
}

public BesuNode createCliqueNodeWithExtraCliOptions(
final String name, final CliqueOptions cliqueOptions, final List<String> extraCliOptions)
throws IOException {
return create(
new BesuNodeConfigurationBuilder()
.name(name)
.miningEnabled()
.jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig())
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.devMode(false)
.genesisConfigProvider(GenesisConfigurationFactory::createCliqueGenesisConfig)
.jsonRpcTxPool()
.genesisConfigProvider(
validators ->
GenesisConfigurationFactory.createCliqueGenesisConfig(
validators, cliqueOptions))
.extraCLIOptions(extraCliOptions)
.build());
}

Expand Down Expand Up @@ -567,6 +584,7 @@ public BesuNode createCliqueNodeWithValidators(final String name, final String..
.miningEnabled()
.jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig())
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.jsonRpcTxPool()
.devMode(false)
.genesisConfigProvider(
nodes ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,17 @@ private GenesisConfigurationFactory() {

public static Optional<String> createCliqueGenesisConfig(
final Collection<? extends RunnableNode> validators) {
final String template = readGenesisFile("/clique/clique.json");
return createCliqueGenesisConfig(validators, CliqueOptions.DEFAULT);
}

public static Optional<String> createCliqueGenesisConfig(
final Collection<? extends RunnableNode> validators, final CliqueOptions cliqueOptions) {
final String template = readGenesisFile("/clique/clique.json.tpl");

return updateGenesisExtraData(
validators, template, CliqueExtraData::createGenesisExtraDataString);
validators,
updateGenesisCliqueOptions(template, cliqueOptions),
CliqueExtraData::createGenesisExtraDataString);
}

public static Optional<String> createIbft2GenesisConfig(
Expand Down Expand Up @@ -138,6 +146,14 @@ private static Optional<String> updateGenesisExtraData(
return Optional.of(genesis);
}

private static String updateGenesisCliqueOptions(
final String template, final CliqueOptions cliqueOptions) {
return template
.replace("%blockperiodseconds%", String.valueOf(cliqueOptions.blockPeriodSeconds))
.replace("%epochlength%", String.valueOf(cliqueOptions.epochLength))
.replace("%createemptyblocks%", String.valueOf(cliqueOptions.createEmptyBlocks));
}

@SuppressWarnings("UnstableApiUsage")
public static String readGenesisFile(final String filepath) {
try {
Expand All @@ -147,4 +163,8 @@ public static String readGenesisFile(final String filepath) {
throw new IllegalStateException("Unable to get test genesis config " + filepath);
}
}

public record CliqueOptions(int blockPeriodSeconds, int epochLength, boolean createEmptyBlocks) {
public static final CliqueOptions DEFAULT = new CliqueOptions(10, 30000, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationFactory.CliqueOptions;

import java.io.IOException;

Expand All @@ -42,6 +43,35 @@ public void shouldMineTransactionsOnSingleNode() throws IOException {
cluster.verify(receiver.balanceEquals(3));
}

@Test
public void shouldNotMineBlocksIfNoTransactionsWhenCreateEmptyBlockIsFalse() throws IOException {
final var cliqueOptionsNoEmptyBlocks =
new CliqueOptions(
CliqueOptions.DEFAULT.blockPeriodSeconds(), CliqueOptions.DEFAULT.epochLength(), false);
final BesuNode minerNode = besu.createCliqueNode("miner1", cliqueOptionsNoEmptyBlocks);
cluster.start(minerNode);

cluster.verify(clique.noNewBlockCreated(minerNode));
}

@Test
public void shouldMineBlocksOnlyWhenTransactionsArePresentWhenCreateEmptyBlockIsFalse()
throws IOException {
final var cliqueOptionsNoEmptyBlocks =
new CliqueOptions(
CliqueOptions.DEFAULT.blockPeriodSeconds(), CliqueOptions.DEFAULT.epochLength(), false);
final BesuNode minerNode = besu.createCliqueNode("miner1", cliqueOptionsNoEmptyBlocks);
cluster.start(minerNode);

final Account sender = accounts.createAccount("account1");

cluster.verify(clique.noNewBlockCreated(minerNode));

minerNode.execute(accountTransactions.createTransfer(sender, 50));

minerNode.verify(clique.blockIsCreatedByProposer(minerNode));
}

@Test
public void shouldMineTransactionsOnMultipleNodes() throws IOException {
final BesuNode minerNode1 = besu.createCliqueNode("miner1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
"constantinopleBlock": 6,
"petersburgBlock": 7,
"clique": {
"blockperiodseconds": 10,
"epochlength": 30000
"blockperiodseconds": %blockperiodseconds%,
"epochlength": %epochlength%,
"createemptyblocks": %createemptyblocks%
}
},
"nonce": "0x0",
Expand Down

0 comments on commit be5cc68

Please sign in to comment.