Skip to content

Commit

Permalink
Add light client bootstrap API test and fix existing ones.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmygchen committed Nov 17, 2023
1 parent 80ff555 commit 75bd2ac
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 9 deletions.
11 changes: 8 additions & 3 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6469,9 +6469,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.fork_name(&self.spec)
.map_err(Error::InconsistentFork)?;

LightClientBootstrap::from_beacon_state(&mut state)
.map(|bootstrap| Some((bootstrap, fork_name)))
.map_err(Error::LightClientError)
match fork_name {
ForkName::Altair | ForkName::Merge => {
LightClientBootstrap::from_beacon_state(&mut state)
.map(|bootstrap| Some((bootstrap, fork_name)))
.map_err(Error::LightClientError)
}
ForkName::Base | ForkName::Capella | ForkName::Deneb => Err(Error::UnsupportedFork),
}
}
}

Expand Down
1 change: 1 addition & 0 deletions beacon_node/beacon_chain/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ pub enum BeaconChainError {
UnableToPublish,
AvailabilityCheckError(AvailabilityCheckError),
LightClientError(LightClientError),
UnsupportedFork,
}

easy_from_to!(SlotProcessingError, BeaconChainError);
Expand Down
1 change: 1 addition & 0 deletions beacon_node/http_api/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ pub async fn create_api_server<T: BeaconChainTypes>(
enabled: true,
listen_port: port,
data_dir: std::path::PathBuf::from(DEFAULT_ROOT_DIR),
enable_light_client_server: true,
..Config::default()
},
chain: Some(chain),
Expand Down
48 changes: 44 additions & 4 deletions beacon_node/http_api/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,26 @@ impl ApiTester {
self
}

pub async fn test_get_beacon_light_client_bootstrap(self) -> Self {
let block_id = BlockId(CoreBlockId::Finalized);
let (block_root, _, _) = block_id.root(&self.chain).unwrap();
let (block, _, _) = block_id.full_block(&self.chain).await.unwrap();

let result = match self
.client
.get_light_client_bootstrap::<E>(block_root)
.await
{
Ok(result) => result.unwrap().data,
Err(e) => panic!("query failed incorrectly: {e:?}"),
};

let expected = block.slot();
assert_eq!(result.header.beacon.slot, expected);

self
}

pub async fn test_get_beacon_light_client_optimistic_update(self) -> Self {
// get_beacon_light_client_optimistic_update returns Ok(None) on 404 NOT FOUND
let result = match self
Expand All @@ -1652,7 +1672,7 @@ impl ApiTester {
.await
{
Ok(result) => result.map(|res| res.data),
Err(_) => panic!("query did not fail correctly"),
Err(e) => panic!("query failed incorrectly: {e:?}"),
};

let expected = self.chain.latest_seen_optimistic_update.lock().clone();
Expand All @@ -1668,7 +1688,7 @@ impl ApiTester {
.await
{
Ok(result) => result.map(|res| res.data),
Err(_) => panic!("query did not fail correctly"),
Err(e) => panic!("query failed incorrectly: {e:?}"),
};

let expected = self.chain.latest_seen_finality_update.lock().clone();
Expand Down Expand Up @@ -5092,17 +5112,37 @@ async fn node_get() {
.await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn get_light_client_bootstrap() {
let config = ApiTesterConfig {
spec: ForkName::Altair.make_genesis_spec(E::default_spec()),
..<_>::default()
};
ApiTester::new_from_config(config)
.await
.test_get_beacon_light_client_bootstrap()
.await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn get_light_client_optimistic_update() {
ApiTester::new()
let config = ApiTesterConfig {
spec: ForkName::Altair.make_genesis_spec(E::default_spec()),
..<_>::default()
};
ApiTester::new_from_config(config)
.await
.test_get_beacon_light_client_optimistic_update()
.await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn get_light_client_finality_update() {
ApiTester::new()
let config = ApiTesterConfig {
spec: ForkName::Altair.make_genesis_spec(E::default_spec()),
..<_>::default()
};
ApiTester::new_from_config(config)
.await
.test_get_beacon_light_client_finality_update()
.await;
Expand Down
3 changes: 1 addition & 2 deletions consensus/types/src/light_client_bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use serde_json::Value;
use ssz_derive::{Decode, Encode};
use std::sync::Arc;
use test_random_derive::TestRandom;
use tree_hash::TreeHash;

/// A LightClientBootstrap is the initializer we send over to lightclient nodes
/// that are trying to generate their basic storage when booting up.
Expand Down Expand Up @@ -37,7 +36,7 @@ pub struct LightClientBootstrap<T: EthSpec> {
impl<T: EthSpec> LightClientBootstrap<T> {
pub fn from_beacon_state(beacon_state: &mut BeaconState<T>) -> Result<Self, Error> {
let mut header = beacon_state.latest_block_header().clone();
header.state_root = beacon_state.tree_hash_root();
header.state_root = beacon_state.update_tree_hash_cache()?;
let current_sync_committee_branch =
beacon_state.compute_merkle_proof(CURRENT_SYNC_COMMITTEE_INDEX)?;
Ok(LightClientBootstrap {
Expand Down

0 comments on commit 75bd2ac

Please sign in to comment.