diff --git a/Cargo.lock b/Cargo.lock index 49c5a77..b5f2b46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,14 +472,13 @@ dependencies = [ "ethereum-ibc", "ibc", "light-client", - "serde", "tiny-keccak 1.5.0", ] [[package]] name = "ethereum-ibc" version = "0.1.0" -source = "git+https://github.com/datachainlab/ethereum-ibc-rs?rev=v0.0.15#d652f330f24d638720cbed03099f3df7ae2d5b30" +source = "git+https://github.com/datachainlab/ethereum-ibc-rs?rev=8243b634ae0953a9e0c2fd5f64c2b830723ab8f6#8243b634ae0953a9e0c2fd5f64c2b830723ab8f6" dependencies = [ "bytes", "displaydoc", @@ -499,7 +498,7 @@ dependencies = [ [[package]] name = "ethereum-ibc-proto" version = "0.1.0" -source = "git+https://github.com/datachainlab/ethereum-ibc-rs?rev=v0.0.15#d652f330f24d638720cbed03099f3df7ae2d5b30" +source = "git+https://github.com/datachainlab/ethereum-ibc-rs?rev=8243b634ae0953a9e0c2fd5f64c2b830723ab8f6#8243b634ae0953a9e0c2fd5f64c2b830723ab8f6" dependencies = [ "prost", "serde", diff --git a/Cargo.toml b/Cargo.toml index 29f41c6..840e156 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,9 +5,8 @@ edition = "2021" [dependencies] ibc = { version = "0.29.0", default-features = false, features = ["serde"] } -serde = { version = "1.0", default-features = false } displaydoc = { version = "0.2", default-features = false } tiny-keccak = { version = "1.4" } light-client = { git = "https://github.com/datachainlab/lcp", rev = "v0.2.11", default-features = false, features = ["ibc"] } -ethereum-ibc = { git = "https://github.com/datachainlab/ethereum-ibc-rs", rev = "v0.0.15", default-features = false } +ethereum-ibc = { git = "https://github.com/datachainlab/ethereum-ibc-rs", rev = "8243b634ae0953a9e0c2fd5f64c2b830723ab8f6", default-features = false } diff --git a/src/client.rs b/src/client.rs index 53a95b1..52633c3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,12 +1,13 @@ use crate::errors::Error; use crate::internal_prelude::*; -use crate::message::{ClientMessage, Header, Misbehaviour}; -use crate::state::{gen_state_id, ClientState, ConsensusState}; +use crate::state::gen_state_id; use core::str::FromStr; use core::time::Duration; -use ethereum_ibc::client_state::ClientState as EthereumClientState; -use ethereum_ibc::consensus_state::ConsensusState as EthereumConsensusState; +use ethereum_ibc::client_state::ClientState; +use ethereum_ibc::consensus_state::ConsensusState; use ethereum_ibc::eth_client_type; +use ethereum_ibc::header::{ClientMessage, Header}; +use ethereum_ibc::misbehaviour::Misbehaviour; use ibc::core::ics02_client::client_state::{ downcast_client_state, ClientState as Ics02ClientState, UpdatedState, }; @@ -22,6 +23,7 @@ use light_client::commitments::{ UpdateStateProxyMessage, ValidationContext, VerifyMembershipProxyMessage, }; use light_client::ibc::IBCContext; +use light_client::types::proto::google::protobuf::Any as IBCAny; use light_client::types::{Any, ClientId, Height, Time}; use light_client::{ CreateClientResult, HostClientReader, LightClient, MisbehaviourData, UpdateStateData, @@ -42,7 +44,9 @@ impl LightClient for EthereumLightClient Result { let client_state: ClientState = - ctx.client_state(client_id)?.try_into()?; + IBCAny::from(ctx.client_state(client_id)?) + .try_into() + .map_err(Error::ICS02)?; Ok(client_state.latest_height().into()) } @@ -52,10 +56,14 @@ impl LightClient for EthereumLightClient Result { - let client_state = ClientState::::try_from(any_client_state.clone())?; - let consensus_state = ConsensusState::try_from(any_consensus_state)?; + let any_client_state = IBCAny::from(any_client_state); + let any_consensus_state = IBCAny::from(any_consensus_state); + let client_state = ClientState::::try_from(any_client_state.clone()) + .map_err(Error::ICS02)?; + let consensus_state = + ConsensusState::try_from(any_consensus_state).map_err(Error::ICS02)?; let _ = client_state - .initialise(consensus_state.0.clone().into()) + .initialise(consensus_state.clone().into()) .map_err(Error::ICS02)?; let height = client_state.latest_height().into(); @@ -68,7 +76,7 @@ impl LightClient for EthereumLightClient LightClient for EthereumLightClient Result { - match ClientMessage::::try_from(any_message.clone())? { + let message = + ClientMessage::::try_from(IBCAny::from(any_message.clone())) + .map_err(Error::IBC)?; + match message { ClientMessage::Header(header) => Ok(self .update_state(ctx, client_id, any_message, header)? .into()), @@ -191,7 +202,9 @@ impl EthereumLightClient light_client::Error, > { let client_state: ClientState = - ctx.client_state(&client_id)?.try_into()?; + IBCAny::from(ctx.client_state(&client_id)?) + .try_into() + .map_err(Error::ICS02)?; if client_state.is_frozen() { return Err(Error::ICS02(ClientError::ClientFrozen { @@ -201,7 +214,9 @@ impl EthereumLightClient } let consensus_state: ConsensusState = - ctx.consensus_state(&client_id, &proof_height)?.try_into()?; + IBCAny::from(ctx.consensus_state(&client_id, &proof_height)?) + .try_into() + .map_err(Error::ICS02)?; let proof: CommitmentProofBytes = proof.try_into().map_err(Error::ICS23)?; let prefix: CommitmentPrefix = counterparty_prefix.try_into().map_err(Error::ICS23)?; @@ -217,7 +232,9 @@ impl EthereumLightClient header: Header, ) -> Result { let client_state: ClientState = - ctx.client_state(&client_id)?.try_into()?; + IBCAny::from(ctx.client_state(&client_id)?) + .try_into() + .map_err(Error::ICS02)?; if client_state.is_frozen() { return Err(Error::ICS02(ClientError::ClientFrozen { @@ -230,15 +247,17 @@ impl EthereumLightClient let header_timestamp: Time = header.timestamp().into(); let trusted_height = header.trusted_sync_committee.height; - let trusted_consensus_state: ConsensusState = ctx - .consensus_state(&client_id, &trusted_height.into()) - .map_err(|_| { - Error::ICS02(ClientError::ConsensusStateNotFound { - client_id: client_id.clone().into(), - height: trusted_height, - }) - })? - .try_into()?; + let trusted_consensus_state: ConsensusState = IBCAny::from( + ctx.consensus_state(&client_id, &trusted_height.into()) + .map_err(|_| { + Error::ICS02(ClientError::ConsensusStateNotFound { + client_id: client_id.clone().into(), + height: trusted_height, + }) + })?, + ) + .try_into() + .map_err(Error::ICS02)?; // Use client_state to validate the new header against the latest consensus_state. // This function will return the new client_state (its latest_height changed) and a @@ -248,10 +267,7 @@ impl EthereumLightClient consensus_state: new_consensus_state, } = client_state .check_header_and_update_state( - &IBCContext::< - EthereumClientState, - EthereumConsensusState, - >::new(ctx), + &IBCContext::, ConsensusState>::new(ctx), client_id.into(), any_message.into(), ) @@ -261,24 +277,20 @@ impl EthereumLightClient }) })?; - let new_client_state = ClientState( - downcast_client_state::>( - new_client_state.as_ref(), - ) - .unwrap() - .clone(), - ); - let new_consensus_state = ConsensusState( - downcast_consensus_state::(new_consensus_state.as_ref()) + let new_client_state = + downcast_client_state::>(new_client_state.as_ref()) + .unwrap() + .clone(); + let new_consensus_state = + downcast_consensus_state::(new_consensus_state.as_ref()) .unwrap() - .clone(), - ); + .clone(); let prev_state_id = gen_state_id(client_state.clone(), trusted_consensus_state.clone())?; let post_state_id = gen_state_id(new_client_state.clone(), new_consensus_state.clone())?; Ok(UpdateStateData { - new_any_client_state: new_client_state.into(), - new_any_consensus_state: new_consensus_state.into(), + new_any_client_state: IBCAny::from(new_client_state).into(), + new_any_consensus_state: IBCAny::from(new_consensus_state).into(), height, message: UpdateStateProxyMessage { prev_height: Some(trusted_height.into()), @@ -306,7 +318,9 @@ impl EthereumLightClient misbehaviour: Misbehaviour, ) -> Result { let client_state: ClientState = - ctx.client_state(&client_id)?.try_into()?; + IBCAny::from(ctx.client_state(&client_id)?) + .try_into() + .map_err(Error::ICS02)?; if client_state.is_frozen() { return Err(Error::ICS02(ClientError::ClientFrozen { @@ -316,20 +330,19 @@ impl EthereumLightClient } let trusted_height = misbehaviour.trusted_sync_committee.height; - let trusted_consensus_state: ConsensusState = ctx - .consensus_state(&client_id, &trusted_height.into()) - .map_err(|_| { - Error::ICS02(ClientError::ConsensusStateNotFound { - client_id: client_id.clone().into(), - height: trusted_height, - }) - })? - .try_into()?; + let trusted_consensus_state: ConsensusState = IBCAny::from( + ctx.consensus_state(&client_id, &trusted_height.into()) + .map_err(|_| { + Error::ICS02(ClientError::ConsensusStateNotFound { + client_id: client_id.clone().into(), + height: trusted_height, + }) + })?, + ) + .try_into() + .map_err(Error::ICS02)?; - let ibc_ctx = - IBCContext::, EthereumConsensusState>::new( - ctx, - ); + let ibc_ctx = IBCContext::, ConsensusState>::new(ctx); let new_client_state = client_state .check_misbehaviour_and_update_state( @@ -342,16 +355,13 @@ impl EthereumLightClient reason: e.to_string(), }) })?; - let new_client_state = ClientState( - downcast_client_state::>( - new_client_state.as_ref(), - ) - .unwrap() - .clone(), - ); + let new_client_state = + downcast_client_state::>(new_client_state.as_ref()) + .unwrap() + .clone(); Ok(MisbehaviourData { - new_any_client_state: new_client_state.into(), + new_any_client_state: IBCAny::from(new_client_state).into(), message: MisbehaviourProxyMessage { prev_states: self.make_prev_states( ctx, @@ -366,7 +376,7 @@ impl EthereumLightClient Time::unix_epoch(), trusted_consensus_state.timestamp.into(), )), - client_message: Any::from(misbehaviour), + client_message: IBCAny::from(misbehaviour).into(), }, }) } @@ -381,15 +391,15 @@ impl EthereumLightClient let mut prev_states = Vec::new(); for height in heights { let ibc_height = height.try_into().map_err(Error::ICS02)?; - let consensus_state: ConsensusState = ctx - .consensus_state(client_id, &height) - .map_err(|_| { + let consensus_state: ConsensusState = + IBCAny::from(ctx.consensus_state(client_id, &height).map_err(|_| { Error::ICS02(ClientError::ConsensusStateNotFound { client_id: client_id.clone().into(), height: ibc_height, }) - })? - .try_into()?; + })?) + .try_into() + .map_err(Error::ICS02)?; prev_states.push(PrevState { height, state_id: gen_state_id(client_state.clone(), consensus_state)?, diff --git a/src/lib.rs b/src/lib.rs index f0a5a10..fadd4e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,6 @@ extern crate alloc; pub mod client; pub mod errors; -pub mod message; pub mod state; pub use ethereum_ibc as ibc; diff --git a/src/message.rs b/src/message.rs deleted file mode 100644 index 835346c..0000000 --- a/src/message.rs +++ /dev/null @@ -1,135 +0,0 @@ -use crate::errors::Error; -use core::ops::Deref; -use ethereum_ibc::header::{Header as EthereumHeader, ETHEREUM_HEADER_TYPE_URL}; -use ethereum_ibc::misbehaviour::{ - Misbehaviour as EthereumMisbehaviour, ETHEREUM_FINALIZED_HEADER_MISBEHAVIOUR_TYPE_URL, - ETHEREUM_NEXT_SYNC_COMMITTEE_MISBEHAVIOUR_TYPE_URL, -}; -use light_client::types::proto::google::protobuf::Any as IBCAny; -use light_client::types::Any; - -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] -pub enum ClientMessage { - Header(Header), - Misbehaviour(Misbehaviour), -} - -impl From> for Any { - fn from(value: ClientMessage) -> Self { - match value { - ClientMessage::Header(header) => header.into(), - ClientMessage::Misbehaviour(misbehaviour) => misbehaviour.into(), - } - } -} - -impl TryFrom for ClientMessage { - type Error = Error; - - fn try_from(value: Any) -> Result { - match value.type_url.as_str() { - ETHEREUM_HEADER_TYPE_URL => Ok(ClientMessage::Header(Header::try_from(value)?)), - ETHEREUM_FINALIZED_HEADER_MISBEHAVIOUR_TYPE_URL - | ETHEREUM_NEXT_SYNC_COMMITTEE_MISBEHAVIOUR_TYPE_URL => { - Ok(ClientMessage::Misbehaviour(Misbehaviour::try_from(value)?)) - } - _ => Err(Error::UnexpectedClientType(value.type_url.clone())), - } - } -} - -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] -pub struct Header(pub(crate) EthereumHeader); - -impl Deref for Header { - type Target = EthereumHeader; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From> - for EthereumHeader -{ - fn from(value: Header) -> Self { - value.0 - } -} - -impl From> - for Header -{ - fn from(value: EthereumHeader) -> Self { - Self(value) - } -} - -impl From> for Any { - fn from(value: Header) -> Self { - IBCAny::from(value.0).into() - } -} - -impl TryFrom for Header { - type Error = Error; - - fn try_from(value: Any) -> Result { - let any: IBCAny = value.into(); - if any.type_url == ETHEREUM_HEADER_TYPE_URL { - Ok(Self(EthereumHeader::try_from(any).map_err(Error::ICS02)?)) - } else { - Err(Error::UnexpectedClientType(any.type_url)) - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -pub struct Misbehaviour( - pub(crate) EthereumMisbehaviour, -); - -impl Deref for Misbehaviour { - type Target = EthereumMisbehaviour; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From> - for EthereumMisbehaviour -{ - fn from(value: Misbehaviour) -> Self { - value.0 - } -} - -impl From> - for Misbehaviour -{ - fn from(value: EthereumMisbehaviour) -> Self { - Self(value) - } -} - -impl From> for Any { - fn from(value: Misbehaviour) -> Self { - IBCAny::from(value.0).into() - } -} - -impl TryFrom for Misbehaviour { - type Error = Error; - - fn try_from(value: Any) -> Result { - let any: IBCAny = value.into(); - if any.type_url == ETHEREUM_FINALIZED_HEADER_MISBEHAVIOUR_TYPE_URL - || any.type_url == ETHEREUM_NEXT_SYNC_COMMITTEE_MISBEHAVIOUR_TYPE_URL - { - Ok(Self( - EthereumMisbehaviour::try_from(any).map_err(Error::ICS02)?, - )) - } else { - Err(Error::UnexpectedClientType(any.type_url)) - } - } -} diff --git a/src/state.rs b/src/state.rs index e9145f7..5a89324 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,90 +1,18 @@ use crate::errors::Error; -use core::ops::Deref; -use ethereum_ibc::client_state::{ - ClientState as EthereumClientState, ETHEREUM_CLIENT_STATE_TYPE_URL, -}; -use ethereum_ibc::consensus_state::{ - ConsensusState as EthereumConsensusState, ETHEREUM_CONSENSUS_STATE_TYPE_URL, -}; +use ethereum_ibc::client_state::ClientState; +use ethereum_ibc::consensus_state::ConsensusState; use light_client::commitments::{gen_state_id_from_any, StateID}; use light_client::types::proto::google::protobuf::Any as IBCAny; -use light_client::types::Any; - -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] -pub struct ClientState( - pub(crate) EthereumClientState, -); - -impl Deref for ClientState { - type Target = EthereumClientState; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl TryFrom for ClientState { - type Error = Error; - - fn try_from(value: Any) -> Result { - let any: IBCAny = value.into(); - if any.type_url == ETHEREUM_CLIENT_STATE_TYPE_URL { - Ok(Self( - EthereumClientState::try_from(any).map_err(Error::ICS02)?, - )) - } else { - Err(Error::UnexpectedClientType(any.type_url)) - } - } -} - -impl From> for Any { - fn from(value: ClientState) -> Self { - IBCAny::from(value.0).into() - } -} - -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] -pub struct ConsensusState(pub(crate) EthereumConsensusState); - -impl Deref for ConsensusState { - type Target = EthereumConsensusState; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl TryFrom for ConsensusState { - type Error = Error; - - fn try_from(value: Any) -> Result { - let any: IBCAny = value.into(); - if any.type_url == ETHEREUM_CONSENSUS_STATE_TYPE_URL { - Ok(Self( - EthereumConsensusState::try_from(any).map_err(Error::ICS02)?, - )) - } else { - Err(Error::UnexpectedClientType(any.type_url)) - } - } -} - -impl From for Any { - fn from(value: ConsensusState) -> Self { - IBCAny::from(value.0).into() - } -} // canonicalize_client_state canonicalizes some fields of specified client state // target fields: latest_execution_block_number, frozen_height pub fn canonicalize_client_state( client_state: ClientState, ) -> ClientState { - let mut client_state = client_state.0; + let mut client_state = client_state; client_state.latest_execution_block_number = 0u64.into(); client_state.frozen_height = None; - ClientState(client_state) + client_state } pub fn gen_state_id( @@ -92,7 +20,7 @@ pub fn gen_state_id( consensus_state: ConsensusState, ) -> Result { Ok(gen_state_id_from_any( - &canonicalize_client_state(client_state).into(), - &consensus_state.into(), + &IBCAny::from(canonicalize_client_state(client_state)).into(), + &IBCAny::from(consensus_state).into(), )?) }