def clock(eth2_config, chain_config, seconds_per_epoch, get_trio_time): return Clock( eth2_config.SECONDS_PER_SLOT, chain_config.genesis_time, eth2_config.SLOTS_PER_EPOCH, seconds_per_epoch, time_provider=get_trio_time, )
def _mk_clock(config: Eth2Config, genesis_time: int, time_provider: TimeProvider) -> Clock: return Clock( config.SECONDS_PER_SLOT, genesis_time, config.SLOTS_PER_EPOCH, config.SECONDS_PER_SLOT * config.SLOTS_PER_EPOCH, time_provider, )
def _mk_clock(config: Eth2Config, genesis_time: int, time_provider: TimeProvider) -> Clock: return Clock( config.SECONDS_PER_SLOT, genesis_time, config.SLOTS_PER_EPOCH, config.SECONDS_PER_SLOT * config.SLOTS_PER_EPOCH, time_provider, # node can wait until genesis genesis_lookahead=0, )
async def _main(logger: logging.Logger, config: Config, arguments: argparse.Namespace) -> None: key_store = KeyStore.from_config(config) clock = Clock( config.seconds_per_slot, config.genesis_time, config.slots_per_epoch, config.seconds_per_epoch, ) beacon_node = BeaconNode.from_config(config) # with key_store.persistence(): async with beacon_node: client = Client(key_store, clock, beacon_node) async with background_trio_service(client): await wait_for_interrupts() logger.info("received interrupt; shutting down...")
async def test_client_works(autojump_clock, sample_bls_key_pairs, eth2_config): """ This test constructs a ``Client`` with enough known inputs to compute an expected set of signatures after running for a given amount of time. The test fails if the expected signatures are not observed as outputs of the client. """ seconds_per_slot = eth2_config.SECONDS_PER_SLOT slots_per_epoch = eth2_config.SLOTS_PER_EPOCH # NOTE: start 2 epochs ahead of genesis to emulate the client # waiting to the time it can start polling the beacon node # and the getting duties in the first epoch in the epoch prior to genesis total_epochs_to_run = 4 epochs_before_genesis_to_start = 2 epochs_after_genesis_to_end = total_epochs_to_run - epochs_before_genesis_to_start # Set genesis so that we aren't aligned with a slot, which could hide some # bugs we will otherwise see... non_aligned_time = trio.current_time() + seconds_per_slot / 3 seconds_per_epoch = seconds_per_slot * slots_per_epoch genesis_time = int( non_aligned_time + epochs_before_genesis_to_start * seconds_per_epoch ) public_key = tuple(sample_bls_key_pairs.keys())[0] key_store = KeyStore(sample_bls_key_pairs) beacon_node = MockBeaconNode( slots_per_epoch, seconds_per_slot, duty_fetcher=_mk_duty_fetcher(public_key, slots_per_epoch, seconds_per_slot), ) clock = Clock( seconds_per_slot, genesis_time, slots_per_epoch, seconds_per_epoch, trio.current_time, ) client = Client(key_store, clock, beacon_node) try: async with background_trio_service(client): await trio.sleep(total_epochs_to_run * seconds_per_epoch) except DaemonTaskExit: # NOTE: there is a race condition in ``async_service`` that will # trigger ``DaemonTaskExit`` when the test would otherwise pass. # See: https://github.com/ethereum/async-service/issues/54 pass fulfilled_duties = tuple( filter( lambda duty: duty.tick_for_execution.epoch < epochs_after_genesis_to_end, beacon_node.given_duties, ) ) assert len(beacon_node.published_signatures) == len(fulfilled_duties) randao_provider = mk_randao_provider(key_store.private_key_for) for duty in fulfilled_duties: if duty.duty_type == DutyType.Attestation: operation = await beacon_node.fetch_attestation( duty.validator_public_key, duty.tick_for_execution.slot, duty.committee_index, ) else: randao_reveal = randao_provider( duty.validator_public_key, duty.tick_for_execution.epoch ) operation = await beacon_node.fetch_block_proposal( duty.tick_for_execution.slot, randao_reveal ) observed_signature = beacon_node.published_signatures[duty] expected_signature = sign(duty, operation, key_store.private_key_for) assert observed_signature == expected_signature