mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
91 lines
3.3 KiB
Go
91 lines
3.3 KiB
Go
package gloas
|
|
|
|
import (
|
|
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
|
|
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
|
|
"github.com/OffchainLabs/prysm/v7/config/params"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// ProcessBuilderPendingPayments processes the builder pending payments from the previous epoch.
|
|
// Spec v1.6.1 (pseudocode):
|
|
// process_builder_pending_payments(state: BeaconState) -> None:
|
|
//
|
|
// quorum = get_builder_payment_quorum_threshold(state)
|
|
// for payment in state.builder_pending_payments[:SLOTS_PER_EPOCH]:
|
|
// if payment.weight >= quorum:
|
|
// exit_epoch = compute_exit_epoch_and_update_churn(state, payment.withdrawal.amount)
|
|
// payment.withdrawal.withdrawable_epoch =
|
|
// Epoch(exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
|
|
// state.builder_pending_withdrawals.append(payment.withdrawal)
|
|
// state.builder_pending_payments =
|
|
// state.builder_pending_payments[SLOTS_PER_EPOCH:]
|
|
// + [BuilderPendingPayment() for _ in range(SLOTS_PER_EPOCH)]
|
|
func ProcessBuilderPendingPayments(state state.BeaconState) error {
|
|
quorum, err := builderQuorumThreshold(state)
|
|
if err != nil {
|
|
return errors.Wrap(err, "could not compute builder payment quorum threshold")
|
|
}
|
|
|
|
payments, err := state.BuilderPendingPayments()
|
|
if err != nil {
|
|
return errors.Wrap(err, "could not get builder pending payments")
|
|
}
|
|
|
|
cfg := params.BeaconConfig()
|
|
slotsPerEpoch := uint64(cfg.SlotsPerEpoch)
|
|
minWithdrawDelay := uint64(cfg.MinValidatorWithdrawabilityDelay)
|
|
for i := uint64(0); i < slotsPerEpoch; i++ {
|
|
payment := payments[i]
|
|
if quorum > payment.Weight {
|
|
continue
|
|
}
|
|
|
|
amount := payment.Withdrawal.Amount
|
|
exitEpoch, err := state.ExitEpochAndUpdateChurn(amount)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "could not compute exit epoch for payment %d", i)
|
|
}
|
|
|
|
withdrawableEpoch, err := exitEpoch.SafeAdd(minWithdrawDelay)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "could not compute withdrawable epoch for payment %d", i)
|
|
}
|
|
payment.Withdrawal.WithdrawableEpoch = withdrawableEpoch
|
|
|
|
if err := state.AppendBuilderPendingWithdrawal(payment.Withdrawal); err != nil {
|
|
return errors.Wrapf(err, "could not append builder pending withdrawal %d", i)
|
|
}
|
|
}
|
|
|
|
if err := state.RotateBuilderPendingPayments(); err != nil {
|
|
return errors.Wrap(err, "could not rotate builder pending payments")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// builderQuorumThreshold calculates the quorum threshold for builder payments.
|
|
// Spec v1.6.1 (pseudocode):
|
|
// def get_builder_payment_quorum_threshold(state: BeaconState) -> uint64:
|
|
//
|
|
// per_slot_balance = get_total_active_balance(state) // SLOTS_PER_EPOCH
|
|
// quorum = per_slot_balance * BUILDER_PAYMENT_THRESHOLD_NUMERATOR
|
|
// return uint64(quorum // BUILDER_PAYMENT_THRESHOLD_DENOMINATOR)
|
|
func builderQuorumThreshold(state state.BeaconState) (primitives.Gwei, error) {
|
|
activeBalance, err := helpers.TotalActiveBalance(state)
|
|
if err != nil {
|
|
return 0, errors.Wrap(err, "could not get total active balance")
|
|
}
|
|
|
|
cfg := params.BeaconConfig()
|
|
slotsPerEpoch := uint64(cfg.SlotsPerEpoch)
|
|
numerator := cfg.BuilderPaymentThresholdNumerator
|
|
denominator := cfg.BuilderPaymentThresholdDenominator
|
|
|
|
activeBalancePerSlot := activeBalance / slotsPerEpoch
|
|
quorum := (activeBalancePerSlot * numerator) / denominator
|
|
return primitives.Gwei(quorum), nil
|
|
}
|