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 { } else if slot == finalized_slot {
self.store.finalized_header.clone().hash_tree_root()? self.store.finalized_header.clone().hash_tree_root()?
} else { } else {
return Err(ConsensusError::PayloadNotFound(slot).into()); self.rpc.get_header(slot).await?.message.hash_tree_root()?
}; };
if verified_block_hash != block_hash { if verified_block_hash != block_hash {

View File

@ -1,7 +1,7 @@
use std::{fs::read_to_string, path::PathBuf}; use std::{fs::read_to_string, path::PathBuf};
use super::ConsensusRpc; 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 async_trait::async_trait;
use eyre::Result; use eyre::Result;
pub struct MockRpc { pub struct MockRpc {
@ -42,6 +42,11 @@ impl ConsensusRpc for MockRpc {
Ok(serde_json::from_str(&block)?) 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> { async fn chain_id(&self) -> Result<u64> {
eyre::bail!("not implemented") eyre::bail!("not implemented")
} }

View File

@ -4,7 +4,7 @@ pub mod nimbus_rpc;
use async_trait::async_trait; use async_trait::async_trait;
use eyre::Result; 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 // implements https://github.com/ethereum/beacon-APIs/tree/master/apis/beacon/light_client
#[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[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_finality_update(&self) -> Result<FinalityUpdate>;
async fn get_optimistic_update(&self) -> Result<OptimisticUpdate>; async fn get_optimistic_update(&self) -> Result<OptimisticUpdate>;
async fn get_block(&self, slot: u64) -> Result<BeaconBlock>; 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>; 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::constants::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
use crate::types::*; use crate::types::*;
use common::errors::RpcError; use common::errors::RpcError;
use common::types::Bytes32;
#[derive(Debug)] #[derive(Debug)]
pub struct NimbusRpc { pub struct NimbusRpc {
@ -97,6 +98,19 @@ impl ConsensusRpc for NimbusRpc {
Ok(res.data.message) 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> { async fn chain_id(&self) -> Result<u64> {
let req = format!("{}/eth/v1/config/spec", self.rpc); let req = format!("{}/eth/v1/config/spec", self.rpc);
let res = reqwest::get(req) 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)] #[derive(serde::Deserialize, Debug)]
struct BeaconBlockResponse { struct BeaconBlockResponse {
data: BeaconBlockData, data: BeaconBlockData,
@ -120,6 +140,14 @@ struct BeaconBlockData {
message: BeaconBlock, message: BeaconBlock,
} }
#[derive(serde::Deserialize, Debug)]
struct BeaconHeaderData {
#[serde(deserialize_with = "bytes32_deserialize")]
root: Bytes32,
header: BeaconHeader,
canonical: bool,
}
type UpdateResponse = Vec<UpdateData>; type UpdateResponse = Vec<UpdateData>;
#[derive(serde::Deserialize, Debug)] #[derive(serde::Deserialize, Debug)]

View File

@ -24,6 +24,13 @@ pub struct BeaconBlock {
pub body: BeaconBlockBody, 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)] #[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
pub struct BeaconBlockBody { pub struct BeaconBlockBody {
#[serde(deserialize_with = "signature_deserialize")] #[serde(deserialize_with = "signature_deserialize")]
@ -395,7 +402,7 @@ where
Ok(U256::from_bytes_le(x_bytes)) 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 where
D: serde::Deserializer<'de>, D: serde::Deserializer<'de>,
{ {