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

Update light client #11

Merged
merged 4 commits into from
Jan 15, 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
4 changes: 2 additions & 2 deletions crates/ibc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ tiny-keccak = { version = "2.0.2", default-features = false }
ssz-rs = { git = "https://github.com/bluele/ssz_rs", branch = "serde-no-std", default-features = false, features = ["serde"] }

ethereum-ibc-proto = { path = "../../proto", default-features = false }
ethereum-consensus = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "aac304f27372e8a0fb950522ee9cd6f41e43f56f", default-features = false }
ethereum-light-client-verifier = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "aac304f27372e8a0fb950522ee9cd6f41e43f56f", default-features = false }
ethereum-consensus = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "d0caaa0d9e25d481dd25bdb8eb4a8b8ad27aca55", default-features = false }
ethereum-light-client-verifier = { git = "https://github.com/datachainlab/ethereum-light-client-rs", rev = "d0caaa0d9e25d481dd25bdb8eb4a8b8ad27aca55", default-features = false }

[dev-dependencies]
time = { version = "0.3", default-features = false, features = ["macros", "parsing"] }
100 changes: 65 additions & 35 deletions crates/ibc/src/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use core::time::Duration;
use ethereum_consensus::beacon::{Epoch, Root, Slot, Version};
use ethereum_consensus::context::ChainContext;
use ethereum_consensus::fork::{ForkParameter, ForkParameters};
use ethereum_consensus::preset;
use ethereum_consensus::types::{Address, H256, U64};
use ethereum_ibc_proto::ibc::lightclients::ethereum::v1::{ClientState as RawClientState, Fork};
use ethereum_light_client_verifier::consensus::{
Expand All @@ -36,11 +35,9 @@ use serde::{Deserialize, Serialize};

pub const ETHEREUM_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.ethereum.v1.ClientState";

pub type MainnetClientState = ClientState<{ preset::mainnet::PRESET.SYNC_COMMITTEE_SIZE }>;
pub type MinimalClientState = ClientState<{ preset::minimal::PRESET.SYNC_COMMITTEE_SIZE }>;

#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClientState<const SYNC_COMMITTEE_SIZE: usize> {
pub struct ClientState<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize>
{
/// Chain parameters
pub genesis_validators_root: Root,
pub min_sync_committee_participants: U64,
Expand All @@ -66,13 +63,18 @@ pub struct ClientState<const SYNC_COMMITTEE_SIZE: usize> {

/// Verifier
#[serde(skip)]
pub consensus_verifier:
CurrentNextSyncProtocolVerifier<TrustedConsensusState<SYNC_COMMITTEE_SIZE>>,
pub consensus_verifier: CurrentNextSyncProtocolVerifier<
SYNC_COMMITTEE_SIZE,
EXECUTION_PAYLOAD_TREE_DEPTH,
TrustedConsensusState<SYNC_COMMITTEE_SIZE>,
>,
#[serde(skip)]
pub execution_verifier: ExecutionVerifier,
}

impl<const SYNC_COMMITTEE_SIZE: usize> ClientState<SYNC_COMMITTEE_SIZE> {
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize>
ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>
{
pub fn with_frozen_height(self, h: Height) -> Self {
Self {
frozen_height: Some(h),
Expand All @@ -99,7 +101,7 @@ impl<const SYNC_COMMITTEE_SIZE: usize> ClientState<SYNC_COMMITTEE_SIZE> {
self.slots_per_epoch,
self.epochs_per_sync_committee_period,
self.genesis_time,
self.genesis_validators_root.clone(),
self.genesis_validators_root,
self.min_sync_committee_participants.0 as usize,
self.trust_level.clone(),
move || current_slot,
Expand Down Expand Up @@ -215,7 +217,9 @@ impl<const SYNC_COMMITTEE_SIZE: usize> ClientState<SYNC_COMMITTEE_SIZE> {
}
}

impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMMITTEE_SIZE> {
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize> Ics2ClientState
for ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>
{
fn chain_id(&self) -> ChainId {
todo!()
}
Expand Down Expand Up @@ -390,7 +394,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
client_cons_state_path: &ibc::core::ics24_host::path::ClientConsensusStatePath,
expected_consensus_state: &dyn ibc::core::ics02_client::consensus_state::ConsensusState,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(proof_height)?;

let value = expected_consensus_state
Expand All @@ -414,7 +419,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
counterparty_conn_path: &ibc::core::ics24_host::path::ConnectionPath,
expected_counterparty_connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(proof_height)?;

let value = expected_counterparty_connection_end
Expand All @@ -438,7 +444,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
counterparty_chan_end_path: &ibc::core::ics24_host::path::ChannelEndPath,
expected_counterparty_channel_end: &ibc::core::ics04_channel::channel::ChannelEnd,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(proof_height)?;

let value = expected_counterparty_channel_end
Expand All @@ -463,7 +470,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
client_state_path: &ibc::core::ics24_host::path::ClientStatePath,
expected_client_state: Any,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(proof_height)?;

let value = expected_client_state.encode_to_vec();
Expand All @@ -487,7 +495,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
commitment_path: &ibc::core::ics24_host::path::CommitmentPath,
commitment: ibc::core::ics04_channel::commitment::PacketCommitment,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(height)?;

self.verify_membership(
Expand All @@ -509,7 +518,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
ack_path: &ibc::core::ics24_host::path::AckPath,
ack: ibc::core::ics04_channel::commitment::AcknowledgementCommitment,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(height)?;

self.verify_membership(
Expand All @@ -531,7 +541,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
seq_recv_path: &ibc::core::ics24_host::path::SeqRecvPath,
sequence: ibc::core::ics04_channel::packet::Sequence,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(height)?;

let mut seq_bytes = Vec::new();
Expand All @@ -557,7 +568,8 @@ impl<const SYNC_COMMITTEE_SIZE: usize> Ics2ClientState for ClientState<SYNC_COMM
root: &ibc::core::ics23_commitment::commitment::CommitmentRoot,
receipt_path: &ibc::core::ics24_host::path::ReceiptPath,
) -> Result<(), ClientError> {
let client_state = downcast_eth_client_state::<SYNC_COMMITTEE_SIZE>(self)?;
let client_state =
downcast_eth_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>(self)?;
client_state.verify_height(height)?;

self.verify_non_membership(
Expand Down Expand Up @@ -595,13 +607,13 @@ fn validate_within_trusting_period(
Ok(())
}

impl<const SYNC_COMMITTEE_SIZE: usize> Protobuf<RawClientState>
for ClientState<SYNC_COMMITTEE_SIZE>
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize>
Protobuf<RawClientState> for ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>
{
}

impl<const SYNC_COMMITTEE_SIZE: usize> TryFrom<RawClientState>
for ClientState<SYNC_COMMITTEE_SIZE>
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize>
TryFrom<RawClientState> for ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>
{
type Error = Error;

Expand Down Expand Up @@ -655,8 +667,10 @@ impl<const SYNC_COMMITTEE_SIZE: usize> TryFrom<RawClientState>
}
}

impl<const SYNC_COMMITTEE_SIZE: usize> From<ClientState<SYNC_COMMITTEE_SIZE>> for RawClientState {
fn from(value: ClientState<SYNC_COMMITTEE_SIZE>) -> Self {
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize>
From<ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>> for RawClientState
{
fn from(value: ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>) -> Self {
use ethereum_ibc_proto::ibc::core::client::v1::Height as ProtoHeight;
use ethereum_ibc_proto::ibc::lightclients::ethereum::v1::{
ForkParameters as ProtoForkParameters, Fraction as ProtoFraction,
Expand Down Expand Up @@ -708,27 +722,38 @@ impl<const SYNC_COMMITTEE_SIZE: usize> From<ClientState<SYNC_COMMITTEE_SIZE>> fo
}
}

impl<const SYNC_COMMITTEE_SIZE: usize> Protobuf<Any> for ClientState<SYNC_COMMITTEE_SIZE> {}
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize> Protobuf<Any>
for ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>
{
}

impl<const SYNC_COMMITTEE_SIZE: usize> TryFrom<Any> for ClientState<SYNC_COMMITTEE_SIZE> {
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize> TryFrom<Any>
for ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>
{
type Error = ClientError;

fn try_from(raw: Any) -> Result<Self, Self::Error> {
use bytes::Buf;
use core::ops::Deref;

fn decode_client_state<const SYNC_COMMITTEE_SIZE: usize, B: Buf>(
fn decode_client_state<
const SYNC_COMMITTEE_SIZE: usize,
const EXECUTION_PAYLOAD_TREE_DEPTH: usize,
B: Buf,
>(
buf: B,
) -> Result<ClientState<SYNC_COMMITTEE_SIZE>, Error> {
) -> Result<ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>, Error> {
RawClientState::decode(buf)
.map_err(Error::Decode)?
.try_into()
}

match raw.type_url.as_str() {
ETHEREUM_CLIENT_STATE_TYPE_URL => {
decode_client_state::<SYNC_COMMITTEE_SIZE, &[u8]>(raw.value.deref())
.map_err(Into::into)
decode_client_state::<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH, &[u8]>(
raw.value.deref(),
)
.map_err(Into::into)
}
_ => Err(ClientError::UnknownClientStateType {
client_state_type: raw.type_url,
Expand All @@ -737,8 +762,10 @@ impl<const SYNC_COMMITTEE_SIZE: usize> TryFrom<Any> for ClientState<SYNC_COMMITT
}
}

impl<const SYNC_COMMITTEE_SIZE: usize> From<ClientState<SYNC_COMMITTEE_SIZE>> for Any {
fn from(value: ClientState<SYNC_COMMITTEE_SIZE>) -> Self {
impl<const SYNC_COMMITTEE_SIZE: usize, const EXECUTION_PAYLOAD_TREE_DEPTH: usize>
From<ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>> for Any
{
fn from(value: ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>) -> Self {
Self {
type_url: ETHEREUM_CLIENT_STATE_TYPE_URL.to_string(),
value: Protobuf::<RawClientState>::encode_vec(&value)
Expand All @@ -747,11 +774,14 @@ impl<const SYNC_COMMITTEE_SIZE: usize> From<ClientState<SYNC_COMMITTEE_SIZE>> fo
}
}

fn downcast_eth_client_state<const SYNC_COMMITTEE_SIZE: usize>(
fn downcast_eth_client_state<
const SYNC_COMMITTEE_SIZE: usize,
const EXECUTION_PAYLOAD_TREE_DEPTH: usize,
>(
cs: &dyn Ics2ClientState,
) -> Result<&ClientState<SYNC_COMMITTEE_SIZE>, ClientError> {
) -> Result<&ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>, ClientError> {
cs.as_any()
.downcast_ref::<ClientState<SYNC_COMMITTEE_SIZE>>()
.downcast_ref::<ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>>()
.ok_or_else(|| ClientError::ClientArgsTypeMismatch {
client_type: eth_client_type(),
})
Expand Down
2 changes: 2 additions & 0 deletions crates/ibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub mod header;
pub mod misbehaviour;
pub mod types;
pub mod update;
pub use ethereum_consensus as consensus;
pub use ethereum_light_client_verifier as light_client_verifier;

mod internal_prelude {
pub use alloc::boxed::Box;
Expand Down
16 changes: 13 additions & 3 deletions crates/ibc/src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,25 @@ pub fn new_consensus_update<const SYNC_COMMITTEE_SIZE: usize>(
}
}

pub fn apply_updates<const SYNC_COMMITTEE_SIZE: usize, C: ChainContext>(
pub fn apply_updates<
const SYNC_COMMITTEE_SIZE: usize,
const EXECUTION_PAYLOAD_TREE_DEPTH: usize,
C: ChainContext,
>(
ctx: &C,
client_state: &ClientState<SYNC_COMMITTEE_SIZE>,
client_state: &ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>,
trusted_consensus_state: &TrustedConsensusState<SYNC_COMMITTEE_SIZE>,
consensus_update: ConsensusUpdateInfo<SYNC_COMMITTEE_SIZE>,
execution_update: ExecutionUpdateInfo,
account_update: AccountUpdateInfo,
timestamp: Timestamp,
) -> Result<(ClientState<SYNC_COMMITTEE_SIZE>, ConsensusState), Error> {
) -> Result<
(
ClientState<SYNC_COMMITTEE_SIZE, EXECUTION_PAYLOAD_TREE_DEPTH>,
ConsensusState,
),
Error,
> {
let mut new_client_state = client_state.clone();

let store_period =
Expand Down