def validate_serenity_proposer_signature( state: BeaconState, block: BaseBeaconBlock, beacon_chain_shard_number: ShardNumber, epoch_length: int) -> None: block_without_signature_root = block.block_without_signature_root # TODO: Replace this root with tree hash root proposal_root = ProposalSignedData( state.slot, beacon_chain_shard_number, block_without_signature_root, ).root # Get the public key of proposer beacon_proposer_index = get_beacon_proposer_index(state, state.slot, epoch_length) proposer_pubkey = state.validator_registry[beacon_proposer_index].pubkey is_valid_signature = bls.verify( pubkey=proposer_pubkey, message=proposal_root, signature=block.signature, domain=get_domain(state.fork_data, state.slot, SignatureDomain.DOMAIN_PROPOSAL), ) if not is_valid_signature: raise ValidationError("Invalid Proposer Signature on block")
def test_get_beacon_proposer_index( monkeypatch, num_validators, cycle_length, committee, slot, success, epoch_length, sample_state): from eth.beacon import helpers def mock_get_shard_committees_at_slot(state, slot, epoch_length): return ( ShardCommittee( shard=1, committee=committee, total_validator_count=num_validators, ), ) monkeypatch.setattr( helpers, 'get_shard_committees_at_slot', mock_get_shard_committees_at_slot ) if success: proposer_index = get_beacon_proposer_index( sample_state, slot, epoch_length ) assert proposer_index == committee[slot % len(committee)] else: with pytest.raises(ValidationError): get_beacon_proposer_index( sample_state, slot, epoch_length )
def test_demo(base_db, sample_beacon_block_params, genesis_state, fixture_sm_class, config, privkeys, pubkeys): chaindb = BeaconChainDB(base_db) state = genesis_state block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot + 2, state_root=state.root, ) # Sign block beacon_proposer_index = get_beacon_proposer_index( state, block.slot, config.EPOCH_LENGTH, ) index_in_privkeys = pubkeys.index( state.validator_registry[beacon_proposer_index].pubkey ) beacon_proposer_privkey = privkeys[index_in_privkeys] empty_signature_block_root = block.block_without_signature_root proposal_root = ProposalSignedData( block.slot, config.BEACON_CHAIN_SHARD_NUMBER, empty_signature_block_root, ).root block = block.copy( signature=bls.sign( message=proposal_root, privkey=beacon_proposer_privkey, domain=SignatureDomain.DOMAIN_PROPOSAL, ), ) # Store in chaindb chaindb.persist_block(block, SerenityBeaconBlock) chaindb.persist_state(state) # Get state machine instance sm = fixture_sm_class(chaindb, block.root, SerenityBeaconBlock) result_state, _ = sm.import_block(block) assert state.slot == 0 assert result_state.slot == block.slot assert isinstance(sm.block, SerenityBeaconBlock)