Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Withdrawals processor #4917

Merged
merged 16 commits into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
Expand All @@ -34,14 +35,16 @@ public MergeBlockProcessor(
final Wei blockReward,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final boolean skipZeroBlockRewards,
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters) {
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters,
final HeaderBasedProtocolSchedule protocolSchedule) {
super(
transactionProcessor,
transactionReceiptFactory,
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
goQuorumPrivacyParameters);
goQuorumPrivacyParameters,
protocolSchedule);
this.mergeContext = PostMergeContext.get();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.SealableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;

Expand Down Expand Up @@ -62,10 +63,12 @@ public class MergeBlockCreator extends AbstractBlockCreator {
public BlockCreationResult createBlock(
final Optional<List<Transaction>> maybeTransactions,
final Bytes32 random,
final long timestamp) {
final long timestamp,
final Optional<List<Withdrawal>> withdrawals) {
return createBlock(
maybeTransactions,
Optional.of(Collections.emptyList()),
withdrawals,
Optional.of(random),
timestamp,
false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BadChainListener;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter;
Expand Down Expand Up @@ -209,7 +210,8 @@ public PayloadIdentifier preparePayload(
final BlockHeader parentHeader,
final Long timestamp,
final Bytes32 prevRandao,
final Address feeRecipient) {
final Address feeRecipient,
final Optional<List<Withdrawal>> withdrawals) {

// we assume that preparePayload is always called sequentially, since the RPC Engine calls
// are sequential, if this assumption changes then more synchronization should be added to
Expand All @@ -234,7 +236,7 @@ public PayloadIdentifier preparePayload(
// put the empty block in first
final Block emptyBlock =
mergeBlockCreator
.createBlock(Optional.of(Collections.emptyList()), prevRandao, timestamp)
.createBlock(Optional.of(Collections.emptyList()), prevRandao, timestamp, withdrawals)
.getBlock();

BlockProcessingResult result = validateBlock(emptyBlock);
Expand All @@ -256,7 +258,7 @@ public PayloadIdentifier preparePayload(
}
}

tryToBuildBetterBlock(timestamp, prevRandao, payloadIdentifier, mergeBlockCreator);
tryToBuildBetterBlock(timestamp, prevRandao, payloadIdentifier, mergeBlockCreator, withdrawals);

return payloadIdentifier;
}
Expand All @@ -276,10 +278,11 @@ private void tryToBuildBetterBlock(
final Long timestamp,
final Bytes32 random,
final PayloadIdentifier payloadIdentifier,
final MergeBlockCreator mergeBlockCreator) {
final MergeBlockCreator mergeBlockCreator,
final Optional<List<Withdrawal>> withdrawals) {

final Supplier<BlockCreationResult> blockCreator =
() -> mergeBlockCreator.createBlock(Optional.empty(), random, timestamp);
() -> mergeBlockCreator.createBlock(Optional.empty(), random, timestamp, withdrawals);

LOG.debug(
"Block creation started for payload id {}, remaining time is {}ms",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Withdrawal;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

Expand All @@ -34,7 +36,8 @@ PayloadIdentifier preparePayload(
final BlockHeader parentHeader,
final Long timestamp,
final Bytes32 prevRandao,
final Address feeRecipient);
final Address feeRecipient,
final Optional<List<Withdrawal>> withdrawals);

@Override
default boolean isCompatibleWithEngineApi() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Withdrawal;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -133,8 +134,10 @@ public PayloadIdentifier preparePayload(
final BlockHeader parentHeader,
final Long timestamp,
final Bytes32 prevRandao,
final Address feeRecipient) {
return mergeCoordinator.preparePayload(parentHeader, timestamp, prevRandao, feeRecipient);
final Address feeRecipient,
final Optional<List<Withdrawal>> withdrawals) {
return mergeCoordinator.preparePayload(
parentHeader, timestamp, prevRandao, feeRecipient, withdrawals);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter;
Expand All @@ -74,6 +75,7 @@
import org.hyperledger.besu.testutil.TestClock;

import java.time.ZoneId;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
Expand Down Expand Up @@ -111,6 +113,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
"ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f"));
private static final KeyPair KEYS1 =
new KeyPair(PRIVATE_KEY1, SIGNATURE_ALGORITHM.get().createPublicKey(PRIVATE_KEY1));
private static final Optional<List<Withdrawal>> EMPTY_WITHDRAWALS = Optional.empty();
@Mock MergeContext mergeContext;
@Mock BackwardSyncContext backwardSyncContext;

Expand Down Expand Up @@ -214,7 +217,8 @@ public void coinbaseShouldMatchSuggestedFeeRecipient() {
genesisState.getBlock().getHeader(),
System.currentTimeMillis() / 1000,
Bytes32.ZERO,
suggestedFeeRecipient);
suggestedFeeRecipient,
EMPTY_WITHDRAWALS);

ArgumentCaptor<BlockWithReceipts> blockWithReceipts =
ArgumentCaptor.forClass(BlockWithReceipts.class);
Expand Down Expand Up @@ -252,7 +256,7 @@ public void exceptionDuringBuildingBlockShouldNotBeInvalid()
.doThrow(new MerkleTrieException("missing leaf"))
.doCallRealMethod()
.when(beingSpiedOn)
.createBlock(any(), any(Bytes32.class), anyLong());
.createBlock(any(), any(Bytes32.class), anyLong(), eq(Optional.empty()));
return beingSpiedOn;
};

Expand Down Expand Up @@ -287,7 +291,8 @@ public void exceptionDuringBuildingBlockShouldNotBeInvalid()
genesisState.getBlock().getHeader(),
System.currentTimeMillis() / 1000,
Bytes32.random(),
suggestedFeeRecipient);
suggestedFeeRecipient,
Optional.empty());

verify(willThrow, never()).addBadBlock(any(), any());
blockCreationTask.get();
Expand Down Expand Up @@ -330,7 +335,8 @@ public void shouldContinueBuildingBlocksUntilFinalizeIsCalled()
genesisState.getBlock().getHeader(),
System.currentTimeMillis() / 1000,
Bytes32.ZERO,
suggestedFeeRecipient);
suggestedFeeRecipient,
Optional.empty());

blockCreationTask.get();

Expand Down Expand Up @@ -380,7 +386,8 @@ public void shouldRetryBlockCreationOnRecoverableError()
genesisState.getBlock().getHeader(),
System.currentTimeMillis() / 1000,
Bytes32.ZERO,
suggestedFeeRecipient);
suggestedFeeRecipient,
Optional.empty());

blockCreationTask.get();

Expand Down Expand Up @@ -413,7 +420,8 @@ public void shouldStopRetryBlockCreationIfTimeExpired() throws InterruptedExcept
genesisState.getBlock().getHeader(),
System.currentTimeMillis() / 1000,
Bytes32.ZERO,
suggestedFeeRecipient);
suggestedFeeRecipient,
Optional.empty());

try {
blockCreationTask.get();
Expand Down Expand Up @@ -454,7 +462,8 @@ public void shouldStopInProgressBlockCreationIfFinalizedIsCalled()
genesisState.getBlock().getHeader(),
System.currentTimeMillis() / 1000,
Bytes32.ZERO,
suggestedFeeRecipient);
suggestedFeeRecipient,
Optional.empty());

waitForBlockCreationInProgress.await();
coordinator.finalizeProposalById(payloadId);
Expand Down Expand Up @@ -496,13 +505,21 @@ public void shouldNotStartAnotherBlockCreationJobIfCalledAgainWithTheSamePayload

var payloadId1 =
coordinator.preparePayload(
genesisState.getBlock().getHeader(), timestamp, Bytes32.ZERO, suggestedFeeRecipient);
genesisState.getBlock().getHeader(),
timestamp,
Bytes32.ZERO,
suggestedFeeRecipient,
Optional.empty());

final CompletableFuture<Void> task1 = blockCreationTask;

var payloadId2 =
coordinator.preparePayload(
genesisState.getBlock().getHeader(), timestamp, Bytes32.ZERO, suggestedFeeRecipient);
genesisState.getBlock().getHeader(),
timestamp,
Bytes32.ZERO,
suggestedFeeRecipient,
Optional.empty());

assertThat(payloadId1).isEqualTo(payloadId2);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
newHead,
payloadAttributes.getTimestamp(),
payloadAttributes.getPrevRandao(),
payloadAttributes.getSuggestedFeeRecipient()));
payloadAttributes.getSuggestedFeeRecipient(),
Optional.empty()));
siladu marked this conversation as resolved.
Show resolved Hide resolved

payloadId.ifPresent(
pid ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ public class EthGetTransactionReceiptTest {
FeeMarket.legacy(),
null,
Optional.of(PoWHasher.ETHASH_LIGHT),
null);
null,
Optional.empty());
private final ProtocolSpec statusTransactionTypeSpec =
new ProtocolSpec(
"status",
Expand All @@ -138,7 +139,8 @@ public class EthGetTransactionReceiptTest {
FeeMarket.legacy(),
null,
Optional.of(PoWHasher.ETHASH_LIGHT),
null);
null,
Optional.empty());

@SuppressWarnings("unchecked")
private final ProtocolSchedule protocolSchedule = mock(ProtocolSchedule.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,11 @@ public void shouldReturnValidWithoutFinalizedWithPayload() {
payloadParams.getSuggestedFeeRecipient());

when(mergeCoordinator.preparePayload(
mockHeader, payloadParams.getTimestamp(), payloadParams.getPrevRandao(), Address.ECREC))
mockHeader,
payloadParams.getTimestamp(),
payloadParams.getPrevRandao(),
Address.ECREC,
Optional.empty()))
.thenReturn(mockPayloadId);

var res =
Expand Down Expand Up @@ -440,7 +444,7 @@ public void shouldIgnoreUpdateToOldHeadAndNotPreparePayload() {

var forkchoiceRes = (EngineUpdateForkchoiceResult) resp.getResult();

verify(mergeCoordinator, never()).preparePayload(any(), any(), any(), any());
verify(mergeCoordinator, never()).preparePayload(any(), any(), any(), any(), any());

assertThat(forkchoiceRes.getPayloadStatus().getStatus()).isEqualTo(VALID);
assertThat(forkchoiceRes.getPayloadStatus().getError()).isNull();
Expand Down Expand Up @@ -523,7 +527,11 @@ public void shouldReturnValidIfWithdrawalsIsNull_WhenWithdrawalsProhibited() {
payloadParams.getSuggestedFeeRecipient());

when(mergeCoordinator.preparePayload(
mockHeader, payloadParams.getTimestamp(), payloadParams.getPrevRandao(), Address.ECREC))
mockHeader,
payloadParams.getTimestamp(),
payloadParams.getPrevRandao(),
Address.ECREC,
Optional.empty()))
.thenReturn(mockPayloadId);

assertSuccessWithPayloadForForkchoiceResult(
Expand Down Expand Up @@ -586,7 +594,11 @@ public void shouldReturnValidIfWithdrawalsIsNotNull_WhenWithdrawalsAllowed() {
payloadParams.getSuggestedFeeRecipient());

when(mergeCoordinator.preparePayload(
mockHeader, payloadParams.getTimestamp(), payloadParams.getPrevRandao(), Address.ECREC))
mockHeader,
payloadParams.getTimestamp(),
payloadParams.getPrevRandao(),
Address.ECREC,
Optional.empty()))
.thenReturn(mockPayloadId);

assertSuccessWithPayloadForForkchoiceResult(
Expand Down Expand Up @@ -621,7 +633,11 @@ public void shouldReturnValidIfTimestampScheduleIsEmpty() {
payloadParams.getSuggestedFeeRecipient());

when(mergeCoordinator.preparePayload(
mockHeader, payloadParams.getTimestamp(), payloadParams.getPrevRandao(), Address.ECREC))
mockHeader,
payloadParams.getTimestamp(),
payloadParams.getPrevRandao(),
Address.ECREC,
Optional.empty()))
.thenReturn(mockPayloadId);

assertSuccessWithPayloadForForkchoiceResult(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ public void assertThatTraceGeneratorReturnValidRewardsForMainnetBlockProcessor()
blockReward,
BlockHeader::getCoinbase,
true,
Optional.empty());
Optional.empty(),
protocolSchedule);
when(protocolSpec.getBlockProcessor()).thenReturn(blockProcessor);

final Stream<Trace> traceStream =
Expand Down Expand Up @@ -151,7 +152,8 @@ public void assertThatTraceGeneratorReturnValidRewardsForClassicBlockProcessor()
blockReward,
BlockHeader::getCoinbase,
true,
eraRounds);
eraRounds,
protocolSchedule);
when(protocolSpec.getBlockProcessor()).thenReturn(blockProcessor);

final Stream<Trace> traceStream =
Expand Down
1 change: 1 addition & 0 deletions ethereum/blockcreation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ dependencies {
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.awaitility:awaitility'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-junit-jupiter'
testImplementation 'org.mockito:mockito-core'

testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
Expand Down
Loading