helpers

package
v1.4.4 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2021 License: GPL-3.0 Imports: 27 Imported by: 204

Documentation

Overview

Package helpers contains helper functions outlined in the Ethereum Beacon Chain spec, such as computing committees, randao, rewards/penalties, and more.

Index

Constants

View Source
const DomainByteLength = 4

DomainByteLength length of domain byte array.

View Source
const ForkVersionByteLength = 4

ForkVersionByteLength length of fork version byte array.

View Source
const MaxSlotBuffer = uint64(1 << 7)

MaxSlotBuffer specifies the max buffer given to slots from incoming objects. (24 mins with mainnet spec)

Variables

View Source
var ErrSigFailedToVerify = errors.New("signature did not verify")

ErrSigFailedToVerify returns when a signature of a block object(ie attestation, slashing, exit... etc) failed to verify.

Functions

func ActivationExitEpoch added in v0.3.2

func ActivationExitEpoch(epoch types.Epoch) types.Epoch

ActivationExitEpoch takes in epoch number and returns when the validator is eligible for activation and exit.

Spec pseudocode definition:

def compute_activation_exit_epoch(epoch: Epoch) -> Epoch:
  """
  Return the epoch during which validator activations and exits initiated in ``epoch`` take effect.
  """
  return Epoch(epoch + 1 + MAX_SEED_LOOKAHEAD)

func ActiveValidatorCount

func ActiveValidatorCount(state iface.ReadOnlyBeaconState, epoch types.Epoch) (uint64, error)

ActiveValidatorCount returns the number of active validators in the state at the given epoch.

func ActiveValidatorIndices

func ActiveValidatorIndices(state iface.ReadOnlyBeaconState, epoch types.Epoch) ([]types.ValidatorIndex, error)

ActiveValidatorIndices filters out active validators based on validator status and returns their indices in a list.

WARNING: This method allocates a new copy of the validator index set and is considered to be very memory expensive. Avoid using this unless you really need the active validator indices for some specific reason.

Spec pseudocode definition:

def get_active_validator_indices(state: BeaconState, epoch: Epoch) -> Sequence[ValidatorIndex]:
  """
  Return the sequence of active validator indices at ``epoch``.
  """
  return [ValidatorIndex(i) for i, v in enumerate(state.validators) if is_active_validator(v, epoch)]

func AggregateSignature added in v0.2.5

func AggregateSignature(attestations []*ethpb.Attestation) (bls.Signature, error)

AggregateSignature returns the aggregated signature of the input attestations.

Spec pseudocode definition:

def get_aggregate_signature(attestations: Sequence[Attestation]) -> BLSSignature:
 signatures = [attestation.signature for attestation in attestations]
 return bls.Aggregate(signatures)

func BeaconCommittee added in v0.2.3

func BeaconCommittee(
	validatorIndices []types.ValidatorIndex,
	seed [32]byte,
	slot types.Slot,
	committeeIndex types.CommitteeIndex,
) ([]types.ValidatorIndex, error)

BeaconCommittee returns the crosslink committee of a given slot and committee index. The validator indices and seed are provided as an argument rather than a imported implementation from the spec definition. Having them as an argument allows for cheaper computation run time.

func BeaconCommitteeFromState added in v0.3.0

func BeaconCommitteeFromState(state iface.ReadOnlyBeaconState, slot types.Slot, committeeIndex types.CommitteeIndex) ([]types.ValidatorIndex, error)

BeaconCommitteeFromState returns the crosslink committee of a given slot and committee index. This is a spec implementation where state is used as an argument. In case of state retrieval becomes expensive, consider using BeaconCommittee below.

Spec pseudocode definition:

def get_beacon_committee(state: BeaconState, slot: Slot, index: CommitteeIndex) -> Sequence[ValidatorIndex]:
 """
 Return the beacon committee at ``slot`` for ``index``.
 """
 epoch = compute_epoch_at_slot(slot)
 committees_per_slot = get_committee_count_per_slot(state, epoch)
 return compute_committee(
     indices=get_active_validator_indices(state, epoch),
     seed=get_seed(state, epoch, DOMAIN_BEACON_ATTESTER),
     index=(slot % SLOTS_PER_EPOCH) * committees_per_slot + index,
     count=committees_per_slot * SLOTS_PER_EPOCH,
 )

func BeaconProposerIndex

func BeaconProposerIndex(state iface.ReadOnlyBeaconState) (types.ValidatorIndex, error)

BeaconProposerIndex returns proposer index of a current slot.

Spec pseudocode definition:

def get_beacon_proposer_index(state: BeaconState) -> ValidatorIndex:
  """
  Return the beacon proposer index at the current slot.
  """
  epoch = get_current_epoch(state)
  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 BlockRoot

func BlockRoot(state iface.ReadOnlyBeaconState, epoch types.Epoch) ([]byte, error)

BlockRoot returns the block root stored in the BeaconState for epoch start slot.

Spec pseudocode definition:

def get_block_root(state: BeaconState, epoch: Epoch) -> Root:
  """
  Return the block root at the start of a recent ``epoch``.
  """
  return get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch))

func BlockRootAtSlot

func BlockRootAtSlot(state iface.ReadOnlyBeaconState, slot types.Slot) ([]byte, error)

BlockRootAtSlot returns the block root stored in the BeaconState for a recent slot. It returns an error if the requested block root is not within the slot range.

Spec pseudocode definition:

def get_block_root_at_slot(state: BeaconState, slot: Slot) -> Root:
  """
  Return the block root at a recent ``slot``.
  """
  assert slot < state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
  return state.block_roots[slot % SLOTS_PER_HISTORICAL_ROOT]

func BlockSignatureSet added in v1.2.0

func BlockSignatureSet(pub, signature, domain []byte, rootFunc func() ([32]byte, error)) (*bls.SignatureSet, error)

BlockSignatureSet retrieves the relevant signature, message and pubkey data from a block and collating it into a signature set object.

func ClearCache added in v0.3.2

func ClearCache()

ClearCache clears the committee cache

func CommitteeAssignments added in v0.3.0

func CommitteeAssignments(
	state iface.BeaconState,
	epoch types.Epoch,
) (map[types.ValidatorIndex]*CommitteeAssignmentContainer, map[types.ValidatorIndex][]types.Slot, error)

CommitteeAssignments is a map of validator indices pointing to the appropriate committee assignment for the given epoch.

1. Determine the proposer validator index for each slot. 2. Compute all committees. 3. Determine the attesting slot for each committee. 4. Construct a map of validator indices pointing to the respective committees.

func ComputeCommittee

func ComputeCommittee(
	indices []types.ValidatorIndex,
	seed [32]byte,
	index, count uint64,
) ([]types.ValidatorIndex, error)

ComputeCommittee returns the requested shuffled committee out of the total committees using validator indices and seed.

Spec pseudocode definition:

def compute_committee(indices: Sequence[ValidatorIndex],
                    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) * uint64(index + 1)) // count
  return [indices[compute_shuffled_index(uint64(i), uint64(len(indices)), seed)] for i in range(start, end)]

func ComputeDomain added in v1.0.0

func ComputeDomain(domainType [DomainByteLength]byte, forkVersion, genesisValidatorsRoot []byte) ([]byte, error)

ComputeDomain returns the domain version for BLS private key to sign and verify with a zeroed 4-byte array as the fork version.

def compute_domain(domain_type: DomainType, fork_version: Version=None, genesis_validators_root: Root=None) -> Domain:

"""
Return the domain for the ``domain_type`` and ``fork_version``.
"""
if fork_version is None:
    fork_version = GENESIS_FORK_VERSION
if genesis_validators_root is None:
    genesis_validators_root = Root()  # all bytes zero by default
fork_data_root = compute_fork_data_root(fork_version, genesis_validators_root)
return Domain(domain_type + fork_data_root[:28])

func ComputeDomainAndSign added in v1.0.0

func ComputeDomainAndSign(st iface.ReadOnlyBeaconState, epoch types.Epoch, obj fssz.HashRoot, domain [4]byte, key bls.SecretKey) ([]byte, error)

ComputeDomainAndSign computes the domain and signing root and sign it using the passed in private key.

func ComputeDomainVerifySigningRoot added in v1.0.0

func ComputeDomainVerifySigningRoot(st iface.BeaconState, index types.ValidatorIndex, epoch types.Epoch, obj fssz.HashRoot, domain [4]byte, sig []byte) error

ComputeDomainVerifySigningRoot computes domain and verifies signing root of an object given the beacon state, validator index and signature.

func ComputeForkDigest added in v1.0.0

func ComputeForkDigest(version, genesisValidatorsRoot []byte) ([4]byte, error)

ComputeForkDigest returns the fork for the current version and genesis validator root

Spec pseudocode definition:

	def compute_fork_digest(current_version: Version, genesis_validators_root: Root) -> ForkDigest:
   """
   Return the 4-byte fork digest for the ``current_version`` and ``genesis_validators_root``.
   This is a digest primarily used for domain separation on the p2p layer.
   4-bytes suffices for practical separation of forks/chains.
   """
   return ForkDigest(compute_fork_data_root(current_version, genesis_validators_root)[:4])

func ComputeProposerIndex added in v0.2.3

func ComputeProposerIndex(bState iface.ReadOnlyValidators, activeIndices []types.ValidatorIndex, seed [32]byte) (types.ValidatorIndex, error)

ComputeProposerIndex returns the index sampled by effective balance, which is used to calculate proposer.

Spec pseudocode definition:

def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Bytes32) -> ValidatorIndex:
  """
  Return from ``indices`` a random index sampled by effective balance.
  """
  assert len(indices) > 0
  MAX_RANDOM_BYTE = 2**8 - 1
  i = uint64(0)
  total = uint64(len(indices))
  while True:
      candidate_index = indices[compute_shuffled_index(i % total, total, seed)]
      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:
          return candidate_index
      i += 1

func ComputeShuffledIndex added in v0.2.3

func ComputeShuffledIndex(index types.ValidatorIndex, indexCount uint64, seed [32]byte, shuffle bool) (types.ValidatorIndex, error)

ComputeShuffledIndex returns the shuffled validator index corresponding to seed and index count. Spec pseudocode definition:

def compute_shuffled_index(index: uint64, index_count: uint64, seed: Bytes32) -> uint64:
 """
 Return the shuffled index corresponding to ``seed`` (and ``index_count``).
 """
 assert index < index_count

 # Swap or not (https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf)
 # See the 'generalized domain' algorithm on page 3
 for current_round in range(SHUFFLE_ROUND_COUNT):
     pivot = bytes_to_uint64(hash(seed + uint_to_bytes(uint8(current_round)))[0:8]) % index_count
     flip = (pivot + index_count - index) % index_count
     position = max(index, flip)
     source = hash(
         seed
         + uint_to_bytes(uint8(current_round))
         + uint_to_bytes(uint32(position // 256))
     )
     byte = uint8(source[(position % 256) // 8])
     bit = (byte >> (position % 8)) % 2
     index = flip if bit else index

 return index

func ComputeSigningRoot added in v1.0.0

func ComputeSigningRoot(object fssz.HashRoot, domain []byte) ([32]byte, error)

ComputeSigningRoot computes the root of the object by calculating the hash tree root of the signing data with the given domain.

Spec pseudocode definition:

	def compute_signing_root(ssz_object: SSZObject, domain: Domain) -> Root:
   """
   Return the signing root for the corresponding signing data.
   """
   return hash_tree_root(SigningData(
       object_root=hash_tree_root(ssz_object),
       domain=domain,
   ))

func ComputeSubnetForAttestation added in v1.0.0

func ComputeSubnetForAttestation(activeValCount uint64, att *ethpb.Attestation) uint64

ComputeSubnetForAttestation returns the subnet for which the provided attestation will be broadcasted to. This differs from the spec definition by instead passing in the active validators indices in the attestation's given epoch.

Spec pseudocode definition: def compute_subnet_for_attestation(committees_per_slot: uint64, slot: Slot, committee_index: CommitteeIndex) -> uint64:

"""
Compute the correct subnet for an attestation for Phase 0.
Note, this mimics expected future behavior where attestations will be mapped to their shard subnet.
"""
slots_since_epoch_start = uint64(slot % SLOTS_PER_EPOCH)
committees_since_epoch_start = committees_per_slot * slots_since_epoch_start

return uint64((committees_since_epoch_start + committee_index) % ATTESTATION_SUBNET_COUNT)

func ComputeSubnetFromCommitteeAndSlot added in v1.0.0

func ComputeSubnetFromCommitteeAndSlot(activeValCount uint64, comIdx types.CommitteeIndex, attSlot types.Slot) uint64

ComputeSubnetFromCommitteeAndSlot is a flattened version of ComputeSubnetForAttestation where we only pass in the relevant fields from the attestation as function arguments.

Spec pseudocode definition: def compute_subnet_for_attestation(committees_per_slot: uint64, slot: Slot, committee_index: CommitteeIndex) -> uint64:

"""
Compute the correct subnet for an attestation for Phase 0.
Note, this mimics expected future behavior where attestations will be mapped to their shard subnet.
"""
slots_since_epoch_start = uint64(slot % SLOTS_PER_EPOCH)
committees_since_epoch_start = committees_per_slot * slots_since_epoch_start

return uint64((committees_since_epoch_start + committee_index) % ATTESTATION_SUBNET_COUNT)

func ComputeWeakSubjectivityPeriod added in v1.3.6

func ComputeWeakSubjectivityPeriod(st iface.ReadOnlyBeaconState) (types.Epoch, error)

ComputeWeakSubjectivityPeriod returns weak subjectivity period for the active validator count and finalized epoch.

Reference spec implementation: https://github.com/ethereum/eth2.0-specs/blob/master/specs/phase0/weak-subjectivity.md#calculating-the-weak-subjectivity-period

def compute_weak_subjectivity_period(state: BeaconState) -> uint64:

"""
Returns the weak subjectivity period for the current ``state``.
This computation takes into account the effect of:
    - validator set churn (bounded by ``get_validator_churn_limit()`` per epoch), and
    - validator balance top-ups (bounded by ``MAX_DEPOSITS * SLOTS_PER_EPOCH`` per epoch).
A detailed calculation can be found at:
https://github.com/runtimeverification/beacon-chain-verification/blob/master/weak-subjectivity/weak-subjectivity-analysis.pdf
"""
ws_period = MIN_VALIDATOR_WITHDRAWABILITY_DELAY
N = len(get_active_validator_indices(state, get_current_epoch(state)))
t = get_total_active_balance(state) // N // ETH_TO_GWEI
T = MAX_EFFECTIVE_BALANCE // ETH_TO_GWEI
delta = get_validator_churn_limit(state)
Delta = MAX_DEPOSITS * SLOTS_PER_EPOCH
D = SAFETY_DECAY

if T * (200 + 3 * D) < t * (200 + 12 * D):
    epochs_for_validator_set_churn = (
        N * (t * (200 + 12 * D) - T * (200 + 3 * D)) // (600 * delta * (2 * t + T))
    )
    epochs_for_balance_top_ups = (
        N * (200 + 3 * D) // (600 * Delta)
    )
    ws_period += max(epochs_for_validator_set_churn, epochs_for_balance_top_ups)
else:
    ws_period += (
        3 * N * D * t // (200 * Delta * (T - t))
    )

return ws_period

func CurrentEpoch

func CurrentEpoch(state iface.ReadOnlyBeaconState) types.Epoch

CurrentEpoch returns the current epoch number calculated from the slot number stored in beacon state.

Spec pseudocode definition:

def get_current_epoch(state: BeaconState) -> Epoch:
  """
  Return the current epoch.
  """
  return compute_epoch_at_slot(state.slot)

func CurrentSlot added in v1.0.0

func CurrentSlot(genesisTimeSec uint64) types.Slot

CurrentSlot returns the current slot as determined by the local clock and provided genesis time.

func DecreaseBalance

func DecreaseBalance(state iface.BeaconState, idx types.ValidatorIndex, delta uint64) error

DecreaseBalance decreases validator with the given 'index' balance by 'delta' in Gwei.

Spec pseudocode definition:

def decrease_balance(state: BeaconState, index: ValidatorIndex, delta: Gwei) -> None:
  """
  Decrease the validator balance at index ``index`` by ``delta``, with underflow protection.
  """
  state.balances[index] = 0 if delta > state.balances[index] else state.balances[index] - delta

func DecreaseBalanceWithVal added in v1.0.0

func DecreaseBalanceWithVal(currBalance, delta uint64) uint64

DecreaseBalanceWithVal decreases validator with the given 'index' balance by 'delta' in Gwei. This method is flattened version of the spec method, taking in the raw balance and returning the post balance.

Spec pseudocode definition:

def decrease_balance(state: BeaconState, index: ValidatorIndex, delta: Gwei) -> None:
  """
  Decrease the validator balance at index ``index`` by ``delta``, with underflow protection.
  """
  state.balances[index] = 0 if delta > state.balances[index] else state.balances[index] - delta

func Domain

func Domain(fork *pb.Fork, epoch types.Epoch, domainType [bls.DomainByteLength]byte, genesisRoot []byte) ([]byte, error)

Domain returns the domain version for BLS private key to sign and verify.

Spec pseudocode definition:

def get_domain(state: BeaconState, domain_type: DomainType, epoch: Epoch=None) -> Domain:
  """
  Return the signature domain (fork version concatenated with domain type) of a message.
  """
  epoch = get_current_epoch(state) if epoch is None else epoch
  fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version
  return compute_domain(domain_type, fork_version, state.genesis_validators_root)

func EndSlot added in v1.0.0

func EndSlot(epoch types.Epoch) (types.Slot, error)

EndSlot returns the last slot number of the current epoch.

func FinalityDelay added in v1.3.7

func FinalityDelay(prevEpoch, finalizedEpoch types.Epoch) types.Epoch

FinalityDelay returns the finality delay using the beacon state.

Spec code: def get_finality_delay(state: BeaconState) -> uint64:

return get_previous_epoch(state) - state.finalized_checkpoint.epoch

func IncreaseBalance

func IncreaseBalance(state iface.BeaconState, idx types.ValidatorIndex, delta uint64) error

IncreaseBalance increases validator with the given 'index' balance by 'delta' in Gwei.

Spec pseudocode definition:

def increase_balance(state: BeaconState, index: ValidatorIndex, delta: Gwei) -> None:
  """
  Increase the validator balance at index ``index`` by ``delta``.
  """
  state.balances[index] += delta

func IncreaseBalanceWithVal added in v1.0.0

func IncreaseBalanceWithVal(currBalance, delta uint64) uint64

IncreaseBalanceWithVal increases validator with the given 'index' balance by 'delta' in Gwei. This method is flattened version of the spec method, taking in the raw balance and returning the post balance.

Spec pseudocode definition:

def increase_balance(state: BeaconState, index: ValidatorIndex, delta: Gwei) -> None:
  """
  Increase the validator balance at index ``index`` by ``delta``.
  """
  state.balances[index] += delta

func IsActiveValidator

func IsActiveValidator(validator *ethpb.Validator, epoch types.Epoch) bool

IsActiveValidator returns the boolean value on whether the validator is active or not.

Spec pseudocode definition:

def is_active_validator(validator: Validator, epoch: Epoch) -> bool:
  """
  Check if ``validator`` is active.
  """
  return validator.activation_epoch <= epoch < validator.exit_epoch

func IsActiveValidatorUsingTrie added in v0.3.2

func IsActiveValidatorUsingTrie(validator iface.ReadOnlyValidator, epoch types.Epoch) bool

IsActiveValidatorUsingTrie checks if a read only validator is active.

func IsAggregated added in v0.3.0

func IsAggregated(attestation *ethpb.Attestation) bool

IsAggregated returns true if the attestation is an aggregated attestation, false otherwise.

func IsAggregator added in v0.2.5

func IsAggregator(committeeCount uint64, slotSig []byte) (bool, error)

IsAggregator returns true if the signature is from the input validator. The committee count is provided as an argument rather than imported implementation from spec. Having committee count as an argument allows cheaper computation at run time.

Spec pseudocode definition:

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_uint64(hash(slot_signature)[0:8]) % modulo == 0

func IsEligibleForActivation added in v0.3.0

func IsEligibleForActivation(state iface.ReadOnlyCheckpoint, validator *ethpb.Validator) bool

IsEligibleForActivation checks if the validator is eligible for activation.

Spec pseudocode definition:

def is_eligible_for_activation(state: BeaconState, validator: Validator) -> bool:
  """
  Check if ``validator`` is eligible for activation.
  """
  return (
      # Placement in queue is finalized
      validator.activation_eligibility_epoch <= state.finalized_checkpoint.epoch
      # Has not yet been activated
      and validator.activation_epoch == FAR_FUTURE_EPOCH
  )

func IsEligibleForActivationQueue added in v0.3.0

func IsEligibleForActivationQueue(validator *ethpb.Validator) bool

IsEligibleForActivationQueue checks if the validator is eligible to be placed into the activation queue.

Spec pseudocode definition:

def is_eligible_for_activation_queue(validator: Validator) -> bool:
  """
  Check if ``validator`` is eligible to be placed into the activation queue.
  """
  return (
      validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH
      and validator.effective_balance == MAX_EFFECTIVE_BALANCE
  )

func IsEligibleForActivationQueueUsingTrie added in v0.3.2

func IsEligibleForActivationQueueUsingTrie(validator iface.ReadOnlyValidator) bool

IsEligibleForActivationQueueUsingTrie checks if the read-only validator is eligible to be placed into the activation queue.

func IsEligibleForActivationUsingTrie added in v0.3.2

func IsEligibleForActivationUsingTrie(state iface.ReadOnlyCheckpoint, validator iface.ReadOnlyValidator) bool

IsEligibleForActivationUsingTrie checks if the validator is eligible for activation.

func IsEpochEnd

func IsEpochEnd(slot types.Slot) bool

IsEpochEnd returns true if the given slot number is an epoch ending slot number.

func IsEpochStart

func IsEpochStart(slot types.Slot) bool

IsEpochStart returns true if the given slot number is an epoch starting slot number.

func IsInInactivityLeak added in v1.3.7

func IsInInactivityLeak(prevEpoch, finalizedEpoch types.Epoch) bool

IsInInactivityLeak returns true if the state is experiencing inactivity leak.

Spec code: def is_in_inactivity_leak(state: BeaconState) -> bool:

return get_finality_delay(state) > MIN_EPOCHS_TO_INACTIVITY_PENALTY

func IsSlashableValidator

func IsSlashableValidator(activationEpoch, withdrawableEpoch types.Epoch, slashed bool, epoch types.Epoch) bool

IsSlashableValidator returns the boolean value on whether the validator is slashable or not.

Spec pseudocode definition:

def is_slashable_validator(validator: Validator, epoch: Epoch) -> bool:
"""
Check if ``validator`` is slashable.
"""
return (not validator.slashed) and (validator.activation_epoch <= epoch < validator.withdrawable_epoch)

func IsSlashableValidatorUsingTrie added in v1.0.0

func IsSlashableValidatorUsingTrie(val iface.ReadOnlyValidator, epoch types.Epoch) bool

IsSlashableValidatorUsingTrie checks if a read only validator is slashable.

func IsWithinWeakSubjectivityPeriod added in v1.3.7

func IsWithinWeakSubjectivityPeriod(
	currentEpoch types.Epoch, wsState iface.ReadOnlyBeaconState, wsCheckpoint *eth.WeakSubjectivityCheckpoint) (bool, error)

IsWithinWeakSubjectivityPeriod verifies if a given weak subjectivity checkpoint is not stale i.e. the current node is so far beyond, that a given state and checkpoint are not for the latest weak subjectivity point. Provided checkpoint still can be used to double-check that node's block root at a given epoch matches that of the checkpoint.

Reference implementation: https://github.com/ethereum/eth2.0-specs/blob/master/specs/phase0/weak-subjectivity.md#checking-for-stale-weak-subjectivity-checkpoint

def is_within_weak_subjectivity_period(store: Store, ws_state: BeaconState, ws_checkpoint: Checkpoint) -> bool:

# Clients may choose to validate the input state against the input Weak Subjectivity Checkpoint
assert ws_state.latest_block_header.state_root == ws_checkpoint.root
assert compute_epoch_at_slot(ws_state.slot) == ws_checkpoint.epoch

ws_period = compute_weak_subjectivity_period(ws_state)
ws_state_epoch = compute_epoch_at_slot(ws_state.slot)
current_epoch = compute_epoch_at_slot(get_current_slot(store))
return current_epoch <= ws_state_epoch + ws_period

func LatestWeakSubjectivityEpoch added in v1.3.7

func LatestWeakSubjectivityEpoch(st iface.ReadOnlyBeaconState) (types.Epoch, error)

LatestWeakSubjectivityEpoch returns epoch of the most recent weak subjectivity checkpoint known to a node.

Within the weak subjectivity period, if two conflicting blocks are finalized, 1/3 - D (D := safety decay) of validators will get slashed. Therefore, it is safe to assume that any finalized checkpoint within that period is protected by this safety margin.

func NextEpoch

func NextEpoch(state iface.ReadOnlyBeaconState) types.Epoch

NextEpoch returns the next epoch number calculated from the slot number stored in beacon state.

func ParseWeakSubjectivityInputString added in v1.3.7

func ParseWeakSubjectivityInputString(wsCheckpointString string) (*eth.Checkpoint, error)

ParseWeakSubjectivityInputString parses "blocks_root:epoch_number" string into a checkpoint.

func PrevEpoch

func PrevEpoch(state iface.ReadOnlyBeaconState) types.Epoch

PrevEpoch returns the previous epoch number calculated from the slot number stored in beacon state. It also checks for underflow condition.

Spec pseudocode definition:

def get_previous_epoch(state: BeaconState) -> Epoch:
  """`
  Return the previous epoch (unless the current epoch is ``GENESIS_EPOCH``).
  """
  current_epoch = get_current_epoch(state)
  return GENESIS_EPOCH if current_epoch == GENESIS_EPOCH else Epoch(current_epoch - 1)

func PrevSlot added in v1.3.10

func PrevSlot(slot types.Slot) types.Slot

PrevSlot returns previous slot, with an exception in slot 0 to prevent underflow.

func RandaoMix

func RandaoMix(state iface.ReadOnlyBeaconState, epoch types.Epoch) ([]byte, error)

RandaoMix returns the randao mix (xor'ed seed) of a given slot. It is used to shuffle validators.

Spec pseudocode definition:

def get_randao_mix(state: BeaconState, epoch: Epoch) -> Bytes32:
 """
 Return the randao mix at a recent ``epoch``.
 """
 return state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR]

func RoundUpToNearestEpoch added in v0.3.2

func RoundUpToNearestEpoch(slot types.Slot) types.Slot

RoundUpToNearestEpoch rounds up the provided slot value to the nearest epoch.

func Seed

func Seed(state iface.ReadOnlyBeaconState, epoch types.Epoch, domain [bls.DomainByteLength]byte) ([32]byte, error)

Seed returns the randao seed used for shuffling of a given epoch.

Spec pseudocode definition:

def get_seed(state: BeaconState, epoch: Epoch, domain_type: DomainType) -> Bytes32:
  """
  Return the seed at ``epoch``.
  """
  mix = get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD - 1))  # Avoid underflow
  return hash(domain_type + uint_to_bytes(epoch) + mix)

func ShuffleList

func ShuffleList(input []types.ValidatorIndex, seed [32]byte) ([]types.ValidatorIndex, error)

ShuffleList returns list of shuffled indexes in a pseudorandom permutation `p` of `0...list_size - 1` with “seed“ as entropy. We utilize 'swap or not' shuffling in this implementation; we are allocating the memory with the seed that stays constant between iterations instead of reallocating it each iteration as in the spec. This implementation is based on the original implementation from protolambda, https://github.com/protolambda/eth2-shuffle

improvements:
 - seed is always the first 32 bytes of the hash input, we just copy it into the buffer one time.
 - add round byte to seed and hash that part of the buffer.
 - split up the for-loop in two:
  1. Handle the part from 0 (incl) to pivot (incl). This is mirrored around (pivot / 2).
  2. Handle the part from pivot (excl) to N (excl). This is mirrored around ((pivot / 2) + (size/2)).
 - hash source every 256 iterations.
 - change byteV every 8 iterations.
 - we start at the edges, and work back to the mirror point.
   this makes us process each pear exactly once (instead of unnecessarily twice, like in the spec).

func ShuffledIndex

func ShuffledIndex(index types.ValidatorIndex, indexCount uint64, seed [32]byte) (types.ValidatorIndex, error)

ShuffledIndex returns `p(index)` in a pseudorandom permutation `p` of `0...list_size - 1` with “seed“ as entropy. We utilize 'swap or not' shuffling in this implementation; we are allocating the memory with the seed that stays constant between iterations instead of reallocating it each iteration as in the spec. This implementation is based on the original implementation from protolambda, https://github.com/protolambda/eth2-shuffle

func ShuffledIndices

func ShuffledIndices(state iface.ReadOnlyBeaconState, epoch types.Epoch) ([]types.ValidatorIndex, error)

ShuffledIndices uses input beacon state and returns the shuffled indices of the input epoch, the shuffled indices then can be used to break up into committees.

func SlotCommitteeCount added in v0.3.0

func SlotCommitteeCount(activeValidatorCount uint64) uint64

SlotCommitteeCount returns the number of crosslink committees of a slot. The active validator count is provided as an argument rather than a imported implementation from the spec definition. Having the active validator count as an argument allows for cheaper computation, instead of retrieving head state, one can retrieve the validator count.

Spec pseudocode definition:

def get_committee_count_per_slot(state: BeaconState, epoch: Epoch) -> uint64:
 """
 Return the number of committees in each slot for the given ``epoch``.
 """
 return max(uint64(1), min(
     MAX_COMMITTEES_PER_SLOT,
     uint64(len(get_active_validator_indices(state, epoch))) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
 ))

func SlotToEpoch

func SlotToEpoch(slot types.Slot) types.Epoch

SlotToEpoch returns the epoch number of the input slot.

Spec pseudocode definition:

def compute_epoch_at_slot(slot: Slot) -> Epoch:
  """
  Return the epoch number at ``slot``.
  """
  return Epoch(slot // SLOTS_PER_EPOCH)

func SlotToTime added in v1.0.0

func SlotToTime(genesisTimeSec uint64, slot types.Slot) (time.Time, error)

SlotToTime takes the given slot and genesis time to determine the start time of the slot.

func SlotsSince added in v0.3.0

func SlotsSince(time time.Time) types.Slot

SlotsSince computes the number of time slots that have occurred since the given timestamp.

func SlotsSinceEpochStarts added in v0.3.0

func SlotsSinceEpochStarts(slot types.Slot) types.Slot

SlotsSinceEpochStarts returns number of slots since the start of the epoch.

func SplitIndices

func SplitIndices(l []uint64, n uint64) [][]uint64

SplitIndices splits a list into n pieces.

func StartSlot

func StartSlot(epoch types.Epoch) (types.Slot, error)

StartSlot returns the first slot number of the current epoch.

Spec pseudocode definition:

def compute_start_slot_at_epoch(epoch: Epoch) -> Slot:
  """
  Return the start slot of ``epoch``.
  """
  return Slot(epoch * SLOTS_PER_EPOCH)

func StateRootAtSlot added in v1.0.0

func StateRootAtSlot(state iface.ReadOnlyBeaconState, slot types.Slot) ([]byte, error)

StateRootAtSlot returns the cached state root at that particular slot. If no state root has been cached it will return a zero-hash.

func TotalActiveBalance

func TotalActiveBalance(state iface.ReadOnlyBeaconState) (uint64, error)

TotalActiveBalance returns the total amount at stake in Gwei of active validators.

Spec pseudocode definition:

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 TotalBalance

func TotalBalance(state iface.ReadOnlyValidators, indices []types.ValidatorIndex) uint64

TotalBalance returns the total amount at stake in Gwei of input validators.

Spec pseudocode definition:

def get_total_balance(state: BeaconState, indices: Set[ValidatorIndex]) -> Gwei:
 """
 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 UnShuffledIndex

func UnShuffledIndex(index types.ValidatorIndex, indexCount uint64, seed [32]byte) (types.ValidatorIndex, error)

UnShuffledIndex returns the inverse of ShuffledIndex. This implementation is based on the original implementation from protolambda, https://github.com/protolambda/eth2-shuffle

func UnshuffleList

func UnshuffleList(input []types.ValidatorIndex, seed [32]byte) ([]types.ValidatorIndex, error)

UnshuffleList un-shuffles the list by running backwards through the round count.

func UpdateCommitteeCache

func UpdateCommitteeCache(state iface.ReadOnlyBeaconState, epoch types.Epoch) error

UpdateCommitteeCache gets called at the beginning of every epoch to cache the committee shuffled indices list with committee index and epoch number. It caches the shuffled indices for current epoch and next epoch.

func UpdateGenesisEth1Data added in v1.4.1

func UpdateGenesisEth1Data(state iface.BeaconState, deposits []*ethpb.Deposit, eth1Data *ethpb.Eth1Data) (iface.BeaconState, error)

UpdateGenesisEth1Data updates eth1 data for genesis state.

func UpdateProposerIndicesInCache added in v0.3.2

func UpdateProposerIndicesInCache(state iface.ReadOnlyBeaconState) error

UpdateProposerIndicesInCache updates proposer indices entry of the committee cache.

func ValidateAttestationTime added in v1.0.0

func ValidateAttestationTime(attSlot types.Slot, genesisTime time.Time, clockDisparity time.Duration) error

ValidateAttestationTime Validates that the incoming attestation is in the desired time range. An attestation is valid only if received within the last ATTESTATION_PROPAGATION_SLOT_RANGE slots.

Example:

ATTESTATION_PROPAGATION_SLOT_RANGE = 5
clockDisparity = 24 seconds
current_slot = 100
invalid_attestation_slot = 92
invalid_attestation_slot = 103
valid_attestation_slot = 98
valid_attestation_slot = 101

In the attestation must be within the range of 95 to 102 in the example above.

func ValidateNilAttestation added in v1.1.0

func ValidateNilAttestation(attestation *ethpb.Attestation) error

ValidateNilAttestation checks if any composite field of input attestation is nil. Access to these nil fields will result in run time panic, it is recommended to run these checks as first line of defense.

func ValidateSlotClock added in v1.0.0

func ValidateSlotClock(slot types.Slot, genesisTimeSec uint64) error

ValidateSlotClock validates a provided slot against the local clock to ensure slots that are unreasonable are returned with an error.

func ValidateSlotTargetEpoch added in v1.2.0

func ValidateSlotTargetEpoch(data *ethpb.AttestationData) error

ValidateSlotTargetEpoch checks if attestation data's epoch matches target checkpoint's epoch. It is recommended to run `ValidateNilAttestation` first to ensure `data.Target` can't be nil.

func ValidatorChurnLimit

func ValidatorChurnLimit(activeValidatorCount uint64) (uint64, error)

ValidatorChurnLimit returns the number of validators that are allowed to enter and exit validator pool for an epoch.

Spec pseudocode definition:

def get_validator_churn_limit(state: BeaconState) -> uint64:
 """
 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, uint64(len(active_validator_indices)) // CHURN_LIMIT_QUOTIENT)

func VerifyAttestationBitfieldLengths

func VerifyAttestationBitfieldLengths(state iface.ReadOnlyBeaconState, att *ethpb.Attestation) error

VerifyAttestationBitfieldLengths verifies that an attestations aggregation bitfields is a valid length matching the size of the committee.

func VerifyBitfieldLength

func VerifyBitfieldLength(bf bitfield.Bitfield, committeeSize uint64) error

VerifyBitfieldLength verifies that a bitfield length matches the given committee size.

func VerifyBlockHeaderSigningRoot added in v1.0.0

func VerifyBlockHeaderSigningRoot(blkHdr *ethpb.BeaconBlockHeader, pub, signature, domain []byte) error

VerifyBlockHeaderSigningRoot verifies the signing root of a block header given it's public key, signature and domain.

func VerifyBlockSigningRoot added in v1.0.0

func VerifyBlockSigningRoot(pub, signature, domain []byte, rootFunc func() ([32]byte, error)) error

VerifyBlockSigningRoot verifies the signing root of a block given it's public key, signature and domain.

func VerifyCheckpointEpoch added in v1.0.0

func VerifyCheckpointEpoch(c *ethpb.Checkpoint, genesis time.Time) bool

VerifyCheckpointEpoch is within current epoch and previous epoch with respect to current time. Returns true if it's within, false if it's not.

func VerifyNilBeaconBlock added in v1.2.2

func VerifyNilBeaconBlock(b interfaces.SignedBeaconBlock) error

VerifyNilBeaconBlock checks if any composite field of input signed beacon block is nil. Access to these nil fields will result in run time panic, it is recommended to run these checks as first line of defense.

func VerifySigningRoot added in v1.0.0

func VerifySigningRoot(obj fssz.HashRoot, pub, signature, domain []byte) error

VerifySigningRoot verifies the signing root of an object given it's public key, signature and domain.

func VerifySlotTime

func VerifySlotTime(genesisTime uint64, slot types.Slot, timeTolerance time.Duration) error

VerifySlotTime validates the input slot is not from the future.

func VotingPeriodStartTime added in v1.0.0

func VotingPeriodStartTime(genesis uint64, slot types.Slot) uint64

VotingPeriodStartTime returns the current voting period's start time depending on the provided genesis and current slot.

Types

type CommitteeAssignmentContainer added in v0.3.0

type CommitteeAssignmentContainer struct {
	Committee      []types.ValidatorIndex
	AttesterSlot   types.Slot
	CommitteeIndex types.CommitteeIndex
}

CommitteeAssignmentContainer represents a committee, index, and attester slot for a given epoch.

Jump to

Keyboard shortcuts

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