Implement checkpoint sync (#2244)

## Issue Addressed

Closes #1891
Closes #1784

## Proposed Changes

Implement checkpoint sync for Lighthouse, enabling it to start from a weak subjectivity checkpoint.

## Additional Info

- [x] Return unavailable status for out-of-range blocks requested by peers (#2561)
- [x] Implement sync daemon for fetching historical blocks (#2561)
- [x] Verify chain hashes (either in `historical_blocks.rs` or the calling module)
- [x] Consistency check for initial block + state
- [x] Fetch the initial state and block from a beacon node HTTP endpoint
- [x] Don't crash fetching beacon states by slot from the API
- [x] Background service for state reconstruction, triggered by CLI flag or API call.

Considered out of scope for this PR:

- Drop the requirement to provide the `--checkpoint-block` (this would require some pretty heavy refactoring of block verification)


Co-authored-by: Diva M <divma@protonmail.com>
This commit is contained in:
Michael Sproul
2021-09-22 00:37:28 +00:00
parent 280e4fe23d
commit 9667dc2f03
71 changed files with 4012 additions and 459 deletions

View File

@@ -34,8 +34,8 @@ pub enum UpdatePattern {
/// Map a chunk index to bytes that can be used to key the NoSQL database.
///
/// We shift chunks up by 1 to make room for a genesis chunk that is handled separately.
pub fn chunk_key(cindex: u64) -> [u8; 8] {
(cindex + 1).to_be_bytes()
pub fn chunk_key(cindex: usize) -> [u8; 8] {
(cindex as u64 + 1).to_be_bytes()
}
/// Return the database key for the genesis value.
@@ -73,6 +73,11 @@ pub trait Field<E: EthSpec>: Copy {
128
}
/// Convert a v-index (vector index) to a chunk index.
fn chunk_index(vindex: usize) -> usize {
vindex / Self::chunk_size()
}
/// Get the value of this field at the given vector index, from the state.
fn get_value(
state: &BeaconState<E>,
@@ -399,7 +404,7 @@ where
I: Iterator<Item = usize>,
{
for chunk_index in range {
let chunk_key = &chunk_key(chunk_index as u64)[..];
let chunk_key = &chunk_key(chunk_index)[..];
let existing_chunk =
Chunk::<F::Value>::load(store, F::column(), chunk_key)?.unwrap_or_else(Chunk::default);
@@ -440,7 +445,7 @@ fn range_query<S: KeyValueStore<E>, E: EthSpec, T: Decode + Encode>(
let mut result = Vec::with_capacity(len);
for chunk_index in range {
let key = &chunk_key(chunk_index as u64)[..];
let key = &chunk_key(chunk_index)[..];
let chunk = Chunk::load(store, column, key)?.ok_or(ChunkError::Missing { chunk_index })?;
result.push(chunk);
}