refactor module structure
This commit is contained in:
parent
a7a5942451
commit
5240385dcd
|
@ -1,7 +1,9 @@
|
||||||
use ethers::prelude::{Address, U256};
|
use ethers::prelude::{Address, U256};
|
||||||
use eyre::Result;
|
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 {
|
pub struct Client {
|
||||||
consensus: ConsensusClient,
|
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 eyre::Result;
|
||||||
use ssz_rs::{Node, Vector};
|
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>> {
|
pub fn hex_str_to_bytes(s: &str) -> Result<Vec<u8>> {
|
||||||
let stripped = s.strip_prefix("0x").unwrap_or(s);
|
let stripped = s.strip_prefix("0x").unwrap_or(s);
|
|
@ -3,11 +3,12 @@ use blst::BLST_ERROR;
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
use ssz_rs::prelude::*;
|
use ssz_rs::prelude::*;
|
||||||
|
|
||||||
use crate::consensus_rpc::*;
|
use crate::common::utils::*;
|
||||||
use crate::utils::*;
|
use super::types::*;
|
||||||
|
use super::rpc::Rpc;
|
||||||
|
|
||||||
pub struct ConsensusClient {
|
pub struct ConsensusClient {
|
||||||
consensus_rpc: ConsensusRpc,
|
rpc: Rpc,
|
||||||
store: Store,
|
store: Store,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,9 +21,9 @@ struct Store {
|
||||||
|
|
||||||
impl ConsensusClient {
|
impl ConsensusClient {
|
||||||
pub async fn new(nimbus_rpc: &str, checkpoint_block_root: &str) -> Result<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(
|
let committee_valid = is_current_committee_proof_valid(
|
||||||
&bootstrap.header,
|
&bootstrap.header,
|
||||||
|
@ -44,14 +45,14 @@ impl ConsensusClient {
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(ConsensusClient {
|
Ok(ConsensusClient {
|
||||||
consensus_rpc,
|
rpc,
|
||||||
store,
|
store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_execution_payload(&mut self) -> Result<ExecutionPayload> {
|
pub async fn get_execution_payload(&mut self) -> Result<ExecutionPayload> {
|
||||||
let slot = self.store.header.slot;
|
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 block_hash = block.hash_tree_root()?;
|
||||||
let verified_block_hash = self.store.header.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<()> {
|
pub async fn sync(&mut self) -> Result<()> {
|
||||||
let current_period = calc_sync_period(self.store.header.slot);
|
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 {
|
for mut update in updates {
|
||||||
self.verify_update(&mut update)?;
|
self.verify_update(&mut update)?;
|
||||||
self.apply_update(&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 {
|
let mut finality_update_generic = Update {
|
||||||
attested_header: finality_update.attested_header,
|
attested_header: finality_update.attested_header,
|
||||||
next_sync_committee: None,
|
next_sync_committee: None,
|
||||||
|
@ -89,7 +90,7 @@ impl ConsensusClient {
|
||||||
self.verify_update(&mut finality_update_generic)?;
|
self.verify_update(&mut finality_update_generic)?;
|
||||||
self.apply_update(&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(())
|
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 serde::de::Error;
|
||||||
use ssz_rs::prelude::*;
|
use ssz_rs::prelude::*;
|
||||||
|
|
||||||
use crate::utils::*;
|
use crate::common::utils::hex_str_to_bytes;
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type BLSPubKey = Vector<u8, 48>;
|
pub type BLSPubKey = Vector<u8, 48>;
|
||||||
pub type SignatureBytes = Vector<u8, 96>;
|
pub type SignatureBytes = Vector<u8, 96>;
|
||||||
|
@ -229,36 +181,6 @@ pub struct SyncAggregate {
|
||||||
pub sync_committee_signature: SignatureBytes,
|
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>
|
fn pubkey_deserialize<'de, D>(deserializer: D) -> Result<BLSPubKey, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
|
@ -2,9 +2,9 @@ use ethers::prelude::{Address, U256, H256};
|
||||||
use ethers::utils::keccak256;
|
use ethers::utils::keccak256;
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
use crate::consensus_rpc::ExecutionPayload;
|
use crate::consensus::types::ExecutionPayload;
|
||||||
use crate::execution_rpc::ExecutionRpc;
|
use super::proof::{encode_account, verify_proof};
|
||||||
use crate::proof::{encode_account, verify_proof};
|
use super::execution_rpc::ExecutionRpc;
|
||||||
|
|
||||||
pub struct ExecutionClient {
|
pub struct ExecutionClient {
|
||||||
execution_rpc: ExecutionRpc,
|
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::keccak256;
|
||||||
use ethers::utils::rlp::{decode_list, RlpStream};
|
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 {
|
pub fn verify_proof(proof: &Vec<Vec<u8>>, root: &Vec<u8>, path: &Vec<u8>, value: &Vec<u8>) -> bool {
|
||||||
let mut expected_hash = root.clone();
|
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 client;
|
||||||
pub mod consensus;
|
pub mod consensus;
|
||||||
pub mod consensus_rpc;
|
|
||||||
pub mod execution;
|
pub mod execution;
|
||||||
pub mod execution_rpc;
|
pub mod common;
|
||||||
pub mod proof;
|
|
||||||
pub mod utils;
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
|
|
Loading…
Reference in New Issue