async def _keep_ticking(self) -> None: """ Ticker should tick three times in one slot: SLOT_START: at the beginning of the slot SLOT_ONE_THIRD: at 1/3 of the slot SLOT_TWO_THIRD: at 2/3 of the slot """ # Use `sent_tick_types_at_slot` set to record # the tick types that haven been sent at current slot. sent_tick_types_at_slot: Set[TickType] = set() while self.is_operational: elapsed_time = Second(int(time.time()) - self.genesis_time) # Skip genesis slot if elapsed_time < self.seconds_per_slot: continue elapsed_slots = elapsed_time // self.seconds_per_slot slot = Slot(elapsed_slots + self.genesis_slot) tick_type = self._get_tick_type(elapsed_time) # New slot if slot > self.latest_slot: self.latest_slot = slot await self._broadcast_slot_tick_event(slot, elapsed_time, tick_type) # Clear set sent_tick_types_at_slot = set() sent_tick_types_at_slot.add(TickType.SLOT_START) elif not tick_type.is_start and tick_type not in sent_tick_types_at_slot: await self._broadcast_slot_tick_event(slot, elapsed_time, tick_type) sent_tick_types_at_slot.add(tick_type) await asyncio.sleep(self.seconds_per_slot // self.check_frequency)
async def _keep_ticking(self) -> None: """ Ticker should tick twice in one slot: one for a new slot, one for the second half of an already ticked slot, e.g., if `seconds_per_slot` is `6`, for slot `49` it should tick once for the first 3 seconds and once for the last 3 seconds. """ # `has_sent_second_half_slot_tick` is used to prevent another tick # for the second half of a ticked slot. has_sent_second_half_slot_tick = False while self.is_operational: elapsed_time = Second(int(time.time()) - self.genesis_time) if elapsed_time >= self.seconds_per_slot: slot = Slot(elapsed_time // self.seconds_per_slot + self.genesis_slot) is_second_tick = ((elapsed_time % self.seconds_per_slot) >= (self.seconds_per_slot / 2)) # Case 1: new slot if slot > self.latest_slot: self.logger.debug( bold_green("Tick this_slot=%s elapsed=%s"), slot, elapsed_time, ) self.latest_slot = slot await self.event_bus.broadcast( SlotTickEvent( slot=slot, elapsed_time=elapsed_time, is_second_tick=is_second_tick, ), BroadcastConfig(internal=True), ) has_sent_second_half_slot_tick = is_second_tick # Case 2: second half of an already ticked slot and it hasn't tick yet elif is_second_tick and not has_sent_second_half_slot_tick: self.logger.debug( bold_green("Tick this_slot=%s (second-tick)"), slot) await self.event_bus.broadcast( SlotTickEvent( slot=slot, elapsed_time=elapsed_time, is_second_tick=is_second_tick, ), BroadcastConfig(internal=True), ) has_sent_second_half_slot_tick = True await asyncio.sleep(self.seconds_per_slot // DEFAULT_CHECK_FREQUENCY)
def _decoder( # NOTE: mypy incorrectly thinks `Field` is a generic type data: Dict[str, EncodedConfigTypes], fields: Collection[Field], # type: ignore ) -> Iterable[Tuple[str, ConfigTypes]]: # NOTE: this code is unwieldly but it satisfies `mypy` for field in fields: if field.type is Gwei: yield field.name, Gwei(cast(int, data[field.name])) elif field.type is Slot: yield field.name, Slot(cast(int, data[field.name])) elif field.type is Epoch: yield field.name, Epoch(cast(int, data[field.name])) elif field.type is Second: yield field.name, Second(cast(int, data[field.name])) elif field.type is bytes: yield field.name, decode_hex(cast(str, data[field.name])) else: yield field.name, int(data[field.name])
async def _keep_ticking(self) -> None: while self.is_operational: elapsed_time = Second(int(time.time()) - self.genesis_time) if elapsed_time >= self.seconds_per_slot: slot = Slot(elapsed_time // self.seconds_per_slot + self.genesis_slot) if slot > self.latest_slot: self.logger.debug( bold_green( f"New slot: {slot}\tElapsed time: {elapsed_time}")) self.latest_slot = slot self.event_bus.broadcast( NewSlotEvent( slot=slot, elapsed_time=elapsed_time, ), BroadcastConfig(internal=True), ) await asyncio.sleep(self.seconds_per_slot // DEFAULT_CHECK_FREQUENCY)
HYSTERESIS_DOWNWARD_MULTIPLIER=1, HYSTERESIS_UPWARD_MULTIPLIER=5, # Genesis MIN_GENESIS_ACTIVE_VALIDATOR_COUNT=2**14, MIN_GENESIS_TIME=1578009600, # (= Jan 3, 2020) # Gwei values MIN_DEPOSIT_AMOUNT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei MAX_EFFECTIVE_BALANCE=Gwei(2**5 * GWEI_PER_ETH), # (= 32,000,000,00) Gwei EJECTION_BALANCE=Gwei(2**4 * GWEI_PER_ETH), # (= 16,000,000,000) Gwei EFFECTIVE_BALANCE_INCREMENT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei # Initial values GENESIS_FORK_VERSION=Version(b"\x00" * 4), BLS_WITHDRAWAL_PREFIX=b"\x00", # Time parameters GENESIS_DELAY=Second(172800), SECONDS_PER_SLOT=Second(12), # seconds MIN_ATTESTATION_INCLUSION_DELAY=2**0, # (= 1) slots SLOTS_PER_EPOCH=2**5, # (= 32) slots MIN_SEED_LOOKAHEAD=2**0, # (= 1) epochs MAX_SEED_LOOKAHEAD=2**2, # (= 4) epochs SLOTS_PER_HISTORICAL_ROOT=2**13, # (= 8,192) slots MIN_VALIDATOR_WITHDRAWABILITY_DELAY=2**8, # (= 256) epochs SHARD_COMMITTEE_PERIOD=2**8, # (= 256) epochs MIN_EPOCHS_TO_INACTIVITY_PENALTY=2**2, # State list lengths EPOCHS_PER_ETH1_VOTING_PERIOD=32, EPOCHS_PER_HISTORICAL_VECTOR=2**16, EPOCHS_PER_SLASHINGS_VECTOR=2**13, HISTORICAL_ROOTS_LIMIT=2**24, VALIDATOR_REGISTRY_LIMIT=2**40,
SHUFFLE_ROUND_COUNT=90, # Genesis MIN_GENESIS_ACTIVE_VALIDATOR_COUNT=2**16, MIN_GENESIS_TIME=1578009600, # (= Jan 3, 2020) # Gwei values MIN_DEPOSIT_AMOUNT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei MAX_EFFECTIVE_BALANCE=Gwei(2**5 * GWEI_PER_ETH), # (= 32,000,000,00) Gwei EJECTION_BALANCE=Gwei(2**4 * GWEI_PER_ETH), # (= 16,000,000,000) Gwei EFFECTIVE_BALANCE_INCREMENT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei # Initial values GENESIS_SLOT=Slot(0), GENESIS_EPOCH=Epoch(0), BLS_WITHDRAWAL_PREFIX=0, # Time parameters SECONDS_PER_SLOT=Second(12), # seconds MIN_ATTESTATION_INCLUSION_DELAY=2**0, # (= 1) slots SLOTS_PER_EPOCH=2**5, # (= 32) slots MIN_SEED_LOOKAHEAD=2**0, # (= 1) epochs MAX_SEED_LOOKAHEAD=2**2, # (= 4) epochs SLOTS_PER_ETH1_VOTING_PERIOD=2**10, # (= 16) epochs SLOTS_PER_HISTORICAL_ROOT=2**13, # (= 8,192) slots MIN_VALIDATOR_WITHDRAWABILITY_DELAY=2**8, # (= 256) epochs PERSISTENT_COMMITTEE_PERIOD=2**11, # (= 2,048) epochs MIN_EPOCHS_TO_INACTIVITY_PENALTY=2**2, # State list lengths EPOCHS_PER_HISTORICAL_VECTOR=2**16, EPOCHS_PER_SLASHINGS_VECTOR=2**13, HISTORICAL_ROOTS_LIMIT=2**24, VALIDATOR_REGISTRY_LIMIT=2**40, # Reward and penalty quotients
DEPOSIT_CONTRACT_ADDRESS=ZERO_ADDRESS, # TBD DEPOSIT_CONTRACT_TREE_DEPTH=2**5, # (= 32) # Gwei values MIN_DEPOSIT_AMOUNT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei MAX_DEPOSIT_AMOUNT=Gwei(2**5 * GWEI_PER_ETH), # (= 32,000,000,00) Gwei FORK_CHOICE_BALANCE_INCREMENT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei EJECTION_BALANCE=Gwei(2**4 * GWEI_PER_ETH), # (= 16,000,000,000) Gwei # Initial values GENESIS_FORK_VERSION=0, GENESIS_SLOT=GENESIS_SLOT, GENESIS_EPOCH=slot_to_epoch(GENESIS_SLOT, SLOTS_PER_EPOCH), GENESIS_START_SHARD=Shard(0), BLS_WITHDRAWAL_PREFIX_BYTE=b'\x00', # Time parameters SECONDS_PER_SLOT=Second(6), # seconds MIN_ATTESTATION_INCLUSION_DELAY=2**2, # (= 4) slots SLOTS_PER_EPOCH=SLOTS_PER_EPOCH, # (= 64) slots MIN_SEED_LOOKAHEAD=2**0, # (= 1) epochs ACTIVATION_EXIT_DELAY=2**2, # (= 4) epochs EPOCHS_PER_ETH1_VOTING_PERIOD=2**4, # (= 16) epochs MIN_VALIDATOR_WITHDRAWABILITY_DELAY=2**8, # (= 256) epochs PERSISTENT_COMMITTEE_PERIOD=2**11, # (= 2,048) epochs # State list lengths SLOTS_PER_HISTORICAL_ROOT=2**13, # (= 8,192) slots LATEST_ACTIVE_INDEX_ROOTS_LENGTH=2**13, # (= 8,192) epochs LATEST_RANDAO_MIXES_LENGTH=2**13, # (= 8,192) epochs LATEST_SLASHED_EXIT_LENGTH=2**13, # (= 8,192) epochs # Reward and penalty quotients BASE_REWARD_QUOTIENT=2**10, # (= 1,024) WHISTLEBLOWER_REWARD_QUOTIENT=2**9, # (= 512)
MAX_CASPER_VOTES=2**10, # (= 1,024) votes LATEST_BLOCK_ROOTS_LENGTH=2**13, # (= 8,192) block roots LATEST_RANDAO_MIXES_LENGTH=2**13, # (= 8,192) randao mixes LATEST_PENALIZED_EXIT_LENGTH=2**13, # (= 8,192) randao mixes # Deposit contract DEPOSIT_CONTRACT_ADDRESS=ZERO_ADDRESS, # TBD DEPOSIT_CONTRACT_TREE_DEPTH=2**5, # (= 32) MIN_DEPOSIT=Ether(2**0), # (= 1) ETH MAX_DEPOSIT=Ether(2**5), # (= 32) ETH # Initial values GENESIS_FORK_VERSION=0, GENESIS_SLOT=SlotNumber(0), GENESIS_START_SHARD=ShardNumber(0), BLS_WITHDRAWAL_PREFIX_BYTE=b'\x00', # Time parameters SLOT_DURATION=Second(6), # seconds MIN_ATTESTATION_INCLUSION_DELAY=2**2, # (= 4) slots EPOCH_LENGTH=2**6, # (= 64) slots SEED_LOOKAHEAD=2**6, # (= 64) slots ENTRY_EXIT_DELAY=2**8, # (= 256) slots ETH1_DATA_VOTING_PERIOD=2**10, # (= 1,024) slots MIN_VALIDATOR_WITHDRAWAL_TIME=2**14, # (= 16,384) slots # Reward and penalty quotients BASE_REWARD_QUOTIENT=2**10, # (= 1,024) WHISTLEBLOWER_REWARD_QUOTIENT=2**9, # (= 512) INCLUDER_REWARD_QUOTIENT=2**3, # (= 8) INACTIVITY_PENALTY_QUOTIENT=2**24, # (= 16,777,216) # Max operations per block MAX_PROPOSER_SLASHINGS=2**4, # (= 16) MAX_CASPER_SLASHINGS=2**4, # (= 16) MAX_ATTESTATIONS=2**7, # (= 128)
HYSTERESIS_DOWNWARD_MULTIPLIER=1, HYSTERESIS_UPWARD_MULTIPLIER=5, # Genesis MIN_GENESIS_ACTIVE_VALIDATOR_COUNT=64, MIN_GENESIS_TIME=1578009600, # (= Jan 3, 2020) # Gwei values MIN_DEPOSIT_AMOUNT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei MAX_EFFECTIVE_BALANCE=Gwei(2**5 * GWEI_PER_ETH), # (= 32,000,000,00) Gwei EJECTION_BALANCE=Gwei(2**4 * GWEI_PER_ETH), # (= 16,000,000,000) Gwei EFFECTIVE_BALANCE_INCREMENT=Gwei(2**0 * GWEI_PER_ETH), # (= 1,000,000,000) Gwei # Initial values GENESIS_FORK_VERSION=Version(b"\x00" * 4), BLS_WITHDRAWAL_PREFIX=b"\x00", # Time parameters GENESIS_DELAY=Second(300), SECONDS_PER_SLOT=Second(6), # seconds MIN_ATTESTATION_INCLUSION_DELAY=2**0, # (= 1) slots SLOTS_PER_EPOCH=8, MIN_SEED_LOOKAHEAD=2**0, # (= 1) epochs MAX_SEED_LOOKAHEAD=2**2, # (= 4) epochs SLOTS_PER_HISTORICAL_ROOT=64, MIN_VALIDATOR_WITHDRAWABILITY_DELAY=256, SHARD_COMMITTEE_PERIOD=2**6, # (= 64) epochs MIN_EPOCHS_TO_INACTIVITY_PENALTY=4, # State list lengths EPOCHS_PER_ETH1_VOTING_PERIOD=2**32, EPOCHS_PER_HISTORICAL_VECTOR=64, EPOCHS_PER_SLASHINGS_VECTOR=64, HISTORICAL_ROOTS_LIMIT=2**24, VALIDATOR_REGISTRY_LIMIT=2**40,