Skip to content

Commit b13bf6b

Browse files
EIP-7251: Implement changes from ethereum/consensus-specs#3776
1 parent 8070fc8 commit b13bf6b

File tree

1 file changed

+65
-13
lines changed

1 file changed

+65
-13
lines changed

beacon-chain/core/electra/deposits.go

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package electra
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/pkg/errors"
78
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
@@ -13,7 +14,9 @@ import (
1314
"github.com/prysmaticlabs/prysm/v5/contracts/deposit"
1415
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
1516
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
17+
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
1618
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
19+
"github.com/prysmaticlabs/prysm/v5/time/slots"
1720
log "github.com/sirupsen/logrus"
1821
"go.opencensus.io/trace"
1922
)
@@ -190,12 +193,27 @@ func verifyDepositDataSigningRoot(obj *ethpb.Deposit_Data, domain []byte) error
190193
// available_for_processing = state.deposit_balance_to_consume + get_activation_exit_churn_limit(state)
191194
// processed_amount = 0
192195
// next_deposit_index = 0
196+
// deposits_to_postpone = []
193197
//
194198
// for deposit in state.pending_balance_deposits:
195-
// if processed_amount + deposit.amount > available_for_processing:
196-
// break
197-
// increase_balance(state, deposit.index, deposit.amount)
198-
// processed_amount += deposit.amount
199+
// validator = state.validators[deposit.index]
200+
// # Validator is exiting, postpone the deposit until after withdrawable epoch
201+
// if validator.exit_epoch < FAR_FUTURE_EPOCH:
202+
// if get_current_epoch(state) <= validator.withdrawable_epoch:
203+
// deposits_to_postpone.append(deposit)
204+
// # Deposited balance will never become active. Increase balance but do not consume churn
205+
// else:
206+
// increase_balance(state, deposit.index, deposit.amount)
207+
// # Validator is not exiting, attempt to process deposit
208+
// else:
209+
// # Deposit does not fit in the churn, no more deposit processing in this epoch.
210+
// if processed_amount + deposit.amount > available_for_processing:
211+
// break
212+
// # Deposit fits in the churn, process it. Increase balance and consume churn.
213+
// else:
214+
// increase_balance(state, deposit.index, deposit.amount)
215+
// processed_amount += deposit.amount
216+
// # Regardless of how the deposit was handled, we move on in the queue.
199217
// next_deposit_index += 1
200218
//
201219
// state.pending_balance_deposits = state.pending_balance_deposits[next_deposit_index:]
@@ -204,6 +222,8 @@ func verifyDepositDataSigningRoot(obj *ethpb.Deposit_Data, domain []byte) error
204222
// state.deposit_balance_to_consume = Gwei(0)
205223
// else:
206224
// state.deposit_balance_to_consume = available_for_processing - processed_amount
225+
//
226+
// state.pending_balance_deposits += deposits_to_postpone
207227
func ProcessPendingBalanceDeposits(ctx context.Context, st state.BeaconState, activeBalance primitives.Gwei) error {
208228
_, span := trace.StartSpan(ctx, "electra.ProcessPendingBalanceDeposits")
209229
defer span.End()
@@ -216,35 +236,67 @@ func ProcessPendingBalanceDeposits(ctx context.Context, st state.BeaconState, ac
216236
if err != nil {
217237
return err
218238
}
219-
220239
availableForProcessing := depBalToConsume + helpers.ActivationExitChurnLimit(activeBalance)
240+
processedAmount := uint64(0)
221241
nextDepositIndex := 0
242+
var depositsToPostpone []*eth.PendingBalanceDeposit
222243

223244
deposits, err := st.PendingBalanceDeposits()
224245
if err != nil {
225246
return err
226247
}
227248

249+
// constants
250+
ffe := params.BeaconConfig().FarFutureEpoch
251+
curEpoch := slots.ToEpoch(st.Slot())
252+
228253
for _, balanceDeposit := range deposits {
229-
if primitives.Gwei(balanceDeposit.Amount) > availableForProcessing {
230-
break
254+
v, err := st.ValidatorAtIndexReadOnly(balanceDeposit.Index)
255+
if err != nil {
256+
return fmt.Errorf("failed to fetch validator at index: %w", err)
231257
}
232-
if err := helpers.IncreaseBalance(st, balanceDeposit.Index, balanceDeposit.Amount); err != nil {
233-
return err
258+
259+
// If the validator is currently exiting, postpone the deposit until after the withdrawable
260+
// epoch.
261+
if v.ExitEpoch() < ffe {
262+
if curEpoch <= v.WithdrawableEpoch() {
263+
depositsToPostpone = append(depositsToPostpone, balanceDeposit)
264+
} else {
265+
// The deposited balance will never become active. Therefore, we increase the balance but do
266+
// not consume the churn.
267+
if err := helpers.IncreaseBalance(st, balanceDeposit.Index, balanceDeposit.Amount); err != nil {
268+
return err
269+
}
270+
}
271+
} else {
272+
if primitives.Gwei(processedAmount + balanceDeposit.Amount) > availableForProcessing {
273+
break
274+
}
275+
276+
if err := helpers.IncreaseBalance(st, balanceDeposit.Index, balanceDeposit.Amount); err != nil {
277+
return err
278+
}
279+
processedAmount += balanceDeposit.Amount
234280
}
235-
availableForProcessing -= primitives.Gwei(balanceDeposit.Amount)
281+
236282
nextDepositIndex++
237283
}
238284

239-
deposits = deposits[nextDepositIndex:]
285+
// Combined operation:
286+
// - state.pending_balance_deposits = state.pending_balance_deposits[next_deposit_index:]
287+
// - state.pending_balance_deposits += deposits_to_postpone
288+
// However, the number of remaining deposits must be maintained to properly update the deposit
289+
// balance to consume.
290+
numRemainingDeposits := len(deposits[nextDepositIndex:])
291+
deposits = append(deposits[nextDepositIndex:], depositsToPostpone...)
240292
if err := st.SetPendingBalanceDeposits(deposits); err != nil {
241293
return err
242294
}
243295

244-
if len(deposits) == 0 {
296+
if numRemainingDeposits == 0 {
245297
return st.SetDepositBalanceToConsume(0)
246298
} else {
247-
return st.SetDepositBalanceToConsume(availableForProcessing)
299+
return st.SetDepositBalanceToConsume(availableForProcessing - primitives.Gwei(processedAmount))
248300
}
249301
}
250302

0 commit comments

Comments
 (0)