Skip to content

Commit

Permalink
Merge branch 'develop' into testnet-9.2-merge
Browse files Browse the repository at this point in the history
  • Loading branch information
mappum committed Oct 28, 2024
2 parents e4b2462 + 4953291 commit 197d75d
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 12 deletions.
18 changes: 18 additions & 0 deletions src/ethereum/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,17 @@ use crate::error::Result;
#[cfg(feature = "ethereum-full")]
pub mod relayer;

/// Maintains the consensus state of an Ethereum chain, which can be updated via
/// consensus proofs based on the Altair light client protocol.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct LightClient {
lcs: LightClientStore,
network: Network,
}

impl LightClient {
/// Create a new `LightClient` with the given bootstrap data and network
/// configuration.
pub fn new(bootstrap: Bootstrap, network: Network) -> Result<Self> {
let bootstrap = bootstrap.into();

Expand All @@ -57,6 +61,11 @@ impl LightClient {
Ok(LightClient { lcs, network })
}

/// Verify and apply the update to the light client state.
///
/// To minimize updates, this is designed to only allow updates that advance
/// to the next finalized slot, or to the next sync committee period.
/// There should be at most one update per epoch.
pub fn update(&mut self, update: Update, now_seconds: u64) -> Result<()> {
let expected_slot = (now_seconds - self.network.genesis_time) / 12;
let genesis_root = (&self.network.genesis_vals_root.0).into();
Expand All @@ -79,10 +88,12 @@ impl LightClient {
Ok(())
}

/// Get the most recently finalized slot.
pub fn slot(&self) -> u64 {
self.lcs.finalized_header.beacon.slot
}

/// Get the most recently finalized block number.
pub fn block_number(&self) -> u64 {
*self
.lcs
Expand All @@ -93,6 +104,7 @@ impl LightClient {
.block_number()
}

/// Get the most recently finalized execution state root.
pub fn state_root(&self) -> Bytes32 {
self.lcs
.finalized_header
Expand All @@ -104,6 +116,7 @@ impl LightClient {
.into()
}

/// Get the underlying `LightClientStore`.
pub fn light_client_store(&self) -> &LightClientStore {
&self.lcs
}
Expand Down Expand Up @@ -238,6 +251,7 @@ impl Describe for LightClient {
}
}

/// The network parameters for an Ethereum chain.
#[derive(Clone, Debug, Default, Encode, Decode, Serialize, Deserialize)]
pub struct Network {
pub genesis_vals_root: Bytes32,
Expand All @@ -246,6 +260,7 @@ pub struct Network {
}

impl Network {
/// Network parameters for the Ethereum mainnet.
pub fn ethereum_mainnet() -> Self {
Network {
genesis_vals_root: "0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"
Expand All @@ -256,6 +271,7 @@ impl Network {
}
}

/// Network parameters for the Ethereum Sepolia testnet.
pub fn ethereum_sepolia() -> Self {
Network {
genesis_vals_root: "0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"
Expand All @@ -267,6 +283,8 @@ impl Network {
}
}

/// An update to the light client state, and all necessary proof and signature
/// data.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Update {
pub attested_header: LightClientHeader,
Expand Down
19 changes: 19 additions & 0 deletions src/ethereum/consensus/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ use serde::{Deserialize, Serialize};
use super::{Bootstrap, Bytes32, LightClient, Update};
use crate::error::Result;

/// Based on the current Nomic state machine state, get the updates needed to
/// bring the light client up to date with the Ethereum chain.
///
/// This may include any number of updates that advance the light client to the
/// next light client period (256 epochs) and a finality update that advances
/// the light client to the most recently finalized slot within the current
/// period.
///
/// If the light client is already up to date, this function will return an
/// empty vector.
pub async fn get_updates<C: OrgaClient<LightClient>>(
app_client: &C,
eth_client: &RpcClient,
Expand Down Expand Up @@ -38,15 +48,19 @@ pub async fn get_updates<C: OrgaClient<LightClient>>(
Ok(updates)
}

/// A client for the Ethereum Beacon API.
pub struct RpcClient {
rpc_addr: String,
}

impl RpcClient {
/// Create a new client to the Beacon API server with the given address.
pub fn new(rpc_addr: String) -> Self {
Self { rpc_addr }
}

/// Get the updates, if any, to advance the light client from the given
/// start period to the current period, up to the given count.
pub async fn get_updates(
&self,
start_period: u64,
Expand All @@ -66,6 +80,7 @@ impl RpcClient {
Ok(res)
}

/// Get the most recent finality update.
pub async fn get_finality_update(&self) -> Result<Response<Update>> {
let url = format!(
"{}/eth/v1/beacon/light_client/finality_update",
Expand All @@ -81,6 +96,7 @@ impl RpcClient {
Ok(res)
}

/// Get the block root for the given slot.
pub async fn block_root(&self, slot: u64) -> Result<Response<Root>> {
let url = format!("{}/eth/v1/beacon/blocks/{}/root", self.rpc_addr, slot,);
let response = get(&url)
Expand All @@ -93,6 +109,7 @@ impl RpcClient {
Ok(res)
}

/// Get the bootstrap data for the given block root.
pub async fn bootstrap(&self, block_root: Bytes32) -> Result<Response<Bootstrap>> {
let url = format!(
"{}/eth/v1/beacon/light_client/bootstrap/{}",
Expand All @@ -109,12 +126,14 @@ impl RpcClient {
}
}

/// A response from the Beacon API.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Response<T> {
pub version: Option<String>,
pub data: T,
}

/// A response containing a block root.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Root {
pub root: Bytes32,
Expand Down
Loading

0 comments on commit 197d75d

Please sign in to comment.