refactor module structure
This commit is contained in:
parent
a7a5942451
commit
5240385dcd
|
@ -1,7 +1,9 @@
|
|||
use ethers::prelude::{Address, U256};
|
||||
use eyre::Result;
|
||||
|
||||
use crate::{consensus::ConsensusClient, execution::ExecutionClient, consensus_rpc::Header};
|
||||
use crate::consensus::types::Header;
|
||||
use crate::consensus::ConsensusClient;
|
||||
use crate::execution::ExecutionClient;
|
||||
|
||||
pub struct Client {
|
||||
consensus: ConsensusClient,
|
|
@ -0,0 +1,2 @@
|
|||
mod client;
|
||||
pub use client::*;
|
|
@ -0,0 +1 @@
|
|||
pub mod utils;
|
|
@ -1,7 +1,7 @@
|
|||
use eyre::Result;
|
||||
use ssz_rs::{Node, Vector};
|
||||
|
||||
use crate::consensus_rpc::Bytes32;
|
||||
use crate::consensus::types::Bytes32;
|
||||
|
||||
pub fn hex_str_to_bytes(s: &str) -> Result<Vec<u8>> {
|
||||
let stripped = s.strip_prefix("0x").unwrap_or(s);
|
|
@ -3,11 +3,12 @@ use blst::BLST_ERROR;
|
|||
use eyre::Result;
|
||||
use ssz_rs::prelude::*;
|
||||
|
||||
use crate::consensus_rpc::*;
|
||||
use crate::utils::*;
|
||||
use crate::common::utils::*;
|
||||
use super::types::*;
|
||||
use super::rpc::Rpc;
|
||||
|
||||
pub struct ConsensusClient {
|
||||
consensus_rpc: ConsensusRpc,
|
||||
rpc: Rpc,
|
||||
store: Store,
|
||||
}
|
||||
|
||||
|
@ -20,9 +21,9 @@ struct Store {
|
|||
|
||||
impl ConsensusClient {
|
||||
pub async fn new(nimbus_rpc: &str, checkpoint_block_root: &str) -> Result<ConsensusClient> {
|
||||
let consensus_rpc = ConsensusRpc::new(nimbus_rpc);
|
||||
let rpc = Rpc::new(nimbus_rpc);
|
||||
|
||||
let mut bootstrap = consensus_rpc.get_bootstrap(checkpoint_block_root).await?;
|
||||
let mut bootstrap = rpc.get_bootstrap(checkpoint_block_root).await?;
|
||||
|
||||
let committee_valid = is_current_committee_proof_valid(
|
||||
&bootstrap.header,
|
||||
|
@ -44,14 +45,14 @@ impl ConsensusClient {
|
|||
};
|
||||
|
||||
Ok(ConsensusClient {
|
||||
consensus_rpc,
|
||||
rpc,
|
||||
store,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn get_execution_payload(&mut self) -> Result<ExecutionPayload> {
|
||||
let slot = self.store.header.slot;
|
||||
let mut block = self.consensus_rpc.get_block(slot).await?;
|
||||
let mut block = self.rpc.get_block(slot).await?;
|
||||
let block_hash = block.hash_tree_root()?;
|
||||
let verified_block_hash = self.store.header.hash_tree_root()?;
|
||||
|
||||
|
@ -68,14 +69,14 @@ impl ConsensusClient {
|
|||
|
||||
pub async fn sync(&mut self) -> Result<()> {
|
||||
let current_period = calc_sync_period(self.store.header.slot);
|
||||
let updates = self.consensus_rpc.get_updates(current_period).await?;
|
||||
let updates = self.rpc.get_updates(current_period).await?;
|
||||
|
||||
for mut update in updates {
|
||||
self.verify_update(&mut update)?;
|
||||
self.apply_update(&update);
|
||||
}
|
||||
|
||||
let finality_update = self.consensus_rpc.get_finality_update().await?;
|
||||
let finality_update = self.rpc.get_finality_update().await?;
|
||||
let mut finality_update_generic = Update {
|
||||
attested_header: finality_update.attested_header,
|
||||
next_sync_committee: None,
|
||||
|
@ -89,7 +90,7 @@ impl ConsensusClient {
|
|||
self.verify_update(&mut finality_update_generic)?;
|
||||
self.apply_update(&finality_update_generic);
|
||||
|
||||
self.consensus_rpc.get_block(self.store.header.slot).await?;
|
||||
self.rpc.get_block(self.store.header.slot).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
pub mod types;
|
||||
|
||||
mod consensus;
|
||||
pub use consensus::*;
|
||||
|
||||
mod rpc;
|
|
@ -0,0 +1,80 @@
|
|||
use eyre::Result;
|
||||
|
||||
use super::types::*;
|
||||
|
||||
pub struct Rpc {
|
||||
rpc: String,
|
||||
}
|
||||
|
||||
impl Rpc {
|
||||
pub fn new(rpc: &str) -> Self {
|
||||
Rpc { rpc: rpc.to_string() }
|
||||
}
|
||||
|
||||
pub async fn get_bootstrap(&self, block_root: &str) -> Result<Bootstrap> {
|
||||
let req = format!(
|
||||
"{}/eth/v0/beacon/light_client/bootstrap/{}",
|
||||
self.rpc, block_root
|
||||
);
|
||||
let res = reqwest::get(req).await?.json::<BootstrapResponse>().await?;
|
||||
Ok(res.data.v)
|
||||
}
|
||||
|
||||
pub async fn get_updates(&self, period: u64) -> Result<Vec<Update>> {
|
||||
let req = format!(
|
||||
"{}/eth/v0/beacon/light_client/updates?start_period={}&count=1000",
|
||||
self.rpc, period
|
||||
);
|
||||
let res = reqwest::get(req).await?.json::<UpdateResponse>().await?;
|
||||
Ok(res.data)
|
||||
}
|
||||
|
||||
pub async fn get_finality_update(&self) -> Result<FinalityUpdate> {
|
||||
let req = format!("{}/eth/v0/beacon/light_client/finality_update", self.rpc);
|
||||
let res = reqwest::get(req)
|
||||
.await?
|
||||
.json::<FinalityUpdateResponse>()
|
||||
.await?;
|
||||
Ok(res.data)
|
||||
}
|
||||
|
||||
pub async fn get_block(&self, slot: u64) -> Result<BeaconBlock> {
|
||||
let req = format!("{}/eth/v2/beacon/blocks/{}", self.rpc, slot);
|
||||
let res = reqwest::get(req)
|
||||
.await?
|
||||
.json::<BeaconBlockResponse>()
|
||||
.await?;
|
||||
Ok(res.data.message)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BeaconBlockResponse {
|
||||
data: BeaconBlockData,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BeaconBlockData {
|
||||
message: BeaconBlock,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct UpdateResponse {
|
||||
data: Vec<Update>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct FinalityUpdateResponse {
|
||||
data: FinalityUpdate,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BootstrapResponse {
|
||||
data: BootstrapData,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BootstrapData {
|
||||
v: Bootstrap,
|
||||
}
|
||||
|
|
@ -2,55 +2,7 @@ use eyre::Result;
|
|||
use serde::de::Error;
|
||||
use ssz_rs::prelude::*;
|
||||
|
||||
use crate::utils::*;
|
||||
|
||||
pub struct ConsensusRpc {
|
||||
rpc: String,
|
||||
}
|
||||
|
||||
impl ConsensusRpc {
|
||||
pub fn new(rpc: &str) -> Self {
|
||||
ConsensusRpc {
|
||||
rpc: rpc.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_bootstrap(&self, block_root: &str) -> Result<Bootstrap> {
|
||||
let req = format!(
|
||||
"{}/eth/v0/beacon/light_client/bootstrap/{}",
|
||||
self.rpc, block_root
|
||||
);
|
||||
let res = reqwest::get(req).await?.json::<BootstrapResponse>().await?;
|
||||
Ok(res.data.v)
|
||||
}
|
||||
|
||||
pub async fn get_updates(&self, period: u64) -> Result<Vec<Update>> {
|
||||
let req = format!(
|
||||
"{}/eth/v0/beacon/light_client/updates?start_period={}&count=1000",
|
||||
self.rpc, period
|
||||
);
|
||||
let res = reqwest::get(req).await?.json::<UpdateResponse>().await?;
|
||||
Ok(res.data)
|
||||
}
|
||||
|
||||
pub async fn get_finality_update(&self) -> Result<FinalityUpdate> {
|
||||
let req = format!("{}/eth/v0/beacon/light_client/finality_update", self.rpc);
|
||||
let res = reqwest::get(req)
|
||||
.await?
|
||||
.json::<FinalityUpdateResponse>()
|
||||
.await?;
|
||||
Ok(res.data)
|
||||
}
|
||||
|
||||
pub async fn get_block(&self, slot: u64) -> Result<BeaconBlock> {
|
||||
let req = format!("{}/eth/v2/beacon/blocks/{}", self.rpc, slot);
|
||||
let res = reqwest::get(req)
|
||||
.await?
|
||||
.json::<BeaconBlockResponse>()
|
||||
.await?;
|
||||
Ok(res.data.message)
|
||||
}
|
||||
}
|
||||
use crate::common::utils::hex_str_to_bytes;
|
||||
|
||||
pub type BLSPubKey = Vector<u8, 48>;
|
||||
pub type SignatureBytes = Vector<u8, 96>;
|
||||
|
@ -229,36 +181,6 @@ pub struct SyncAggregate {
|
|||
pub sync_committee_signature: SignatureBytes,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BeaconBlockResponse {
|
||||
data: BeaconBlockData,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BeaconBlockData {
|
||||
message: BeaconBlock,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct UpdateResponse {
|
||||
data: Vec<Update>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct FinalityUpdateResponse {
|
||||
data: FinalityUpdate,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BootstrapResponse {
|
||||
data: BootstrapData,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct BootstrapData {
|
||||
v: Bootstrap,
|
||||
}
|
||||
|
||||
fn pubkey_deserialize<'de, D>(deserializer: D) -> Result<BLSPubKey, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
|
@ -2,9 +2,9 @@ use ethers::prelude::{Address, U256, H256};
|
|||
use ethers::utils::keccak256;
|
||||
use eyre::Result;
|
||||
|
||||
use crate::consensus_rpc::ExecutionPayload;
|
||||
use crate::execution_rpc::ExecutionRpc;
|
||||
use crate::proof::{encode_account, verify_proof};
|
||||
use crate::consensus::types::ExecutionPayload;
|
||||
use super::proof::{encode_account, verify_proof};
|
||||
use super::execution_rpc::ExecutionRpc;
|
||||
|
||||
pub struct ExecutionClient {
|
||||
execution_rpc: ExecutionRpc,
|
|
@ -0,0 +1,26 @@
|
|||
use ethers::prelude::Address;
|
||||
use eyre::Result;
|
||||
use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder, rpc_params};
|
||||
|
||||
use super::types::Proof;
|
||||
|
||||
pub struct ExecutionRpc {
|
||||
rpc: String,
|
||||
}
|
||||
|
||||
impl ExecutionRpc {
|
||||
pub fn new(rpc: &str) -> Self {
|
||||
ExecutionRpc {
|
||||
rpc: rpc.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_proof(&self, address: &Address, block: u64) -> Result<Proof> {
|
||||
let client = HttpClientBuilder::default().build(&self.rpc)?;
|
||||
let block_hex = format!("0x{:x}", block);
|
||||
let addr_hex = format!("0x{}", hex::encode(address.as_bytes()));
|
||||
let params = rpc_params!(addr_hex, [""], block_hex);
|
||||
Ok(client.request("eth_getProof", params).await?)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
pub mod types;
|
||||
|
||||
mod execution;
|
||||
pub use execution::*;
|
||||
|
||||
mod execution_rpc;
|
||||
mod proof;
|
|
@ -1,7 +1,7 @@
|
|||
use ethers::utils::keccak256;
|
||||
use ethers::utils::rlp::{decode_list, RlpStream};
|
||||
|
||||
use crate::execution_rpc::Proof;
|
||||
use crate::execution::types::Proof;
|
||||
|
||||
pub fn verify_proof(proof: &Vec<Vec<u8>>, root: &Vec<u8>, path: &Vec<u8>, value: &Vec<u8>) -> bool {
|
||||
let mut expected_hash = root.clone();
|
|
@ -0,0 +1,30 @@
|
|||
use serde::de::Error;
|
||||
use serde::Deserialize;
|
||||
use ethers::prelude::{U256, H256, Address};
|
||||
use eyre::Result;
|
||||
|
||||
use crate::common::utils::hex_str_to_bytes;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Proof {
|
||||
pub address: Address,
|
||||
pub balance: U256,
|
||||
pub code_hash: H256,
|
||||
pub nonce: U256,
|
||||
pub storage_hash: H256,
|
||||
#[serde(deserialize_with = "proof_deserialize")]
|
||||
pub account_proof: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
fn proof_deserialize<'de, D>(deserializer: D) -> Result<Vec<Vec<u8>>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let branch: Vec<String> = serde::Deserialize::deserialize(deserializer)?;
|
||||
Ok(branch
|
||||
.iter()
|
||||
.map(|elem| hex_str_to_bytes(elem))
|
||||
.collect::<Result<_>>()
|
||||
.map_err(D::Error::custom)?)
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
use ethers::prelude::{Address, H256, U256};
|
||||
use eyre::Result;
|
||||
use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder, rpc_params};
|
||||
use serde::de::Error;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::utils::hex_str_to_bytes;
|
||||
|
||||
pub struct ExecutionRpc {
|
||||
rpc: String,
|
||||
}
|
||||
|
||||
impl ExecutionRpc {
|
||||
pub fn new(rpc: &str) -> Self {
|
||||
ExecutionRpc {
|
||||
rpc: rpc.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_proof(&self, address: &Address, block: u64) -> Result<Proof> {
|
||||
let client = HttpClientBuilder::default().build(&self.rpc)?;
|
||||
let block_hex = format!("0x{:x}", block);
|
||||
let addr_hex = format!("0x{}", hex::encode(address.as_bytes()));
|
||||
let params = rpc_params!(addr_hex, [""], block_hex);
|
||||
Ok(client.request("eth_getProof", params).await?)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Proof {
|
||||
pub address: Address,
|
||||
pub balance: U256,
|
||||
pub code_hash: H256,
|
||||
pub nonce: U256,
|
||||
pub storage_hash: H256,
|
||||
#[serde(deserialize_with = "proof_deserialize")]
|
||||
pub account_proof: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
fn proof_deserialize<'de, D>(deserializer: D) -> Result<Vec<Vec<u8>>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let branch: Vec<String> = serde::Deserialize::deserialize(deserializer)?;
|
||||
Ok(branch
|
||||
.iter()
|
||||
.map(|elem| hex_str_to_bytes(elem))
|
||||
.collect::<Result<_>>()
|
||||
.map_err(D::Error::custom)?)
|
||||
}
|
|
@ -7,11 +7,8 @@ use client::Client;
|
|||
|
||||
pub mod client;
|
||||
pub mod consensus;
|
||||
pub mod consensus_rpc;
|
||||
pub mod execution;
|
||||
pub mod execution_rpc;
|
||||
pub mod proof;
|
||||
pub mod utils;
|
||||
pub mod common;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
|
|
Loading…
Reference in New Issue