Skip to content

Commit

Permalink
Test Clique mines a block only when txs are present, if create empty …
Browse files Browse the repository at this point in the history
…blocks is false

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
  • Loading branch information
fab-10 committed Nov 22, 2023
1 parent 1c18e7d commit 3669fed
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,9 @@ public BesuNode createCliqueNode(final String name) throws IOException {
.build());
}

public BesuNode createCliqueNoEmptyBlockNode(final String name) throws IOException {
public BesuNode createCliqueNode(
final String name, final GenesisConfigurationFactory.CliqueOptions cliqueOptions)
throws IOException {
return create(
new BesuNodeConfigurationBuilder()
.name(name)
Expand All @@ -388,7 +390,9 @@ public BesuNode createCliqueNoEmptyBlockNode(final String name) throws IOExcepti
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.devMode(false)
.genesisConfigProvider(
GenesisConfigurationFactory::createCliqueNoEmptyBlocksGenesisConfig)
validators ->
GenesisConfigurationFactory.createCliqueGenesisConfig(
validators, cliqueOptions))
.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,17 @@ private GenesisConfigurationFactory() {

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

public static Optional<String> createCliqueNoEmptyBlocksGenesisConfig(
final Collection<? extends RunnableNode> validators) {
final String template = readGenesisFile("/clique/clique-no-empty-blocks.json");
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 @@ -145,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 @@ -154,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 Down Expand Up @@ -44,12 +45,33 @@ public void shouldMineTransactionsOnSingleNode() throws IOException {

@Test
public void shouldNotMineBlocksIfNoTransactionsOnSingleNode() throws IOException {
final BesuNode minerNode = besu.createCliqueNoEmptyBlockNode("miner1");
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
42 changes: 0 additions & 42 deletions acceptance-tests/tests/src/test/resources/clique/clique.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"constantinopleBlock": 6,
"petersburgBlock": 7,
"clique": {
"blockperiodseconds": 10,
"epochlength": 30000,
"createemptyblocks": false
"blockperiodseconds": %blockperiodseconds%,
"epochlength": %epochlength%,
"createemptyblocks": %createemptyblocks%
}
},
"nonce": "0x0",
Expand Down

0 comments on commit 3669fed

Please sign in to comment.