2022-09-04 23:32:16 +00:00
|
|
|
use async_trait::async_trait;
|
2022-08-21 15:21:50 +00:00
|
|
|
use eyre::Result;
|
2022-11-08 21:24:55 +00:00
|
|
|
use std::cmp;
|
2022-08-21 15:21:50 +00:00
|
|
|
|
2022-11-02 03:52:28 +00:00
|
|
|
use super::ConsensusRpc;
|
2022-11-08 21:24:55 +00:00
|
|
|
use crate::constants::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
|
2022-09-04 23:32:16 +00:00
|
|
|
use crate::types::*;
|
2023-01-23 15:07:11 +00:00
|
|
|
use common::errors::RpcError;
|
2022-08-21 15:21:50 +00:00
|
|
|
|
2023-01-31 02:38:46 +00:00
|
|
|
#[derive(Debug)]
|
2022-09-04 23:32:16 +00:00
|
|
|
pub struct NimbusRpc {
|
2022-08-21 15:21:50 +00:00
|
|
|
rpc: String,
|
|
|
|
}
|
|
|
|
|
2023-01-31 02:38:46 +00:00
|
|
|
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
|
|
|
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
2022-11-02 03:52:28 +00:00
|
|
|
impl ConsensusRpc for NimbusRpc {
|
2022-09-04 23:32:16 +00:00
|
|
|
fn new(rpc: &str) -> Self {
|
|
|
|
NimbusRpc {
|
2022-08-21 16:59:47 +00:00
|
|
|
rpc: rpc.to_string(),
|
|
|
|
}
|
2022-08-21 15:21:50 +00:00
|
|
|
}
|
|
|
|
|
2022-11-30 01:31:25 +00:00
|
|
|
async fn get_bootstrap(&self, block_root: &'_ [u8]) -> Result<Bootstrap> {
|
2022-08-27 00:05:12 +00:00
|
|
|
let root_hex = hex::encode(block_root);
|
2022-08-21 15:21:50 +00:00
|
|
|
let req = format!(
|
2022-10-13 17:59:37 +00:00
|
|
|
"{}/eth/v1/beacon/light_client/bootstrap/0x{}",
|
2022-08-27 00:05:12 +00:00
|
|
|
self.rpc, root_hex
|
2022-08-21 15:21:50 +00:00
|
|
|
);
|
2022-09-29 23:35:43 +00:00
|
|
|
|
2023-01-31 02:38:46 +00:00
|
|
|
let client = reqwest::Client::new();
|
|
|
|
let res = client
|
2022-11-04 15:05:18 +00:00
|
|
|
.get(req)
|
|
|
|
.send()
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("bootstrap", e))?
|
2022-09-29 23:35:43 +00:00
|
|
|
.json::<BootstrapResponse>()
|
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("bootstrap", e))?;
|
2022-09-29 23:35:43 +00:00
|
|
|
|
2022-10-13 17:59:37 +00:00
|
|
|
Ok(res.data)
|
2022-08-21 15:21:50 +00:00
|
|
|
}
|
|
|
|
|
2022-11-08 21:24:55 +00:00
|
|
|
async fn get_updates(&self, period: u64, count: u8) -> Result<Vec<Update>> {
|
|
|
|
let count = cmp::min(count, MAX_REQUEST_LIGHT_CLIENT_UPDATES);
|
2022-08-21 15:21:50 +00:00
|
|
|
let req = format!(
|
2022-11-08 21:24:55 +00:00
|
|
|
"{}/eth/v1/beacon/light_client/updates?start_period={}&count={}",
|
|
|
|
self.rpc, period, count
|
2022-08-21 15:21:50 +00:00
|
|
|
);
|
2022-09-29 23:35:43 +00:00
|
|
|
|
2023-01-31 02:38:46 +00:00
|
|
|
let client = reqwest::Client::new();
|
|
|
|
let res = client
|
2022-11-04 15:05:18 +00:00
|
|
|
.get(req)
|
|
|
|
.send()
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("updates", e))?
|
2022-09-29 23:35:43 +00:00
|
|
|
.json::<UpdateResponse>()
|
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("updates", e))?;
|
2022-09-29 23:35:43 +00:00
|
|
|
|
2022-10-13 17:59:37 +00:00
|
|
|
Ok(res.iter().map(|d| d.data.clone()).collect())
|
2022-08-21 15:21:50 +00:00
|
|
|
}
|
|
|
|
|
2022-09-04 23:32:16 +00:00
|
|
|
async fn get_finality_update(&self) -> Result<FinalityUpdate> {
|
2022-10-13 17:59:37 +00:00
|
|
|
let req = format!("{}/eth/v1/beacon/light_client/finality_update", self.rpc);
|
2023-01-31 02:38:46 +00:00
|
|
|
let res = reqwest::get(req)
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("finality_update", e))?
|
2022-08-21 15:21:50 +00:00
|
|
|
.json::<FinalityUpdateResponse>()
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("finality_update", e))?;
|
2022-09-29 23:35:43 +00:00
|
|
|
|
2022-08-21 15:21:50 +00:00
|
|
|
Ok(res.data)
|
|
|
|
}
|
|
|
|
|
2022-09-04 23:32:16 +00:00
|
|
|
async fn get_optimistic_update(&self) -> Result<OptimisticUpdate> {
|
2022-10-13 17:59:37 +00:00
|
|
|
let req = format!("{}/eth/v1/beacon/light_client/optimistic_update", self.rpc);
|
2023-01-31 02:38:46 +00:00
|
|
|
let res = reqwest::get(req)
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("optimistic_update", e))?
|
2022-08-31 00:31:58 +00:00
|
|
|
.json::<OptimisticUpdateResponse>()
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("optimistic_update", e))?;
|
2022-09-29 23:35:43 +00:00
|
|
|
|
2022-08-31 00:31:58 +00:00
|
|
|
Ok(res.data)
|
|
|
|
}
|
|
|
|
|
2022-09-04 23:32:16 +00:00
|
|
|
async fn get_block(&self, slot: u64) -> Result<BeaconBlock> {
|
2022-08-21 15:21:50 +00:00
|
|
|
let req = format!("{}/eth/v2/beacon/blocks/{}", self.rpc, slot);
|
2023-01-31 02:38:46 +00:00
|
|
|
let res = reqwest::get(req)
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("blocks", e))?
|
2022-08-21 15:21:50 +00:00
|
|
|
.json::<BeaconBlockResponse>()
|
2022-09-29 23:35:43 +00:00
|
|
|
.await
|
2022-10-13 17:59:37 +00:00
|
|
|
.map_err(|e| RpcError::new("blocks", e))?;
|
2022-09-29 23:35:43 +00:00
|
|
|
|
2022-08-21 15:21:50 +00:00
|
|
|
Ok(res.data.message)
|
|
|
|
}
|
2023-01-23 15:07:11 +00:00
|
|
|
|
|
|
|
async fn chain_id(&self) -> Result<u64> {
|
|
|
|
let req = format!("{}/eth/v1/config/spec", self.rpc);
|
2023-01-31 02:38:46 +00:00
|
|
|
let res = reqwest::get(req)
|
2023-01-23 15:07:11 +00:00
|
|
|
.await
|
|
|
|
.map_err(|e| RpcError::new("spec", e))?
|
|
|
|
.json::<SpecResponse>()
|
|
|
|
.await
|
|
|
|
.map_err(|e| RpcError::new("spec", e))?;
|
|
|
|
|
|
|
|
Ok(res.data.chain_id)
|
|
|
|
}
|
2022-08-21 15:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(serde::Deserialize, Debug)]
|
|
|
|
struct BeaconBlockResponse {
|
|
|
|
data: BeaconBlockData,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(serde::Deserialize, Debug)]
|
|
|
|
struct BeaconBlockData {
|
|
|
|
message: BeaconBlock,
|
|
|
|
}
|
|
|
|
|
2022-10-13 17:59:37 +00:00
|
|
|
type UpdateResponse = Vec<UpdateData>;
|
|
|
|
|
2022-08-21 15:21:50 +00:00
|
|
|
#[derive(serde::Deserialize, Debug)]
|
2022-10-13 17:59:37 +00:00
|
|
|
struct UpdateData {
|
|
|
|
data: Update,
|
2022-08-21 15:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(serde::Deserialize, Debug)]
|
|
|
|
struct FinalityUpdateResponse {
|
|
|
|
data: FinalityUpdate,
|
|
|
|
}
|
|
|
|
|
2022-08-31 00:31:58 +00:00
|
|
|
#[derive(serde::Deserialize, Debug)]
|
|
|
|
struct OptimisticUpdateResponse {
|
|
|
|
data: OptimisticUpdate,
|
|
|
|
}
|
|
|
|
|
2022-08-21 15:21:50 +00:00
|
|
|
#[derive(serde::Deserialize, Debug)]
|
|
|
|
struct BootstrapResponse {
|
2022-10-13 17:59:37 +00:00
|
|
|
data: Bootstrap,
|
2022-08-21 15:21:50 +00:00
|
|
|
}
|
2023-01-23 15:07:11 +00:00
|
|
|
|
|
|
|
#[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,
|
|
|
|
}
|