API for LightClientBootstrap, LightClientFinalityUpdate, LightClientOptimisticUpdate and light client events (#3954)

* 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

* Add missing test file

* Update light client types to comply with Altair light client spec.

* Fix test compilation

* 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.

* Fix test for `light-client-server` http api config.

* Appease clippy

* Efficiency improvement when retrieving beacon state.

---------

Co-authored-by: Jimmy Chen <jchen.tc@gmail.com>
This commit is contained in:
GeemoCandama
2023-11-28 00:14:29 -06:00
committed by GitHub
parent 44c1817c2b
commit 8a599ec7dc
24 changed files with 632 additions and 111 deletions

View File

@@ -18,9 +18,7 @@ use std::sync::Arc;
use task_executor::TaskExecutor;
use tokio_stream::StreamExt;
use types::blob_sidecar::BlobIdentifier;
use types::{
light_client_bootstrap::LightClientBootstrap, Epoch, EthSpec, ForkName, Hash256, Slot,
};
use types::{Epoch, EthSpec, ForkName, Hash256, Slot};
impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
/* Auxiliary functions */
@@ -304,66 +302,32 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
request: LightClientBootstrapRequest,
) {
let block_root = request.root;
let state_root = match self.chain.get_blinded_block(&block_root) {
Ok(signed_block) => match signed_block {
Some(signed_block) => signed_block.state_root(),
None => {
self.send_error_response(
peer_id,
RPCResponseErrorCode::ResourceUnavailable,
"Bootstrap not available".into(),
request_id,
);
return;
}
},
Err(_) => {
self.send_error_response(
peer_id,
RPCResponseErrorCode::ResourceUnavailable,
"Bootstrap not available".into(),
request_id,
);
return;
}
};
let mut beacon_state = match self.chain.get_state(&state_root, None) {
Ok(beacon_state) => match beacon_state {
Some(state) => state,
None => {
self.send_error_response(
peer_id,
RPCResponseErrorCode::ResourceUnavailable,
"Bootstrap not available".into(),
request_id,
);
return;
}
},
Err(_) => {
self.send_error_response(
peer_id,
RPCResponseErrorCode::ResourceUnavailable,
"Bootstrap not available".into(),
request_id,
);
return;
}
};
let Ok(bootstrap) = LightClientBootstrap::from_beacon_state(&mut beacon_state) else {
self.send_error_response(
match self.chain.get_light_client_bootstrap(&block_root) {
Ok(Some((bootstrap, _))) => self.send_response(
peer_id,
Response::LightClientBootstrap(bootstrap),
request_id,
),
Ok(None) => self.send_error_response(
peer_id,
RPCResponseErrorCode::ResourceUnavailable,
"Bootstrap not available".into(),
request_id,
);
return;
),
Err(e) => {
self.send_error_response(
peer_id,
RPCResponseErrorCode::ResourceUnavailable,
"Bootstrap not available".into(),
request_id,
);
error!(self.log, "Error getting LightClientBootstrap instance";
"block_root" => ?block_root,
"peer" => %peer_id,
"error" => ?e
)
}
};
self.send_response(
peer_id,
Response::LightClientBootstrap(bootstrap),
request_id,
)
}
/// Handle a `BlocksByRange` request from the peer.