Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ethereum module doc comments #324

Merged
merged 2 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading