Upgrade codebase to new SlotClock API
This commit is contained in:
parent
4557d2c84b
commit
7d03806107
@ -148,11 +148,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Slot clock
|
// Slot clock
|
||||||
let slot_clock = T::SlotClock::new(
|
let slot_clock = T::SlotClock::from_eth2_genesis(
|
||||||
spec.genesis_slot,
|
spec.genesis_slot,
|
||||||
genesis_state.genesis_time,
|
genesis_state.genesis_time,
|
||||||
spec.seconds_per_slot,
|
Duration::from_secs(spec.seconds_per_slot),
|
||||||
);
|
)
|
||||||
|
.ok_or_else(|| Error::SlotClockDidNotStart)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
spec,
|
spec,
|
||||||
@ -224,18 +225,13 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the slot clock, returns `Err` if the slot is unavailable.
|
/// Returns the slot _right now_ according to `self.slot_clock`. Returns `Err` if the slot is
|
||||||
|
/// unavailable.
|
||||||
///
|
///
|
||||||
/// The slot might be unavailable due to an error with the system clock, or if the present time
|
/// The slot might be unavailable due to an error with the system clock, or if the present time
|
||||||
/// is before genesis (i.e., a negative slot).
|
/// is before genesis (i.e., a negative slot).
|
||||||
///
|
pub fn slot(&self) -> Result<Slot, Error> {
|
||||||
/// This is distinct to `present_slot`, which simply reads the latest state. If a
|
self.slot_clock.now().ok_or_else(|| Error::UnableToReadSlot)
|
||||||
/// call to `read_slot_clock` results in a higher slot than a call to `present_slot`,
|
|
||||||
/// `self.state` should undergo per slot processing.
|
|
||||||
pub fn present_slot(&self) -> Result<Slot, Error> {
|
|
||||||
self.slot_clock
|
|
||||||
.present_slot()
|
|
||||||
.ok_or_else(|| Error::UnableToReadSlot)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the beacon block body for each beacon block root in `roots`.
|
/// Returns the beacon block body for each beacon block root in `roots`.
|
||||||
@ -348,10 +344,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
pub fn catchup_state(&self) -> Result<(), Error> {
|
pub fn catchup_state(&self) -> Result<(), Error> {
|
||||||
let spec = &self.spec;
|
let spec = &self.spec;
|
||||||
|
|
||||||
let present_slot = self
|
let present_slot = self.slot()?;
|
||||||
.slot_clock
|
|
||||||
.present_slot()
|
|
||||||
.ok_or_else(|| Error::UnableToReadSlot)?;
|
|
||||||
|
|
||||||
if self.state.read().slot < present_slot {
|
if self.state.read().slot < present_slot {
|
||||||
let mut state = self.state.write();
|
let mut state = self.state.write();
|
||||||
@ -394,7 +387,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
/// Reads the slot clock (see `self.read_slot_clock()` and returns the number of slots since
|
/// Reads the slot clock (see `self.read_slot_clock()` and returns the number of slots since
|
||||||
/// genesis.
|
/// genesis.
|
||||||
pub fn slots_since_genesis(&self) -> Option<SlotHeight> {
|
pub fn slots_since_genesis(&self) -> Option<SlotHeight> {
|
||||||
let now = self.slot_clock.present_slot()?;
|
let now = self.slot().ok()?;
|
||||||
let genesis_slot = self.spec.genesis_slot;
|
let genesis_slot = self.spec.genesis_slot;
|
||||||
|
|
||||||
if now < genesis_slot {
|
if now < genesis_slot {
|
||||||
@ -847,10 +840,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
return Ok(BlockProcessingOutcome::GenesisBlock);
|
return Ok(BlockProcessingOutcome::GenesisBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
let present_slot = self
|
let present_slot = self.slot()?;
|
||||||
.slot_clock
|
|
||||||
.present_slot()
|
|
||||||
.ok_or_else(|| Error::UnableToReadSlot)?;
|
|
||||||
|
|
||||||
if block.slot > present_slot {
|
if block.slot > present_slot {
|
||||||
return Ok(BlockProcessingOutcome::FutureSlot {
|
return Ok(BlockProcessingOutcome::FutureSlot {
|
||||||
@ -1013,9 +1003,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
) -> Result<(BeaconBlock<T::EthSpec>, BeaconState<T::EthSpec>), BlockProductionError> {
|
) -> Result<(BeaconBlock<T::EthSpec>, BeaconState<T::EthSpec>), BlockProductionError> {
|
||||||
let state = self.state.read().clone();
|
let state = self.state.read().clone();
|
||||||
let slot = self
|
let slot = self
|
||||||
.slot_clock
|
.slot()
|
||||||
.present_slot()
|
.map_err(|_| BlockProductionError::UnableToReadSlot)?;
|
||||||
.ok_or_else(|| BlockProductionError::UnableToReadSlot)?;
|
|
||||||
|
|
||||||
self.produce_block_on_state(state, slot, randao_reveal)
|
self.produce_block_on_state(state, slot, randao_reveal)
|
||||||
}
|
}
|
||||||
@ -1191,7 +1180,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
*self.state.write() = {
|
*self.state.write() = {
|
||||||
let mut state = self.canonical_head.read().beacon_state.clone();
|
let mut state = self.canonical_head.read().beacon_state.clone();
|
||||||
|
|
||||||
let present_slot = self.present_slot()?;
|
let present_slot = self.slot()?;
|
||||||
|
|
||||||
// If required, transition the new state to the present slot.
|
// If required, transition the new state to the present slot.
|
||||||
for _ in state.slot.as_u64()..present_slot.as_u64() {
|
for _ in state.slot.as_u64()..present_slot.as_u64() {
|
||||||
|
@ -151,7 +151,7 @@ where
|
|||||||
// Determine the slot for the first block (or skipped block).
|
// Determine the slot for the first block (or skipped block).
|
||||||
let state_slot = match block_strategy {
|
let state_slot = match block_strategy {
|
||||||
BlockStrategy::OnCanonicalHead => {
|
BlockStrategy::OnCanonicalHead => {
|
||||||
self.chain.present_slot().expect("should have a slot") - 1
|
self.chain.slot().expect("should have a slot") - 1
|
||||||
}
|
}
|
||||||
BlockStrategy::ForkCanonicalChainAt { previous_slot, .. } => previous_slot,
|
BlockStrategy::ForkCanonicalChainAt { previous_slot, .. } => previous_slot,
|
||||||
};
|
};
|
||||||
@ -161,16 +161,14 @@ where
|
|||||||
|
|
||||||
// Determine the first slot where a block should be built.
|
// Determine the first slot where a block should be built.
|
||||||
let mut slot = match block_strategy {
|
let mut slot = match block_strategy {
|
||||||
BlockStrategy::OnCanonicalHead => {
|
BlockStrategy::OnCanonicalHead => self.chain.slot().expect("should have a slot"),
|
||||||
self.chain.present_slot().expect("should have a slot")
|
|
||||||
}
|
|
||||||
BlockStrategy::ForkCanonicalChainAt { first_slot, .. } => first_slot,
|
BlockStrategy::ForkCanonicalChainAt { first_slot, .. } => first_slot,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut head_block_root = None;
|
let mut head_block_root = None;
|
||||||
|
|
||||||
for _ in 0..num_blocks {
|
for _ in 0..num_blocks {
|
||||||
while self.chain.present_slot().expect("should have a slot") < slot {
|
while self.chain.slot().expect("should have a slot") < slot {
|
||||||
self.advance_slot();
|
self.advance_slot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ where
|
|||||||
.map_err(error::Error::from)?,
|
.map_err(error::Error::from)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
if beacon_chain.read_slot_clock().is_none() {
|
if beacon_chain.slot().is_err() {
|
||||||
panic!("Cannot start client before genesis!")
|
panic!("Cannot start client before genesis!")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,9 @@ where
|
|||||||
// blocks and we're basically useless.
|
// blocks and we're basically useless.
|
||||||
{
|
{
|
||||||
let state_slot = beacon_chain.head().beacon_state.slot;
|
let state_slot = beacon_chain.head().beacon_state.slot;
|
||||||
let wall_clock_slot = beacon_chain.read_slot_clock().unwrap();
|
let wall_clock_slot = beacon_chain
|
||||||
|
.slot()
|
||||||
|
.expect("Cannot start client before genesis");
|
||||||
let slots_since_genesis = beacon_chain.slots_since_genesis().unwrap();
|
let slots_since_genesis = beacon_chain.slots_since_genesis().unwrap();
|
||||||
info!(
|
info!(
|
||||||
log,
|
log,
|
||||||
@ -176,7 +178,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (slot_timer_exit_signal, exit) = exit_future::signal();
|
let (slot_timer_exit_signal, exit) = exit_future::signal();
|
||||||
if let Ok(Some(duration_to_next_slot)) = beacon_chain.slot_clock.duration_to_next_slot() {
|
if let Some(duration_to_next_slot) = beacon_chain.slot_clock.duration_to_next_slot() {
|
||||||
// set up the validator work interval - start at next slot and proceed every slot
|
// set up the validator work interval - start at next slot and proceed every slot
|
||||||
let interval = {
|
let interval = {
|
||||||
// Set the interval to start at the next slot, and every slot after
|
// Set the interval to start at the next slot, and every slot after
|
||||||
@ -223,7 +225,7 @@ impl<T: BeaconChainTypes> Drop for Client<T> {
|
|||||||
|
|
||||||
fn do_state_catchup<T: BeaconChainTypes>(chain: &Arc<BeaconChain<T>>, log: &slog::Logger) {
|
fn do_state_catchup<T: BeaconChainTypes>(chain: &Arc<BeaconChain<T>>, log: &slog::Logger) {
|
||||||
// Only attempt to `catchup_state` if we can read the slot clock.
|
// Only attempt to `catchup_state` if we can read the slot clock.
|
||||||
if let Some(current_slot) = chain.read_slot_clock() {
|
if let Ok(current_slot) = chain.slot() {
|
||||||
let state_catchup_result = chain.catchup_state();
|
let state_catchup_result = chain.catchup_state();
|
||||||
|
|
||||||
let best_slot = chain.head().beacon_block.slot;
|
let best_slot = chain.head().beacon_block.slot;
|
||||||
|
@ -387,7 +387,7 @@ impl<T: BeaconChainTypes> SimpleSync<T> {
|
|||||||
"peer" => format!("{:?}", peer_id),
|
"peer" => format!("{:?}", peer_id),
|
||||||
"msg" => "Failed to return all requested hashes",
|
"msg" => "Failed to return all requested hashes",
|
||||||
"start_slot" => req.start_slot,
|
"start_slot" => req.start_slot,
|
||||||
"current_slot" => format!("{:?}", self.chain.present_slot()),
|
"current_slot" => format!("{:?}", self.chain.slot()),
|
||||||
"requested" => req.count,
|
"requested" => req.count,
|
||||||
"returned" => blocks.len(),
|
"returned" => blocks.len(),
|
||||||
);
|
);
|
||||||
|
@ -88,7 +88,7 @@ pub fn state_root_at_slot<T: BeaconChainTypes>(
|
|||||||
) -> Result<Hash256, ApiError> {
|
) -> Result<Hash256, ApiError> {
|
||||||
let head_state = &beacon_chain.head().beacon_state;
|
let head_state = &beacon_chain.head().beacon_state;
|
||||||
let current_slot = beacon_chain
|
let current_slot = beacon_chain
|
||||||
.present_slot()
|
.slot()
|
||||||
.map_err(|_| ApiError::ServerError("Unable to read slot clock".to_string()))?;
|
.map_err(|_| ApiError::ServerError("Unable to read slot clock".to_string()))?;
|
||||||
|
|
||||||
// There are four scenarios when obtaining a state for a given slot:
|
// There are four scenarios when obtaining a state for a given slot:
|
||||||
|
@ -123,8 +123,10 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
|
let genesis_time = 1567052589; // 29 August, 2019;
|
||||||
|
|
||||||
let mut state = BeaconState::new(
|
let mut state = BeaconState::new(
|
||||||
spec.min_genesis_time,
|
genesis_time,
|
||||||
Eth1Data {
|
Eth1Data {
|
||||||
deposit_root: Hash256::zero(),
|
deposit_root: Hash256::zero(),
|
||||||
deposit_count: 0,
|
deposit_count: 0,
|
||||||
|
@ -33,7 +33,7 @@ pub trait SlotClock: Send + Sync + Sized {
|
|||||||
|
|
||||||
fn new(genesis_slot: Slot, genesis: Instant, slot_duration: Duration) -> Self;
|
fn new(genesis_slot: Slot, genesis: Instant, slot_duration: Duration) -> Self;
|
||||||
|
|
||||||
fn present_slot(&self) -> Option<Slot>;
|
fn now(&self) -> Option<Slot>;
|
||||||
|
|
||||||
fn duration_to_next_slot(&self) -> Option<Duration>;
|
fn duration_to_next_slot(&self) -> Option<Duration>;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ lazy_static! {
|
|||||||
|
|
||||||
/// Update the global metrics `DEFAULT_REGISTRY` with info from the slot clock.
|
/// Update the global metrics `DEFAULT_REGISTRY` with info from the slot clock.
|
||||||
pub fn scrape_for_metrics<T: EthSpec, U: SlotClock>(clock: &U) {
|
pub fn scrape_for_metrics<T: EthSpec, U: SlotClock>(clock: &U) {
|
||||||
let present_slot = match clock.present_slot() {
|
let present_slot = match clock.now() {
|
||||||
Some(slot) => slot,
|
Some(slot) => slot,
|
||||||
_ => Slot::new(0),
|
_ => Slot::new(0),
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,7 @@ impl SlotClock for SystemTimeSlotClock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn present_slot(&self) -> Option<Slot> {
|
fn now(&self) -> Option<Slot> {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
if now < self.genesis {
|
if now < self.genesis {
|
||||||
@ -80,18 +80,18 @@ mod tests {
|
|||||||
|
|
||||||
let clock =
|
let clock =
|
||||||
SystemTimeSlotClock::new(genesis_slot, prior_genesis(0), Duration::from_secs(1));
|
SystemTimeSlotClock::new(genesis_slot, prior_genesis(0), Duration::from_secs(1));
|
||||||
assert_eq!(clock.present_slot(), Some(Slot::new(0)));
|
assert_eq!(clock.now(), Some(Slot::new(0)));
|
||||||
|
|
||||||
let clock =
|
let clock =
|
||||||
SystemTimeSlotClock::new(genesis_slot, prior_genesis(5), Duration::from_secs(1));
|
SystemTimeSlotClock::new(genesis_slot, prior_genesis(5), Duration::from_secs(1));
|
||||||
assert_eq!(clock.present_slot(), Some(Slot::new(5)));
|
assert_eq!(clock.now(), Some(Slot::new(5)));
|
||||||
|
|
||||||
let clock = SystemTimeSlotClock::new(
|
let clock = SystemTimeSlotClock::new(
|
||||||
genesis_slot,
|
genesis_slot,
|
||||||
Instant::now() - Duration::from_millis(500),
|
Instant::now() - Duration::from_millis(500),
|
||||||
Duration::from_secs(1),
|
Duration::from_secs(1),
|
||||||
);
|
);
|
||||||
assert_eq!(clock.present_slot(), Some(Slot::new(0)));
|
assert_eq!(clock.now(), Some(Slot::new(0)));
|
||||||
assert!(clock.duration_to_next_slot().unwrap() < Duration::from_millis(500));
|
assert!(clock.duration_to_next_slot().unwrap() < Duration::from_millis(500));
|
||||||
|
|
||||||
let clock = SystemTimeSlotClock::new(
|
let clock = SystemTimeSlotClock::new(
|
||||||
@ -99,7 +99,7 @@ mod tests {
|
|||||||
Instant::now() - Duration::from_millis(1_500),
|
Instant::now() - Duration::from_millis(1_500),
|
||||||
Duration::from_secs(1),
|
Duration::from_secs(1),
|
||||||
);
|
);
|
||||||
assert_eq!(clock.present_slot(), Some(Slot::new(1)));
|
assert_eq!(clock.now(), Some(Slot::new(1)));
|
||||||
assert!(clock.duration_to_next_slot().unwrap() < Duration::from_millis(500));
|
assert!(clock.duration_to_next_slot().unwrap() < Duration::from_millis(500));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ impl TestingSlotClock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn advance_slot(&self) {
|
pub fn advance_slot(&self) {
|
||||||
self.set_slot(self.present_slot().unwrap().as_u64() + 1)
|
self.set_slot(self.now().unwrap().as_u64() + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ impl SlotClock for TestingSlotClock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn present_slot(&self) -> Option<Slot> {
|
fn now(&self) -> Option<Slot> {
|
||||||
let slot = *self.slot.read().expect("TestingSlotClock poisoned.");
|
let slot = *self.slot.read().expect("TestingSlotClock poisoned.");
|
||||||
Some(slot)
|
Some(slot)
|
||||||
}
|
}
|
||||||
@ -50,8 +50,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_slot_now() {
|
fn test_slot_now() {
|
||||||
let clock = TestingSlotClock::new(Slot::new(10), Instant::now(), Duration::from_secs(0));
|
let clock = TestingSlotClock::new(Slot::new(10), Instant::now(), Duration::from_secs(0));
|
||||||
assert_eq!(clock.present_slot(), Some(Slot::new(10)));
|
assert_eq!(clock.now(), Some(Slot::new(10)));
|
||||||
clock.set_slot(123);
|
clock.set_slot(123);
|
||||||
assert_eq!(clock.present_slot(), Some(Slot::new(123)));
|
assert_eq!(clock.now(), Some(Slot::new(123)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,11 +167,9 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
|||||||
"Unable to start slot clock. Genesis may not have occurred yet. Exiting.".into()
|
"Unable to start slot clock. Genesis may not have occurred yet. Exiting.".into()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let current_slot = slot_clock
|
let current_slot = slot_clock.now().ok_or_else::<error_chain::Error, _>(|| {
|
||||||
.present_slot()
|
"Genesis has not yet occurred. Exiting.".into()
|
||||||
.ok_or_else::<error_chain::Error, _>(|| {
|
})?;
|
||||||
"Genesis has not yet occurred. Exiting.".into()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
/* Generate the duties manager */
|
/* Generate the duties manager */
|
||||||
|
|
||||||
@ -293,7 +291,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static, E: EthSpec> Service<B,
|
|||||||
fn update_current_slot(&mut self) -> error_chain::Result<()> {
|
fn update_current_slot(&mut self) -> error_chain::Result<()> {
|
||||||
let current_slot = self
|
let current_slot = self
|
||||||
.slot_clock
|
.slot_clock
|
||||||
.present_slot()
|
.now()
|
||||||
.ok_or_else::<error_chain::Error, _>(|| {
|
.ok_or_else::<error_chain::Error, _>(|| {
|
||||||
"Genesis is not in the past. Exiting.".into()
|
"Genesis is not in the past. Exiting.".into()
|
||||||
})?;
|
})?;
|
||||||
|
Loading…
Reference in New Issue
Block a user