mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 19:51:47 +00:00
Add Capella & Deneb light client support (#4946)
* rebase and add comment * conditional test * test * optimistic chould be working now * finality should be working now * try again * try again * clippy fix * add lc bootstrap beacon api * add lc optimistic/finality update to events * fmt * That error isn't occuring on my computer but I think this should fix it * Merge branch 'unstable' into light_client_beacon_api_1 # Conflicts: # beacon_node/beacon_chain/src/events.rs # beacon_node/http_api/src/lib.rs # beacon_node/http_api/src/test_utils.rs # beacon_node/http_api/tests/main.rs # beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs # beacon_node/lighthouse_network/src/rpc/methods.rs # beacon_node/lighthouse_network/src/service/api_types.rs # beacon_node/network/src/beacon_processor/worker/rpc_methods.rs # beacon_node/tests/test.rs # common/eth2/src/types.rs # lighthouse/src/main.rs * Add missing test file * Update light client types to comply with Altair light client spec. * Fix test compilation * Merge branch 'unstable' into light_client_beacon_api_1 * Support deserializing light client structures for the Bellatrix fork * Move `get_light_client_bootstrap` logic to `BeaconChain`. `LightClientBootstrap` API to return `ForkVersionedResponse`. * Misc fixes. - log cleanup - move http_api config mutation to `config::get_config` for consistency - fix light client API responses * Add light client bootstrap API test and fix existing ones. * Merge branch 'unstable' into light_client_beacon_api_1 * Fix test for `light-client-server` http api config. * Appease clippy * Add Altair light client SSZ tests * Merge branch 'unstable' of https://github.com/sigp/lighthouse into light_client_beacon_api_1 * updates to light client header * light client header from signed beacon block * using options * implement helper functions * placeholder conversion from vec hash256 to exec branch * add deneb * using fixed vector * remove unwraps * by epoch * compute merkle proof * merkle proof * update comments * resolve merge conflicts * linting * Merge branch 'unstable' into light-client-ssz-tests # Conflicts: # beacon_node/beacon_chain/src/beacon_chain.rs # consensus/types/src/light_client_bootstrap.rs # consensus/types/src/light_client_header.rs * superstruct attempt * superstruct changes * lint * altair * update * update * changes to light_client_optimistic_ and finality * merge unstable * refactor * resolved merge conflicts * Merge branch 'unstable' of https://github.com/sigp/lighthouse into capella_deneb_light_client_types * block_to_light_client_header fork aware * fmt * comment fix * comment fix * include merge fork, update deserialize_by_fork, refactor * fmt * pass by ref to prevent clone * rename merkle proof fn * add FIXME * LightClientHeader TestRandom * fix comments * fork version deserialize * merge unstable * move fn arguments, fork name calc * use task executor * remove unneeded fns * remove dead code * add manual ssz decoding/encoding and add ssz_tests_by_fork macro * merge deneb types with tests * merge ssz tests, revert code deletion, cleanup * move chainspec * update ssz tests * fmt * light client ssz tests * change to superstruct * changes from feedback * linting * Merge branch 'unstable' of https://github.com/sigp/lighthouse into capella_deneb_light_client_types * test fix * cleanup * Remove unused `derive`. * Merge branch 'unstable' of https://github.com/sigp/lighthouse into capella_deneb_light_client_types * beta compiler fix * merge
This commit is contained in:
@@ -8,7 +8,7 @@ use types::light_client_update::{FinalizedRootProofLen, FINALIZED_ROOT_INDEX};
|
||||
use types::non_zero_usize::new_non_zero_usize;
|
||||
use types::{
|
||||
BeaconBlockRef, BeaconState, ChainSpec, EthSpec, ForkName, Hash256, LightClientFinalityUpdate,
|
||||
LightClientHeader, LightClientOptimisticUpdate, Slot, SyncAggregate,
|
||||
LightClientOptimisticUpdate, Slot, SyncAggregate,
|
||||
};
|
||||
|
||||
/// A prev block cache miss requires to re-generate the state of the post-parent block. Items in the
|
||||
@@ -71,11 +71,12 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
|
||||
/// results are cached either on disk or memory to be served via p2p and rest API
|
||||
pub fn recompute_and_cache_updates(
|
||||
&self,
|
||||
log: &Logger,
|
||||
store: BeaconStore<T>,
|
||||
block_parent_root: &Hash256,
|
||||
block_slot: Slot,
|
||||
sync_aggregate: &SyncAggregate<T::EthSpec>,
|
||||
log: &Logger,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<(), BeaconChainError> {
|
||||
let _timer =
|
||||
metrics::start_timer(&metrics::LIGHT_CLIENT_SERVER_CACHE_RECOMPUTE_UPDATES_TIMES);
|
||||
@@ -83,12 +84,13 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
|
||||
let signature_slot = block_slot;
|
||||
let attested_block_root = block_parent_root;
|
||||
|
||||
let attested_block = store.get_blinded_block(attested_block_root)?.ok_or(
|
||||
BeaconChainError::DBInconsistent(format!(
|
||||
"Block not available {:?}",
|
||||
attested_block_root
|
||||
)),
|
||||
)?;
|
||||
let attested_block =
|
||||
store
|
||||
.get_full_block(attested_block_root)?
|
||||
.ok_or(BeaconChainError::DBInconsistent(format!(
|
||||
"Block not available {:?}",
|
||||
attested_block_root
|
||||
)))?;
|
||||
|
||||
let cached_parts = self.get_or_compute_prev_block_cache(
|
||||
store.clone(),
|
||||
@@ -109,11 +111,12 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
|
||||
};
|
||||
if is_latest_optimistic {
|
||||
// can create an optimistic update, that is more recent
|
||||
*self.latest_optimistic_update.write() = Some(LightClientOptimisticUpdate {
|
||||
attested_header: block_to_light_client_header(attested_block.message()),
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
*self.latest_optimistic_update.write() = Some(LightClientOptimisticUpdate::new(
|
||||
&attested_block,
|
||||
sync_aggregate.clone(),
|
||||
signature_slot,
|
||||
});
|
||||
chain_spec,
|
||||
)?);
|
||||
};
|
||||
|
||||
// Spec: Full nodes SHOULD provide the LightClientFinalityUpdate with the highest
|
||||
@@ -127,17 +130,16 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
|
||||
if is_latest_finality & !cached_parts.finalized_block_root.is_zero() {
|
||||
// Immediately after checkpoint sync the finalized block may not be available yet.
|
||||
if let Some(finalized_block) =
|
||||
store.get_blinded_block(&cached_parts.finalized_block_root)?
|
||||
store.get_full_block(&cached_parts.finalized_block_root)?
|
||||
{
|
||||
*self.latest_finality_update.write() = Some(LightClientFinalityUpdate {
|
||||
// TODO: may want to cache this result from latest_optimistic_update if producing a
|
||||
// light_client header becomes expensive
|
||||
attested_header: block_to_light_client_header(attested_block.message()),
|
||||
finalized_header: block_to_light_client_header(finalized_block.message()),
|
||||
finality_branch: cached_parts.finality_branch.clone(),
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
*self.latest_finality_update.write() = Some(LightClientFinalityUpdate::new(
|
||||
&attested_block,
|
||||
&finalized_block,
|
||||
cached_parts.finality_branch.clone(),
|
||||
sync_aggregate.clone(),
|
||||
signature_slot,
|
||||
});
|
||||
chain_spec,
|
||||
)?);
|
||||
} else {
|
||||
debug!(
|
||||
log,
|
||||
@@ -214,7 +216,7 @@ impl LightClientCachedData {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements spec priorization rules:
|
||||
// Implements spec prioritization rules:
|
||||
// > Full nodes SHOULD provide the LightClientFinalityUpdate with the highest attested_header.beacon.slot (if multiple, highest signature_slot)
|
||||
//
|
||||
// ref: https://github.com/ethereum/consensus-specs/blob/113c58f9bf9c08867f6f5f633c4d98e0364d612a/specs/altair/light-client/full-node.md#create_light_client_finality_update
|
||||
@@ -223,14 +225,15 @@ fn is_latest_finality_update<T: EthSpec>(
|
||||
attested_slot: Slot,
|
||||
signature_slot: Slot,
|
||||
) -> bool {
|
||||
if attested_slot > prev.attested_header.beacon.slot {
|
||||
let prev_slot = prev.get_attested_header_slot();
|
||||
if attested_slot > prev_slot {
|
||||
true
|
||||
} else {
|
||||
attested_slot == prev.attested_header.beacon.slot && signature_slot > prev.signature_slot
|
||||
attested_slot == prev_slot && signature_slot > *prev.signature_slot()
|
||||
}
|
||||
}
|
||||
|
||||
// Implements spec priorization rules:
|
||||
// Implements spec prioritization rules:
|
||||
// > Full nodes SHOULD provide the LightClientOptimisticUpdate with the highest attested_header.beacon.slot (if multiple, highest signature_slot)
|
||||
//
|
||||
// ref: https://github.com/ethereum/consensus-specs/blob/113c58f9bf9c08867f6f5f633c4d98e0364d612a/specs/altair/light-client/full-node.md#create_light_client_optimistic_update
|
||||
@@ -239,18 +242,10 @@ fn is_latest_optimistic_update<T: EthSpec>(
|
||||
attested_slot: Slot,
|
||||
signature_slot: Slot,
|
||||
) -> bool {
|
||||
if attested_slot > prev.attested_header.beacon.slot {
|
||||
let prev_slot = prev.get_slot();
|
||||
if attested_slot > prev_slot {
|
||||
true
|
||||
} else {
|
||||
attested_slot == prev.attested_header.beacon.slot && signature_slot > prev.signature_slot
|
||||
}
|
||||
}
|
||||
|
||||
fn block_to_light_client_header<T: EthSpec>(
|
||||
block: BeaconBlockRef<T, types::BlindedPayload<T>>,
|
||||
) -> LightClientHeader {
|
||||
// TODO: make fork aware
|
||||
LightClientHeader {
|
||||
beacon: block.block_header(),
|
||||
attested_slot == prev_slot && signature_slot > *prev.signature_slot()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user