diff --git a/build.gradle b/build.gradle index ed2abc501eb..703421eb619 100644 --- a/build.gradle +++ b/build.gradle @@ -318,7 +318,7 @@ allprojects { } } -def refTestVersion = 'v1.5.0-alpha.7' +def refTestVersion = 'v1.5.0-alpha.8' def blsRefTestVersion = 'v0.1.2' def slashingProtectionInterchangeRefTestVersion = 'v5.3.0' def refTestBaseUrl = 'https://github.com/ethereum/consensus-spec-tests/releases/download' diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java index 0d70afb7eff..9d290a8ded7 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java @@ -130,10 +130,12 @@ private static ExpectedWithdrawals createFromElectraState( final MiscHelpersElectra miscHelpers, final SpecConfigElectra specConfig, final PredicatesElectra predicates) { - final List partialPendingWithdrawals = + final WithdrawalSummary expectedPendingPartialWithdrawals = getPendingPartialWithdrawals(preState, schemaDefinitions, miscHelpers, specConfig); - final int partialWithdrawalsCount = partialPendingWithdrawals.size(); - final List capellaWithdrawals = + final List partialPendingWithdrawals = + expectedPendingPartialWithdrawals.withdrawalList(); + final int partialWithdrawalsCount = expectedPendingPartialWithdrawals.partialWithdrawalCount(); + final List withdrawals = getExpectedWithdrawals( preState, schemaDefinitions, @@ -141,7 +143,7 @@ private static ExpectedWithdrawals createFromElectraState( specConfig, predicates, partialPendingWithdrawals); - return new ExpectedWithdrawals(capellaWithdrawals, partialWithdrawalsCount, schemaDefinitions); + return new ExpectedWithdrawals(withdrawals, partialWithdrawalsCount, schemaDefinitions); } public List getWithdrawalList() { @@ -152,7 +154,7 @@ public int getPartialWithdrawalCount() { return partialWithdrawalCount; } - private static List getPendingPartialWithdrawals( + private static WithdrawalSummary getPendingPartialWithdrawals( final BeaconStateElectra preState, final SchemaDefinitionsElectra schemaDefinitions, final MiscHelpersElectra miscHelpers, @@ -162,6 +164,7 @@ private static List getPendingPartialWithdrawals( final List partialWithdrawals = new ArrayList<>(); final SszList pendingPartialWithdrawals = preState.getPendingPartialWithdrawals(); + int partialWithdrawalsCount = 0; UInt64 withdrawalIndex = preState.getNextWithdrawalIndex(); for (int i = 0; i < pendingPartialWithdrawals.size() && i < maxPendingPartialWithdrawals; i++) { @@ -195,8 +198,9 @@ private static List getPendingPartialWithdrawals( withdrawableBalance)); withdrawalIndex = withdrawalIndex.increment(); } + partialWithdrawalsCount++; } - return partialWithdrawals; + return new WithdrawalSummary(partialWithdrawals, partialWithdrawalsCount); } // get_expected_withdrawals @@ -371,4 +375,6 @@ private static void assertWithdrawalsInExecutionPayloadMatchExpected( private static UInt64 nextWithdrawalAfter(final List partialWithdrawals) { return partialWithdrawals.getLast().getIndex().increment(); } + + public record WithdrawalSummary(List withdrawalList, int partialWithdrawalCount) {} } diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml index 126c84727c9..71adaa4aaa0 100644 --- a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/minimal/electra.yaml @@ -41,8 +41,8 @@ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2 # Withdrawals processing # --------------------------------------------------------------- -# 2**0 ( = 1) pending withdrawals -MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 1 +# 2**1 ( = 2) pending withdrawals +MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 2 # Pending deposits processing # --------------------------------------------------------------- diff --git a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml index 126c84727c9..71adaa4aaa0 100644 --- a/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml +++ b/ethereum/spec/src/main/resources/tech/pegasys/teku/spec/config/presets/swift/electra.yaml @@ -41,8 +41,8 @@ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2 # Withdrawals processing # --------------------------------------------------------------- -# 2**0 ( = 1) pending withdrawals -MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 1 +# 2**1 ( = 2) pending withdrawals +MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 2 # Pending deposits processing # --------------------------------------------------------------- diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawalsTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawalsTest.java index dbfba6ad754..1abd324d72d 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawalsTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawalsTest.java @@ -126,15 +126,51 @@ void electraPendingPartialWithdrawals() { spec.getBlockProcessor(preState.getSlot()).getExpectedWithdrawals(preState); final MutableBeaconStateElectra mutableBeaconStateElectra = MutableBeaconStateElectra.required(preState.createWritableCopy()); - assertThat(withdrawals.getPartialWithdrawalCount()).isEqualTo(1); + assertThat(withdrawals.getPartialWithdrawalCount()).isEqualTo(2); withdrawals.processWithdrawalsUnchecked( mutableBeaconStateElectra, SchemaDefinitionsElectra.required(spec.getGenesisSchemaDefinitions()), spec.getGenesisSpec().beaconStateMutators(), SpecConfigElectra.required(spec.getGenesisSpecConfig())); - assertThat(mutableBeaconStateElectra.getPendingPartialWithdrawals().size()).isEqualTo(2); - assertThat(mutableBeaconStateElectra.getNextWithdrawalIndex()).isEqualTo(UInt64.ONE); + assertThat(mutableBeaconStateElectra.getPendingPartialWithdrawals().size()).isEqualTo(1); + assertThat(mutableBeaconStateElectra.getNextWithdrawalIndex()).isEqualTo(UInt64.valueOf(2)); assertThat(mutableBeaconStateElectra.getValidators().size()).isEqualTo(3); } + + @Test + void electraPendingPartialCountsSkippedWithdrawals() { + spec = TestSpecFactory.createMinimalElectra(); + dataStructureUtil = new DataStructureUtil(spec); + final SpecConfigElectra specConfigElectra = + SpecConfigElectra.required(spec.getGenesisSpec().getConfig()); + final UInt64 electraMaxBalance = specConfigElectra.getMaxEffectiveBalance(); + final long partialWithdrawalBalance = 10241024L; + + final BeaconStateElectra preState = + BeaconStateElectra.required( + new BeaconStateTestBuilder(dataStructureUtil) + .activeConsolidatingValidator(electraMaxBalance.plus(partialWithdrawalBalance)) + // the two validators below are skipped because they are queued for exit therefore + // they're withdrawals are skipped + .activeConsolidatingValidatorQueuedForExit( + electraMaxBalance.plus(partialWithdrawalBalance + 1)) + .activeConsolidatingValidatorQueuedForExit( + electraMaxBalance.plus(partialWithdrawalBalance + 2)) + .pendingPartialWithdrawal(0, electraMaxBalance.plus(partialWithdrawalBalance)) + .pendingPartialWithdrawal( + 1, electraMaxBalance.plus(partialWithdrawalBalance).plus(1)) + .pendingPartialWithdrawal( + 2, electraMaxBalance.plus(partialWithdrawalBalance).plus(2)) + .build()); + + final ExpectedWithdrawals withdrawals = + spec.getBlockProcessor(preState.getSlot()).getExpectedWithdrawals(preState); + + // even having 2 of the 3 partial withdrawals skipped, + // the count should be 2(which is the MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP for minimal + // spec) + // because we consider the skipped in the count + assertThat(withdrawals.getPartialWithdrawalCount()).isEqualTo(2); + } } diff --git a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/datastructures/state/BeaconStateTestBuilder.java b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/datastructures/state/BeaconStateTestBuilder.java index 117d19cb2c2..687d856d212 100644 --- a/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/datastructures/state/BeaconStateTestBuilder.java +++ b/ethereum/spec/src/testFixtures/java/tech/pegasys/teku/spec/datastructures/state/BeaconStateTestBuilder.java @@ -106,6 +106,19 @@ public BeaconStateTestBuilder activeConsolidatingValidator(final UInt64 balance) return this; } + public BeaconStateTestBuilder activeConsolidatingValidatorQueuedForExit(final UInt64 balance) { + validators.add( + dataStructureUtil + .randomValidator() + .withWithdrawalCredentials(dataStructureUtil.randomCompoundingWithdrawalCredentials()) + .withEffectiveBalance( + SpecConfigElectra.required(specConfig).getMaxEffectiveBalanceElectra().min(balance)) + .withActivationEpoch(UInt64.ZERO) + .withExitEpoch(FAR_FUTURE_EPOCH.minus(1))); + balances.add(balance); + return this; + } + public BeaconState build() { final SpecVersion specVersion = dataStructureUtil.getSpec().atSlot(slot); return specVersion