Skip to content
/ besu Public
forked from hyperledger/besu

Commit

Permalink
Implementing support for emptyBlockPeriodSeconds in QBFT (Issue hyper…
Browse files Browse the repository at this point in the history
…ledger#3810)

Signed-off-by: amsmota <[email protected]>
  • Loading branch information
amsmota committed Apr 16, 2024
1 parent 1437b33 commit 6f047b2
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 10 deletions.
19 changes: 19 additions & 0 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2128,6 +2128,8 @@ private MiningParameters getMiningParameters() {
if (miningParameters == null) {
miningOptions.setGenesisBlockPeriodSeconds(
getGenesisBlockPeriodSeconds(getActualGenesisConfigOptions()));
miningOptions.setGenesisEmptyBlockPeriodSeconds(
getGenesisEmptyBlockPeriodSeconds(getActualGenesisConfigOptions()));
miningParameters = miningOptions.toDomainObject();
initMiningParametersMetrics(miningParameters);
}
Expand Down Expand Up @@ -2162,6 +2164,23 @@ private OptionalInt getGenesisBlockPeriodSeconds(
return OptionalInt.empty();
}

private OptionalInt getGenesisEmptyBlockPeriodSeconds(
final GenesisConfigOptions genesisConfigOptions) {
if (genesisConfigOptions.isClique()) {
return OptionalInt.of(genesisConfigOptions.getCliqueConfigOptions().getEmptyBlockPeriodSeconds());
}

if (genesisConfigOptions.isIbft2()) {
return OptionalInt.of(genesisConfigOptions.getBftConfigOptions().getEmptyBlockPeriodSeconds());
}

if (genesisConfigOptions.isQbft()) {
return OptionalInt.of(genesisConfigOptions.getQbftConfigOptions().getEmptyBlockPeriodSeconds());
}

return OptionalInt.empty();
}

private boolean isPruningEnabled() {
return pruningEnabled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ static class Unstable {
}

private OptionalInt maybeGenesisBlockPeriodSeconds;
private OptionalInt maybeEmptyGenesisBlockPeriodSeconds;

private MiningOptions() {}

Expand All @@ -212,6 +213,16 @@ public void setGenesisBlockPeriodSeconds(final OptionalInt genesisBlockPeriodSec
maybeGenesisBlockPeriodSeconds = genesisBlockPeriodSeconds;
}

/**
* Set the optional genesis empty block period per seconds
*
* @param genesisEmptyBlockPeriodSeconds if the network is PoA then the empty block period in seconds
* specified in the genesis file, otherwise empty.
*/
public void setGenesisEmptyBlockPeriodSeconds(final OptionalInt genesisEmptyBlockPeriodSeconds) {
maybeEmptyGenesisBlockPeriodSeconds = genesisEmptyBlockPeriodSeconds;
}

/**
* Validate that there are no inconsistencies in the specified options. For example that the
* options are valid for the selected implementation.
Expand Down Expand Up @@ -299,6 +310,7 @@ public void validate(
static MiningOptions fromConfig(final MiningParameters miningParameters) {
final MiningOptions miningOptions = MiningOptions.create();
miningOptions.setGenesisBlockPeriodSeconds(miningParameters.getGenesisBlockPeriodSeconds());
miningOptions.setGenesisEmptyBlockPeriodSeconds(miningParameters.getGenesisEmptyBlockPeriodSeconds());
miningOptions.isMiningEnabled = miningParameters.isMiningEnabled();
miningOptions.iStratumMiningEnabled = miningParameters.isStratumMiningEnabled();
miningOptions.stratumNetworkInterface = miningParameters.getStratumNetworkInterface();
Expand Down Expand Up @@ -337,6 +349,10 @@ public MiningParameters toDomainObject() {
throw new IllegalStateException(
"genesisBlockPeriodSeconds must be set before using this object");
}
if (maybeGenesisEmptyBlockPeriodSeconds == null) {
throw new IllegalStateException(
"genesisEmptyBlockPeriodSeconds must be set before using this object");
}

final var updatableInitValuesBuilder =
MutableInitValues.builder()
Expand All @@ -355,6 +371,7 @@ public MiningParameters toDomainObject() {

return ImmutableMiningParameters.builder()
.genesisBlockPeriodSeconds(maybeGenesisBlockPeriodSeconds)
.genesisEmptyBBlockPeriodSeconds(maybeGenesisEmptyBBlockPeriodSeconds)
.mutableInitValues(updatableInitValuesBuilder.build())
.isStratumMiningEnabled(iStratumMiningEnabled)
.stratumNetworkInterface(stratumNetworkInterface)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public interface BftConfigOptions {
/**
* Gets empty block period seconds.
*
* @return the block period seconds
* @return the empty block period seconds
*/
int getEmptyBlockPeriodSeconds();

Expand Down
5 changes: 3 additions & 2 deletions config/src/main/java/org/hyperledger/besu/config/BftFork.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,11 @@ public OptionalInt getBlockPeriodSeconds() {
/**
* Gets empty block period seconds.
*
* @return the block empty period seconds
* @return the empty block period seconds
*/
public OptionalInt getEmptyBlockPeriodSeconds() {
return JsonUtil.getPositiveInt(forkConfigRoot, EMPTY_BLOCK_PERIOD_SECONDS_KEY);
// it can be 0 for emptyblockperiodseconds
return JsonUtil.getInt(forkConfigRoot, EMPTY_BLOCK_PERIOD_SECONDS_KEY);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class JsonBftConfigOptions implements BftConfigOptions {
private static final long DEFAULT_EPOCH_LENGTH = 30_000;
private static final int DEFAULT_BLOCK_PERIOD_SECONDS = 1;
private static final int DEFAULT_EMPTY_BLOCK_PERIOD_SECONDS = 0;
// 0 keeps working as before, increase to activate itby default if needed
// 0 keeps working as before, increase to activate it
private static final int DEFAULT_ROUND_EXPIRY_SECONDS = 1;
// In a healthy network this can be very small. This default limit will allow for suitable
// protection for on a typical 20 node validator network with multiple rounds
Expand Down Expand Up @@ -73,7 +73,6 @@ public int getEmptyBlockPeriodSeconds() {
bftConfigRoot, "emptyblockperiodseconds", DEFAULT_EMPTY_BLOCK_PERIOD_SECONDS);
}


@Override
public int getRequestTimeoutSeconds() {
return JsonUtil.getInt(bftConfigRoot, "requesttimeoutseconds", DEFAULT_ROUND_EXPIRY_SECONDS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ public synchronized void startTimer(
final ConsensusRoundIdentifier round, final BlockHeader chainHeadHeader) {

// absolute time when the timer is supposed to expire
final int blockPeriodSeconds =
final int currentBlockPeriodSeconds =
forksSchedule.getFork(round.getSequenceNumber()).getValue().getBlockPeriodSeconds();
final long minimumTimeBetweenBlocksMillis = blockPeriodSeconds * 1000L;
final long minimumTimeBetweenBlocksMillis = currentBlockPeriodSeconds * 1000L;
final long expiryTime = chainHeadHeader.getTimestamp() * 1_000 + minimumTimeBetweenBlocksMillis;

setBlockTimes(round, false);
Expand Down Expand Up @@ -136,12 +136,16 @@ private synchronized void setBlockTimes(final ConsensusRoundIdentifier round, fi
? this.emptyBlockPeriodSeconds
: this.blockPeriodSeconds;

LOG.debug("NEW CURRENTBLOCKPERIODSECONDS SET TO {}: {}", isEmpty?"EMPTYBLOCKPERIODSECONDS":"BLOCKPERIODSECONDS", currentBlockPeriodSeconds);
LOG.debug(
"NEW CURRENTBLOCKPERIODSECONDS SET TO {}: {}"
, isEmpty?"EMPTYBLOCKPERIODSECONDS":"BLOCKPERIODSECONDS"
, currentBlockPeriodSeconds);
}

public synchronized long getBlockPeriodSeconds(){
return blockPeriodSeconds;
}

public synchronized long getEmptyBlockPeriodSeconds(){
return emptyBlockPeriodSeconds;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public static BlockHeaderValidator.Builder blockHeaderValidator(
DEFAULT_MIN_GAS_LIMIT, DEFAULT_MAX_GAS_LIMIT, baseFeeMarket))
.addRule(new TimestampBoundedByFutureParameter(1))
//.addRule(new TimestampMoreRecentThanParent(secondsBetweenBlocks))
// removed because of conflict with emptyblockperiodseconds
.addRule(
new ConstantFieldValidationRule<>(
"MixHash", BlockHeader::getMixHash, BftHelpers.EXPECTED_MIX_HASH))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ public ConsensusRoundIdentifier getRoundIdentifier() {
* @return a Block
*/
public Block createBlock(final long headerTimeStampSeconds) {
LOG.debug("Creating proposed block. round={}", roundState.getRoundIdentifier());
LOG.debug(
"Creating proposed block. round={}",
roundState.getRoundIdentifier());
return blockCreator.createBlock(headerTimeStampSeconds).getBlock();
}

Expand All @@ -138,7 +140,9 @@ public Block createBlock(final long headerTimeStampSeconds) {
* @param headerTimeStampSeconds the header time stamp seconds
*/
public void sendProposalMessage(final Block block) {
LOG.trace("Creating proposed block blockHeader={}", block.getHeader());
LOG.trace(
"Creating proposed block blockHeader={}",
block.getHeader());
updateStateWithProposalAndTransmit(block, emptyList(), emptyList());
}

Expand Down

0 comments on commit 6f047b2

Please sign in to comment.