Persist light client bootstrap (#5915)

* persist light client updates

* update beacon chain to serve light client updates

* resolve todos

* cache best update

* extend cache parts

* is better light client update

* resolve merge conflict

* initial api changes

* add lc update db column

* fmt

* added tests

* add sim

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates

* fix some weird issues with the simulator

* tests

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates

* test changes

* merge conflict

* testing

* started work on ef tests and some code clean up

* update tests

* linting

* noop pre altair, were still failing on electra though

* allow for zeroed light client header

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates

* merge unstable

* remove unwraps

* remove unwraps

* fetch bootstrap without always querying for state

* storing bootstrap parts in db

* mroe code cleanup

* test

* prune sync committee branches from dropped chains

* Update light_client_update.rs

* merge unstable

* move functionality to helper methods

* refactor is best update fn

* refactor is best update fn

* improve organization of light client server cache logic

* fork diget calc, and only spawn as many blcoks as we need for the lc update test

* resovle merge conflict

* add electra bootstrap logic, add logic to cache current sync committee

* add latest sync committe branch cache

* fetch lc update from the cache if it exists

* fmt

* Fix beacon_chain tests

* Add debug code to update ranking_order ef test

* Fix compare code

* merge conflicts

* merge conflict

* add better error messaging

* resolve merge conflicts

* remove lc update from basicsim

* rename sync comittte variable and fix persist condition

* refactor get_light_client_update logic

* add better comments, return helpful error messages over http and rpc

* pruning canonical non checkpoint slots

* fix test

* rerun test

* update pruning logic, add tests

* fix tests

* fix imports

* fmt

* refactor db code

* Refactor db method

* Refactor db method

* add additional comments

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-bootstrap

* fix merge

* linting

* merge conflict

* prevent overflow

* enable lc server for http api tests

* fix tests

* remove prints

* remove warning

* revert change
This commit is contained in:
Eitan Seri-Levi
2024-09-09 17:27:49 -07:00
committed by GitHub
parent 51091a40fa
commit a94b12b4d5
19 changed files with 733 additions and 238 deletions

View File

@@ -31,7 +31,7 @@ mod validator_inclusion;
mod validators;
mod version;
use crate::light_client::get_light_client_updates;
use crate::light_client::{get_light_client_bootstrap, get_light_client_updates};
use crate::produce_block::{produce_blinded_block_v2, produce_block_v2, produce_block_v3};
use crate::version::fork_versioned_response;
use beacon_chain::{
@@ -2411,40 +2411,7 @@ pub fn serve<T: BeaconChainTypes>(
block_root: Hash256,
accept_header: Option<api_types::Accept>| {
task_spawner.blocking_response_task(Priority::P1, move || {
let (bootstrap, fork_name) = match chain.get_light_client_bootstrap(&block_root)
{
Ok(Some(res)) => res,
Ok(None) => {
return Err(warp_utils::reject::custom_not_found(
"Light client bootstrap unavailable".to_string(),
));
}
Err(e) => {
return Err(warp_utils::reject::custom_server_error(format!(
"Unable to obtain LightClientBootstrap instance: {e:?}"
)));
}
};
match accept_header {
Some(api_types::Accept::Ssz) => Response::builder()
.status(200)
.body(bootstrap.as_ssz_bytes().into())
.map(|res: Response<Body>| add_ssz_content_type_header(res))
.map_err(|e| {
warp_utils::reject::custom_server_error(format!(
"failed to create response: {}",
e
))
}),
_ => Ok(warp::reply::json(&ForkVersionedResponse {
version: Some(fork_name),
metadata: EmptyMetadata {},
data: bootstrap,
})
.into_response()),
}
.map(|resp| add_consensus_version_header(resp, fork_name))
get_light_client_bootstrap::<T>(chain, &block_root, accept_header)
})
},
);

View File

@@ -1,18 +1,20 @@
use beacon_chain::{BeaconChain, BeaconChainTypes};
use crate::version::{
add_consensus_version_header, add_ssz_content_type_header, fork_versioned_response, V1,
};
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes};
use eth2::types::{
self as api_types, ChainSpec, ForkVersionedResponse, LightClientUpdate,
LightClientUpdateResponseChunk, LightClientUpdateSszResponse, LightClientUpdatesQuery,
};
use ssz::Encode;
use std::sync::Arc;
use types::{ForkName, Hash256, LightClientBootstrap};
use warp::{
hyper::{Body, Response},
reply::Reply,
Rejection,
};
use crate::version::{add_ssz_content_type_header, fork_versioned_response, V1};
const MAX_REQUEST_LIGHT_CLIENT_UPDATES: u64 = 128;
pub fn get_light_client_updates<T: BeaconChainTypes>(
@@ -62,6 +64,45 @@ pub fn get_light_client_updates<T: BeaconChainTypes>(
}
}
pub fn get_light_client_bootstrap<T: BeaconChainTypes>(
chain: Arc<BeaconChain<T>>,
block_root: &Hash256,
accept_header: Option<api_types::Accept>,
) -> Result<Response<Body>, Rejection> {
let (light_client_bootstrap, fork_name) = chain
.get_light_client_bootstrap(block_root)
.map_err(|err| {
let error_message = if let BeaconChainError::LightClientBootstrapError(err) = err {
println!("{:?}", err);
err
} else {
"No LightClientBootstrap found".to_string()
};
warp_utils::reject::custom_not_found(error_message)
})?
.ok_or(warp_utils::reject::custom_not_found(
"No LightClientBootstrap found".to_string(),
))?;
match accept_header {
Some(api_types::Accept::Ssz) => Response::builder()
.status(200)
.body(light_client_bootstrap.as_ssz_bytes().into())
.map(|res: Response<Body>| add_consensus_version_header(res, fork_name))
.map(|res: Response<Body>| add_ssz_content_type_header(res))
.map_err(|e| {
warp_utils::reject::custom_server_error(format!("failed to create response: {}", e))
}),
_ => {
let fork_versioned_response = map_light_client_bootstrap_to_json_response::<T>(
fork_name,
light_client_bootstrap,
)?;
Ok(warp::reply::json(&fork_versioned_response).into_response())
}
}
}
pub fn validate_light_client_updates_request<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
query: &LightClientUpdatesQuery,
@@ -131,6 +172,13 @@ fn map_light_client_update_to_ssz_chunk<T: BeaconChainTypes>(
}
}
fn map_light_client_bootstrap_to_json_response<T: BeaconChainTypes>(
fork_name: ForkName,
light_client_bootstrap: LightClientBootstrap<T::EthSpec>,
) -> Result<ForkVersionedResponse<LightClientBootstrap<T::EthSpec>>, Rejection> {
fork_versioned_response(V1, fork_name, light_client_bootstrap)
}
fn map_light_client_update_to_json_response<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
light_client_update: LightClientUpdate<T::EthSpec>,