def case_fn(): value = value_fn() yield "value", "data", encode(value) yield "serialized", "ssz", serialize(value) yield "root", "meta", '0x' + hash_tree_root(value).hex() if isinstance(value, Container): yield "signing_root", "meta", '0x' + signing_root(value).hex()
def test_on_block_update_justified_checkpoint_within_safe_slots(spec, state): # Initialization store = spec.get_genesis_store(state) time = 100 spec.on_tick(store, time) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) state, store, last_block = apply_next_epoch_with_attestations( spec, state, store) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) last_block_root = signing_root(last_block) # Mock the justified checkpoint just_state = store.block_states[last_block_root] new_justified = spec.Checkpoint( epoch=just_state.current_justified_checkpoint.epoch + 1, root=b'\x77' * 32, ) just_state.current_justified_checkpoint = new_justified block = build_empty_block_for_next_slot(spec, just_state) state_transition_and_sign_block(spec, deepcopy(just_state), block) assert spec.get_current_slot( store) % spec.SLOTS_PER_EPOCH < spec.SAFE_SLOTS_TO_UPDATE_JUSTIFIED run_on_block(spec, store, block) assert store.justified_checkpoint == new_justified
def sign_block(spec, state, block, proposer_index=None): assert state.slot <= block.slot if proposer_index is None: if block.slot == state.slot: proposer_index = spec.get_beacon_proposer_index(state) else: if spec.compute_epoch_at_slot( state.slot) + 1 > spec.compute_epoch_at_slot(block.slot): print( "warning: block slot far away, and no proposer index manually given." " Signing block is slow due to transition for proposer index calculation." ) # use stub state to get proposer index of future slot stub_state = deepcopy(state) spec.process_slots(stub_state, block.slot) proposer_index = spec.get_beacon_proposer_index(stub_state) privkey = privkeys[proposer_index] block.body.randao_reveal = bls_sign( privkey=privkey, message_hash=hash_tree_root(spec.compute_epoch_at_slot(block.slot)), domain=spec.get_domain( state, message_epoch=spec.compute_epoch_at_slot(block.slot), domain_type=spec.DOMAIN_RANDAO, )) block.signature = bls_sign(message_hash=signing_root(block), privkey=privkey, domain=spec.get_domain( state, spec.DOMAIN_BEACON_PROPOSER, spec.compute_epoch_at_slot(block.slot)))
def sign_voluntary_exit(spec, state, voluntary_exit, privkey): voluntary_exit.signature = bls_sign( message_hash=signing_root(voluntary_exit), privkey=privkey, domain=spec.get_domain( state=state, domain_type=spec.DOMAIN_VOLUNTARY_EXIT, message_epoch=voluntary_exit.epoch, ))
def create_test_case(rng: Random, typ, mode: random_value.RandomizationMode, chaos: bool) -> Iterable[gen_typing.TestCasePart]: value = random_value.get_random_ssz_object(rng, typ, MAX_BYTES_LENGTH, MAX_LIST_LENGTH, mode, chaos) yield "value", "data", encode.encode(value) yield "serialized", "ssz", serialize(value) roots_data = {"root": '0x' + hash_tree_root(value).hex()} if isinstance(value, Container) and hasattr(value, "signature"): roots_data["signing_root"] = '0x' + signing_root(value).hex() yield "roots", "data", roots_data
def sign_deposit_data(spec, state, deposit_data, privkey): signature = bls_sign( message_hash=signing_root(deposit_data), privkey=privkey, domain=spec.get_domain( state, spec.DOMAIN_DEPOSIT, ) ) deposit_data.signature = signature
def sign_block_header(spec, state, header, privkey): domain = spec.get_domain( state=state, domain_type=spec.DOMAIN_BEACON_PROPOSER, ) header.signature = bls_sign( message_hash=signing_root(header), privkey=privkey, domain=domain, )
def apply_next_epoch_with_attestations(spec, state, store): _, new_blocks, post_state = next_epoch_with_attestations( spec, state, True, False) for block in new_blocks: block_root = signing_root(block) store.blocks[block_root] = block store.block_states[block_root] = post_state last_block = block spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) return post_state, store, last_block
def sign_transfer(spec, state, transfer, privkey): transfer.signature = bls_sign( message_hash=signing_root(transfer), privkey=privkey, domain=spec.get_domain( state=state, domain_type=spec.DOMAIN_TRANSFER, message_epoch=spec.get_current_epoch(state), )) return transfer
def run_on_block(spec, store, block, valid=True): if not valid: try: spec.on_block(store, block) except AssertionError: return else: assert False spec.on_block(store, block) assert store.blocks[signing_root(block)] == block
def build_empty_block(spec, state, slot=None, signed=False): if slot is None: slot = state.slot empty_block = spec.BeaconBlock() empty_block.slot = slot empty_block.body.eth1_data.deposit_count = state.eth1_deposit_index previous_block_header = deepcopy(state.latest_block_header) if previous_block_header.state_root == spec.Hash(): previous_block_header.state_root = state.hash_tree_root() empty_block.parent_root = signing_root(previous_block_header) if signed: sign_block(spec, state, empty_block) return empty_block
def sign_shard_block(spec, beacon_state, shard_state, block, proposer_index=None): if proposer_index is None: proposer_index = spec.get_shard_proposer_index(beacon_state, shard_state.shard, block.slot) privkey = privkeys[proposer_index] block.signature = bls_sign( message_hash=signing_root(block), privkey=privkey, domain=spec.get_domain( beacon_state, spec.DOMAIN_SHARD_PROPOSER, spec.compute_epoch_of_shard_slot(block.slot), ) )
def build_empty_shard_block(spec, beacon_state, shard_state, slot, signed=False, full_attestation=False): if slot is None: slot = shard_state.slot previous_beacon_header = deepcopy(beacon_state.latest_block_header) if previous_beacon_header.state_root == spec.Bytes32(): previous_beacon_header.state_root = beacon_state.hash_tree_root() beacon_block_root = spec.signing_root(previous_beacon_header) previous_block_header = deepcopy(shard_state.latest_block_header) if previous_block_header.state_root == spec.Bytes32(): previous_block_header.state_root = shard_state.hash_tree_root() parent_root = signing_root(previous_block_header) block = spec.ShardBlock( shard=shard_state.shard, slot=slot, beacon_block_root=beacon_block_root, parent_root=parent_root, block_size_sum=shard_state.block_size_sum + spec.SHARD_HEADER_SIZE, ) if full_attestation: shard_committee = spec.get_shard_committee(beacon_state, shard_state.shard, block.slot) block.aggregation_bits = list( (True,) * len(shard_committee) + (False,) * (spec.MAX_PERIOD_COMMITTEE_SIZE * 2 - len(shard_committee)) ) else: shard_committee = [] block.attestations = sign_shard_attestation( spec, beacon_state, shard_state, block, participants=shard_committee, ) if signed: sign_shard_block(spec, beacon_state, shard_state, block) return block
def sign_deposit_data(spec, deposit_data, privkey, state=None): if state is None: # Genesis domain = spec.compute_domain(spec.DOMAIN_DEPOSIT) else: domain = spec.get_domain( state, spec.DOMAIN_DEPOSIT, ) signature = bls_sign( message_hash=signing_root(deposit_data), privkey=privkey, domain=domain, ) deposit_data.signature = signature
def test_voluntary_exit(spec, state): validator_index = spec.get_active_validator_indices( state, spec.get_current_epoch(state) )[-1] # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH yield 'pre', state voluntary_exit = spec.VoluntaryExit( epoch=spec.get_current_epoch(state), validator_index=validator_index, ) voluntary_exit.signature = bls_sign( message_hash=signing_root(voluntary_exit), privkey=privkeys[validator_index], domain=spec.get_domain( state=state, domain_type=spec.DOMAIN_VOLUNTARY_EXIT, ) ) # Add to state via block transition initiate_exit_block = build_empty_block_for_next_slot(spec, state) initiate_exit_block.body.voluntary_exits.append(voluntary_exit) sign_block(spec, state, initiate_exit_block) state_transition_and_sign_block(spec, state, initiate_exit_block) assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH # Process within epoch transition exit_block = build_empty_block_for_next_slot(spec, state) exit_block.slot += spec.SLOTS_PER_EPOCH sign_block(spec, state, exit_block) state_transition_and_sign_block(spec, state, exit_block) yield 'blocks', [initiate_exit_block, exit_block], List[spec.BeaconBlock] yield 'post', state assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
def test_on_block_outside_safe_slots_and_old_block(spec, state): # Initialization store = spec.get_genesis_store(state) time = 100 spec.on_tick(store, time) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) state, store, last_block = apply_next_epoch_with_attestations( spec, state, store) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) last_block_root = signing_root(last_block) # Mock justified block in store just_block = build_empty_block_for_next_slot(spec, state) # Slot is same as justified checkpoint so does not trigger an override in the store just_block.slot = spec.compute_start_slot_at_epoch( store.justified_checkpoint.epoch) store.blocks[just_block.hash_tree_root()] = just_block # Mock the justified checkpoint just_state = store.block_states[last_block_root] new_justified = spec.Checkpoint( epoch=just_state.current_justified_checkpoint.epoch + 1, root=just_block.hash_tree_root(), ) just_state.current_justified_checkpoint = new_justified block = build_empty_block_for_next_slot(spec, just_state) state_transition_and_sign_block(spec, deepcopy(just_state), block) spec.on_tick( store, store.time + spec.SAFE_SLOTS_TO_UPDATE_JUSTIFIED * spec.SECONDS_PER_SLOT) assert spec.get_current_slot( store) % spec.SLOTS_PER_EPOCH >= spec.SAFE_SLOTS_TO_UPDATE_JUSTIFIED run_on_block(spec, store, block) assert store.justified_checkpoint != new_justified assert store.best_justified_checkpoint == new_justified
def test_on_block_checkpoints(spec, state): # Initialization store = spec.get_genesis_store(state) time = 100 spec.on_tick(store, time) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) state, store, last_block = apply_next_epoch_with_attestations( spec, state, store) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) last_block_root = signing_root(last_block) # Mock the finalized_checkpoint store.block_states[last_block_root].finalized_checkpoint = ( store.block_states[last_block_root].current_justified_checkpoint) # On receiving a block of `GENESIS_SLOT + 1` slot block = build_empty_block_for_next_slot(spec, state) run_on_block(spec, state, store, block)
def test_on_block_checkpoints(spec, state): # Initialization store = spec.get_genesis_store(state) time = 100 spec.on_tick(store, time) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) state, store, last_block = apply_next_epoch_with_attestations( spec, state, store) next_epoch(spec, state) spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT) last_block_root = signing_root(last_block) # Mock the finalized_checkpoint fin_state = store.block_states[last_block_root] fin_state.finalized_checkpoint = ( store.block_states[last_block_root].current_justified_checkpoint) block = build_empty_block_for_next_slot(spec, fin_state) state_transition_and_sign_block(spec, deepcopy(fin_state), block) run_on_block(spec, store, block)
def create_test_case_contents(value, typ): yield "value", encode.encode(value, typ) yield "serialized", '0x' + serialize(value).hex() yield "root", '0x' + hash_tree_root(value).hex() if hasattr(value, "signature"): yield "signing_root", '0x' + signing_root(value).hex()