altair

package
v5.0.1-rc.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 8, 2024 License: GPL-3.0 Imports: 29 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrTooLate = errors.New("sync message is too late")
)

Functions

func AddValidatorFlag

func AddValidatorFlag(flag, flagPosition uint8) (uint8, error)

AddValidatorFlag adds new validator flag to existing one.

func AttestationParticipationFlagIndices

func AttestationParticipationFlagIndices(beaconState state.BeaconState, data *ethpb.AttestationData, delay primitives.Slot) (map[uint8]bool, error)

AttestationParticipationFlagIndices retrieves a map of attestation scoring based on Altair's participation flag indices. This is used to facilitate process attestation during state transition and during upgrade to altair state.

Spec code: def get_attestation_participation_flag_indices(state: BeaconState,

                                           data: AttestationData,
                                           inclusion_delay: uint64) -> Sequence[int]:
"""
Return the flag indices that are satisfied by an attestation.
"""
if data.target.epoch == get_current_epoch(state):
    justified_checkpoint = state.current_justified_checkpoint
else:
    justified_checkpoint = state.previous_justified_checkpoint

# Matching roots
is_matching_source = data.source == justified_checkpoint
is_matching_target = is_matching_source and data.target.root == get_block_root(state, data.target.epoch)
is_matching_head = is_matching_target and data.beacon_block_root == get_block_root_at_slot(state, data.slot)
assert is_matching_source

participation_flag_indices = []
if is_matching_source and inclusion_delay <= integer_squareroot(SLOTS_PER_EPOCH):
    participation_flag_indices.append(TIMELY_SOURCE_FLAG_INDEX)
if is_matching_target and inclusion_delay <= SLOTS_PER_EPOCH:
    participation_flag_indices.append(TIMELY_TARGET_FLAG_INDEX)
if is_matching_head and inclusion_delay == MIN_ATTESTATION_INCLUSION_DELAY:
    participation_flag_indices.append(TIMELY_HEAD_FLAG_INDEX)

return participation_flag_indices

func BaseReward

BaseReward takes state and validator index and calculate individual validator's base reward.

Spec code:

def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
  """
  Return the base reward for the validator defined by ``index`` with respect to the current ``state``.

  Note: An optimally performing validator can earn one base reward per epoch over a long time horizon.
  This takes into account both per-epoch (e.g. attestation) and intermittent duties (e.g. block proposal
  and sync committees).
  """
  increments = state.validators[index].effective_balance // EFFECTIVE_BALANCE_INCREMENT
  return Gwei(increments * get_base_reward_per_increment(state))

func BaseRewardPerIncrement

func BaseRewardPerIncrement(activeBalance uint64) (uint64, error)

BaseRewardPerIncrement of the beacon state

Spec code: def get_base_reward_per_increment(state: BeaconState) -> Gwei:

return Gwei(EFFECTIVE_BALANCE_INCREMENT * BASE_REWARD_FACTOR // integer_squareroot(get_total_active_balance(state)))

func BaseRewardWithTotalBalance

func BaseRewardWithTotalBalance(s state.ReadOnlyBeaconState, index primitives.ValidatorIndex, totalBalance uint64) (uint64, error)

BaseRewardWithTotalBalance calculates the base reward with the provided total balance.

func EpochParticipation

func EpochParticipation(beaconState state.BeaconState, indices []uint64, epochParticipation []byte, participatedFlags map[uint8]bool, totalBalance uint64) (uint64, []byte, error)

EpochParticipation sets and returns the proposer reward numerator and epoch participation.

Spec code:

proposer_reward_numerator = 0
for index in get_attesting_indices(state, data, attestation.aggregation_bits):
    for flag_index, weight in enumerate(PARTICIPATION_FLAG_WEIGHTS):
        if flag_index in participation_flag_indices and not has_flag(epoch_participation[index], flag_index):
            epoch_participation[index] = add_flag(epoch_participation[index], flag_index)
            proposer_reward_numerator += get_base_reward(state, index) * weight

func HasValidatorFlag

func HasValidatorFlag(flag, flagPosition uint8) (bool, error)

HasValidatorFlag returns true if the flag at position has set.

func InitializePrecomputeValidators

func InitializePrecomputeValidators(ctx context.Context, beaconState state.BeaconState) ([]*precompute.Validator, *precompute.Balance, error)

InitializePrecomputeValidators precomputes individual validator for its attested balances and the total sum of validators attested balances of the epoch.

func IsSyncCommitteeAggregator

func IsSyncCommitteeAggregator(sig []byte) (bool, error)

IsSyncCommitteeAggregator checks whether the provided signature is for a valid aggregator.

def is_sync_committee_aggregator(signature: BLSSignature) -> bool:

modulo = max(1, SYNC_COMMITTEE_SIZE // SYNC_COMMITTEE_SUBNET_COUNT // TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE)
return bytes_to_uint64(hash(signature)[0:8]) % modulo == 0

func MatchingStatus

func MatchingStatus(beaconState state.BeaconState, data *ethpb.AttestationData, cp *ethpb.Checkpoint) (matchedSrc, matchedTgt, matchedHead bool, err error)

MatchingStatus returns the matching statues for attestation data's source target and head.

Spec code:

is_matching_source = data.source == justified_checkpoint
is_matching_target = is_matching_source and data.target.root == get_block_root(state, data.target.epoch)
is_matching_head = is_matching_target and data.beacon_block_root == get_block_root_at_slot(state, data.slot)

func NextSyncCommittee

func NextSyncCommittee(ctx context.Context, s state.BeaconState) (*ethpb.SyncCommittee, error)

NextSyncCommittee returns the next sync committee for a given state.

Spec code: def get_next_sync_committee(state: BeaconState) -> SyncCommittee:

"""
Return the next sync committee, with possible pubkey duplicates.
"""
indices = get_next_sync_committee_indices(state)
pubkeys = [state.validators[index].pubkey for index in indices]
aggregate_pubkey = bls.AggregatePKs(pubkeys)
return SyncCommittee(pubkeys=pubkeys, aggregate_pubkey=aggregate_pubkey)

func NextSyncCommitteeIndices

func NextSyncCommitteeIndices(ctx context.Context, s state.BeaconState) ([]primitives.ValidatorIndex, error)

NextSyncCommitteeIndices returns the next sync committee indices for a given state.

Spec code: def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorIndex]:

"""
Return the sync committee indices, with possible duplicates, for the next sync committee.
"""
epoch = Epoch(get_current_epoch(state) + 1)

MAX_RANDOM_BYTE = 2**8 - 1
active_validator_indices = get_active_validator_indices(state, epoch)
active_validator_count = uint64(len(active_validator_indices))
seed = get_seed(state, epoch, DOMAIN_SYNC_COMMITTEE)
i = 0
sync_committee_indices: List[ValidatorIndex] = []
while len(sync_committee_indices) < SYNC_COMMITTEE_SIZE:
    shuffled_index = compute_shuffled_index(uint64(i % active_validator_count), active_validator_count, seed)
    candidate_index = active_validator_indices[shuffled_index]
    random_byte = hash(seed + uint_to_bytes(uint64(i // 32)))[i % 32]
    effective_balance = state.validators[candidate_index].effective_balance
    if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte:
        sync_committee_indices.append(candidate_index)
    i += 1
return sync_committee_indices

func ProcessAttestationNoVerifySignature

func ProcessAttestationNoVerifySignature(
	ctx context.Context,
	beaconState state.BeaconState,
	att *ethpb.Attestation,
	totalBalance uint64,
) (state.BeaconState, error)

ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This method is used to validate attestations whose signatures have already been verified or will be verified later.

func ProcessAttestationsNoVerifySignature

func ProcessAttestationsNoVerifySignature(
	ctx context.Context,
	beaconState state.BeaconState,
	b interfaces.ReadOnlyBeaconBlock,
) (state.BeaconState, error)

ProcessAttestationsNoVerifySignature applies processing operations to a block's inner attestation records. The only difference would be that the attestation signature would not be verified.

func ProcessDeposit

func ProcessDeposit(beaconState state.BeaconState, deposit *ethpb.Deposit, verifySignature bool) (state.BeaconState, error)

ProcessDeposit processes validator deposit for beacon state Altair.

func ProcessDeposits

func ProcessDeposits(
	ctx context.Context,
	beaconState state.BeaconState,
	deposits []*ethpb.Deposit,
) (state.BeaconState, error)

ProcessDeposits processes validator deposits for beacon state Altair.

func ProcessEpoch

func ProcessEpoch(ctx context.Context, state state.BeaconState) (state.BeaconState, error)

ProcessEpoch describes the per epoch operations that are performed on the beacon state. It's optimized by pre computing validator attested info and epoch total/attested balances upfront.

Spec code: def process_epoch(state: BeaconState) -> None:

process_justification_and_finalization(state)  # [Modified in Altair]
process_inactivity_updates(state)  # [New in Altair]
process_rewards_and_penalties(state)  # [Modified in Altair]
process_registry_updates(state)
process_slashings(state)  # [Modified in Altair]
process_eth1_data_reset(state)
process_effective_balance_updates(state)
process_slashings_reset(state)
process_randao_mixes_reset(state)
process_historical_roots_update(state)
process_participation_flag_updates(state)  # [New in Altair]
process_sync_committee_updates(state)  # [New in Altair]

func ProcessEpochParticipation

func ProcessEpochParticipation(
	ctx context.Context,
	beaconState state.BeaconState,
	bal *precompute.Balance,
	vals []*precompute.Validator,
) ([]*precompute.Validator, *precompute.Balance, error)

ProcessEpochParticipation processes the epoch participation in state and updates individual validator's pre computes, it also tracks and updates epoch attesting balances. Spec code: if epoch == get_current_epoch(state):

    epoch_participation = state.current_epoch_participation
else:
    epoch_participation = state.previous_epoch_participation
active_validator_indices = get_active_validator_indices(state, epoch)
participating_indices = [i for i in active_validator_indices if has_flag(epoch_participation[i], flag_index)]
return set(filter(lambda index: not state.validators[index].slashed, participating_indices))

func ProcessInactivityScores

func ProcessInactivityScores(
	ctx context.Context,
	beaconState state.BeaconState,
	vals []*precompute.Validator,
) (state.BeaconState, []*precompute.Validator, error)

ProcessInactivityScores of beacon chain. This updates inactivity scores of beacon chain and updates the precompute validator struct for later processing. The inactivity scores work as following: For fully inactive validators and perfect active validators, the effect is the same as before Altair. For a validator is inactive and the chain fails to finalize, the inactivity score increases by a fixed number, the total loss after N epochs is proportional to N**2/2. For imperfectly active validators. The inactivity score's behavior is specified by this function:

If a validator fails to submit an attestation with the correct target, their inactivity score goes up by 4.
If they successfully submit an attestation with the correct source and target, their inactivity score drops by 1
If the chain has recently finalized, each validator's score drops by 16.

func ProcessParticipationFlagUpdates

func ProcessParticipationFlagUpdates(beaconState state.BeaconState) (state.BeaconState, error)

ProcessParticipationFlagUpdates processes participation flag updates by rotating current to previous.

nolint:dupword Spec code: def process_participation_flag_updates(state: BeaconState) -> None:

state.previous_epoch_participation = state.current_epoch_participation
state.current_epoch_participation = [ParticipationFlags(0b0000_0000) for _ in range(len(state.validators))]

func ProcessRewardsAndPenaltiesPrecompute

func ProcessRewardsAndPenaltiesPrecompute(
	beaconState state.BeaconState,
	bal *precompute.Balance,
	vals []*precompute.Validator,
) (state.BeaconState, error)

ProcessRewardsAndPenaltiesPrecompute processes the rewards and penalties of individual validator. This is an optimized version by passing in precomputed validator attesting records and total epoch balances.

func ProcessSyncAggregate

func ProcessSyncAggregate(ctx context.Context, s state.BeaconState, sync *ethpb.SyncAggregate) (state.BeaconState, uint64, error)

ProcessSyncAggregate verifies sync committee aggregate signature signing over the previous slot block root.

Spec code: def process_sync_aggregate(state: BeaconState, sync_aggregate: SyncAggregate) -> None:

# Verify sync committee aggregate signature signing over the previous slot block root
committee_pubkeys = state.current_sync_committee.pubkeys
participant_pubkeys = [pubkey for pubkey, bit in zip(committee_pubkeys, sync_aggregate.sync_committee_bits) if bit]
previous_slot = max(state.slot, Slot(1)) - Slot(1)
domain = get_domain(state, DOMAIN_SYNC_COMMITTEE, compute_epoch_at_slot(previous_slot))
signing_root = compute_signing_root(get_block_root_at_slot(state, previous_slot), domain)
assert eth2_fast_aggregate_verify(participant_pubkeys, signing_root, sync_aggregate.sync_committee_signature)

# Compute participant and proposer rewards
total_active_increments = get_total_active_balance(state) // EFFECTIVE_BALANCE_INCREMENT
total_base_rewards = Gwei(get_base_reward_per_increment(state) * total_active_increments)
max_participant_rewards = Gwei(total_base_rewards * SYNC_REWARD_WEIGHT // WEIGHT_DENOMINATOR // SLOTS_PER_EPOCH)
participant_reward = Gwei(max_participant_rewards // SYNC_COMMITTEE_SIZE)
proposer_reward = Gwei(participant_reward * PROPOSER_WEIGHT // (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT))

# Apply participant and proposer rewards
all_pubkeys = [v.pubkey for v in state.validators]
committee_indices = [ValidatorIndex(all_pubkeys.index(pubkey)) for pubkey in state.current_sync_committee.pubkeys]
for participant_index, participation_bit in zip(committee_indices, sync_aggregate.sync_committee_bits):
    if participation_bit:
        increase_balance(state, participant_index, participant_reward)
        increase_balance(state, get_beacon_proposer_index(state), proposer_reward)
    else:
        decrease_balance(state, participant_index, participant_reward)

func ProcessSyncCommitteeUpdates

func ProcessSyncCommitteeUpdates(ctx context.Context, beaconState state.BeaconState) (state.BeaconState, error)

ProcessSyncCommitteeUpdates processes sync client committee updates for the beacon state.

nolint:dupword Spec code: def process_sync_committee_updates(state: BeaconState) -> None:

next_epoch = get_current_epoch(state) + Epoch(1)
if next_epoch % EPOCHS_PER_SYNC_COMMITTEE_PERIOD == 0:
    state.current_sync_committee = state.next_sync_committee
    state.next_sync_committee = get_next_sync_committee(state)

func RewardProposer

func RewardProposer(ctx context.Context, beaconState state.BeaconState, proposerRewardNumerator uint64) error

RewardProposer rewards proposer by increasing proposer's balance with input reward numerator and calculated reward denominator.

Spec code:

proposer_reward_denominator = (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT) * WEIGHT_DENOMINATOR // PROPOSER_WEIGHT
proposer_reward = Gwei(proposer_reward_numerator // proposer_reward_denominator)
increase_balance(state, get_beacon_proposer_index(state), proposer_reward)

func SetParticipationAndRewardProposer

func SetParticipationAndRewardProposer(
	ctx context.Context,
	beaconState state.BeaconState,
	targetEpoch primitives.Epoch,
	indices []uint64,
	participatedFlags map[uint8]bool, totalBalance uint64) (state.BeaconState, error)

SetParticipationAndRewardProposer retrieves and sets the epoch participation bits in state. Based on the epoch participation, it rewards the proposer in state.

Spec code:

 # Update epoch participation flags
if data.target.epoch == get_current_epoch(state):
    epoch_participation = state.current_epoch_participation
else:
    epoch_participation = state.previous_epoch_participation

proposer_reward_numerator = 0
for index in get_attesting_indices(state, data, attestation.aggregation_bits):
    for flag_index, weight in enumerate(PARTICIPATION_FLAG_WEIGHTS):
        if flag_index in participation_flag_indices and not has_flag(epoch_participation[index], flag_index):
            epoch_participation[index] = add_flag(epoch_participation[index], flag_index)
            proposer_reward_numerator += get_base_reward(state, index) * weight

# Reward proposer
proposer_reward_denominator = (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT) * WEIGHT_DENOMINATOR // PROPOSER_WEIGHT
proposer_reward = Gwei(proposer_reward_numerator // proposer_reward_denominator)
increase_balance(state, get_beacon_proposer_index(state), proposer_reward)

func SyncRewards

func SyncRewards(activeBalance uint64) (proposerReward, participantReward uint64, err error)

SyncRewards returns the proposer reward and the sync participant reward given the total active balance in state.

func SyncSubCommitteePubkeys

func SyncSubCommitteePubkeys(syncCommittee *ethpb.SyncCommittee, subComIdx primitives.CommitteeIndex) ([][]byte, error)

SyncSubCommitteePubkeys returns the pubkeys participating in a sync subcommittee.

def get_sync_subcommittee_pubkeys(state: BeaconState, subcommittee_index: uint64) -> Sequence[BLSPubkey]:

# Committees assigned to `slot` sign for `slot - 1`
# This creates the exceptional logic below when transitioning between sync committee periods
next_slot_epoch = compute_epoch_at_slot(Slot(state.slot + 1))
if compute_sync_committee_period(get_current_epoch(state)) == compute_sync_committee_period(next_slot_epoch):
    sync_committee = state.current_sync_committee
else:
    sync_committee = state.next_sync_committee

# Return pubkeys for the subcommittee index
sync_subcommittee_size = SYNC_COMMITTEE_SIZE // SYNC_COMMITTEE_SUBNET_COUNT
i = subcommittee_index * sync_subcommittee_size
return sync_committee.pubkeys[i:i + sync_subcommittee_size]

func TranslateParticipation

func TranslateParticipation(ctx context.Context, state state.BeaconState, atts []*ethpb.PendingAttestation) (state.BeaconState, error)

TranslateParticipation translates pending attestations into participation bits, then inserts the bits into beacon state. This is helper function to convert phase 0 beacon state(pending_attestations) to Altair beacon state(participation_bits).

Spec code: def translate_participation(state: BeaconState, pending_attestations: Sequence[phase0.PendingAttestation]) -> None:

for attestation in pending_attestations:
    data = attestation.data
    inclusion_delay = attestation.inclusion_delay
    # Translate attestation inclusion info to flag indices
    participation_flag_indices = get_attestation_participation_flag_indices(state, data, inclusion_delay)

    # Apply flags to all attesting validators
    epoch_participation = state.previous_epoch_participation
    for index in get_attesting_indices(state, data, attestation.aggregation_bits):
        for flag_index in participation_flag_indices:
            epoch_participation[index] = add_flag(epoch_participation[index], flag_index)

func UpgradeToAltair

func UpgradeToAltair(ctx context.Context, state state.BeaconState) (state.BeaconState, error)

UpgradeToAltair updates input state to return the version Altair state.

Spec code: def upgrade_to_altair(pre: phase0.BeaconState) -> BeaconState:

epoch = phase0.get_current_epoch(pre)
post = BeaconState(
    # Versioning
    genesis_time=pre.genesis_time,
    genesis_validators_root=pre.genesis_validators_root,
    slot=pre.slot,
    fork=Fork(
        previous_version=pre.fork.current_version,
        current_version=ALTAIR_FORK_VERSION,
        epoch=epoch,
    ),
    # History
    latest_block_header=pre.latest_block_header,
    block_roots=pre.block_roots,
    state_roots=pre.state_roots,
    historical_roots=pre.historical_roots,
    # Eth1
    eth1_data=pre.eth1_data,
    eth1_data_votes=pre.eth1_data_votes,
    eth1_deposit_index=pre.eth1_deposit_index,
    # Registry
    validators=pre.validators,
    balances=pre.balances,
    # Randomness
    randao_mixes=pre.randao_mixes,
    # Slashings
    slashings=pre.slashings,
    # Participation
    previous_epoch_participation=[ParticipationFlags(0b0000_0000) for _ in range(len(pre.validators))],
    current_epoch_participation=[ParticipationFlags(0b0000_0000) for _ in range(len(pre.validators))],
    # Finality
    justification_bits=pre.justification_bits,
    previous_justified_checkpoint=pre.previous_justified_checkpoint,
    current_justified_checkpoint=pre.current_justified_checkpoint,
    finalized_checkpoint=pre.finalized_checkpoint,
    # Inactivity
    inactivity_scores=[uint64(0) for _ in range(len(pre.validators))],
)
# Fill in previous epoch participation from the pre state's pending attestations
translate_participation(post, pre.previous_epoch_attestations)

# Fill in sync committees
# Note: A duplicate committee is assigned for the current and next committee at the fork boundary
post.current_sync_committee = get_next_sync_committee(post)
post.next_sync_committee = get_next_sync_committee(post)
return post

func ValidateNilSyncContribution

func ValidateNilSyncContribution(s *ethpb.SignedContributionAndProof) error

ValidateNilSyncContribution validates the following fields are not nil: -the contribution and proof itself -the message within contribution and proof -the contribution within contribution and proof -the aggregation bits within contribution

func ValidateSyncMessageTime

func ValidateSyncMessageTime(slot primitives.Slot, genesisTime time.Time, clockDisparity time.Duration) error

ValidateSyncMessageTime validates sync message to ensure that the provided slot is valid. Spec: [IGNORE] The message's slot is for the current slot (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance), i.e. sync_committee_message.slot == current_slot

func VerifySyncCommitteeSig

func VerifySyncCommitteeSig(s state.BeaconState, syncKeys []bls.PublicKey, syncSig []byte) error

VerifySyncCommitteeSig verifies sync committee signature `syncSig` is valid with respect to public keys `syncKeys`.

Types

type AttDelta

type AttDelta struct {
	HeadReward        uint64
	SourceReward      uint64
	SourcePenalty     uint64
	TargetReward      uint64
	TargetPenalty     uint64
	InactivityPenalty uint64
}

AttDelta contains rewards and penalties for a single attestation.

func AttestationsDelta

func AttestationsDelta(beaconState state.BeaconState, bal *precompute.Balance, vals []*precompute.Validator) ([]*AttDelta, error)

AttestationsDelta computes and returns the rewards and penalties differences for individual validators based on the voting records.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL