def create_block_on_state( *, state: BeaconState, config: BeaconConfig, state_machine: BaseBeaconStateMachine, block_class: BaseBeaconBlock, parent_block: BaseBeaconBlock, slot: SlotNumber, validator_index: ValidatorIndex, privkey: int, attestations: Sequence[Attestation], check_proposer_index: bool = True) -> BaseBeaconBlock: """ Create a beacon block with the given parameters. """ # Check proposer if check_proposer_index: validate_proposer_index(state, config, slot, validator_index) # Prepare block: slot and parent_root block = block_class.from_parent( parent_block=parent_block, block_params=FromBlockParams(slot=slot), ) # TODO: Add more operations randao_reveal = ZERO_HASH32 eth1_data = Eth1Data.create_empty_data() body = BeaconBlockBody.create_empty_body().copy( attestations=attestations, ) block = block.copy( randao_reveal=randao_reveal, eth1_data=eth1_data, body=body, ) # Apply state transition to get state root state, block = state_machine.import_block(block, check_proposer_signature=True) # Sign empty_signature_block_root = block.block_without_signature_root proposal_root = ProposalSignedData( slot, config.BEACON_CHAIN_SHARD_NUMBER, empty_signature_block_root, ).root domain = get_domain( state.fork, slot_to_epoch(slot, config.EPOCH_LENGTH), SignatureDomain.DOMAIN_PROPOSAL, ) block = block.copy(signature=bls.sign( message=proposal_root, privkey=privkey, domain=domain, ), ) return block
def create_block_on_state(state: BeaconState, config: BeaconConfig, block_class: BaseBeaconBlock, parent_block: BaseBeaconBlock, slot: SlotNumber, validator_index: int, privkey: int, attestations: Sequence[Attestation]): """ Create a beacon block with the given parameters. """ # Check proposer beacon_proposer_index = get_beacon_proposer_index( state.copy(slot=slot, ), slot, config.EPOCH_LENGTH, config.TARGET_COMMITTEE_SIZE, config.SHARD_COUNT, ) if validator_index != beacon_proposer_index: raise ProposerIndexError # Prepare block: slot and parent_root block = block_class.from_parent( parent_block=parent_block, block_params=FromBlockParams(slot=slot), ) # TODO: Add more operations randao_reveal = ZERO_HASH32 eth1_data = Eth1Data.create_empty_data() body = BeaconBlockBody.create_empty_body().copy( attestations=attestations, ) block = block.copy( randao_reveal=randao_reveal, eth1_data=eth1_data, body=body, ) # Sign empty_signature_block_root = block.block_without_signature_root proposal_root = ProposalSignedData( slot, config.BEACON_CHAIN_SHARD_NUMBER, empty_signature_block_root, ).root domain = get_domain( state.fork, slot, SignatureDomain.DOMAIN_PROPOSAL, ) block = block.copy(signature=bls.sign( message=proposal_root, privkey=privkey, domain=domain, ), ) return block
def create_block_on_state( *, state: BeaconState, config: Eth2Config, state_machine: BaseBeaconStateMachine, block_class: Type[BaseBeaconBlock], parent_block: BaseBeaconBlock, slot: Slot, validator_index: ValidatorIndex, privkey: int, attestations: Sequence[Attestation], check_proposer_index: bool = True) -> BaseBeaconBlock: """ Create a beacon block with the given parameters. """ # Check proposer if check_proposer_index: validate_proposer_index(state, config, slot, validator_index) # Prepare block: slot and previous_block_root block = block_class.from_parent( parent_block=parent_block, block_params=FromBlockParams(slot=slot), ) # TODO: Add more operations randao_reveal = _generate_randao_reveal(privkey, slot, state.fork, config) eth1_data = Eth1Data.create_empty_data() body = BeaconBlockBody.create_empty_body().copy( randao_reveal=randao_reveal, eth1_data=eth1_data, attestations=attestations, ) block = block.copy(body=body, ) # Apply state transition to get state root state, block = state_machine.import_block(block, check_proposer_signature=False) # Sign # TODO make sure we use the correct signed_root signature = sign_transaction( message_hash=block.signed_root, privkey=privkey, fork=state.fork, slot=slot, signature_domain=SignatureDomain.DOMAIN_BEACON_BLOCK, slots_per_epoch=config.SLOTS_PER_EPOCH, ) block = block.copy(signature=signature, ) return block
def get_genesis_block(startup_state_root: Hash32, genesis_slot: SlotNumber, block_class: Type[BaseBeaconBlock]) -> BaseBeaconBlock: return block_class( slot=genesis_slot, parent_root=ZERO_HASH32, state_root=startup_state_root, randao_reveal=ZERO_HASH32, eth1_data=Eth1Data.create_empty_data(), signature=EMPTY_SIGNATURE, body=BeaconBlockBody.create_empty_body(), )
def test_block_body_empty(sample_attestation_params): block_body = BeaconBlockBody.create_empty_body() assert block_body.proposer_slashings == () assert block_body.attester_slashings == () assert block_body.attestations == () assert block_body.deposits == () assert block_body.exits == () assert block_body.is_empty block_body = block_body.copy( attestations=(Attestation(**sample_attestation_params), ), ) assert not block_body.is_empty
def create_test_block(parent=None, **kwargs): defaults = { "slot": SERENITY_CONFIG.GENESIS_SLOT, "previous_block_root": ZERO_HASH32, "state_root": ZERO_HASH32, # note: not the actual genesis state root "signature": EMPTY_SIGNATURE, "body": BeaconBlockBody.create_empty_body() } if parent is not None: kwargs["previous_block_root"] = parent.signing_root kwargs["slot"] = parent.slot + 1 return BeaconBlock(**merge(defaults, kwargs))
def create_test_block(parent=None, **kwargs): defaults = { "slot": 0, "parent_root": ZERO_HASH32, "state_root": ZERO_HASH32, # note: not the actual genesis state root "randao_reveal": EMPTY_SIGNATURE, "eth1_data": Eth1Data.create_empty_data(), "signature": EMPTY_SIGNATURE, "body": BeaconBlockBody.create_empty_body() } if parent is not None: kwargs["parent_root"] = parent.root kwargs["slot"] = parent.slot + 1 return BeaconBlock(**merge(defaults, kwargs))
async def test_send_single_block(request, event_loop): alice, msg_buffer = await get_command_setup(request, event_loop) request_id = 5 block = BeaconBlock( slot=1, previous_block_root=ZERO_HASH32, state_root=ZERO_HASH32, signature=EMPTY_SIGNATURE, body=BeaconBlockBody.create_empty_body(), ) alice.sub_proto.send_blocks((block, ), request_id=request_id) message = await msg_buffer.msg_queue.get() assert isinstance(message.command, BeaconBlocks) assert message.payload == { "request_id": request_id, "encoded_blocks": (ssz.encode(block), ), }
async def test_send_multiple_blocks(request, event_loop): alice, msg_buffer = await get_command_setup(request, event_loop) request_id = 5 blocks = tuple( BeaconBlock( slot=slot, parent_root=ZERO_HASH32, state_root=ZERO_HASH32, randao_reveal=EMPTY_SIGNATURE, eth1_data=Eth1Data.create_empty_data(), signature=EMPTY_SIGNATURE, body=BeaconBlockBody.create_empty_body(), ) for slot in range(3)) alice.sub_proto.send_blocks(blocks, request_id=request_id) message = await msg_buffer.msg_queue.get() assert isinstance(message.command, BeaconBlocks) assert message.payload == { "request_id": request_id, "encoded_blocks": tuple(ssz.encode(block) for block in blocks), }
def create_block_on_state( *, state: BeaconState, config: BeaconConfig, state_machine: BaseBeaconStateMachine, block_class: Type[BaseBeaconBlock], parent_block: BaseBeaconBlock, slot: Slot, validator_index: ValidatorIndex, privkey: int, attestations: Sequence[Attestation], check_proposer_index: bool = True) -> BaseBeaconBlock: """ Create a beacon block with the given parameters. """ # Check proposer if check_proposer_index: validate_proposer_index(state, config, slot, validator_index) # Prepare block: slot and parent_root block = block_class.from_parent( parent_block=parent_block, block_params=FromBlockParams(slot=slot), ) # TODO: Add more operations randao_reveal = EMPTY_SIGNATURE eth1_data = Eth1Data.create_empty_data() body = BeaconBlockBody.create_empty_body().copy( attestations=attestations, ) block = block.copy( randao_reveal=randao_reveal, eth1_data=eth1_data, body=body, ) # Apply state transition to get state root state, block = state_machine.import_block(block, check_proposer_signature=False) # Sign empty_signature_block_root = block.block_without_signature_root proposal_root = Proposal( slot, config.BEACON_CHAIN_SHARD_NUMBER, empty_signature_block_root, ).root signature = sign_transaction( message_hash=proposal_root, privkey=privkey, fork=state.fork, slot=slot, signature_domain=SignatureDomain.DOMAIN_PROPOSAL, slots_per_epoch=config.SLOTS_PER_EPOCH, ) block = block.copy(signature=signature, ) return block