def test_randao_reveal_validation( is_valid, epoch, expected_epoch, proposer_key_index, expected_proposer_key_index, privkeys, pubkeys, sample_fork_params, genesis_state, config, ): state = genesis_state.set( "slot", compute_start_slot_at_epoch(epoch, config.SLOTS_PER_EPOCH)) slots_per_epoch = config.SLOTS_PER_EPOCH domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, slots_per_epoch) signing_root = compute_signing_root(SerializableUint64(epoch), domain) proposer_privkey = privkeys[proposer_key_index] randao_reveal = bls.sign(proposer_privkey, signing_root) try: validate_randao_reveal( state=state, proposer_index=expected_proposer_key_index, epoch=expected_epoch, randao_reveal=randao_reveal, slots_per_epoch=slots_per_epoch, ) except ValidationError: if is_valid: raise else: if not is_valid: pytest.fail("Did not raise")
def get_slot_signature( state: BeaconState, slot: Slot, privkey: int, config: Eth2Config ) -> BLSSignature: """ Sign on ``slot`` and return the signature. """ domain = get_domain( state, SignatureDomain.DOMAIN_BEACON_ATTESTER, config.SLOTS_PER_EPOCH, message_epoch=compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH), ) signing_root = compute_signing_root(SerializableUint64(slot), domain) return bls.sign(privkey, signing_root)
def validate_aggregator_proof( state: BeaconState, aggregate_and_proof: AggregateAndProof, config: Eth2Config ) -> None: slot = aggregate_and_proof.aggregate.data.slot pubkey = state.validators[aggregate_and_proof.aggregator_index].pubkey domain = get_domain( state, SignatureDomain.DOMAIN_BEACON_ATTESTER, config.SLOTS_PER_EPOCH, message_epoch=compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH), ) signing_root = compute_signing_root(SerializableUint64(slot), domain) bls.validate(signing_root, aggregate_and_proof.selection_proof, pubkey)
def generate_randao_reveal(privkey: int, slot: Slot, state: BeaconState, config: Eth2Config) -> BLSSignature: """ Return the RANDAO reveal for the validator represented by ``privkey``. The current implementation requires a validator to provide the BLS signature over the SSZ-serialized epoch in which they are proposing a block. """ epoch = compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH) randao_reveal = sign_transaction( object=SerializableUint64(epoch), privkey=privkey, state=state, slot=slot, signature_domain=SignatureDomain.DOMAIN_RANDAO, slots_per_epoch=config.SLOTS_PER_EPOCH, ) return randao_reveal
def _randao_provider_of_epoch_signature( public_key: BLSPubkey, epoch: Epoch ) -> BLSSignature: privkey = private_key_provider(public_key) # NOTE: hardcoded for testing, based on generating the minimal set of validators genesis_validators_root = Root( Hash32( bytes.fromhex( "83431ec7fcf92cfc44947fc0418e831c25e1d0806590231c439830db7ad54fda" ) ) ) domain = compute_domain( SignatureDomain.DOMAIN_RANDAO, genesis_validators_root=genesis_validators_root, ) signing_root = compute_signing_root(SerializableUint64(epoch), domain) return bls.sign(privkey, signing_root)
def validate_randao_reveal( state: BeaconState, proposer_index: int, epoch: Epoch, randao_reveal: BLSSignature, slots_per_epoch: int, ) -> None: proposer = state.validators[proposer_index] proposer_pubkey = proposer.pubkey domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, slots_per_epoch) signing_root = compute_signing_root(SerializableUint64(epoch), domain) try: bls.validate(signing_root, randao_reveal, proposer_pubkey) except SignatureError as error: raise ValidationError( f"RANDAO reveal is invalid for proposer index {proposer_index} at slot {state.slot}", error, )
def _randao_provider_of_epoch_signature(public_key: BLSPubkey, epoch: Epoch) -> BLSSignature: privkey = private_key_provider(public_key) domain = compute_domain(SignatureDomain.DOMAIN_RANDAO) signing_root = compute_signing_root(SerializableUint64(epoch), domain) return bls.sign(privkey, signing_root)