mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-08 23:08:15 -05:00
Decouple block creators (#7468)
* wip decoupled parent block header from block creators --------- Signed-off-by: Justin Florentine <justin+github@florentine.us>
This commit is contained in:
committed by
GitHub
parent
2a52b0278b
commit
9a570d415e
@@ -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
|
||||
*/
|
||||
@@ -65,7 +64,6 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final NodeKey nodeKey,
|
||||
final BlockHeader parentHeader,
|
||||
final EpochManager epochManager,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(
|
||||
@@ -75,7 +73,6 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
|
||||
transactionPool,
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
parentHeader,
|
||||
ethScheduler);
|
||||
this.nodeKey = nodeKey;
|
||||
this.epochManager = epochManager;
|
||||
@@ -112,6 +109,8 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
|
||||
|
||||
private Optional<ValidatorVote> determineCliqueVote(
|
||||
final SealableBlockHeader sealableBlockHeader) {
|
||||
BlockHeader parentHeader =
|
||||
protocolContext.getBlockchain().getBlockHeader(sealableBlockHeader.getParentHash()).get();
|
||||
if (epochManager.isEpochBlock(sealableBlockHeader.getNumber())) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
|
||||
@@ -103,7 +103,6 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor<CliqueBlockMiner>
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
nodeKey,
|
||||
header,
|
||||
epochManager,
|
||||
ethScheduler);
|
||||
|
||||
|
||||
@@ -156,11 +156,11 @@ public class CliqueBlockCreatorTest {
|
||||
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);
|
||||
@@ -185,11 +185,11 @@ public class CliqueBlockCreatorTest {
|
||||
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);
|
||||
}
|
||||
@@ -219,11 +219,11 @@ public class CliqueBlockCreatorTest {
|
||||
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"));
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class CliqueBlockMinerTest {
|
||||
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()));
|
||||
@@ -147,7 +147,7 @@ class CliqueBlockMinerTest {
|
||||
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()));
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -65,7 +64,6 @@ public class BftBlockCreator extends AbstractBlockCreator {
|
||||
final TransactionPool transactionPool,
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockHeader parentHeader,
|
||||
final BftExtraDataCodec bftExtraDataCodec,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(
|
||||
@@ -75,21 +73,20 @@ public class BftBlockCreator extends AbstractBlockCreator {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,9 +97,14 @@ public class BftBlockCreator extends AbstractBlockCreator {
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -106,11 +106,10 @@ public class BftBlockCreatorFactory<T extends BftConfigOptions> {
|
||||
/**
|
||||
* 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,
|
||||
@@ -119,7 +118,6 @@ public class BftBlockCreatorFactory<T extends BftConfigOptions> {
|
||||
transactionPool,
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
parentHeader,
|
||||
bftExtraDataCodec,
|
||||
ethScheduler);
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@ public class TestContext {
|
||||
final BlockHeader parent, final int round, final long timestamp) {
|
||||
return finalState
|
||||
.getBlockCreatorFactory()
|
||||
.create(parent, round)
|
||||
.createBlock(timestamp)
|
||||
.create(round)
|
||||
.createBlock(timestamp, parent)
|
||||
.getBlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ public class IbftRoundIntegrationTest {
|
||||
private MessageFactory throwingMessageFactory;
|
||||
private IbftMessageTransmitter transmitter;
|
||||
@Mock private StubValidatorMulticaster multicaster;
|
||||
@Mock BlockHeader parentHeader;
|
||||
|
||||
private Block proposedBlock;
|
||||
|
||||
@@ -145,7 +146,8 @@ public class IbftRoundIntegrationTest {
|
||||
throwingMessageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataEncoder);
|
||||
bftExtraDataEncoder,
|
||||
parentHeader);
|
||||
|
||||
round.handleProposalMessage(
|
||||
peerMessageFactory.createProposal(roundIdentifier, proposedBlock, Optional.empty()));
|
||||
@@ -172,7 +174,8 @@ public class IbftRoundIntegrationTest {
|
||||
throwingMessageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataEncoder);
|
||||
bftExtraDataEncoder,
|
||||
parentHeader);
|
||||
|
||||
// inject a block first, then a prepare on it.
|
||||
round.handleProposalMessage(
|
||||
|
||||
@@ -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.
|
||||
@@ -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,
|
||||
@@ -91,7 +93,8 @@ public class 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;
|
||||
@@ -101,6 +104,7 @@ public class IbftRound {
|
||||
this.messageFactory = messageFactory;
|
||||
this.transmitter = transmitter;
|
||||
this.bftExtraDataCodec = bftExtraDataCodec;
|
||||
this.parentHeader = parentHeader;
|
||||
roundTimer.startTimer(getRoundIdentifier());
|
||||
}
|
||||
|
||||
@@ -119,7 +123,8 @@ public class IbftRound {
|
||||
* @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(
|
||||
@@ -142,7 +147,7 @@ public class IbftRound {
|
||||
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());
|
||||
|
||||
@@ -100,7 +100,7 @@ public class IbftRoundFactory {
|
||||
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());
|
||||
@@ -115,6 +115,7 @@ public class IbftRoundFactory {
|
||||
messageFactory,
|
||||
messageTransmitter,
|
||||
finalState.getRoundTimer(),
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,12 +191,12 @@ public class BftBlockCreatorTest {
|
||||
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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -158,7 +159,7 @@ public class IbftBlockHeightManagerTest {
|
||||
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()));
|
||||
@@ -210,7 +211,8 @@ public class IbftBlockHeightManagerTest {
|
||||
messageFactory,
|
||||
messageTransmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
});
|
||||
|
||||
lenient()
|
||||
@@ -228,7 +230,8 @@ public class IbftBlockHeightManagerTest {
|
||||
messageFactory,
|
||||
messageTransmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ public class IbftRoundTest {
|
||||
@Mock private RoundTimer roundTimer;
|
||||
@Mock private ProtocolSpec protocolSpec;
|
||||
@Mock private BlockImporter blockImporter;
|
||||
@Mock private BlockHeader parentHeader;
|
||||
|
||||
@Captor private ArgumentCaptor<Block> blockCaptor;
|
||||
|
||||
@@ -131,7 +132,7 @@ public class IbftRoundTest {
|
||||
proposedBlock = new Block(header, new BlockBody(emptyList(), emptyList()));
|
||||
|
||||
lenient()
|
||||
.when(blockCreator.createBlock(anyLong()))
|
||||
.when(blockCreator.createBlock(anyLong(), any()))
|
||||
.thenReturn(
|
||||
new BlockCreationResult(
|
||||
proposedBlock, new TransactionSelectionResults(), new BlockCreationTiming()));
|
||||
@@ -159,7 +160,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
verify(roundTimer, times(1)).startTimer(roundIdentifier);
|
||||
}
|
||||
|
||||
@@ -177,7 +179,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleProposalMessage(
|
||||
messageFactory.createProposal(roundIdentifier, proposedBlock, Optional.empty()));
|
||||
@@ -199,7 +202,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(transmitter, times(1))
|
||||
@@ -222,7 +226,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(transmitter, times(1))
|
||||
.multicastProposal(roundIdentifier, proposedBlock, Optional.empty());
|
||||
@@ -245,7 +250,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final Hash commitSealHash =
|
||||
new BftBlockHashing(new IbftExtraDataCodec())
|
||||
@@ -292,7 +298,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final Hash commitSealHash =
|
||||
new BftBlockHashing(new IbftExtraDataCodec())
|
||||
@@ -329,7 +336,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final RoundChangeCertificate roundChangeCertificate = new RoundChangeCertificate(emptyList());
|
||||
|
||||
@@ -353,7 +361,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final RoundChangeArtifacts roundChangeArtifacts =
|
||||
RoundChangeArtifacts.create(
|
||||
@@ -400,7 +409,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final RoundChangeArtifacts roundChangeArtifacts =
|
||||
RoundChangeArtifacts.create(
|
||||
@@ -434,7 +444,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(minedBlockObserver).blockMined(any());
|
||||
}
|
||||
@@ -455,7 +466,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleCommitMessage(
|
||||
messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal));
|
||||
@@ -481,7 +493,8 @@ public class IbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleCommitMessage(
|
||||
messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal));
|
||||
@@ -511,7 +524,8 @@ public class IbftRoundTest {
|
||||
throwingMessageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleProposalMessage(
|
||||
messageFactory.createProposal(roundIdentifier, proposedBlock, Optional.empty()));
|
||||
|
||||
@@ -61,7 +61,6 @@ class MergeBlockCreator extends AbstractBlockCreator {
|
||||
transactionPool,
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
parentHeader,
|
||||
ethScheduler);
|
||||
}
|
||||
|
||||
@@ -80,7 +79,8 @@ class MergeBlockCreator extends AbstractBlockCreator {
|
||||
final Bytes32 random,
|
||||
final long timestamp,
|
||||
final Optional<List<Withdrawal>> withdrawals,
|
||||
final Optional<Bytes32> parentBeaconBlockRoot) {
|
||||
final Optional<Bytes32> parentBeaconBlockRoot,
|
||||
final BlockHeader parentHeader) {
|
||||
|
||||
return createBlock(
|
||||
maybeTransactions,
|
||||
@@ -89,14 +89,16 @@ class MergeBlockCreator extends AbstractBlockCreator {
|
||||
Optional.of(random),
|
||||
parentBeaconBlockRoot,
|
||||
timestamp,
|
||||
false);
|
||||
false,
|
||||
parentHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockCreationResult createBlock(
|
||||
final Optional<List<Transaction>> maybeTransactions,
|
||||
final Optional<List<BlockHeader>> maybeOmmers,
|
||||
final long timestamp) {
|
||||
final long timestamp,
|
||||
final BlockHeader parentHeader) {
|
||||
throw new UnsupportedOperationException("random is required");
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +294,8 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
prevRandao,
|
||||
timestamp,
|
||||
withdrawals,
|
||||
parentBeaconBlockRoot)
|
||||
parentBeaconBlockRoot,
|
||||
parentHeader)
|
||||
.getBlock();
|
||||
|
||||
BlockProcessingResult result = validateProposedBlock(emptyBlock);
|
||||
@@ -322,7 +323,8 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
payloadIdentifier,
|
||||
mergeBlockCreator,
|
||||
withdrawals,
|
||||
parentBeaconBlockRoot);
|
||||
parentBeaconBlockRoot,
|
||||
parentHeader);
|
||||
|
||||
return payloadIdentifier;
|
||||
}
|
||||
@@ -363,12 +365,18 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
final PayloadIdentifier payloadIdentifier,
|
||||
final MergeBlockCreator mergeBlockCreator,
|
||||
final Optional<List<Withdrawal>> withdrawals,
|
||||
final Optional<Bytes32> parentBeaconBlockRoot) {
|
||||
final Optional<Bytes32> parentBeaconBlockRoot,
|
||||
final BlockHeader parentHeader) {
|
||||
|
||||
final Supplier<BlockCreationResult> blockCreator =
|
||||
() ->
|
||||
mergeBlockCreator.createBlock(
|
||||
Optional.empty(), random, timestamp, withdrawals, parentBeaconBlockRoot);
|
||||
Optional.empty(),
|
||||
random,
|
||||
timestamp,
|
||||
withdrawals,
|
||||
parentBeaconBlockRoot,
|
||||
parentHeader);
|
||||
|
||||
LOG.debug(
|
||||
"Block creation started for payload id {}, remaining time is {}ms",
|
||||
|
||||
@@ -285,7 +285,12 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
|
||||
.doCallRealMethod()
|
||||
.when(beingSpiedOn)
|
||||
.createBlock(
|
||||
any(), any(Bytes32.class), anyLong(), eq(Optional.empty()), eq(Optional.empty()));
|
||||
any(),
|
||||
any(Bytes32.class),
|
||||
anyLong(),
|
||||
eq(Optional.empty()),
|
||||
eq(Optional.empty()),
|
||||
any());
|
||||
return beingSpiedOn;
|
||||
};
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public class TestContext {
|
||||
public Block createBlockForProposal(
|
||||
final BlockHeader parent, final long timestamp, final Address proposer) {
|
||||
final Block block =
|
||||
finalState.getBlockCreatorFactory().create(parent, 0).createBlock(timestamp).getBlock();
|
||||
finalState.getBlockCreatorFactory().create(0).createBlock(timestamp, parent).getBlock();
|
||||
|
||||
final BlockHeaderBuilder headerBuilder = BlockHeaderBuilder.fromHeader(block.getHeader());
|
||||
headerBuilder
|
||||
|
||||
@@ -92,6 +92,7 @@ public class QbftRoundIntegrationTest {
|
||||
private MessageFactory throwingMessageFactory;
|
||||
private QbftMessageTransmitter transmitter;
|
||||
@Mock private StubValidatorMulticaster multicaster;
|
||||
@Mock private BlockHeader parentHeader;
|
||||
|
||||
private Block proposedBlock;
|
||||
|
||||
@@ -148,7 +149,8 @@ public class QbftRoundIntegrationTest {
|
||||
throwingMessageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleProposalMessage(
|
||||
peerMessageFactory.createProposal(
|
||||
@@ -176,7 +178,8 @@ public class QbftRoundIntegrationTest {
|
||||
throwingMessageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
// inject a block first, then a prepare on it.
|
||||
round.handleProposalMessage(
|
||||
|
||||
@@ -80,6 +80,8 @@ public class QbftRound {
|
||||
/** The Bft extra data codec. */
|
||||
protected final BftExtraDataCodec bftExtraDataCodec;
|
||||
|
||||
private final BlockHeader parentHeader;
|
||||
|
||||
/**
|
||||
* Instantiates a new Qbft round.
|
||||
*
|
||||
@@ -93,6 +95,7 @@ public class QbftRound {
|
||||
* @param transmitter the transmitter
|
||||
* @param roundTimer the round timer
|
||||
* @param bftExtraDataCodec the bft extra data codec
|
||||
* @param parentHeader the parent header
|
||||
*/
|
||||
public QbftRound(
|
||||
final RoundState roundState,
|
||||
@@ -104,7 +107,8 @@ public class QbftRound {
|
||||
final MessageFactory messageFactory,
|
||||
final QbftMessageTransmitter transmitter,
|
||||
final RoundTimer roundTimer,
|
||||
final BftExtraDataCodec bftExtraDataCodec) {
|
||||
final BftExtraDataCodec bftExtraDataCodec,
|
||||
final BlockHeader parentHeader) {
|
||||
this.roundState = roundState;
|
||||
this.blockCreator = blockCreator;
|
||||
this.protocolContext = protocolContext;
|
||||
@@ -114,7 +118,7 @@ public class QbftRound {
|
||||
this.messageFactory = messageFactory;
|
||||
this.transmitter = transmitter;
|
||||
this.bftExtraDataCodec = bftExtraDataCodec;
|
||||
|
||||
this.parentHeader = parentHeader;
|
||||
roundTimer.startTimer(getRoundIdentifier());
|
||||
}
|
||||
|
||||
@@ -134,7 +138,8 @@ public class QbftRound {
|
||||
*/
|
||||
public void createAndSendProposalMessage(final long headerTimeStampSeconds) {
|
||||
LOG.debug("Creating proposed block. round={}", roundState.getRoundIdentifier());
|
||||
final Block block = blockCreator.createBlock(headerTimeStampSeconds).getBlock();
|
||||
final Block block =
|
||||
blockCreator.createBlock(headerTimeStampSeconds, this.parentHeader).getBlock();
|
||||
|
||||
LOG.trace("Creating proposed block blockHeader={}", block.getHeader());
|
||||
updateStateWithProposalAndTransmit(block, emptyList(), emptyList());
|
||||
@@ -154,7 +159,7 @@ public class QbftRound {
|
||||
final Block blockToPublish;
|
||||
if (bestPreparedCertificate.isEmpty()) {
|
||||
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());
|
||||
|
||||
@@ -99,7 +99,7 @@ public class QbftRoundFactory {
|
||||
*/
|
||||
public QbftRound createNewRoundWithState(
|
||||
final BlockHeader parentHeader, final RoundState roundState) {
|
||||
final BlockCreator blockCreator = blockCreatorFactory.create(parentHeader, 0);
|
||||
final BlockCreator blockCreator = blockCreatorFactory.create(0);
|
||||
|
||||
// TODO(tmm): Why is this created everytime?!
|
||||
final QbftMessageTransmitter messageTransmitter =
|
||||
@@ -115,6 +115,7 @@ public class QbftRoundFactory {
|
||||
messageFactory,
|
||||
messageTransmitter,
|
||||
finalState.getRoundTimer(),
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ public class QbftBlockHeightManagerTest {
|
||||
@Mock private DefaultBlockchain blockchain;
|
||||
@Mock private FutureRoundProposalMessageValidator futureRoundProposalMessageValidator;
|
||||
@Mock private ValidatorMulticaster validatorMulticaster;
|
||||
@Mock private BlockHeader parentHeader;
|
||||
|
||||
@Captor private ArgumentCaptor<MessageData> sentMessageArgCaptor;
|
||||
|
||||
@@ -158,7 +159,7 @@ public class QbftBlockHeightManagerTest {
|
||||
when(finalState.getBlockTimer()).thenReturn(blockTimer);
|
||||
when(finalState.getQuorum()).thenReturn(3);
|
||||
when(finalState.getValidatorMulticaster()).thenReturn(validatorMulticaster);
|
||||
when(blockCreator.createBlock(anyLong()))
|
||||
when(blockCreator.createBlock(anyLong(), any()))
|
||||
.thenReturn(
|
||||
new BlockCreationResult(
|
||||
createdBlock, new TransactionSelectionResults(), new BlockCreationTiming()));
|
||||
@@ -210,7 +211,8 @@ public class QbftBlockHeightManagerTest {
|
||||
messageFactory,
|
||||
messageTransmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
});
|
||||
|
||||
when(roundFactory.createNewRoundWithState(any(), any()))
|
||||
@@ -227,7 +229,8 @@ public class QbftBlockHeightManagerTest {
|
||||
messageFactory,
|
||||
messageTransmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ public class QbftRoundTest {
|
||||
@Mock private RoundTimer roundTimer;
|
||||
@Mock private ProtocolSpec protocolSpec;
|
||||
@Mock private BlockImporter blockImporter;
|
||||
@Mock private BlockHeader parentHeader;
|
||||
|
||||
@Captor private ArgumentCaptor<Block> blockCaptor;
|
||||
|
||||
@@ -139,7 +140,7 @@ public class QbftRoundTest {
|
||||
final BlockHeader header = headerTestFixture.buildHeader();
|
||||
proposedBlock = new Block(header, new BlockBody(emptyList(), emptyList()));
|
||||
|
||||
when(blockCreator.createBlock(anyLong()))
|
||||
when(blockCreator.createBlock(anyLong(), any()))
|
||||
.thenReturn(
|
||||
new BlockCreationResult(
|
||||
proposedBlock, new TransactionSelectionResults(), new BlockCreationTiming()));
|
||||
@@ -166,7 +167,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
verify(roundTimer, times(1)).startTimer(roundIdentifier);
|
||||
}
|
||||
|
||||
@@ -184,7 +186,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleProposalMessage(
|
||||
messageFactory.createProposal(
|
||||
@@ -207,7 +210,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(transmitter, times(1))
|
||||
@@ -231,7 +235,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(transmitter, times(1))
|
||||
.multicastProposal(
|
||||
@@ -254,7 +259,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final Hash commitSealHash =
|
||||
new BftBlockHashing(new QbftExtraDataCodec())
|
||||
@@ -288,7 +294,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.startRoundWith(new RoundChangeArtifacts(emptyList(), Optional.empty()), 15);
|
||||
verify(transmitter, times(1))
|
||||
@@ -311,7 +318,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final SignedData<PreparePayload> preparedPayload =
|
||||
messageFactory.createPrepare(priorRoundChange, proposedBlock.getHash()).getSignedPayload();
|
||||
@@ -359,7 +367,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
final RoundChange roundChange =
|
||||
messageFactory.createRoundChange(roundIdentifier, Optional.empty());
|
||||
@@ -398,7 +407,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(minedBlockObserver).blockMined(any());
|
||||
}
|
||||
@@ -419,7 +429,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleCommitMessage(
|
||||
messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal));
|
||||
@@ -444,7 +455,8 @@ public class QbftRoundTest {
|
||||
messageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleCommitMessage(
|
||||
messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal));
|
||||
@@ -473,7 +485,8 @@ public class QbftRoundTest {
|
||||
throwingMessageFactory,
|
||||
transmitter,
|
||||
roundTimer,
|
||||
bftExtraDataCodec);
|
||||
bftExtraDataCodec,
|
||||
parentHeader);
|
||||
|
||||
round.handleProposalMessage(
|
||||
messageFactory.createProposal(
|
||||
|
||||
@@ -88,7 +88,6 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
protected final ProtocolContext protocolContext;
|
||||
protected final ProtocolSchedule protocolSchedule;
|
||||
protected final BlockHeaderFunctions blockHeaderFunctions;
|
||||
protected final BlockHeader parentHeader;
|
||||
private final EthScheduler ethScheduler;
|
||||
private final AtomicBoolean isCancelled = new AtomicBoolean(false);
|
||||
|
||||
@@ -99,7 +98,6 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
final TransactionPool transactionPool,
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockHeader parentHeader,
|
||||
final EthScheduler ethScheduler) {
|
||||
this.miningParameters = miningParameters;
|
||||
this.miningBeneficiaryCalculator = miningBeneficiaryCalculator;
|
||||
@@ -107,7 +105,6 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
this.transactionPool = transactionPool;
|
||||
this.protocolContext = protocolContext;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.parentHeader = parentHeader;
|
||||
this.ethScheduler = ethScheduler;
|
||||
blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule);
|
||||
}
|
||||
@@ -130,21 +127,25 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
* @return a block with appropriately selected transactions, seals and ommers.
|
||||
*/
|
||||
@Override
|
||||
public BlockCreationResult createBlock(final long timestamp) {
|
||||
return createBlock(Optional.empty(), Optional.empty(), timestamp);
|
||||
public BlockCreationResult createBlock(final long timestamp, final BlockHeader parentHeader) {
|
||||
return createBlock(Optional.empty(), Optional.empty(), timestamp, parentHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockCreationResult createBlock(
|
||||
final List<Transaction> transactions, final List<BlockHeader> ommers, final long timestamp) {
|
||||
return createBlock(Optional.of(transactions), Optional.of(ommers), timestamp);
|
||||
final List<Transaction> transactions,
|
||||
final List<BlockHeader> ommers,
|
||||
final long timestamp,
|
||||
final BlockHeader parentHeader) {
|
||||
return createBlock(Optional.of(transactions), Optional.of(ommers), timestamp, parentHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockCreationResult createBlock(
|
||||
final Optional<List<Transaction>> maybeTransactions,
|
||||
final Optional<List<BlockHeader>> maybeOmmers,
|
||||
final long timestamp) {
|
||||
final long timestamp,
|
||||
final BlockHeader parentHeader) {
|
||||
return createBlock(
|
||||
maybeTransactions,
|
||||
maybeOmmers,
|
||||
@@ -152,11 +153,13 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
timestamp,
|
||||
true);
|
||||
true,
|
||||
parentHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockCreationResult createEmptyWithdrawalsBlock(final long timestamp) {
|
||||
public BlockCreationResult createEmptyWithdrawalsBlock(
|
||||
final long timestamp, final BlockHeader parentHeader) {
|
||||
throw new UnsupportedOperationException("Only used by BFT block creators");
|
||||
}
|
||||
|
||||
@@ -164,7 +167,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
final Optional<List<Transaction>> maybeTransactions,
|
||||
final Optional<List<BlockHeader>> maybeOmmers,
|
||||
final Optional<List<Withdrawal>> maybeWithdrawals,
|
||||
final long timestamp) {
|
||||
final long timestamp,
|
||||
final BlockHeader parentHeader) {
|
||||
return createBlock(
|
||||
maybeTransactions,
|
||||
maybeOmmers,
|
||||
@@ -172,7 +176,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
timestamp,
|
||||
true);
|
||||
true,
|
||||
parentHeader);
|
||||
}
|
||||
|
||||
protected BlockCreationResult createBlock(
|
||||
@@ -182,18 +187,23 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
final Optional<Bytes32> maybePrevRandao,
|
||||
final Optional<Bytes32> maybeParentBeaconBlockRoot,
|
||||
final long timestamp,
|
||||
boolean rewardCoinbase) {
|
||||
boolean rewardCoinbase,
|
||||
final BlockHeader parentHeader) {
|
||||
|
||||
final var timings = new BlockCreationTiming();
|
||||
|
||||
try (final MutableWorldState disposableWorldState = duplicateWorldStateAtParent()) {
|
||||
try (final MutableWorldState disposableWorldState = duplicateWorldStateAtParent(parentHeader)) {
|
||||
timings.register("duplicateWorldState");
|
||||
final ProtocolSpec newProtocolSpec =
|
||||
protocolSchedule.getForNextBlockHeader(parentHeader, timestamp);
|
||||
|
||||
final ProcessableBlockHeader processableBlockHeader =
|
||||
createPendingBlockHeader(
|
||||
timestamp, maybePrevRandao, maybeParentBeaconBlockRoot, newProtocolSpec);
|
||||
timestamp,
|
||||
maybePrevRandao,
|
||||
maybeParentBeaconBlockRoot,
|
||||
newProtocolSpec,
|
||||
parentHeader);
|
||||
final Address miningBeneficiary =
|
||||
miningBeneficiaryCalculator.getMiningBeneficiary(processableBlockHeader.getNumber());
|
||||
|
||||
@@ -223,7 +233,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
maybeTransactions,
|
||||
miningBeneficiary,
|
||||
newProtocolSpec,
|
||||
pluginTransactionSelector);
|
||||
pluginTransactionSelector,
|
||||
parentHeader);
|
||||
transactionResults.logSelectionStats();
|
||||
timings.register("txsSelection");
|
||||
throwIfStopped();
|
||||
@@ -273,7 +284,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
|
||||
throwIfStopped();
|
||||
|
||||
final GasUsage usage = computeExcessBlobGas(transactionResults, newProtocolSpec);
|
||||
final GasUsage usage =
|
||||
computeExcessBlobGas(transactionResults, newProtocolSpec, parentHeader);
|
||||
|
||||
throwIfStopped();
|
||||
|
||||
@@ -324,7 +336,9 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
record GasUsage(BlobGas excessBlobGas, BlobGas used) {}
|
||||
|
||||
private GasUsage computeExcessBlobGas(
|
||||
final TransactionSelectionResults transactionResults, final ProtocolSpec newProtocolSpec) {
|
||||
final TransactionSelectionResults transactionResults,
|
||||
final ProtocolSpec newProtocolSpec,
|
||||
final BlockHeader parentHeader) {
|
||||
|
||||
if (newProtocolSpec.getFeeMarket().implementsDataFee()) {
|
||||
final var gasCalculator = newProtocolSpec.getGasCalculator();
|
||||
@@ -349,7 +363,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
final Optional<List<Transaction>> transactions,
|
||||
final Address miningBeneficiary,
|
||||
final ProtocolSpec protocolSpec,
|
||||
final PluginTransactionSelector pluginTransactionSelector)
|
||||
final PluginTransactionSelector pluginTransactionSelector,
|
||||
final BlockHeader parentHeader)
|
||||
throws RuntimeException {
|
||||
final MainnetTransactionProcessor transactionProcessor = protocolSpec.getTransactionProcessor();
|
||||
|
||||
@@ -387,7 +402,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
}
|
||||
}
|
||||
|
||||
private MutableWorldState duplicateWorldStateAtParent() {
|
||||
private MutableWorldState duplicateWorldStateAtParent(final BlockHeader parentHeader) {
|
||||
final Hash parentStateRoot = parentHeader.getStateRoot();
|
||||
return protocolContext
|
||||
.getWorldStateArchive()
|
||||
@@ -411,7 +426,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
final long timestamp,
|
||||
final Optional<Bytes32> maybePrevRandao,
|
||||
final Optional<Bytes32> maybeParentBeaconBlockRoot,
|
||||
final ProtocolSpec protocolSpec) {
|
||||
final ProtocolSpec protocolSpec,
|
||||
final BlockHeader parentHeader) {
|
||||
final long newBlockNumber = parentHeader.getNumber() + 1;
|
||||
long gasLimit =
|
||||
protocolSpec
|
||||
|
||||
@@ -50,15 +50,20 @@ public interface BlockCreator {
|
||||
}
|
||||
}
|
||||
|
||||
BlockCreationResult createBlock(final long timestamp);
|
||||
BlockCreationResult createBlock(final long timestamp, final BlockHeader parentHeader);
|
||||
|
||||
BlockCreationResult createEmptyWithdrawalsBlock(final long timestamp);
|
||||
BlockCreationResult createEmptyWithdrawalsBlock(
|
||||
final long timestamp, final BlockHeader parentHeader);
|
||||
|
||||
BlockCreationResult createBlock(
|
||||
final List<Transaction> transactions, final List<BlockHeader> ommers, final long timestamp);
|
||||
final List<Transaction> transactions,
|
||||
final List<BlockHeader> ommers,
|
||||
final long timestamp,
|
||||
final BlockHeader parentHeader);
|
||||
|
||||
BlockCreationResult createBlock(
|
||||
final Optional<List<Transaction>> maybeTransactions,
|
||||
final Optional<List<BlockHeader>> maybeOmmers,
|
||||
final long timestamp);
|
||||
final long timestamp,
|
||||
final BlockHeader parentHeader);
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class BlockMiner<M extends AbstractBlockCreator> implements Runnable {
|
||||
final List<BlockHeader> ommers) {
|
||||
final BlockCreator blockCreator = this.blockCreatorFactory.apply(parentHeader);
|
||||
final long timestamp = scheduler.getNextTimestamp(parentHeader).timestampForHeader();
|
||||
return blockCreator.createBlock(transactions, ommers, timestamp);
|
||||
return blockCreator.createBlock(transactions, ommers, timestamp, parentHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +121,7 @@ public class BlockMiner<M extends AbstractBlockCreator> implements Runnable {
|
||||
*/
|
||||
public BlockCreationResult createBlock(final BlockHeader parentHeader, final long timestamp) {
|
||||
final BlockCreator blockCreator = this.blockCreatorFactory.apply(parentHeader);
|
||||
return blockCreator.createBlock(Optional.empty(), Optional.empty(), timestamp);
|
||||
return blockCreator.createBlock(Optional.empty(), Optional.empty(), timestamp, parentHeader);
|
||||
}
|
||||
|
||||
protected boolean shouldImportBlock(final Block block) throws InterruptedException {
|
||||
@@ -140,7 +140,7 @@ public class BlockMiner<M extends AbstractBlockCreator> implements Runnable {
|
||||
|
||||
LOG.trace("Mining a new block with timestamp {}", newBlockTimestamp);
|
||||
|
||||
final var blockCreationResult = minerBlockCreator.createBlock(newBlockTimestamp);
|
||||
final var blockCreationResult = minerBlockCreator.createBlock(newBlockTimestamp, parentHeader);
|
||||
timing.registerAll(blockCreationResult.getBlockCreationTimings());
|
||||
|
||||
final Block block = blockCreationResult.getBlock();
|
||||
|
||||
@@ -45,7 +45,6 @@ public class PoWBlockCreator extends AbstractBlockCreator {
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final PoWSolver nonceSolver,
|
||||
final BlockHeader parentHeader,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(
|
||||
miningParameters,
|
||||
@@ -54,7 +53,6 @@ public class PoWBlockCreator extends AbstractBlockCreator {
|
||||
transactionPool,
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
parentHeader,
|
||||
ethScheduler);
|
||||
|
||||
this.nonceSolver = nonceSolver;
|
||||
|
||||
@@ -93,7 +93,6 @@ public class PoWMinerExecutor extends AbstractMinerExecutor<PoWBlockMiner> {
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
solver,
|
||||
parentHeader,
|
||||
ethScheduler);
|
||||
|
||||
return new PoWBlockMiner(
|
||||
|
||||
@@ -161,18 +161,19 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void withAllowedDepositRequestsAndContractAddress_DepositRequestsAreParsed() {
|
||||
final AbstractBlockCreator blockCreator =
|
||||
final CreateOn miningOn =
|
||||
blockCreatorWithAllowedDepositRequests(DEFAULT_DEPOSIT_CONTRACT_ADDRESS);
|
||||
|
||||
final BlockCreationResult blockCreationResult =
|
||||
blockCreator.createBlock(
|
||||
miningOn.blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(emptyList()),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
|
||||
List<Request> depositRequests = emptyList();
|
||||
final Hash requestsRoot = BodyValidation.requestsRoot(depositRequests);
|
||||
@@ -182,17 +183,18 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void withAllowedDepositRequestsAndNoContractAddress_DepositRequestsAreNotParsed() {
|
||||
final AbstractBlockCreator blockCreator = blockCreatorWithAllowedDepositRequests(null);
|
||||
final CreateOn miningOn = blockCreatorWithAllowedDepositRequests(null);
|
||||
|
||||
final BlockCreationResult blockCreationResult =
|
||||
blockCreator.createBlock(
|
||||
miningOn.blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(emptyList()),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty();
|
||||
assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty();
|
||||
@@ -200,53 +202,28 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void withProhibitedDepositRequests_DepositRequestsAreNotParsed() {
|
||||
final AbstractBlockCreator blockCreator = blockCreatorWithProhibitedDepositRequests();
|
||||
|
||||
final CreateOn miningOn = blockCreatorWithProhibitedDepositRequests();
|
||||
|
||||
final BlockCreationResult blockCreationResult =
|
||||
blockCreator.createBlock(
|
||||
miningOn.blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(emptyList()),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty();
|
||||
assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty();
|
||||
}
|
||||
|
||||
private AbstractBlockCreator blockCreatorWithAllowedDepositRequests(
|
||||
final Address depositContractAddress) {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(
|
||||
0,
|
||||
specBuilder ->
|
||||
specBuilder
|
||||
.requestsValidator(
|
||||
new RequestsValidatorCoordinator.Builder()
|
||||
.addValidator(
|
||||
RequestType.DEPOSIT,
|
||||
new DepositRequestValidator((depositContractAddress)))
|
||||
.build())
|
||||
.requestProcessorCoordinator(
|
||||
new RequestProcessorCoordinator.Builder()
|
||||
.addProcessor(
|
||||
RequestType.DEPOSIT,
|
||||
new DepositRequestProcessor(depositContractAddress))
|
||||
.build()));
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private AbstractBlockCreator blockCreatorWithProhibitedDepositRequests() {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(0, specBuilder -> specBuilder);
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withProcessorAndEmptyWithdrawals_NoWithdrawalsAreProcessed() {
|
||||
final AbstractBlockCreator blockCreator = blockCreatorWithWithdrawalsProcessor();
|
||||
final CreateOn miningOn = blockCreatorWithWithdrawalsProcessor();
|
||||
final AbstractBlockCreator blockCreator = miningOn.blockCreator;
|
||||
final BlockCreationResult blockCreationResult =
|
||||
blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
@@ -255,7 +232,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
verify(withdrawalsProcessor, never()).processWithdrawals(any(), any());
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getWithdrawalsRoot()).isEmpty();
|
||||
assertThat(blockCreationResult.getBlock().getBody().getWithdrawals()).isEmpty();
|
||||
@@ -263,7 +241,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void withNoProcessorAndEmptyWithdrawals_NoWithdrawalsAreNotProcessed() {
|
||||
final AbstractBlockCreator blockCreator = blockCreatorWithoutWithdrawalsProcessor();
|
||||
final CreateOn miningOn = blockCreatorWithoutWithdrawalsProcessor();
|
||||
final AbstractBlockCreator blockCreator = miningOn.blockCreator;
|
||||
final BlockCreationResult blockCreationResult =
|
||||
blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
@@ -272,7 +251,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
verify(withdrawalsProcessor, never()).processWithdrawals(any(), any());
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getWithdrawalsRoot()).isEmpty();
|
||||
assertThat(blockCreationResult.getBlock().getBody().getWithdrawals()).isEmpty();
|
||||
@@ -280,7 +260,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void withProcessorAndWithdrawals_WithdrawalsAreProcessed() {
|
||||
final AbstractBlockCreator blockCreator = blockCreatorWithWithdrawalsProcessor();
|
||||
final CreateOn miningOn = blockCreatorWithWithdrawalsProcessor();
|
||||
final AbstractBlockCreator blockCreator = miningOn.blockCreator;
|
||||
final List<Withdrawal> withdrawals =
|
||||
List.of(new Withdrawal(UInt64.ONE, UInt64.ONE, Address.fromHexString("0x1"), GWei.ONE));
|
||||
final BlockCreationResult blockCreationResult =
|
||||
@@ -291,7 +272,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
|
||||
final Hash withdrawalsRoot = BodyValidation.withdrawalsRoot(withdrawals);
|
||||
verify(withdrawalsProcessor).processWithdrawals(eq(withdrawals), any());
|
||||
@@ -302,7 +284,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void withNoProcessorAndWithdrawals_WithdrawalsAreNotProcessed() {
|
||||
final AbstractBlockCreator blockCreator = blockCreatorWithoutWithdrawalsProcessor();
|
||||
final CreateOn miningOn = blockCreatorWithoutWithdrawalsProcessor();
|
||||
final AbstractBlockCreator blockCreator = miningOn.blockCreator;
|
||||
final List<Withdrawal> withdrawals =
|
||||
List.of(new Withdrawal(UInt64.ONE, UInt64.ONE, Address.fromHexString("0x1"), GWei.ONE));
|
||||
final BlockCreationResult blockCreationResult =
|
||||
@@ -313,7 +296,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
verify(withdrawalsProcessor, never()).processWithdrawals(any(), any());
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getWithdrawalsRoot()).isEmpty();
|
||||
assertThat(blockCreationResult.getBlock().getBody().getWithdrawals()).isEmpty();
|
||||
@@ -321,7 +305,8 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
public void computesGasUsageFromIncludedTransactions() {
|
||||
final AbstractBlockCreator blockCreator = blockCreatorWithBlobGasSupport();
|
||||
final CreateOn miningOn = blockCreatorWithBlobGasSupport();
|
||||
final AbstractBlockCreator blockCreator = miningOn.blockCreator;
|
||||
BlobTestFixture blobTestFixture = new BlobTestFixture();
|
||||
BlobsWithCommitments bwc = blobTestFixture.createBlobsWithCommitments(6);
|
||||
TransactionTestFixture ttf = new TransactionTestFixture();
|
||||
@@ -345,14 +330,15 @@ abstract class AbstractBlockCreatorTest {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false);
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
long blobGasUsage = blockCreationResult.getBlock().getHeader().getGasUsed();
|
||||
assertThat(blobGasUsage).isNotZero();
|
||||
BlobGas excessBlobGas = blockCreationResult.getBlock().getHeader().getExcessBlobGas().get();
|
||||
assertThat(excessBlobGas).isNotNull();
|
||||
}
|
||||
|
||||
private AbstractBlockCreator blockCreatorWithBlobGasSupport() {
|
||||
private CreateOn blockCreatorWithBlobGasSupport() {
|
||||
final var alwaysValidTransactionValidatorFactory = mock(TransactionValidatorFactory.class);
|
||||
when(alwaysValidTransactionValidatorFactory.get())
|
||||
.thenReturn(new AlwaysValidTransactionValidator());
|
||||
@@ -369,20 +355,49 @@ abstract class AbstractBlockCreatorTest {
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private AbstractBlockCreator blockCreatorWithWithdrawalsProcessor() {
|
||||
private CreateOn blockCreatorWithProhibitedDepositRequests() {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(0, specBuilder -> specBuilder);
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private CreateOn blockCreatorWithWithdrawalsProcessor() {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(
|
||||
0, specBuilder -> specBuilder.withdrawalsProcessor(withdrawalsProcessor));
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private AbstractBlockCreator blockCreatorWithoutWithdrawalsProcessor() {
|
||||
private CreateOn blockCreatorWithoutWithdrawalsProcessor() {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(0, specBuilder -> specBuilder.withdrawalsProcessor(null));
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private AbstractBlockCreator createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) {
|
||||
private CreateOn blockCreatorWithAllowedDepositRequests(final Address depositContractAddress) {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(
|
||||
0,
|
||||
specBuilder ->
|
||||
specBuilder
|
||||
.requestsValidator(
|
||||
new RequestsValidatorCoordinator.Builder()
|
||||
.addValidator(
|
||||
RequestType.DEPOSIT,
|
||||
new DepositRequestValidator((depositContractAddress)))
|
||||
.build())
|
||||
.requestProcessorCoordinator(
|
||||
new RequestProcessorCoordinator.Builder()
|
||||
.addProcessor(
|
||||
RequestType.DEPOSIT,
|
||||
new DepositRequestProcessor(depositContractAddress))
|
||||
.build()));
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
record CreateOn(AbstractBlockCreator blockCreator, BlockHeader parentHeader) {}
|
||||
|
||||
private CreateOn createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) {
|
||||
|
||||
final var genesisConfigFile = GenesisConfigFile.fromResource("/block-creation-genesis.json");
|
||||
final ExecutionContextTestFixture executionContextTestFixture =
|
||||
@@ -403,11 +418,15 @@ abstract class AbstractBlockCreatorTest {
|
||||
.build();
|
||||
|
||||
final MutableBlockchain blockchain = executionContextTestFixture.getBlockchain();
|
||||
BlockHeader parentHeader = blockchain.getChainHeadHeader();
|
||||
final TransactionPoolConfiguration poolConf =
|
||||
ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(100).build();
|
||||
final AbstractPendingTransactionsSorter sorter =
|
||||
new GasPricePendingTransactionsSorter(
|
||||
poolConf, Clock.systemUTC(), new NoOpMetricsSystem(), blockchain::getChainHeadHeader);
|
||||
poolConf,
|
||||
Clock.systemUTC(),
|
||||
new NoOpMetricsSystem(),
|
||||
Suppliers.ofInstance(parentHeader));
|
||||
|
||||
final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
|
||||
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
|
||||
@@ -435,15 +454,16 @@ abstract class AbstractBlockCreatorTest {
|
||||
.build())
|
||||
.build();
|
||||
|
||||
return new TestBlockCreator(
|
||||
miningParameters,
|
||||
__ -> Address.ZERO,
|
||||
__ -> Bytes.fromHexString("deadbeef"),
|
||||
transactionPool,
|
||||
executionContextTestFixture.getProtocolContext(),
|
||||
executionContextTestFixture.getProtocolSchedule(),
|
||||
blockchain.getChainHeadHeader(),
|
||||
ethScheduler);
|
||||
return new CreateOn(
|
||||
new TestBlockCreator(
|
||||
miningParameters,
|
||||
__ -> Address.ZERO,
|
||||
__ -> Bytes.fromHexString("deadbeef"),
|
||||
transactionPool,
|
||||
executionContextTestFixture.getProtocolContext(),
|
||||
executionContextTestFixture.getProtocolSchedule(),
|
||||
ethScheduler),
|
||||
parentHeader);
|
||||
}
|
||||
|
||||
static class TestBlockCreator extends AbstractBlockCreator {
|
||||
@@ -455,7 +475,6 @@ abstract class AbstractBlockCreatorTest {
|
||||
final TransactionPool transactionPool,
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockHeader parentHeader,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(
|
||||
miningParameters,
|
||||
@@ -464,7 +483,6 @@ abstract class AbstractBlockCreatorTest {
|
||||
transactionPool,
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
parentHeader,
|
||||
ethScheduler);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public class BlockMinerTest {
|
||||
final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class);
|
||||
final Function<BlockHeader, PoWBlockCreator> blockCreatorSupplier =
|
||||
(parentHeader) -> blockCreator;
|
||||
when(blockCreator.createBlock(anyLong()))
|
||||
when(blockCreator.createBlock(anyLong(), any()))
|
||||
.thenReturn(
|
||||
new BlockCreationResult(
|
||||
blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming()));
|
||||
@@ -107,7 +107,7 @@ public class BlockMinerTest {
|
||||
final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class);
|
||||
final Function<BlockHeader, PoWBlockCreator> blockCreatorSupplier =
|
||||
(parentHeader) -> blockCreator;
|
||||
when(blockCreator.createBlock(anyLong()))
|
||||
when(blockCreator.createBlock(anyLong(), any()))
|
||||
.thenReturn(
|
||||
new BlockCreationResult(
|
||||
blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming()));
|
||||
@@ -155,7 +155,7 @@ public class BlockMinerTest {
|
||||
final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class);
|
||||
final Function<BlockHeader, PoWBlockCreator> blockCreatorSupplier =
|
||||
(parentHeader) -> blockCreator;
|
||||
when(blockCreator.createBlock(anyLong()))
|
||||
when(blockCreator.createBlock(anyLong(), any()))
|
||||
.thenReturn(
|
||||
new BlockCreationResult(
|
||||
blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming()));
|
||||
|
||||
@@ -123,13 +123,14 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
executionContextTestFixture.getProtocolContext(),
|
||||
executionContextTestFixture.getProtocolSchedule(),
|
||||
solver,
|
||||
executionContextTestFixture.getBlockchain().getChainHeadHeader(),
|
||||
ethScheduler);
|
||||
|
||||
// A Hashrate should not exist in the block creator prior to creating a block
|
||||
assertThat(blockCreator.getHashesPerSecond()).isNotPresent();
|
||||
|
||||
final BlockCreationResult blockResult = blockCreator.createBlock(BLOCK_1_TIMESTAMP);
|
||||
final BlockCreationResult blockResult =
|
||||
blockCreator.createBlock(
|
||||
BLOCK_1_TIMESTAMP, executionContextTestFixture.getBlockchain().getChainHeadHeader());
|
||||
final Block actualBlock = blockResult.getBlock();
|
||||
final Block expectedBlock = ValidationTestUtils.readBlock(1);
|
||||
|
||||
@@ -186,10 +187,13 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
executionContextTestFixture.getProtocolContext(),
|
||||
executionContextTestFixture.getProtocolSchedule(),
|
||||
solver,
|
||||
executionContextTestFixture.getBlockchain().getChainHeadHeader(),
|
||||
ethScheduler);
|
||||
|
||||
assertThat(blockCreator.createBlock(BLOCK_1_TIMESTAMP)).isNotNull();
|
||||
assertThat(
|
||||
blockCreator.createBlock(
|
||||
BLOCK_1_TIMESTAMP,
|
||||
executionContextTestFixture.getBlockchain().getChainHeadHeader()))
|
||||
.isNotNull();
|
||||
// If we weren't setting difficulty to 2^256-1 a difficulty of 1 would have caused a
|
||||
// IllegalArgumentException at the previous line, as 2^256 is 33 bytes.
|
||||
}
|
||||
@@ -242,7 +246,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
executionContextTestFixture.getProtocolContext(),
|
||||
executionContextTestFixture.getProtocolSchedule(),
|
||||
solver,
|
||||
executionContextTestFixture.getBlockchain().getChainHeadHeader(),
|
||||
ethScheduler);
|
||||
|
||||
final MutableWorldState mutableWorldState =
|
||||
@@ -320,7 +323,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
executionContextTestFixture.getProtocolContext(),
|
||||
executionContextTestFixture.getProtocolSchedule(),
|
||||
solver,
|
||||
executionContextTestFixture.getBlockchain().getChainHeadHeader(),
|
||||
ethScheduler);
|
||||
|
||||
final MutableWorldState mutableWorldState =
|
||||
|
||||
@@ -260,7 +260,6 @@ public abstract class AbstractIsolationTests {
|
||||
final TransactionPool transactionPool,
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockHeader parentHeader,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(
|
||||
miningParameters,
|
||||
@@ -269,12 +268,10 @@ public abstract class AbstractIsolationTests {
|
||||
transactionPool,
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
parentHeader,
|
||||
ethScheduler);
|
||||
}
|
||||
|
||||
static TestBlockCreator forHeader(
|
||||
final BlockHeader parentHeader,
|
||||
final ProtocolContext protocolContext,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final TransactionPool transactionPool,
|
||||
@@ -299,7 +296,6 @@ public abstract class AbstractIsolationTests {
|
||||
transactionPool,
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
parentHeader,
|
||||
ethScheduler);
|
||||
}
|
||||
|
||||
@@ -332,8 +328,8 @@ public abstract class AbstractIsolationTests {
|
||||
protected Block forTransactions(
|
||||
final List<Transaction> transactions, final BlockHeader forHeader) {
|
||||
return TestBlockCreator.forHeader(
|
||||
forHeader, protocolContext, protocolSchedule, transactionPool, ethScheduler)
|
||||
.createBlock(transactions, Collections.emptyList(), System.currentTimeMillis())
|
||||
protocolContext, protocolSchedule, transactionPool, ethScheduler)
|
||||
.createBlock(transactions, Collections.emptyList(), System.currentTimeMillis(), forHeader)
|
||||
.getBlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,10 +78,11 @@ public class TestMineBlocks implements JsonRpcMethod {
|
||||
protocolContext,
|
||||
protocolSchedule,
|
||||
context.getEthHashSolver(),
|
||||
blockchain.getChainHeadHeader(),
|
||||
context.getEthScheduler());
|
||||
final Block block =
|
||||
blockCreator.createBlock(retesethClock.instant().getEpochSecond()).getBlock();
|
||||
blockCreator
|
||||
.createBlock(retesethClock.instant().getEpochSecond(), blockchain.getChainHeadHeader())
|
||||
.getBlock();
|
||||
|
||||
// advance clock so next mine won't hit the same timestamp
|
||||
retesethClock.advanceSeconds(1);
|
||||
|
||||
Reference in New Issue
Block a user