feat: check consensus rpc network (#177)

* feat: check consensus rpc network

* cleanup
This commit is contained in:
Noah Citron 2023-01-23 10:07:11 -05:00 committed by GitHub
parent de90eb9158
commit 2c5c318529
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 59 additions and 21 deletions

View File

@ -1,5 +1,5 @@
use common::errors::BlockNotFoundError;
use execution::errors::{EvmError, ExecutionError};
use execution::errors::EvmError;
use eyre::Report;
use thiserror::Error;
@ -9,8 +9,8 @@ pub enum NodeError {
#[error(transparent)]
ExecutionEvmError(#[from] EvmError),
#[error(transparent)]
ExecutionError(#[from] ExecutionError),
#[error("execution error: {0}")]
ExecutionError(Report),
#[error("out of sync: {0} slots behind")]
OutOfSync(u64),

View File

@ -60,6 +60,11 @@ impl Node {
.await
.map_err(NodeError::ExecutionError)?;
self.consensus
.check_rpc()
.await
.map_err(NodeError::ConsensusSyncError)?;
self.consensus
.sync()
.await

View File

@ -59,6 +59,16 @@ impl<R: ConsensusRpc> ConsensusClient<R> {
})
}
pub async fn check_rpc(&self) -> Result<()> {
let chain_id = self.rpc.chain_id().await?;
if chain_id != self.config.chain.chain_id {
Err(ConsensusError::IncorrectRpcNetwork.into())
} else {
Ok(())
}
}
pub async fn get_execution_payload(&self, slot: &Option<u64>) -> Result<ExecutionPayload> {
let slot = slot.unwrap_or(self.store.optimistic_header.slot);
let mut block = self.rpc.get_block(slot).await?;

View File

@ -24,4 +24,6 @@ pub enum ConsensusError {
PayloadNotFound(u64),
#[error("checkpoint is too old")]
CheckpointTooOld,
#[error("consensus rpc is for the incorrect network")]
IncorrectRpcNetwork,
}

View File

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

View File

@ -15,4 +15,5 @@ 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 chain_id(&self) -> Result<u64>;
}

View File

@ -1,5 +1,4 @@
use async_trait::async_trait;
use common::errors::RpcError;
use eyre::Result;
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
@ -8,6 +7,7 @@ use std::cmp;
use super::ConsensusRpc;
use crate::constants::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
use crate::types::*;
use common::errors::RpcError;
pub struct NimbusRpc {
rpc: String,
@ -115,6 +115,21 @@ impl ConsensusRpc for NimbusRpc {
Ok(res.data.message)
}
async fn chain_id(&self) -> Result<u64> {
let req = format!("{}/eth/v1/config/spec", self.rpc);
let res = self
.client
.get(req)
.send()
.await
.map_err(|e| RpcError::new("spec", e))?
.json::<SpecResponse>()
.await
.map_err(|e| RpcError::new("spec", e))?;
Ok(res.data.chain_id)
}
}
#[derive(serde::Deserialize, Debug)]
@ -148,3 +163,14 @@ struct OptimisticUpdateResponse {
struct BootstrapResponse {
data: Bootstrap,
}
#[derive(serde::Deserialize, Debug)]
struct SpecResponse {
data: Spec,
}
#[derive(serde::Deserialize, Debug)]
struct Spec {
#[serde(rename = "DEPOSIT_NETWORK_ID", deserialize_with = "u64_deserialize")]
chain_id: u64,
}

View File

@ -376,7 +376,7 @@ where
.map_err(D::Error::custom)
}
fn u64_deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
pub fn u64_deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: serde::Deserializer<'de>,
{

View File

@ -24,8 +24,6 @@ pub enum ExecutionError {
MissingLog(String, U256),
#[error("too many logs to prove: {0}, current limit is: {1}")]
TooManyLogsToProve(usize, usize),
#[error("rpc error: {0:?}")]
RpcError(Report),
#[error("execution rpc is for the incorect network")]
IncorrectRpcNetwork(),
}

View File

@ -36,15 +36,9 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
Ok(ExecutionClient { rpc })
}
pub async fn check_rpc(&self, chain_id: u64) -> Result<(), ExecutionError> {
if self
.rpc
.chain_id()
.await
.map_err(ExecutionError::RpcError)?
!= chain_id
{
Err(ExecutionError::IncorrectRpcNetwork())
pub async fn check_rpc(&self, chain_id: u64) -> Result<()> {
if self.rpc.chain_id().await? != chain_id {
Err(ExecutionError::IncorrectRpcNetwork().into())
} else {
Ok(())
}

View File

@ -1,7 +1,6 @@
use std::str::FromStr;
use async_trait::async_trait;
use common::errors::RpcError;
use ethers::prelude::{Address, Http};
use ethers::providers::{HttpRateLimitRetryPolicy, Middleware, Provider, RetryClient};
use ethers::types::transaction::eip2718::TypedTransaction;
@ -13,6 +12,7 @@ use ethers::types::{
use eyre::Result;
use crate::types::CallOpts;
use common::errors::RpcError;
use super::ExecutionRpc;