From 0c2464c497d59fbf42dcd7615e78154085ec7fcc Mon Sep 17 00:00:00 2001 From: Nishant Das Date: Fri, 4 Apr 2025 00:07:33 +0800 Subject: [PATCH] Handle Consolidation Processing Edge Case (#15122) * Clean it up * Add regression test case * changelog --- beacon-chain/core/electra/consolidations.go | 4 +- .../core/electra/consolidations_test.go | 38 +++++++++++++++++++ changelog/nisdas_handle_consolidation_bug.md | 3 ++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 changelog/nisdas_handle_consolidation_bug.md diff --git a/beacon-chain/core/electra/consolidations.go b/beacon-chain/core/electra/consolidations.go index 978b72ad1d..b239f10ba6 100644 --- a/beacon-chain/core/electra/consolidations.go +++ b/beacon-chain/core/electra/consolidations.go @@ -211,7 +211,7 @@ func ProcessConsolidationRequests(ctx context.Context, st state.BeaconState, req if npc, err := st.NumPendingConsolidations(); err != nil { return fmt.Errorf("failed to fetch number of pending consolidations: %w", err) // This should never happen. } else if npc >= pcLimit { - return nil + continue } activeBal, err := helpers.TotalActiveBalance(st) @@ -220,7 +220,7 @@ func ProcessConsolidationRequests(ctx context.Context, st state.BeaconState, req } churnLimit := helpers.ConsolidationChurnLimit(primitives.Gwei(activeBal)) if churnLimit <= primitives.Gwei(params.BeaconConfig().MinActivationBalance) { - return nil + continue } srcIdx, ok := st.ValidatorIndexByPubkey(sourcePubkey) diff --git a/beacon-chain/core/electra/consolidations_test.go b/beacon-chain/core/electra/consolidations_test.go index 611dda2ed9..55e54a166d 100644 --- a/beacon-chain/core/electra/consolidations_test.go +++ b/beacon-chain/core/electra/consolidations_test.go @@ -415,6 +415,44 @@ func TestProcessConsolidationRequests(t *testing.T) { require.Equal(t, params.BeaconConfig().FarFutureEpoch, src.WithdrawableEpoch, "source validator withdrawable epoch should not be updated") }, }, + { + name: "pending consolidations limit reached and compounded consolidation after", + state: func() state.BeaconState { + st := ð.BeaconStateElectra{ + Slot: params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod)), + Validators: createValidatorsWithTotalActiveBalance(32000000000000000), // 32M ETH + PendingConsolidations: make([]*eth.PendingConsolidation, params.BeaconConfig().PendingConsolidationsLimit), + } + // To allow compounding consolidation requests. + st.Validators[3].WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte + s, err := state_native.InitializeFromProtoElectra(st) + require.NoError(t, err) + return s + }(), + reqs: []*enginev1.ConsolidationRequest{ + { + SourceAddress: append(bytesutil.PadTo(nil, 19), byte(1)), + SourcePubkey: []byte("val_1"), + TargetPubkey: []byte("val_2"), + }, + { + SourceAddress: append(bytesutil.PadTo(nil, 19), byte(3)), + SourcePubkey: []byte("val_3"), + TargetPubkey: []byte("val_3"), + }, + }, + validate: func(t *testing.T, st state.BeaconState) { + // Verify a pending consolidation is created. + numPC, err := st.NumPendingConsolidations() + require.NoError(t, err) + require.Equal(t, params.BeaconConfig().PendingConsolidationsLimit, numPC) + + // Verify that the last consolidation was included + src, err := st.ValidatorAtIndex(3) + require.NoError(t, err) + require.Equal(t, params.BeaconConfig().CompoundingWithdrawalPrefixByte, src.WithdrawalCredentials[0], "source validator was not compounded") + }, + }, } for _, tt := range tests { diff --git a/changelog/nisdas_handle_consolidation_bug.md b/changelog/nisdas_handle_consolidation_bug.md new file mode 100644 index 0000000000..ebafddf226 --- /dev/null +++ b/changelog/nisdas_handle_consolidation_bug.md @@ -0,0 +1,3 @@ +### Fixed + +- Fixed a bug in consolidation request processing.