def generate_seed(state: 'BeaconState', epoch: EpochNumber, epoch_length: int, seed_lookahead: int, entry_exit_delay: int, latest_index_roots_length: int, latest_randao_mixes_length: int) -> Hash32: """ Generate a seed for the given ``epoch``. """ randao_mix = get_randao_mix( state=state, epoch=EpochNumber(epoch - seed_lookahead), epoch_length=epoch_length, latest_randao_mixes_length=latest_randao_mixes_length, ) active_index_root = get_active_index_root( state=state, epoch=epoch, epoch_length=epoch_length, entry_exit_delay=entry_exit_delay, latest_index_roots_length=latest_index_roots_length, ) epoch_as_bytes = epoch.to_bytes(32, byteorder="little") return hash_eth2(randao_mix + active_index_root + epoch_as_bytes)
def get_shuffling(*, seed: Hash32, validators: Sequence['ValidatorRecord'], epoch: EpochNumber, epoch_length: int, target_committee_size: int, shard_count: int) -> Tuple[Iterable[ValidatorIndex], ...]: """ Shuffle ``validators`` into crosslink committees seeded by ``seed`` and ``epoch``. Return a list of ``committee_per_epoch`` committees where each committee is itself a list of validator indices. If ``get_shuffling(seed, validators, epoch)`` returns some value ``x`` for some ``epoch <= get_current_epoch(state) + ENTRY_EXIT_DELAY``, it should return the same value ``x`` for the same ``seed`` and ``epoch`` and possible future modifications of ``validators`` forever in phase 0, and until the ~1 year deletion delay in phase 2 and in the future. """ active_validator_indices = get_active_validator_indices(validators, epoch) committees_per_epoch = get_epoch_committee_count( len(active_validator_indices), shard_count, epoch_length, target_committee_size, ) # Shuffle seed = bitwise_xor(seed, Hash32(epoch.to_bytes(32, byteorder="big"))) shuffled_active_validator_indices = shuffle(active_validator_indices, seed) # Split the shuffled list into committees_per_epoch pieces return tuple( split( shuffled_active_validator_indices, committees_per_epoch, ))
def validate_randao_reveal(randao_reveal: BLSSignature, proposer_pubkey: BLSPubkey, epoch: EpochNumber, fork: Fork) -> None: message = epoch.to_bytes(32, byteorder="big") domain = get_domain(fork, epoch, SignatureDomain.DOMAIN_RANDAO) is_randao_reveal_valid = bls.verify( pubkey=proposer_pubkey, message=message, signature=randao_reveal, domain=domain, ) if not is_randao_reveal_valid: raise ValidationError( f"RANDAO reveal is invalid. " f"reveal={randao_reveal}, proposer_pubkey={proposer_pubkey}, message={message}, " f"domain={domain}")