Adjust get_block_header function to allow getting headers of past blocks

This commit is contained in:
ckoopmann 2023-02-03 08:33:27 +08:00
parent daa1e3792c
commit 5895118046
5 changed files with 45 additions and 4 deletions

View File

@ -92,7 +92,7 @@ impl<R: ConsensusRpc> ConsensusClient<R> {
} else if slot == finalized_slot {
self.store.finalized_header.clone().hash_tree_root()?
} else {
return Err(ConsensusError::PayloadNotFound(slot).into());
self.rpc.get_header(slot).await?.message.hash_tree_root()?
};
if verified_block_hash != block_hash {

View File

@ -1,7 +1,7 @@
use std::{fs::read_to_string, path::PathBuf};
use super::ConsensusRpc;
use crate::types::{BeaconBlock, Bootstrap, FinalityUpdate, OptimisticUpdate, Update};
use crate::types::{BeaconBlock, BeaconHeader, Bootstrap, FinalityUpdate, OptimisticUpdate, Update};
use async_trait::async_trait;
use eyre::Result;
pub struct MockRpc {
@ -42,6 +42,11 @@ impl ConsensusRpc for MockRpc {
Ok(serde_json::from_str(&block)?)
}
async fn get_header(&self, _slot: u64) -> Result<BeaconHeader> {
let header = read_to_string(self.testdata.join("headers.json"))?;
Ok(serde_json::from_str(&header)?)
}
async fn chain_id(&self) -> Result<u64> {
eyre::bail!("not implemented")
}

View File

@ -4,7 +4,7 @@ pub mod nimbus_rpc;
use async_trait::async_trait;
use eyre::Result;
use crate::types::{BeaconBlock, Bootstrap, FinalityUpdate, OptimisticUpdate, Update};
use crate::types::{BeaconBlock, BeaconHeader, Bootstrap, FinalityUpdate, Header, OptimisticUpdate, Update};
// implements https://github.com/ethereum/beacon-APIs/tree/master/apis/beacon/light_client
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
@ -16,5 +16,6 @@ pub trait ConsensusRpc {
async fn get_finality_update(&self) -> Result<FinalityUpdate>;
async fn get_optimistic_update(&self) -> Result<OptimisticUpdate>;
async fn get_block(&self, slot: u64) -> Result<BeaconBlock>;
async fn get_header(&self, slot: u64) -> Result<BeaconHeader>;
async fn chain_id(&self) -> Result<u64>;
}

View File

@ -6,6 +6,7 @@ use super::ConsensusRpc;
use crate::constants::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
use crate::types::*;
use common::errors::RpcError;
use common::types::Bytes32;
#[derive(Debug)]
pub struct NimbusRpc {
@ -97,6 +98,19 @@ impl ConsensusRpc for NimbusRpc {
Ok(res.data.message)
}
async fn get_header(&self, slot: u64) -> Result<BeaconHeader> {
let req = format!("{}/eth/v1/beacon/headers/{}", self.rpc, slot);
let res = reqwest::get(req)
.await
.map_err(|e| RpcError::new("headers", e))?
.json::<BeaconHeaderResponse>()
.await
.map_err(|e| RpcError::new("headers", e))?;
Ok(res.data.header)
}
async fn chain_id(&self) -> Result<u64> {
let req = format!("{}/eth/v1/config/spec", self.rpc);
let res = reqwest::get(req)
@ -110,6 +124,12 @@ impl ConsensusRpc for NimbusRpc {
}
}
#[derive(serde::Deserialize, Debug)]
struct BeaconHeaderResponse {
data: BeaconHeaderData,
execution_optimistic: bool,
}
#[derive(serde::Deserialize, Debug)]
struct BeaconBlockResponse {
data: BeaconBlockData,
@ -120,6 +140,14 @@ struct BeaconBlockData {
message: BeaconBlock,
}
#[derive(serde::Deserialize, Debug)]
struct BeaconHeaderData {
#[serde(deserialize_with = "bytes32_deserialize")]
root: Bytes32,
header: BeaconHeader,
canonical: bool,
}
type UpdateResponse = Vec<UpdateData>;
#[derive(serde::Deserialize, Debug)]

View File

@ -24,6 +24,13 @@ pub struct BeaconBlock {
pub body: BeaconBlockBody,
}
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
pub struct BeaconHeader {
pub message: Header,
#[serde(deserialize_with = "signature_deserialize")]
signature: SignatureBytes,
}
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
pub struct BeaconBlockBody {
#[serde(deserialize_with = "signature_deserialize")]
@ -395,7 +402,7 @@ where
Ok(U256::from_bytes_le(x_bytes))
}
fn bytes32_deserialize<'de, D>(deserializer: D) -> Result<Bytes32, D::Error>
pub fn bytes32_deserialize<'de, D>(deserializer: D) -> Result<Bytes32, D::Error>
where
D: serde::Deserializer<'de>,
{