Skip to content

Commit

Permalink
Decouple block creators (#7468)
Browse files Browse the repository at this point in the history
* wip decoupled parent block header from block creators

---------

Signed-off-by: Justin Florentine <[email protected]>
  • Loading branch information
jflo authored Sep 9, 2024
1 parent 2a52b02 commit 9a570d4
Show file tree
Hide file tree
Showing 32 changed files with 295 additions and 196 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param nodeKey the node key
* @param parentHeader the parent header
* @param epochManager the epoch manager
* @param ethScheduler the scheduler for asynchronous block creation tasks
*/
Expand All @@ -65,7 +64,6 @@ public CliqueBlockCreator(
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final NodeKey nodeKey,
final BlockHeader parentHeader,
final EpochManager epochManager,
final EthScheduler ethScheduler) {
super(
Expand All @@ -75,7 +73,6 @@ public CliqueBlockCreator(
transactionPool,
protocolContext,
protocolSchedule,
parentHeader,
ethScheduler);
this.nodeKey = nodeKey;
this.epochManager = epochManager;
Expand Down Expand Up @@ -112,6 +109,8 @@ protected BlockHeader createFinalBlockHeader(final SealableBlockHeader sealableB

private Optional<ValidatorVote> determineCliqueVote(
final SealableBlockHeader sealableBlockHeader) {
BlockHeader parentHeader =
protocolContext.getBlockchain().getBlockHeader(sealableBlockHeader.getParentHash()).get();
if (epochManager.isEpochBlock(sealableBlockHeader.getNumber())) {
return Optional.empty();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ public CliqueBlockMiner createMiner(
protocolContext,
protocolSchedule,
nodeKey,
header,
epochManager,
ethScheduler);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,11 @@ public void proposerAddressCanBeExtractFromAConstructedBlock() {
protocolContext,
protocolSchedule,
proposerNodeKey,
blockchain.getChainHeadHeader(),
epochManager,
ethScheduler);

final Block createdBlock = blockCreator.createBlock(5L).getBlock();
final Block createdBlock =
blockCreator.createBlock(5L, blockchain.getChainHeadHeader()).getBlock();

assertThat(CliqueHelpers.getProposerOfBlock(createdBlock.getHeader()))
.isEqualTo(proposerAddress);
Expand All @@ -185,11 +185,11 @@ public void insertsValidVoteIntoConstructedBlock() {
protocolContext,
protocolSchedule,
proposerNodeKey,
blockchain.getChainHeadHeader(),
epochManager,
ethScheduler);

final Block createdBlock = blockCreator.createBlock(0L).getBlock();
final Block createdBlock =
blockCreator.createBlock(0L, blockchain.getChainHeadHeader()).getBlock();
assertThat(createdBlock.getHeader().getNonce()).isEqualTo(CliqueBlockInterface.ADD_NONCE);
assertThat(createdBlock.getHeader().getCoinbase()).isEqualTo(a1);
}
Expand Down Expand Up @@ -219,11 +219,11 @@ public void insertsNoVoteWhenAtEpoch() {
protocolContext,
protocolSchedule,
proposerNodeKey,
blockchain.getChainHeadHeader(),
epochManager,
ethScheduler);

final Block createdBlock = blockCreator.createBlock(0L).getBlock();
final Block createdBlock =
blockCreator.createBlock(0L, blockchain.getChainHeadHeader()).getBlock();
assertThat(createdBlock.getHeader().getNonce()).isEqualTo(CliqueBlockInterface.DROP_NONCE);
assertThat(createdBlock.getHeader().getCoinbase()).isEqualTo(Address.fromHexString("0"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void doesNotMineBlockIfNoTransactionsWhenEmptyBlocksNotAllowed() throws Interrup
final CliqueBlockCreator blockCreator = mock(CliqueBlockCreator.class);
final Function<BlockHeader, CliqueBlockCreator> blockCreatorSupplier =
(parentHeader) -> blockCreator;
when(blockCreator.createBlock(anyLong()))
when(blockCreator.createBlock(anyLong(), any()))
.thenReturn(
new BlockCreator.BlockCreationResult(
blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming()));
Expand Down Expand Up @@ -147,7 +147,7 @@ void minesBlockIfHasTransactionsWhenEmptyBlocksNotAllowed() throws InterruptedEx
final CliqueBlockCreator blockCreator = mock(CliqueBlockCreator.class);
final Function<BlockHeader, CliqueBlockCreator> blockCreatorSupplier =
(parentHeader) -> blockCreator;
when(blockCreator.createBlock(anyLong()))
when(blockCreator.createBlock(anyLong(), any()))
.thenReturn(
new BlockCreator.BlockCreationResult(
blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public class BftBlockCreator extends AbstractBlockCreator {
* @param transactionPool the pending transactions
* @param protocolContext the protocol context
* @param protocolSchedule the protocol schedule
* @param parentHeader the parent header
* @param bftExtraDataCodec the bft extra data codec
* @param ethScheduler the scheduler for asynchronous block creation tasks
*/
Expand All @@ -65,7 +64,6 @@ public BftBlockCreator(
final TransactionPool transactionPool,
final ProtocolContext protocolContext,
final ProtocolSchedule protocolSchedule,
final BlockHeader parentHeader,
final BftExtraDataCodec bftExtraDataCodec,
final EthScheduler ethScheduler) {
super(
Expand All @@ -75,21 +73,20 @@ public BftBlockCreator(
transactionPool,
protocolContext,
protocolSchedule,
parentHeader,
ethScheduler);
this.bftExtraDataCodec = bftExtraDataCodec;
}

@Override
public BlockCreationResult createBlock(final long timestamp) {
public BlockCreationResult createBlock(final long timestamp, final BlockHeader parentHeader) {
ProtocolSpec protocolSpec =
((BftProtocolSchedule) protocolSchedule)
.getByBlockNumberOrTimestamp(parentHeader.getNumber() + 1, timestamp);

if (protocolSpec.getWithdrawalsValidator() instanceof WithdrawalsValidator.AllowedWithdrawals) {
return createEmptyWithdrawalsBlock(timestamp);
return createEmptyWithdrawalsBlock(timestamp, parentHeader);
} else {
return createBlock(Optional.empty(), Optional.empty(), timestamp);
return createBlock(Optional.empty(), Optional.empty(), timestamp, parentHeader);
}
}

Expand All @@ -100,9 +97,14 @@ private static MiningBeneficiaryCalculator miningBeneficiaryCalculator(
}

@Override
public BlockCreationResult createEmptyWithdrawalsBlock(final long timestamp) {
public BlockCreationResult createEmptyWithdrawalsBlock(
final long timestamp, final BlockHeader parentHeader) {
return createBlock(
Optional.empty(), Optional.empty(), Optional.of(Collections.emptyList()), timestamp);
Optional.empty(),
Optional.empty(),
Optional.of(Collections.emptyList()),
timestamp,
parentHeader);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,10 @@ public BftBlockCreatorFactory(
/**
* Create block creator.
*
* @param parentHeader the parent header
* @param round the round
* @return the block creator
*/
public BlockCreator create(final BlockHeader parentHeader, final int round) {
public BlockCreator create(final int round) {
return new BftBlockCreator(
miningParameters,
forksSchedule,
Expand All @@ -119,7 +118,6 @@ public BlockCreator create(final BlockHeader parentHeader, final int round) {
transactionPool,
protocolContext,
protocolSchedule,
parentHeader,
bftExtraDataCodec,
ethScheduler);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ public Block createBlockForProposal(
final BlockHeader parent, final int round, final long timestamp) {
return finalState
.getBlockCreatorFactory()
.create(parent, round)
.createBlock(timestamp)
.create(round)
.createBlock(timestamp, parent)
.getBlock();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public class IbftRoundIntegrationTest {
private MessageFactory throwingMessageFactory;
private IbftMessageTransmitter transmitter;
@Mock private StubValidatorMulticaster multicaster;
@Mock BlockHeader parentHeader;

private Block proposedBlock;

Expand Down Expand Up @@ -145,7 +146,8 @@ public void signingFailsOnReceiptOfProposalUpdatesRoundButTransmitsNothing() {
throwingMessageFactory,
transmitter,
roundTimer,
bftExtraDataEncoder);
bftExtraDataEncoder,
parentHeader);

round.handleProposalMessage(
peerMessageFactory.createProposal(roundIdentifier, proposedBlock, Optional.empty()));
Expand All @@ -172,7 +174,8 @@ public void failuresToSignStillAllowBlockToBeImported() {
throwingMessageFactory,
transmitter,
roundTimer,
bftExtraDataEncoder);
bftExtraDataEncoder,
parentHeader);

// inject a block first, then a prepare on it.
round.handleProposalMessage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public class IbftRound {
private final MessageFactory messageFactory; // used only to create stored local msgs
private final IbftMessageTransmitter transmitter;
private final BftExtraDataCodec bftExtraDataCodec;
private final BlockHeader parentHeader;

/**
* Instantiates a new Ibft round.
Expand All @@ -80,6 +81,7 @@ public class IbftRound {
* @param transmitter the transmitter
* @param roundTimer the round timer
* @param bftExtraDataCodec the bft extra data codec
* @param parentHeader the parent header
*/
public IbftRound(
final RoundState roundState,
Expand All @@ -91,7 +93,8 @@ public IbftRound(
final MessageFactory messageFactory,
final IbftMessageTransmitter transmitter,
final RoundTimer roundTimer,
final BftExtraDataCodec bftExtraDataCodec) {
final BftExtraDataCodec bftExtraDataCodec,
final BlockHeader parentHeader) {
this.roundState = roundState;
this.blockCreator = blockCreator;
this.protocolContext = protocolContext;
Expand All @@ -101,6 +104,7 @@ public IbftRound(
this.messageFactory = messageFactory;
this.transmitter = transmitter;
this.bftExtraDataCodec = bftExtraDataCodec;
this.parentHeader = parentHeader;
roundTimer.startTimer(getRoundIdentifier());
}

Expand All @@ -119,7 +123,8 @@ public ConsensusRoundIdentifier getRoundIdentifier() {
* @param headerTimeStampSeconds the header time stamp seconds
*/
public void createAndSendProposalMessage(final long headerTimeStampSeconds) {
final Block block = blockCreator.createBlock(headerTimeStampSeconds).getBlock();
final Block block =
blockCreator.createBlock(headerTimeStampSeconds, this.parentHeader).getBlock();
final BftExtraData extraData = bftExtraDataCodec.decode(block.getHeader());
LOG.debug("Creating proposed block. round={}", roundState.getRoundIdentifier());
LOG.trace(
Expand All @@ -142,7 +147,7 @@ public void startRoundWith(
final Block blockToPublish;
if (!bestBlockFromRoundChange.isPresent()) {
LOG.debug("Sending proposal with new block. round={}", roundState.getRoundIdentifier());
blockToPublish = blockCreator.createBlock(headerTimestamp).getBlock();
blockToPublish = blockCreator.createBlock(headerTimestamp, this.parentHeader).getBlock();
} else {
LOG.debug(
"Sending proposal from PreparedCertificate. round={}", roundState.getRoundIdentifier());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public IbftRound createNewRound(final BlockHeader parentHeader, final int round)
public IbftRound createNewRoundWithState(
final BlockHeader parentHeader, final RoundState roundState) {
final BlockCreator blockCreator =
blockCreatorFactory.create(parentHeader, roundState.getRoundIdentifier().getRoundNumber());
blockCreatorFactory.create(roundState.getRoundIdentifier().getRoundNumber());

final IbftMessageTransmitter messageTransmitter =
new IbftMessageTransmitter(messageFactory, finalState.getValidatorMulticaster());
Expand All @@ -115,6 +115,7 @@ public IbftRound createNewRoundWithState(
messageFactory,
messageTransmitter,
finalState.getRoundTimer(),
bftExtraDataCodec);
bftExtraDataCodec,
parentHeader);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@ public BlockHeaderValidator.Builder createBlockHeaderRuleset(
transactionPool,
protContext,
protocolSchedule,
parentHeader,
bftExtraDataEncoder,
new DeterministicEthScheduler());

final int secondsBetweenBlocks = 1;
final Block block = blockCreator.createBlock(parentHeader.getTimestamp() + 1).getBlock();
final Block block =
blockCreator.createBlock(parentHeader.getTimestamp() + 1, parentHeader).getBlock();

final BlockHeaderValidator rules =
IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public class IbftBlockHeightManagerTest {
@Mock private RoundTimer roundTimer;
@Mock private FutureRoundProposalMessageValidator futureRoundProposalMessageValidator;
@Mock private ValidatorMulticaster validatorMulticaster;
@Mock private BlockHeader parentHeader;

@Captor private ArgumentCaptor<MessageData> sentMessageArgCaptor;

Expand Down Expand Up @@ -158,7 +159,7 @@ public void setup() {
lenient().when(finalState.getQuorum()).thenReturn(3);
when(finalState.getValidatorMulticaster()).thenReturn(validatorMulticaster);
lenient()
.when(blockCreator.createBlock(anyLong()))
.when(blockCreator.createBlock(anyLong(), any()))
.thenReturn(
new BlockCreationResult(
createdBlock, new TransactionSelectionResults(), new BlockCreationTiming()));
Expand Down Expand Up @@ -210,7 +211,8 @@ public void setup() {
messageFactory,
messageTransmitter,
roundTimer,
bftExtraDataCodec);
bftExtraDataCodec,
parentHeader);
});

lenient()
Expand All @@ -228,7 +230,8 @@ public void setup() {
messageFactory,
messageTransmitter,
roundTimer,
bftExtraDataCodec);
bftExtraDataCodec,
parentHeader);
});
}

Expand Down
Loading

0 comments on commit 9a570d4

Please sign in to comment.