def test_update_attestations(sample_attestation_params, sample_beacon_block_params): block = SerenityBeaconBlock(**sample_beacon_block_params) attestations = block.body.attestations attestations = list(attestations) attestations.append(Attestation(**sample_attestation_params)) body2 = block.body.copy(attestations=attestations) block2 = block.copy(body=body2) assert block2.num_attestations == 1
def test_process_voluntary_exits(genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, success): state = genesis_state.copy(slot=get_epoch_start_slot( config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD, config.SLOTS_PER_EPOCH, ), ) validator_index = 0 validator = state.validators[validator_index].copy( activation_epoch=config.GENESIS_EPOCH, ) state = state.update_validator(validator_index, validator) valid_voluntary_exit = create_mock_voluntary_exit( state, config, keymap, validator_index, ) if success: block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( voluntary_exits=(valid_voluntary_exit, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) new_state = process_voluntary_exits( state, block, config, ) updated_validator = new_state.validators[validator_index] assert updated_validator.exit_epoch != FAR_FUTURE_EPOCH assert updated_validator.exit_epoch > state.current_epoch( config.SLOTS_PER_EPOCH) assert updated_validator.withdrawable_epoch == ( updated_validator.exit_epoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY) else: invalid_voluntary_exit = valid_voluntary_exit.copy( signature=b'\x12' * 96, # Put wrong signature ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( voluntary_exits=(invalid_voluntary_exit, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) with pytest.raises(ValidationError): process_voluntary_exits( state, block, config, )
def test_process_attester_slashings(genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, min_attestation_inclusion_delay, success): attesting_state = genesis_state.copy( slot=genesis_state.slot + config.SLOTS_PER_EPOCH, block_roots=tuple( i.to_bytes(32, "little") for i in range(config.SLOTS_PER_HISTORICAL_ROOT))) valid_attester_slashing = create_mock_attester_slashing_is_double_vote( attesting_state, config, keymap, attestation_epoch=0, ) state = attesting_state.copy(slot=attesting_state.slot + min_attestation_inclusion_delay, ) if success: block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attester_slashings=(valid_attester_slashing, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) attester_index = valid_attester_slashing.attestation_1.custody_bit_0_indices[ 0] new_state = process_attester_slashings( state, block, config, ) # Check if slashed assert not state.validators[attester_index].slashed assert new_state.validators[attester_index].slashed else: invalid_attester_slashing = valid_attester_slashing.copy( attestation_2=valid_attester_slashing.attestation_2.copy( data=valid_attester_slashing.attestation_1.data, )) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attester_slashings=(invalid_attester_slashing, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) with pytest.raises(ValidationError): process_attester_slashings( state, block, config, )
def test_process_attester_slashings(genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, min_attestation_inclusion_delay, success): attesting_state = genesis_state.copy(slot=genesis_state.slot + config.SLOTS_PER_EPOCH, ) valid_attester_slashing = create_mock_attester_slashing_is_double_vote( attesting_state, config, keymap, attestation_epoch=0, ) state = attesting_state.copy(slot=attesting_state.slot + min_attestation_inclusion_delay, ) if success: block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attester_slashings=(valid_attester_slashing, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) attester_index = valid_attester_slashing.slashable_attestation_1.validator_indices[ 0] new_state = process_attester_slashings( state, block, config, ) # Check if slashed assert (new_state.validator_balances[attester_index] < state.validator_balances[attester_index]) else: invalid_attester_slashing = valid_attester_slashing.copy( slashable_attestation_2=valid_attester_slashing. slashable_attestation_2.copy( data=valid_attester_slashing.slashable_attestation_1.data, )) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attester_slashings=(invalid_attester_slashing, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) with pytest.raises(ValidationError): process_attester_slashings( state, block, config, )
def test_process_voluntary_exits(genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, success): state = genesis_state.copy(slot=get_epoch_start_slot( config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD, config.SLOTS_PER_EPOCH, ), ) validator_index = 0 validator = state.validator_registry[validator_index].copy( activation_epoch=config.GENESIS_EPOCH, ) state = state.update_validator_registry(validator_index, validator) valid_voluntary_exit = create_mock_voluntary_exit( state, config, keymap, validator_index, ) if success: block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( voluntary_exits=(valid_voluntary_exit, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) new_state = process_voluntary_exits( state, block, config, ) # Check if initiated exit assert (new_state.validator_registry[validator_index].initiated_exit) else: invalid_voluntary_exit = valid_voluntary_exit.copy( signature=b'\x12' * 96, # Put wrong signature ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( voluntary_exits=(invalid_voluntary_exit, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) with pytest.raises(ValidationError): process_voluntary_exits( state, block, config, )
def test_process_voluntary_exits( genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, success, ): state = genesis_state.set( "slot", compute_start_slot_at_epoch( config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD, config.SLOTS_PER_EPOCH, ), ) validator_index = 0 validator = state.validators[validator_index].set("activation_epoch", config.GENESIS_EPOCH) state = state.transform(["validators", validator_index], validator) valid_voluntary_exit = create_mock_voluntary_exit(state, config, keymap, validator_index) if success: block_body = BeaconBlockBody.create( **sample_beacon_block_body_params).set("voluntary_exits", (valid_voluntary_exit, )) block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset( "slot", state.slot, "body", block_body) new_state = process_voluntary_exits(state, block, config) updated_validator = new_state.validators[validator_index] assert updated_validator.exit_epoch != FAR_FUTURE_EPOCH assert updated_validator.exit_epoch > state.current_epoch( config.SLOTS_PER_EPOCH) assert updated_validator.withdrawable_epoch == ( updated_validator.exit_epoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY) else: invalid_voluntary_exit = valid_voluntary_exit.set( "signature", b"\x12" * 96 # Put wrong signature ) block_body = BeaconBlockBody.create( **sample_beacon_block_body_params).set("voluntary_exits", (invalid_voluntary_exit, )) block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset( "slot", state.slot, "body", block_body) with pytest.raises(ValidationError): process_voluntary_exits(state, block, config)
def test_process_attester_slashings( genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, min_attestation_inclusion_delay, success, ): attesting_state = genesis_state.mset( "slot", genesis_state.slot + config.SLOTS_PER_EPOCH, "block_roots", tuple( i.to_bytes(32, "little") for i in range(config.SLOTS_PER_HISTORICAL_ROOT)), ) valid_attester_slashing = create_mock_attester_slashing_is_double_vote( attesting_state, config, keymap, attestation_epoch=0) state = attesting_state.set( "slot", attesting_state.slot + min_attestation_inclusion_delay) if success: block_body = BeaconBlockBody.create( **sample_beacon_block_body_params).set("attester_slashings", (valid_attester_slashing, )) block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset( "slot", state.slot, "body", block_body) attester_index = valid_attester_slashing.attestation_1.attesting_indices[ 0] new_state = process_attester_slashings(state, block, config) # Check if slashed assert not state.validators[attester_index].slashed assert new_state.validators[attester_index].slashed else: invalid_attester_slashing = valid_attester_slashing.transform( ["attestation_2", "data"], valid_attester_slashing.attestation_1.data) block_body = BeaconBlockBody.create( **sample_beacon_block_body_params).set( "attester_slashings", (invalid_attester_slashing, )) block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset( "slot", state.slot, "body", block_body) with pytest.raises(ValidationError): process_attester_slashings(state, block, config)
def test_randao_processing_validates_randao_reveal(sample_beacon_block_params, sample_beacon_state_params, sample_fork_params, keymap, config): proposer_pubkey, proposer_privkey = first(keymap.items()) state = SerenityBeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator_record(proposer_pubkey) for _ in range(config.TARGET_COMMITTEE_SIZE)), validator_balances=(config.MAX_DEPOSIT_AMOUNT, ) * config.TARGET_COMMITTEE_SIZE, latest_randao_mixes=tuple( ZERO_HASH32 for _ in range(config.LATEST_RANDAO_MIXES_LENGTH)), ) epoch = state.current_epoch(config.EPOCH_LENGTH) slot = epoch * config.EPOCH_LENGTH message = (epoch + 1).to_bytes(32, byteorder="big") fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) randao_reveal = bls.sign(message, proposer_privkey, domain) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( randao_reveal=randao_reveal, ) with pytest.raises(ValidationError): process_randao(state, block, config)
def test_randao_processing_validates_randao_reveal( sample_beacon_block_params, sample_beacon_block_body_params, sample_beacon_state_params, sample_fork_params, keymap, config, ): proposer_pubkey, proposer_privkey = first(keymap.items()) state = SerenityBeaconState.create(**sample_beacon_state_params).mset( "validators", tuple( create_mock_validator(proposer_pubkey, config) for _ in range(config.TARGET_COMMITTEE_SIZE)), "balances", (config.MAX_EFFECTIVE_BALANCE, ) * config.TARGET_COMMITTEE_SIZE, "randao_mixes", tuple(ZERO_HASH32 for _ in range(config.EPOCHS_PER_HISTORICAL_VECTOR)), ) epoch = state.current_epoch(config.SLOTS_PER_EPOCH) message_hash = (epoch + 1).to_bytes(32, byteorder="little") domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, config.SLOTS_PER_EPOCH) randao_reveal = bls.sign(message_hash, proposer_privkey, domain) block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set( "randao_reveal", randao_reveal) block = SerenityBeaconBlock.create(**sample_beacon_block_params).set( "body", block_body) with pytest.raises(ValidationError): process_randao(state, block, config)
def test_randao_processing(sample_beacon_block_params, sample_beacon_state_params, sample_fork_params, keymap, config): proposer_pubkey, proposer_privkey = first(keymap.items()) state = SerenityBeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator_record(proposer_pubkey) for _ in range(config.TARGET_COMMITTEE_SIZE)), validator_balances=(config.MAX_DEPOSIT_AMOUNT, ) * config.TARGET_COMMITTEE_SIZE, latest_randao_mixes=tuple( ZERO_HASH32 for _ in range(config.LATEST_RANDAO_MIXES_LENGTH)), ) epoch = state.current_epoch(config.EPOCH_LENGTH) slot = epoch * config.EPOCH_LENGTH message = epoch.to_bytes(32, byteorder="big") fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) randao_reveal = bls.sign(message, proposer_privkey, domain) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( randao_reveal=randao_reveal, ) new_state = process_randao(state, block, config) updated_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH original_mixes = state.latest_randao_mixes updated_mixes = new_state.latest_randao_mixes assert all( updated == original if index != updated_index else updated != original for index, (updated, original) in enumerate(zip(updated_mixes, original_mixes)))
def test_process_max_attestations(genesis_state, genesis_block, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap): attestation_slot = config.GENESIS_SLOT current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY state = genesis_state.copy(slot=current_slot, ) attestations = create_mock_signed_attestations_at_slot( state=state, config=config, attestation_slot=attestation_slot, beacon_block_root=genesis_block.root, keymap=keymap, voted_attesters_ratio=1.0, ) attestations_count = len(attestations) assert attestations_count > 0 block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attestations=attestations * (attestations_count // config.MAX_ATTESTATIONS + 1), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=current_slot, body=block_body, ) with pytest.raises(ValidationError): process_attestations( state, block, config, )
def test_process_attestations(genesis_state, genesis_block, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, fixture_sm_class, chaindb, empty_attestation_pool, success): attestation_slot = 0 current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY state = genesis_state.copy(slot=current_slot, ) attestations = create_mock_signed_attestations_at_slot( state=state, config=config, state_machine=fixture_sm_class( chaindb, empty_attestation_pool, genesis_block.slot, ), attestation_slot=attestation_slot, beacon_block_root=genesis_block.signing_root, keymap=keymap, voted_attesters_ratio=1.0, ) assert len(attestations) > 0 if not success: # create invalid attestation by shard # i.e. wrong parent invalid_attestation_data = attestations[-1].data.copy( crosslink=attestations[-1].data.crosslink.copy( parent_root=Crosslink(shard=333, ).root, )) invalid_attestation = attestations[-1].copy( data=invalid_attestation_data, ) attestations = attestations[:-1] + (invalid_attestation, ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attestations=attestations, ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=current_slot, body=block_body, ) if success: new_state = process_attestations( state, block, config, ) assert len(new_state.current_epoch_attestations) == len(attestations) else: with pytest.raises(ValidationError): process_attestations( state, block, config, )
def test_process_voluntary_exits(genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, min_attestation_inclusion_delay, success): state = genesis_state validator_index = 0 valid_voluntary_exit = create_mock_voluntary_exit( state, config, keymap, validator_index, ) if success: block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( voluntary_exits=(valid_voluntary_exit, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) new_state = process_voluntary_exits( state, block, config, ) # Check if initiated exit assert (new_state.validator_registry[validator_index].initiated_exit) else: invalid_voluntary_exit = valid_voluntary_exit.copy( signature=b'\x12' * 96, # Put wrong signature ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( voluntary_exits=(invalid_voluntary_exit, ), ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=state.slot, body=block_body, ) with pytest.raises(ValidationError): process_voluntary_exits( state, block, config, )
def test_process_attestations(genesis_state, genesis_block, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, fixture_sm_class, base_db, success): attestation_slot = 0 current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY state = genesis_state.copy(slot=current_slot, ) attestations = create_mock_signed_attestations_at_slot( state=state, config=config, state_machine=fixture_sm_class( BeaconChainDB(base_db), genesis_block, ), attestation_slot=attestation_slot, beacon_block_root=genesis_block.signed_root, keymap=keymap, voted_attesters_ratio=1.0, ) assert len(attestations) > 0 if not success: # create invalid attestation in the future invalid_attestation_data = attestations[-1].data.copy(slot=state.slot + 10, ) invalid_attestation = attestations[-1].copy( data=invalid_attestation_data, ) attestations = attestations[:-1] + (invalid_attestation, ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attestations=attestations, ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=current_slot, body=block_body, ) if success: new_state = process_attestations( state, block, config, ) assert len(new_state.current_epoch_attestations) == len(attestations) else: with pytest.raises(ValidationError): process_attestations( state, block, config, )
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)
def test_process_proposer_slashings(genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, block_root_1, block_root_2, success): current_slot = config.GENESIS_SLOT + 1 state = genesis_state.copy( slot=current_slot, ) whistleblower_index = get_beacon_proposer_index( state, CommitteeConfig(config), ) slashing_proposer_index = (whistleblower_index + 1) % len(state.validators) proposer_slashing = create_mock_proposer_slashing_at_block( state, config, keymap, block_root_1=block_root_1, block_root_2=block_root_2, proposer_index=slashing_proposer_index, ) proposer_slashings = (proposer_slashing,) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( proposer_slashings=proposer_slashings, ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=current_slot, body=block_body, ) if success: new_state = process_proposer_slashings( state, block, config, ) # Check if slashed assert ( new_state.balances[slashing_proposer_index] < state.balances[slashing_proposer_index] ) else: with pytest.raises(ValidationError): process_proposer_slashings( state, block, config, )
def test_process_attestations( genesis_state, genesis_block, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, fixture_sm_class, chaindb, genesis_fork_choice_context, success, ): attestation_slot = 0 current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY state = genesis_state.set("slot", current_slot) attestations = create_mock_signed_attestations_at_slot( state=state, config=config, state_machine=fixture_sm_class(chaindb, genesis_fork_choice_context), attestation_slot=attestation_slot, beacon_block_root=genesis_block.message.hash_tree_root, keymap=keymap, voted_attesters_ratio=1.0, ) assert len(attestations) > 0 if not success: # create invalid attestation # i.e. wrong slot invalid_attestation_data = attestations[-1].data.set( "slot", state.slot + 1) invalid_attestation = attestations[-1].set("data", invalid_attestation_data) attestations = attestations[:-1] + (invalid_attestation, ) block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set( "attestations", attestations) block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset( "slot", current_slot, "body", block_body) if success: new_state = process_attestations(state, block, config) assert len(new_state.current_epoch_attestations) == len(attestations) else: with pytest.raises(ValidationError): process_attestations(state, block, config)
def test_process_attestations(genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, success): attestation_slot = 0 current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY state = genesis_state.copy(slot=current_slot, ) attestations = create_mock_signed_attestations_at_slot( state, config, attestation_slot, keymap, 1.0, ) assert len(attestations) > 0 if not success: # create invalid attestation in the future invalid_attestation_data = attestations[-1].data.copy(slot=state.slot + 10, ) invalid_attestation = attestations[-1].copy( data=invalid_attestation_data, ) attestations = attestations[:-1] + (invalid_attestation, ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attestations=attestations, ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=current_slot, body=block_body, ) if success: new_state = process_attestations( state, block, config, ) assert len(new_state.latest_attestations) == len(attestations) else: with pytest.raises(ValidationError): process_attestations( state, block, config, )
def test_randao_processing(sample_beacon_block_params, sample_beacon_block_body_params, sample_beacon_state_params, keymap, config): proposer_pubkey, proposer_privkey = first(keymap.items()) state = SerenityBeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator_record(proposer_pubkey, config) for _ in range(config.TARGET_COMMITTEE_SIZE) ), validator_balances=(config.MAX_DEPOSIT_AMOUNT,) * config.TARGET_COMMITTEE_SIZE, latest_randao_mixes=tuple( ZERO_HASH32 for _ in range(config.LATEST_RANDAO_MIXES_LENGTH) ), ) epoch = state.current_epoch(config.SLOTS_PER_EPOCH) slot = get_epoch_start_slot(epoch, config.SLOTS_PER_EPOCH) randao_reveal = _generate_randao_reveal( privkey=proposer_privkey, slot=slot, fork=state.fork, config=config, ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( randao_reveal=randao_reveal, ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( body=block_body, ) new_state = process_randao(state, block, config) updated_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH original_mixes = state.latest_randao_mixes updated_mixes = new_state.latest_randao_mixes assert all( updated == original if index != updated_index else updated != original for index, (updated, original) in enumerate(zip(updated_mixes, original_mixes)) )
def test_randao_processing(sample_beacon_block_params, sample_beacon_block_body_params, sample_beacon_state_params, keymap, config): proposer_pubkey, proposer_privkey = first(keymap.items()) state = SerenityBeaconState(**sample_beacon_state_params).copy( validators=tuple( create_mock_validator(proposer_pubkey, config) for _ in range(config.TARGET_COMMITTEE_SIZE) ), balances=(config.MAX_EFFECTIVE_BALANCE,) * config.TARGET_COMMITTEE_SIZE, randao_mixes=tuple( ZERO_HASH32 for _ in range(config.EPOCHS_PER_HISTORICAL_VECTOR) ), ) epoch = state.current_epoch(config.SLOTS_PER_EPOCH) slot = get_epoch_start_slot(epoch, config.SLOTS_PER_EPOCH) randao_reveal = _generate_randao_reveal( privkey=proposer_privkey, slot=slot, state=state, config=config, ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( randao_reveal=randao_reveal, ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( body=block_body, ) new_state = process_randao(state, block, config) updated_index = epoch % config.EPOCHS_PER_HISTORICAL_VECTOR original_mixes = state.randao_mixes updated_mixes = new_state.randao_mixes assert all( updated == original if index != updated_index else updated != original for index, (updated, original) in enumerate(zip(updated_mixes, original_mixes)) )
def test_process_proposer_slashings( genesis_state, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, block_root_1, block_root_2, success, ): current_slot = config.GENESIS_SLOT + 1 state = genesis_state.set("slot", current_slot) whistleblower_index = get_beacon_proposer_index(state, config) slashing_proposer_index = (whistleblower_index + 1) % len(state.validators) proposer_slashing = create_mock_proposer_slashing_at_block( state, config, keymap, block_root_1=block_root_1, block_root_2=block_root_2, proposer_index=slashing_proposer_index, ) proposer_slashings = (proposer_slashing, ) block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set( "proposer_slashings", proposer_slashings) block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset( "slot", current_slot, "body", block_body) if success: new_state = process_proposer_slashings(state, block, config) # Check if slashed assert (new_state.balances[slashing_proposer_index] < state.balances[slashing_proposer_index]) else: with pytest.raises(ValidationError): process_proposer_slashings(state, block, config)
def test_process_max_attestations( genesis_state, genesis_block, sample_beacon_block_params, sample_beacon_block_body_params, config, keymap, fixture_sm_class, chaindb, genesis_fork_choice_context, ): attestation_slot = config.GENESIS_SLOT current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY state = genesis_state.copy(slot=current_slot) attestations = create_mock_signed_attestations_at_slot( state=state, config=config, state_machine=fixture_sm_class(chaindb, genesis_fork_choice_context), attestation_slot=attestation_slot, beacon_block_root=genesis_block.signing_root, keymap=keymap, voted_attesters_ratio=1.0, ) attestations_count = len(attestations) assert attestations_count > 0 block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( attestations=attestations * (config.MAX_ATTESTATIONS // attestations_count + 1) ) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( slot=current_slot, body=block_body ) with pytest.raises(ValidationError): process_attestations(state, block, config)
def sample_block(sample_beacon_block_params): return SerenityBeaconBlock(**sample_beacon_block_params)
def test_defaults(sample_beacon_block_params): block = SerenityBeaconBlock(**sample_beacon_block_params) assert block.slot == sample_beacon_block_params['slot'] assert len(block.body.custody_challenges) == 0