mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Update specs comments (#8750)
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -64,7 +64,7 @@ func ProcessAttestations(
|
||||
// assert data.source == state.previous_justified_checkpoint
|
||||
// state.previous_epoch_attestations.append(pending_attestation)
|
||||
//
|
||||
// # Check signature
|
||||
// # Verify signature
|
||||
// assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
|
||||
func ProcessAttestation(
|
||||
ctx context.Context,
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
// def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
|
||||
// state.eth1_data_votes.append(body.eth1_data)
|
||||
// if state.eth1_data_votes.count(body.eth1_data) * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
|
||||
// state.latest_eth1_data = body.eth1_data
|
||||
// state.eth1_data = body.eth1_data
|
||||
func ProcessEth1DataInBlock(_ context.Context, beaconState iface.BeaconState, b *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
|
||||
block := b.Block
|
||||
if beaconState == nil {
|
||||
|
||||
@@ -19,23 +19,24 @@ import (
|
||||
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
|
||||
// # Verify that the slots match
|
||||
// assert block.slot == state.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// # Verify that the block is newer than latest block header
|
||||
// assert block.slot > state.latest_block_header.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// assert block.proposer_index == get_beacon_proposer_index(state)
|
||||
// # Verify that the parent matches
|
||||
// assert block.parent_root == hash_tree_root(state.latest_block_header)
|
||||
// # Save current block as the new latest block
|
||||
// # Cache current block as the new latest block
|
||||
// state.latest_block_header = BeaconBlockHeader(
|
||||
// slot=block.slot,
|
||||
// proposer_index=block.proposer_index,
|
||||
// parent_root=block.parent_root,
|
||||
// # state_root: zeroed, overwritten in the next `process_slot` call
|
||||
// state_root=Bytes32(), # Overwritten in the next process_slot call
|
||||
// body_root=hash_tree_root(block.body),
|
||||
// # signature is always zeroed
|
||||
// )
|
||||
//
|
||||
// # Verify proposer is not slashed
|
||||
// proposer = state.validators[get_beacon_proposer_index(state)]
|
||||
// proposer = state.validators[block.proposer_index]
|
||||
// assert not proposer.slashed
|
||||
// # Verify proposer signature
|
||||
// assert bls_verify(proposer.pubkey, signing_root(block), block.signature, get_domain(state, DOMAIN_BEACON_PROPOSER))
|
||||
func ProcessBlockHeader(
|
||||
_ context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
@@ -64,20 +65,23 @@ func ProcessBlockHeader(
|
||||
// def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
|
||||
// # Verify that the slots match
|
||||
// assert block.slot == state.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// # Verify that the block is newer than latest block header
|
||||
// assert block.slot > state.latest_block_header.slot
|
||||
// # Verify that proposer index is the correct index
|
||||
// assert block.proposer_index == get_beacon_proposer_index(state)
|
||||
// # Verify that the parent matches
|
||||
// assert block.parent_root == hash_tree_root(state.latest_block_header)
|
||||
// # Save current block as the new latest block
|
||||
// # Cache current block as the new latest block
|
||||
// state.latest_block_header = BeaconBlockHeader(
|
||||
// slot=block.slot,
|
||||
// proposer_index=block.proposer_index,
|
||||
// parent_root=block.parent_root,
|
||||
// # state_root: zeroed, overwritten in the next `process_slot` call
|
||||
// state_root=Bytes32(), # Overwritten in the next process_slot call
|
||||
// body_root=hash_tree_root(block.body),
|
||||
// # signature is always zeroed
|
||||
// )
|
||||
//
|
||||
// # Verify proposer is not slashed
|
||||
// proposer = state.validators[get_beacon_proposer_index(state)]
|
||||
// proposer = state.validators[block.proposer_index]
|
||||
// assert not proposer.slashed
|
||||
func ProcessBlockHeaderNoVerify(
|
||||
beaconState iface.BeaconState,
|
||||
|
||||
@@ -19,22 +19,25 @@ import (
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_proposer_slashing(state: BeaconState, proposer_slashing: ProposerSlashing) -> None:
|
||||
// """
|
||||
// Process ``ProposerSlashing`` operation.
|
||||
// """
|
||||
// proposer = state.validator_registry[proposer_slashing.proposer_index]
|
||||
// # Verify slots match
|
||||
// assert proposer_slashing.header_1.slot == proposer_slashing.header_2.slot
|
||||
// # But the headers are different
|
||||
// assert proposer_slashing.header_1 != proposer_slashing.header_2
|
||||
// # Check proposer is slashable
|
||||
// assert is_slashable_validator(proposer, get_current_epoch(state))
|
||||
// # Signatures are valid
|
||||
// for header in (proposer_slashing.header_1, proposer_slashing.header_2):
|
||||
// domain = get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(header.slot))
|
||||
// assert bls_verify(proposer.pubkey, signing_root(header), header.signature, domain)
|
||||
// header_1 = proposer_slashing.signed_header_1.message
|
||||
// header_2 = proposer_slashing.signed_header_2.message
|
||||
//
|
||||
// slash_validator(state, proposer_slashing.proposer_index)
|
||||
// # Verify header slots match
|
||||
// assert header_1.slot == header_2.slot
|
||||
// # Verify header proposer indices match
|
||||
// assert header_1.proposer_index == header_2.proposer_index
|
||||
// # Verify the headers are different
|
||||
// assert header_1 != header_2
|
||||
// # Verify the proposer is slashable
|
||||
// proposer = state.validators[header_1.proposer_index]
|
||||
// assert is_slashable_validator(proposer, get_current_epoch(state))
|
||||
// # Verify signatures
|
||||
// for signed_header in (proposer_slashing.signed_header_1, proposer_slashing.signed_header_2):
|
||||
// domain = get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_at_slot(signed_header.message.slot))
|
||||
// signing_root = compute_signing_root(signed_header.message, domain)
|
||||
// assert bls.Verify(proposer.pubkey, signing_root, signed_header.signature)
|
||||
//
|
||||
// slash_validator(state, header_1.proposer_index)
|
||||
func ProcessProposerSlashings(
|
||||
_ context.Context,
|
||||
beaconState iface.BeaconState,
|
||||
|
||||
@@ -157,7 +157,7 @@ func ProcessRegistryUpdates(state iface.BeaconState) (iface.BeaconState, error)
|
||||
// for index, validator in enumerate(state.validators):
|
||||
// if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch:
|
||||
// increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty numerator to avoid uint64 overflow
|
||||
// penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance
|
||||
// penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance
|
||||
// penalty = penalty_numerator // total_balance * increment
|
||||
// decrease_balance(state, ValidatorIndex(index), penalty)
|
||||
func ProcessSlashings(state iface.BeaconState) (iface.BeaconState, error) {
|
||||
@@ -474,9 +474,9 @@ func UnslashedAttestingIndices(state iface.ReadOnlyBeaconState, atts []*pb.Pendi
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
|
||||
// total_balance = get_total_active_balance(state)
|
||||
// effective_balance = state.validator_registry[index].effective_balance
|
||||
// return effective_balance * BASE_REWARD_FACTOR // integer_squareroot(total_balance) // BASE_REWARDS_PER_EPOCH
|
||||
// total_balance = get_total_active_balance(state)
|
||||
// effective_balance = state.validators[index].effective_balance
|
||||
// return Gwei(effective_balance * BASE_REWARD_FACTOR // integer_squareroot(total_balance) // BASE_REWARDS_PER_EPOCH)
|
||||
func BaseReward(state iface.ReadOnlyBeaconState, index types.ValidatorIndex) (uint64, error) {
|
||||
totalBalance, err := helpers.TotalActiveBalance(state)
|
||||
if err != nil {
|
||||
|
||||
@@ -53,7 +53,7 @@ func ValidateSlotTargetEpoch(data *ethpb.AttestationData) error {
|
||||
// def is_aggregator(state: BeaconState, slot: Slot, index: CommitteeIndex, slot_signature: BLSSignature) -> bool:
|
||||
// committee = get_beacon_committee(state, slot, index)
|
||||
// modulo = max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)
|
||||
// return bytes_to_int(hash(slot_signature)[0:8]) % modulo == 0
|
||||
// return bytes_to_uint64(hash(slot_signature)[0:8]) % modulo == 0
|
||||
func IsAggregator(committeeCount uint64, slotSig []byte) (bool, error) {
|
||||
modulo := uint64(1)
|
||||
if committeeCount/params.BeaconConfig().TargetAggregatorsPerCommittee > 1 {
|
||||
@@ -69,7 +69,7 @@ func IsAggregator(committeeCount uint64, slotSig []byte) (bool, error) {
|
||||
// Spec pseudocode definition:
|
||||
// def get_aggregate_signature(attestations: Sequence[Attestation]) -> BLSSignature:
|
||||
// signatures = [attestation.signature for attestation in attestations]
|
||||
// return bls_aggregate_signatures(signatures)
|
||||
// return bls.Aggregate(signatures)
|
||||
func AggregateSignature(attestations []*ethpb.Attestation) (bls.Signature, error) {
|
||||
sigs := make([]bls.Signature, len(attestations))
|
||||
var err error
|
||||
|
||||
@@ -34,9 +34,9 @@ var proposerIndicesCache = cache.NewProposerIndicesCache()
|
||||
// """
|
||||
// Return the number of committees in each slot for the given ``epoch``.
|
||||
// """
|
||||
// return max(1, min(
|
||||
// return max(uint64(1), min(
|
||||
// MAX_COMMITTEES_PER_SLOT,
|
||||
// len(get_active_validator_indices(state, epoch)) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
|
||||
// uint64(len(get_active_validator_indices(state, epoch))) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
|
||||
// ))
|
||||
func SlotCommitteeCount(activeValidatorCount uint64) uint64 {
|
||||
var committeePerSlot = activeValidatorCount / uint64(params.BeaconConfig().SlotsPerEpoch) / params.BeaconConfig().TargetCommitteeSize
|
||||
@@ -121,15 +121,15 @@ func BeaconCommittee(
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def compute_committee(indices: Sequence[ValidatorIndex],
|
||||
// seed: Hash,
|
||||
// seed: Bytes32,
|
||||
// index: uint64,
|
||||
// count: uint64) -> Sequence[ValidatorIndex]:
|
||||
// """
|
||||
// Return the committee corresponding to ``indices``, ``seed``, ``index``, and committee ``count``.
|
||||
// """
|
||||
// start = (len(indices) * index) // count
|
||||
// end = (len(indices) * (index + 1)) // count
|
||||
// return [indices[compute_shuffled_index(ValidatorIndex(i), len(indices), seed)] for i in range(start, end)
|
||||
// end = (len(indices) * uint64(index + 1)) // count
|
||||
// return [indices[compute_shuffled_index(uint64(i), uint64(len(indices)), seed)] for i in range(start, end)]
|
||||
func ComputeCommittee(
|
||||
indices []types.ValidatorIndex,
|
||||
seed [32]byte,
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
// """
|
||||
// Return the combined effective balance of the ``indices``.
|
||||
// ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
||||
// Math safe up to ~10B ETH, afterwhich this overflows uint64.
|
||||
// """
|
||||
// return Gwei(max(EFFECTIVE_BALANCE_INCREMENT, sum([state.validators[index].effective_balance for index in indices])))
|
||||
func TotalBalance(state iface.ReadOnlyValidators, indices []types.ValidatorIndex) uint64 {
|
||||
@@ -42,6 +43,7 @@ func TotalBalance(state iface.ReadOnlyValidators, indices []types.ValidatorIndex
|
||||
// def get_total_active_balance(state: BeaconState) -> Gwei:
|
||||
// """
|
||||
// Return the combined effective balance of the active validators.
|
||||
// Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
||||
// """
|
||||
// return get_total_balance(state, set(get_active_validator_indices(state, get_current_epoch(state))))
|
||||
func TotalActiveBalance(state iface.ReadOnlyBeaconState) (uint64, error) {
|
||||
|
||||
@@ -21,7 +21,7 @@ const MaxSlotBuffer = uint64(1 << 7)
|
||||
// Spec pseudocode definition:
|
||||
// def compute_epoch_at_slot(slot: Slot) -> Epoch:
|
||||
// """
|
||||
// Return the epoch number of ``slot``.
|
||||
// Return the epoch number at ``slot``.
|
||||
// """
|
||||
// return Epoch(slot // SLOTS_PER_EPOCH)
|
||||
func SlotToEpoch(slot types.Slot) types.Epoch {
|
||||
@@ -36,7 +36,7 @@ func SlotToEpoch(slot types.Slot) types.Epoch {
|
||||
// """
|
||||
// Return the current epoch.
|
||||
// """
|
||||
// return compute_epoch_of_slot(state.slot)
|
||||
// return compute_epoch_at_slot(state.slot)
|
||||
func CurrentEpoch(state iface.ReadOnlyBeaconState) types.Epoch {
|
||||
return SlotToEpoch(state.Slot())
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ func ActivationExitEpoch(epoch types.Epoch) types.Epoch {
|
||||
// Return the validator churn limit for the current epoch.
|
||||
// """
|
||||
// active_validator_indices = get_active_validator_indices(state, get_current_epoch(state))
|
||||
// return max(MIN_PER_EPOCH_CHURN_LIMIT, len(active_validator_indices) // CHURN_LIMIT_QUOTIENT)
|
||||
// return max(MIN_PER_EPOCH_CHURN_LIMIT, uint64(len(active_validator_indices)) // CHURN_LIMIT_QUOTIENT)
|
||||
func ValidatorChurnLimit(activeValidatorCount uint64) (uint64, error) {
|
||||
churnLimit := activeValidatorCount / params.BeaconConfig().ChurnLimitQuotient
|
||||
if churnLimit < params.BeaconConfig().MinPerEpochChurnLimit {
|
||||
@@ -173,7 +173,7 @@ func ValidatorChurnLimit(activeValidatorCount uint64) (uint64, error) {
|
||||
// Return the beacon proposer index at the current slot.
|
||||
// """
|
||||
// epoch = get_current_epoch(state)
|
||||
// seed = hash(get_seed(state, epoch, DOMAIN_BEACON_PROPOSER) + int_to_bytes(state.slot, length=8))
|
||||
// seed = hash(get_seed(state, epoch, DOMAIN_BEACON_PROPOSER) + uint_to_bytes(state.slot))
|
||||
// indices = get_active_validator_indices(state, epoch)
|
||||
// return compute_proposer_index(state, indices, seed)
|
||||
func BeaconProposerIndex(state iface.ReadOnlyBeaconState) (types.ValidatorIndex, error) {
|
||||
|
||||
@@ -109,11 +109,9 @@ func ExecuteStateTransition(
|
||||
// # Cache state root
|
||||
// previous_state_root = hash_tree_root(state)
|
||||
// state.state_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_state_root
|
||||
//
|
||||
// # Cache latest block header state root
|
||||
// if state.latest_block_header.state_root == Bytes32():
|
||||
// state.latest_block_header.state_root = previous_state_root
|
||||
//
|
||||
// # Cache block root
|
||||
// previous_block_root = hash_tree_root(state.latest_block_header)
|
||||
// state.block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_block_root
|
||||
@@ -192,14 +190,13 @@ func ProcessSlotsUsingNextSlotCache(
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def process_slots(state: BeaconState, slot: Slot) -> None:
|
||||
// assert state.slot <= slot
|
||||
// assert state.slot < slot
|
||||
// while state.slot < slot:
|
||||
// process_slot(state)
|
||||
// # Process epoch on the first slot of the next epoch
|
||||
// # Process epoch on the start slot of the next epoch
|
||||
// if (state.slot + 1) % SLOTS_PER_EPOCH == 0:
|
||||
// process_epoch(state)
|
||||
// state.slot += 1
|
||||
// ]
|
||||
// state.slot = Slot(state.slot + 1)
|
||||
func ProcessSlots(ctx context.Context, state iface.BeaconState, slot types.Slot) (iface.BeaconState, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "core.state.ProcessSlots")
|
||||
defer span.End()
|
||||
|
||||
@@ -88,18 +88,18 @@ func AttestingIndices(bf bitfield.Bitfield, committee []types.ValidatorIndex) ([
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def is_valid_indexed_attestation(state: BeaconState, indexed_attestation: IndexedAttestation) -> bool:
|
||||
// """
|
||||
// Check if ``indexed_attestation`` has sorted and unique indices and a valid aggregate signature.
|
||||
// """
|
||||
// # Verify indices are sorted and unique
|
||||
// indices = indexed_attestation.attesting_indices
|
||||
// if not indices == sorted(set(indices)):
|
||||
// """
|
||||
// Check if ``indexed_attestation`` is not empty, has sorted and unique indices and has a valid aggregate signature.
|
||||
// """
|
||||
// # Verify indices are sorted and unique
|
||||
// indices = indexed_attestation.attesting_indices
|
||||
// if len(indices) == 0 or not indices == sorted(set(indices)):
|
||||
// return False
|
||||
// # Verify aggregate signature
|
||||
// pubkeys = [state.validators[i].pubkey for i in indices]
|
||||
// domain = get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
|
||||
// signing_root = compute_signing_root(indexed_attestation.data, domain)
|
||||
// return bls.FastAggregateVerify(pubkeys, signing_root, indexed_attestation.signature)
|
||||
// # Verify aggregate signature
|
||||
// pubkeys = [state.validators[i].pubkey for i in indices]
|
||||
// domain = get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
|
||||
// signing_root = compute_signing_root(indexed_attestation.data, domain)
|
||||
// return bls.FastAggregateVerify(pubkeys, signing_root, indexed_attestation.signature)
|
||||
func VerifyIndexedAttestationSig(ctx context.Context, indexedAtt *ethpb.IndexedAttestation, pubKeys []bls.PublicKey, domain []byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "attestationutil.VerifyIndexedAttestationSig")
|
||||
defer span.End()
|
||||
@@ -128,24 +128,17 @@ func VerifyIndexedAttestationSig(ctx context.Context, indexedAtt *ethpb.IndexedA
|
||||
// Spec pseudocode definition:
|
||||
// def is_valid_indexed_attestation(state: BeaconState, indexed_attestation: IndexedAttestation) -> bool:
|
||||
// """
|
||||
// Check if ``indexed_attestation``is not empty, has valid indices, and signature.
|
||||
// Check if ``indexed_attestation`` is not empty, has sorted and unique indices and has a valid aggregate signature.
|
||||
// """
|
||||
// indices = indexed_attestation.attesting_indices
|
||||
//
|
||||
// # Verify max number of indices
|
||||
// if not len(indices) <= MAX_VALIDATORS_PER_COMMITTEE:
|
||||
// return False
|
||||
// # Verify indices are sorted and unique
|
||||
// if not indices == sorted(set(indices)):
|
||||
// # Verify aggregate signature
|
||||
// if not bls_verify(
|
||||
// pubkey=bls_aggregate_pubkeys([state.validators[i].pubkey for i in indices]),
|
||||
// message_hash=hash_tree_root(indexed_attestation.data),
|
||||
// signature=indexed_attestation.signature,
|
||||
// domain=get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch),
|
||||
// ):
|
||||
// indices = indexed_attestation.attesting_indices
|
||||
// if len(indices) == 0 or not indices == sorted(set(indices)):
|
||||
// return False
|
||||
// return True
|
||||
// # Verify aggregate signature
|
||||
// pubkeys = [state.validators[i].pubkey for i in indices]
|
||||
// domain = get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
|
||||
// signing_root = compute_signing_root(indexed_attestation.data, domain)
|
||||
// return bls.FastAggregateVerify(pubkeys, signing_root, indexed_attestation.signature)
|
||||
func IsValidAttestationIndices(ctx context.Context, indexedAttestation *ethpb.IndexedAttestation) error {
|
||||
ctx, span := trace.StartSpan(ctx, "attestationutil.IsValidAttestationIndices")
|
||||
defer span.End()
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
// - Let amount be the amount in Gwei to be deposited by the validator where MIN_DEPOSIT_AMOUNT <= amount <= MAX_EFFECTIVE_BALANCE.
|
||||
// - Set deposit_data.amount = amount.
|
||||
// - Let signature be the result of bls_sign of the signing_root(deposit_data) with domain=compute_domain(DOMAIN_DEPOSIT). (Deposits are valid regardless of fork version, compute_domain will default to zeroes there).
|
||||
// - Send a transaction on the Ethereum 1.0 chain to DEPOSIT_CONTRACT_ADDRESS executing def deposit(pubkey: bytes[48], withdrawal_credentials: bytes[32], signature: bytes[96]) along with a deposit of amount Gwei.
|
||||
// - Send a transaction on the Ethereum 1.0 chain to DEPOSIT_CONTRACT_ADDRESS executing `deposit(pubkey: bytes[48], withdrawal_credentials: bytes[32], signature: bytes[96])` along with a deposit of amount Gwei.
|
||||
//
|
||||
// See: https://github.com/ethereum/eth2.0-specs/blob/master/specs/validator/0_beacon-chain-validator.md#submit-deposit
|
||||
func DepositInput(depositKey, withdrawalKey bls.SecretKey, amountInGwei uint64) (*ethpb.Deposit_Data, [32]byte, error) {
|
||||
|
||||
Reference in New Issue
Block a user