mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-03 21:04:28 +00:00
Add fork choice persistence
This commit is contained in:
@@ -145,6 +145,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
op_pool: PersistedOperationPool::from_operation_pool(&self.op_pool),
|
op_pool: PersistedOperationPool::from_operation_pool(&self.op_pool),
|
||||||
genesis_block_root: self.genesis_block_root,
|
genesis_block_root: self.genesis_block_root,
|
||||||
ssz_head_tracker: self.head_tracker.to_ssz_container(),
|
ssz_head_tracker: self.head_tracker.to_ssz_container(),
|
||||||
|
fork_choice_ssz_bytes: self.fork_choice.as_bytes(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let key = Hash256::from_slice(&BEACON_CHAIN_DB_KEY.as_bytes());
|
let key = Hash256::from_slice(&BEACON_CHAIN_DB_KEY.as_bytes());
|
||||||
|
|||||||
@@ -388,9 +388,7 @@ where
|
|||||||
event_handler: self
|
event_handler: self
|
||||||
.event_handler
|
.event_handler
|
||||||
.ok_or_else(|| "Cannot build without an event handler".to_string())?,
|
.ok_or_else(|| "Cannot build without an event handler".to_string())?,
|
||||||
head_tracker: self
|
head_tracker: self.head_tracker.unwrap_or_default(),
|
||||||
.head_tracker
|
|
||||||
.ok_or_else(|| "Cannot build without a head tracker".to_string())?,
|
|
||||||
log: log.clone(),
|
log: log.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -430,21 +428,27 @@ where
|
|||||||
/// `ThreadSafeReducedTree` backend.
|
/// `ThreadSafeReducedTree` backend.
|
||||||
///
|
///
|
||||||
/// Requires the store and state to be initialized.
|
/// Requires the store and state to be initialized.
|
||||||
pub fn empty_reduced_tree_fork_choice(self) -> Result<Self, String> {
|
pub fn reduced_tree_fork_choice(self) -> Result<Self, String> {
|
||||||
let store = self
|
let store = self
|
||||||
.store
|
.store
|
||||||
.clone()
|
.clone()
|
||||||
.ok_or_else(|| "reduced_tree_fork_choice requires a store")?;
|
.ok_or_else(|| "reduced_tree_fork_choice requires a store")?;
|
||||||
let finalized_checkpoint = &self
|
|
||||||
.finalized_checkpoint
|
|
||||||
.as_ref()
|
|
||||||
.expect("should have finalized checkpoint");
|
|
||||||
|
|
||||||
let backend = ThreadSafeReducedTree::new(
|
let backend = if let Some(persisted_beacon_chain) = &self.persisted_beacon_chain {
|
||||||
store.clone(),
|
ThreadSafeReducedTree::from_bytes(&persisted_beacon_chain.fork_choice_ssz_bytes, store)
|
||||||
&finalized_checkpoint.beacon_block,
|
.map_err(|e| format!("Unable to decode fork choice from db: {:?}", e))?
|
||||||
finalized_checkpoint.beacon_block_root,
|
} else {
|
||||||
);
|
let finalized_checkpoint = &self
|
||||||
|
.finalized_checkpoint
|
||||||
|
.as_ref()
|
||||||
|
.expect("should have finalized checkpoint");
|
||||||
|
|
||||||
|
ThreadSafeReducedTree::new(
|
||||||
|
store.clone(),
|
||||||
|
&finalized_checkpoint.beacon_block,
|
||||||
|
finalized_checkpoint.beacon_block_root,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
self.fork_choice_backend(backend)
|
self.fork_choice_backend(backend)
|
||||||
}
|
}
|
||||||
@@ -623,7 +627,7 @@ mod test {
|
|||||||
.null_event_handler()
|
.null_event_handler()
|
||||||
.testing_slot_clock(Duration::from_secs(1))
|
.testing_slot_clock(Duration::from_secs(1))
|
||||||
.expect("should configure testing slot clock")
|
.expect("should configure testing slot clock")
|
||||||
.empty_reduced_tree_fork_choice()
|
.reduced_tree_fork_choice()
|
||||||
.expect("should add fork choice to builder")
|
.expect("should add fork choice to builder")
|
||||||
.build()
|
.build()
|
||||||
.expect("should build");
|
.expect("should build");
|
||||||
|
|||||||
@@ -291,6 +291,14 @@ impl<T: BeaconChainTypes> ForkChoice<T> {
|
|||||||
.update_finalized_root(finalized_block, finalized_block_root)
|
.update_finalized_root(finalized_block, finalized_block_root)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a byte-level representation of the present state of the fork choice cache.
|
||||||
|
///
|
||||||
|
/// This simply calls `as_bytes()`, on the backend. To decode these bytes, decode the backend
|
||||||
|
/// directly then use `Self::new(..)`.
|
||||||
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
|
self.backend.as_bytes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BeaconStateError> for Error {
|
impl From<BeaconStateError> for Error {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub struct PersistedBeaconChain<T: BeaconChainTypes> {
|
|||||||
pub op_pool: PersistedOperationPool<T::EthSpec>,
|
pub op_pool: PersistedOperationPool<T::EthSpec>,
|
||||||
pub genesis_block_root: Hash256,
|
pub genesis_block_root: Hash256,
|
||||||
pub ssz_head_tracker: SszHeadTracker,
|
pub ssz_head_tracker: SszHeadTracker,
|
||||||
|
pub fork_choice_ssz_bytes: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BeaconChainTypes> SimpleStoreItem for PersistedBeaconChain<T> {
|
impl<T: BeaconChainTypes> SimpleStoreItem for PersistedBeaconChain<T> {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl<E: EthSpec> BeaconChainHarness<HarnessType<E>> {
|
|||||||
.null_event_handler()
|
.null_event_handler()
|
||||||
.testing_slot_clock(Duration::from_secs(1))
|
.testing_slot_clock(Duration::from_secs(1))
|
||||||
.expect("should configure testing slot clock")
|
.expect("should configure testing slot clock")
|
||||||
.empty_reduced_tree_fork_choice()
|
.reduced_tree_fork_choice()
|
||||||
.expect("should add fork choice to builder")
|
.expect("should add fork choice to builder")
|
||||||
.build()
|
.build()
|
||||||
.expect("should build");
|
.expect("should build");
|
||||||
@@ -142,7 +142,7 @@ impl<E: EthSpec> BeaconChainHarness<DiskHarnessType<E>> {
|
|||||||
.null_event_handler()
|
.null_event_handler()
|
||||||
.testing_slot_clock(Duration::from_secs(1))
|
.testing_slot_clock(Duration::from_secs(1))
|
||||||
.expect("should configure testing slot clock")
|
.expect("should configure testing slot clock")
|
||||||
.empty_reduced_tree_fork_choice()
|
.reduced_tree_fork_choice()
|
||||||
.expect("should add fork choice to builder")
|
.expect("should add fork choice to builder")
|
||||||
.build()
|
.build()
|
||||||
.expect("should build");
|
.expect("should build");
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ where
|
|||||||
.clone()
|
.clone()
|
||||||
.ok_or_else(|| "beacon_chain requires a slot clock")?,
|
.ok_or_else(|| "beacon_chain requires a slot clock")?,
|
||||||
)
|
)
|
||||||
.empty_reduced_tree_fork_choice()
|
.reduced_tree_fork_choice()
|
||||||
.map_err(|e| format!("Failed to init fork choice: {}", e))?
|
.map_err(|e| format!("Failed to init fork choice: {}", e))?
|
||||||
.build()
|
.build()
|
||||||
.map_err(|e| format!("Failed to build beacon chain: {}", e))?;
|
.map_err(|e| format!("Failed to build beacon chain: {}", e))?;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ pub trait LmdGhost<S: Store, E: EthSpec>: Send + Sync + Sized {
|
|||||||
fn verify_integrity(&self) -> Result<()>;
|
fn verify_integrity(&self) -> Result<()>;
|
||||||
|
|
||||||
/// Encode the `LmdGhost` instance to bytes.
|
/// Encode the `LmdGhost` instance to bytes.
|
||||||
fn as_bytes(self) -> Vec<u8>;
|
fn as_bytes(&self) -> Vec<u8>;
|
||||||
|
|
||||||
/// Create a new `LmdGhost` instance given a `store` and encoded bytes.
|
/// Create a new `LmdGhost` instance given a `store` and encoded bytes.
|
||||||
fn from_bytes(bytes: &[u8], store: Arc<S>) -> Result<Self>;
|
fn from_bytes(bytes: &[u8], store: Arc<S>) -> Result<Self>;
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Consume the `ReducedTree` object and return its ssz encoded bytes representation.
|
/// Consume the `ReducedTree` object and return its ssz encoded bytes representation.
|
||||||
fn as_bytes(self) -> Vec<u8> {
|
fn as_bytes(&self) -> Vec<u8> {
|
||||||
self.core.into_inner().as_bytes()
|
self.core.read().as_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new `ThreadSafeReducedTree` instance from a `store` and the
|
/// Create a new `ThreadSafeReducedTree` instance from a `store` and the
|
||||||
|
|||||||
Reference in New Issue
Block a user