Tidy BeaconStateCow
This commit is contained in:
parent
a0e019b4d7
commit
969b6d7575
@ -77,25 +77,31 @@ pub enum AttestationProcessingOutcome {
|
|||||||
Invalid(AttestationValidationError),
|
Invalid(AttestationValidationError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum StateCow<'a, T: EthSpec> {
|
/// Effectively a `Cow<BeaconState>`, however when it is `Borrowed` it holds a `RwLockReadGuard` (a
|
||||||
|
/// read-lock on some read/write-locked state).
|
||||||
|
///
|
||||||
|
/// Only has a small subset of the functionality of a `std::borrow::Cow`.
|
||||||
|
pub enum BeaconStateCow<'a, T: EthSpec> {
|
||||||
Borrowed(RwLockReadGuard<'a, CheckPoint<T>>),
|
Borrowed(RwLockReadGuard<'a, CheckPoint<T>>),
|
||||||
Owned(BeaconState<T>),
|
Owned(BeaconState<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec> AsRef<BeaconState<T>> for StateCow<'a, T> {
|
impl<'a, T: EthSpec> BeaconStateCow<'a, T> {
|
||||||
fn as_ref(&self) -> &BeaconState<T> {
|
pub fn maybe_as_mut_ref(&mut self) -> Option<&mut BeaconState<T>> {
|
||||||
match self {
|
match self {
|
||||||
StateCow::Borrowed(checkpoint) => &checkpoint.beacon_state,
|
BeaconStateCow::Borrowed(_) => None,
|
||||||
StateCow::Owned(state) => &state,
|
BeaconStateCow::Owned(ref mut state) => Some(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec> StateCow<'a, T> {
|
impl<'a, T: EthSpec> std::ops::Deref for BeaconStateCow<'a, T> {
|
||||||
pub fn as_mut_ref(&mut self) -> Option<&mut BeaconState<T>> {
|
type Target = BeaconState<T>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &BeaconState<T> {
|
||||||
match self {
|
match self {
|
||||||
StateCow::Borrowed(_) => None,
|
BeaconStateCow::Borrowed(checkpoint) => &checkpoint.beacon_state,
|
||||||
StateCow::Owned(ref mut state) => Some(state),
|
BeaconStateCow::Owned(state) => &state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,11 +380,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
///
|
///
|
||||||
/// Returns `None` when the state is not found in the database or there is an error skipping
|
/// Returns `None` when the state is not found in the database or there is an error skipping
|
||||||
/// to a future state.
|
/// to a future state.
|
||||||
pub fn state_at_slot(&self, slot: Slot) -> Result<StateCow<T::EthSpec>, Error> {
|
pub fn state_at_slot(&self, slot: Slot) -> Result<BeaconStateCow<T::EthSpec>, Error> {
|
||||||
let head_state = &self.head().beacon_state;
|
let head_state = &self.head().beacon_state;
|
||||||
|
|
||||||
if slot == head_state.slot {
|
if slot == head_state.slot {
|
||||||
Ok(StateCow::Borrowed(self.head()))
|
Ok(BeaconStateCow::Borrowed(self.head()))
|
||||||
} else if slot > head_state.slot {
|
} else if slot > head_state.slot {
|
||||||
let head_state_slot = head_state.slot;
|
let head_state_slot = head_state.slot;
|
||||||
let mut state = head_state.clone();
|
let mut state = head_state.clone();
|
||||||
@ -398,7 +404,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(StateCow::Owned(state))
|
Ok(BeaconStateCow::Owned(state))
|
||||||
} else {
|
} else {
|
||||||
let state_root = self
|
let state_root = self
|
||||||
.rev_iter_state_roots()
|
.rev_iter_state_roots()
|
||||||
@ -406,7 +412,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
.map(|(root, _slot)| root)
|
.map(|(root, _slot)| root)
|
||||||
.ok_or_else(|| Error::NoStateForSlot(slot))?;
|
.ok_or_else(|| Error::NoStateForSlot(slot))?;
|
||||||
|
|
||||||
Ok(StateCow::Owned(
|
Ok(BeaconStateCow::Owned(
|
||||||
self.store
|
self.store
|
||||||
.get(&state_root)?
|
.get(&state_root)?
|
||||||
.ok_or_else(|| Error::NoStateForSlot(slot))?,
|
.ok_or_else(|| Error::NoStateForSlot(slot))?,
|
||||||
@ -422,7 +428,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
///
|
///
|
||||||
/// Returns `None` when there is an error skipping to a future state or the slot clock cannot
|
/// Returns `None` when there is an error skipping to a future state or the slot clock cannot
|
||||||
/// be read.
|
/// be read.
|
||||||
pub fn state_now(&self) -> Result<StateCow<T::EthSpec>, Error> {
|
pub fn state_now(&self) -> Result<BeaconStateCow<T::EthSpec>, Error> {
|
||||||
self.state_at_slot(self.slot()?)
|
self.state_at_slot(self.slot()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,25 +471,24 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let head_state = &self.head().beacon_state;
|
let head_state = &self.head().beacon_state;
|
||||||
|
|
||||||
let mut state = if epoch(slot) == epoch(head_state.slot) {
|
let mut state = if epoch(slot) == epoch(head_state.slot) {
|
||||||
StateCow::Borrowed(self.head())
|
BeaconStateCow::Borrowed(self.head())
|
||||||
} else {
|
} else {
|
||||||
self.state_at_slot(slot)?
|
self.state_at_slot(slot)?
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(state) = state.as_mut_ref() {
|
if let Some(state) = state.maybe_as_mut_ref() {
|
||||||
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
|
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if epoch(state.as_ref().slot) != epoch(slot) {
|
if epoch(state.slot) != epoch(slot) {
|
||||||
return Err(Error::InvariantViolated(format!(
|
return Err(Error::InvariantViolated(format!(
|
||||||
"Epochs in consistent in proposer lookup: state: {}, requested: {}",
|
"Epochs in consistent in proposer lookup: state: {}, requested: {}",
|
||||||
epoch(state.as_ref().slot),
|
epoch(state.slot),
|
||||||
epoch(slot)
|
epoch(slot)
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
state
|
state
|
||||||
.as_ref()
|
|
||||||
.get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.spec)
|
.get_beacon_proposer_index(slot, RelativeEpoch::Current, &self.spec)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
@ -501,26 +506,25 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let head_state = &self.head().beacon_state;
|
let head_state = &self.head().beacon_state;
|
||||||
|
|
||||||
let mut state = if epoch == as_epoch(head_state.slot) {
|
let mut state = if epoch == as_epoch(head_state.slot) {
|
||||||
StateCow::Borrowed(self.head())
|
BeaconStateCow::Borrowed(self.head())
|
||||||
} else {
|
} else {
|
||||||
self.state_at_slot(epoch.start_slot(T::EthSpec::slots_per_epoch()))?
|
self.state_at_slot(epoch.start_slot(T::EthSpec::slots_per_epoch()))?
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(state) = state.as_mut_ref() {
|
if let Some(state) = state.maybe_as_mut_ref() {
|
||||||
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
|
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if as_epoch(state.as_ref().slot) != epoch {
|
if as_epoch(state.slot) != epoch {
|
||||||
return Err(Error::InvariantViolated(format!(
|
return Err(Error::InvariantViolated(format!(
|
||||||
"Epochs in consistent in attestation duties lookup: state: {}, requested: {}",
|
"Epochs in consistent in attestation duties lookup: state: {}, requested: {}",
|
||||||
as_epoch(state.as_ref().slot),
|
as_epoch(state.slot),
|
||||||
epoch
|
epoch
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(attestation_duty) = state
|
if let Some(attestation_duty) =
|
||||||
.as_ref()
|
state.get_attestation_duties(validator_index, RelativeEpoch::Current)?
|
||||||
.get_attestation_duties(validator_index, RelativeEpoch::Current)?
|
|
||||||
{
|
{
|
||||||
Ok(Some((attestation_duty.slot, attestation_duty.shard)))
|
Ok(Some((attestation_duty.slot, attestation_duty.shard)))
|
||||||
} else {
|
} else {
|
||||||
@ -541,12 +545,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let head_block_root = self.head().beacon_block_root;
|
let head_block_root = self.head().beacon_block_root;
|
||||||
let head_block_slot = self.head().beacon_block.slot;
|
let head_block_slot = self.head().beacon_block.slot;
|
||||||
|
|
||||||
self.produce_attestation_data_for_block(
|
self.produce_attestation_data_for_block(shard, head_block_root, head_block_slot, &*state)
|
||||||
shard,
|
|
||||||
head_block_root,
|
|
||||||
head_block_slot,
|
|
||||||
state.as_ref(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produce an `AttestationData` that attests to the chain denoted by `block_root` and `state`.
|
/// Produce an `AttestationData` that attests to the chain denoted by `block_root` and `state`.
|
||||||
@ -868,7 +867,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
match self.state_now() {
|
match self.state_now() {
|
||||||
Ok(state) => self
|
Ok(state) => self
|
||||||
.op_pool
|
.op_pool
|
||||||
.insert_voluntary_exit(exit, state.as_ref(), &self.spec),
|
.insert_voluntary_exit(exit, &*state, &self.spec),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!(
|
||||||
&self.log,
|
&self.log,
|
||||||
@ -884,9 +883,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
/// Accept some transfer and queue it for inclusion in an appropriate block.
|
/// Accept some transfer and queue it for inclusion in an appropriate block.
|
||||||
pub fn process_transfer(&self, transfer: Transfer) -> Result<(), TransferValidationError> {
|
pub fn process_transfer(&self, transfer: Transfer) -> Result<(), TransferValidationError> {
|
||||||
match self.state_now() {
|
match self.state_now() {
|
||||||
Ok(state) => self
|
Ok(state) => self.op_pool.insert_transfer(transfer, &*state, &self.spec),
|
||||||
.op_pool
|
|
||||||
.insert_transfer(transfer, state.as_ref(), &self.spec),
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!(
|
||||||
&self.log,
|
&self.log,
|
||||||
@ -907,7 +904,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
match self.state_now() {
|
match self.state_now() {
|
||||||
Ok(state) => {
|
Ok(state) => {
|
||||||
self.op_pool
|
self.op_pool
|
||||||
.insert_proposer_slashing(proposer_slashing, state.as_ref(), &self.spec)
|
.insert_proposer_slashing(proposer_slashing, &*state, &self.spec)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!(
|
||||||
@ -929,7 +926,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
match self.state_now() {
|
match self.state_now() {
|
||||||
Ok(state) => {
|
Ok(state) => {
|
||||||
self.op_pool
|
self.op_pool
|
||||||
.insert_attester_slashing(attester_slashing, state.as_ref(), &self.spec)
|
.insert_attester_slashing(attester_slashing, &*state, &self.spec)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!(
|
||||||
@ -1150,7 +1147,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
.state_at_slot(slot - 1)
|
.state_at_slot(slot - 1)
|
||||||
.map_err(|_| BlockProductionError::UnableToProduceAtSlot(slot))?;
|
.map_err(|_| BlockProductionError::UnableToProduceAtSlot(slot))?;
|
||||||
|
|
||||||
self.produce_block_on_state(state.as_ref().clone(), slot, randao_reveal)
|
self.produce_block_on_state(state.clone(), slot, randao_reveal)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produce a block for some `slot` upon the given `state`.
|
/// Produce a block for some `slot` upon the given `state`.
|
||||||
|
@ -32,7 +32,7 @@ impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
|
|||||||
let slot = epoch.start_slot(T::EthSpec::slots_per_epoch());
|
let slot = epoch.start_slot(T::EthSpec::slots_per_epoch());
|
||||||
|
|
||||||
let mut state = if let Ok(state) = self.chain.state_at_slot(slot) {
|
let mut state = if let Ok(state) = self.chain.state_at_slot(slot) {
|
||||||
state.as_ref().clone()
|
state.clone()
|
||||||
} else {
|
} else {
|
||||||
let log_clone = self.log.clone();
|
let log_clone = self.log.clone();
|
||||||
let f = sink
|
let f = sink
|
||||||
|
Loading…
Reference in New Issue
Block a user