From f4302f70538852418cf744a315132f27c2d29990 Mon Sep 17 00:00:00 2001 From: benluelo Date: Tue, 31 Oct 2023 16:39:58 +0000 Subject: [PATCH 1/2] fix: ignore all vendor directories in .ignore, not .gitignore --- .ignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.ignore b/.ignore index 0c45cfec73..ca77028315 100644 --- a/.ignore +++ b/.ignore @@ -1,2 +1 @@ -uniond/vendor -unionpd/vendor \ No newline at end of file +**/vendor From e329384952009a6784999f6b6791538e52f98277 Mon Sep 17 00:00:00 2001 From: benluelo Date: Wed, 1 Nov 2023 18:53:37 +0000 Subject: [PATCH 2/2] feat(voyager): remove unnecessary epoch wait on evm --- lib/unionlabs/src/proof.rs | 2 +- voyager/src/chain.rs | 32 +- voyager/src/chain/evm.rs | 288 +++++++++-- voyager/src/chain/proof.rs | 33 +- voyager/src/chain/union.rs | 259 ++++++++-- voyager/src/msg.rs | 140 +++-- voyager/src/msg/data.rs | 62 +-- voyager/src/queue.rs | 776 ++++++++++++++-------------- voyager/src/queue/aggregate_data.rs | 9 +- 9 files changed, 1048 insertions(+), 553 deletions(-) diff --git a/lib/unionlabs/src/proof.rs b/lib/unionlabs/src/proof.rs index 3c7fba819e..f301728af6 100644 --- a/lib/unionlabs/src/proof.rs +++ b/lib/unionlabs/src/proof.rs @@ -15,7 +15,7 @@ use crate::{ /// `IbcPath` represents the path to a light client's ibc storage. The values stored at each path /// are strongly typed, i.e. `connections/{connection_id}` always stores a [`ConnectionEnd`]. -pub trait IbcPath: Display + Clone + Sized { +pub trait IbcPath: Display + Clone + Sized { type Output: Debug + Clone + Serialize; } diff --git a/voyager/src/chain.rs b/voyager/src/chain.rs index 0f9b670248..89fbdfc500 100644 --- a/voyager/src/chain.rs +++ b/voyager/src/chain.rs @@ -12,17 +12,22 @@ use futures::Future; use serde::{Deserialize, Serialize}; use unionlabs::{ ethereum_consts_traits::{Mainnet, Minimal}, - ibc::core::client::height::{HeightFromStrError, IsHeight}, + ibc::core::{ + channel::channel::Channel, + client::height::{HeightFromStrError, IsHeight}, + connection::connection_end::ConnectionEnd, + }, + id::{ChannelId, ConnectionId, PortId}, traits::{self, Chain}, }; use crate::{ - chain::proof::{IbcStateRead, IbcStateReadPaths, StateProof}, + chain::proof::{IbcStateRead, IbcStateReadPaths}, config::{self, ChainConfig, EvmChainConfig}, msg::{ aggregate::LightClientSpecificAggregate, data::LightClientSpecificData, - fetch::{FetchUpdateHeaders, LightClientSpecificFetch}, + fetch::{FetchStateProof, FetchUpdateHeaders, LightClientSpecificFetch}, msg::Msg, DoAggregate, RelayerMsg, }, @@ -118,6 +123,25 @@ pub trait LightClientBase: Send + Sync + Sized { fn from_chain(chain: Self::HostChain) -> Self; + fn channel( + &self, + channel_id: ChannelId, + port_id: PortId, + at: HeightOf, + ) -> impl Future + '_; + + fn connection( + &self, + connection_id: ConnectionId, + at: HeightOf, + ) -> impl Future< + Output = ConnectionEnd< + Self::ClientId, + ::ClientId, + String, + >, + > + '_; + // TODO: Use state_proof instead fn query_client_state( &self, @@ -157,6 +181,8 @@ pub trait LightClient: LightClientBase { /// Error type for [`Self::msg`]. type MsgError: MaybeRecoverableError; + fn proof(&self, msg: FetchStateProof) -> RelayerMsg; + fn msg(&self, msg: Msg) -> impl Future> + '_; fn do_fetch(&self, msg: Self::Fetch) -> impl Future> + '_; diff --git a/voyager/src/chain/evm.rs b/voyager/src/chain/evm.rs index abf1397b82..f0c72299f9 100644 --- a/voyager/src/chain/evm.rs +++ b/voyager/src/chain/evm.rs @@ -38,9 +38,12 @@ use unionlabs::{ }, ethereum_consts_traits::{ChainSpec, Mainnet, Minimal}, ibc::{ - core::client::{ - height::{Height, IsHeight}, - msg_update_client::MsgUpdateClient, + core::{ + client::{ + height::{Height, IsHeight}, + msg_update_client::MsgUpdateClient, + }, + connection::connection_end::ConnectionEnd, }, google::protobuf::any::Any, lightclients::{ @@ -67,15 +70,21 @@ use crate::{ chain::{ try_from_relayer_msg, union::{EthereumMainnet, EthereumMinimal}, - ClientStateOf, ConsensusStateOf, HeaderOf, HeightOf, IbcStateRead, LightClient, - LightClientBase, QueryHeight, StateProof, + ChainOf, ClientStateOf, ConsensusStateOf, HeaderOf, HeightOf, IbcStateRead, LightClient, + LightClientBase, QueryHeight, }, msg::{ aggregate::{Aggregate, AnyAggregate, LightClientSpecificAggregate}, data, - data::{Data, LightClientSpecificData}, + data::{ + AcknowledgementProof, ChannelEndProof, ClientConsensusStateProof, ClientStateProof, + CommitmentProof, ConnectionProof, Data, LightClientSpecificData, + }, fetch, - fetch::{Fetch, FetchTrustedClientState, FetchUpdateHeaders, LightClientSpecificFetch}, + fetch::{ + Fetch, FetchStateProof, FetchTrustedClientState, FetchUpdateHeaders, + LightClientSpecificFetch, + }, identified, msg::{Msg, MsgUpdateClientData}, seq, wait, @@ -200,6 +209,40 @@ impl LightClientBase for CometblsMainnet { Self { chain } } + fn channel( + &self, + channel_id: unionlabs::id::ChannelId, + port_id: unionlabs::id::PortId, + at: HeightOf, + ) -> impl Future + '_ { + read_ibc_state::, _, _>( + &self.chain, + ChannelEndPath { + port_id, + channel_id, + }, + at.revision_height(), + ) + } + + fn connection( + &self, + connection_id: unionlabs::id::ConnectionId, + at: HeightOf, + ) -> impl Future< + Output = ConnectionEnd< + Self::ClientId, + ::ClientId, + String, + >, + > + '_ { + read_ibc_state::, _, _>( + &self.chain, + ConnectionPath { connection_id }, + at.revision_height(), + ) + } + fn query_client_state( &self, client_id: ::ClientId, @@ -214,11 +257,21 @@ impl LightClient for CometblsMainnet { type BaseCounterparty = Self::Counterparty; type Data = CometblsDataMsg; - type Fetch = CometblsFetchMsg; + type Fetch = CometblsFetchMsg; type Aggregate = CometblsAggregateMsg; type MsgError = TxSubmitError; + fn proof(&self, msg: FetchStateProof) -> RelayerMsg { + fetch( + self.chain.chain_id(), + LightClientSpecificFetch::(CometblsFetchMsg::FetchGetProof(GetProof { + path: msg.path, + height: msg.at, + })), + ) + } + fn msg(&self, msg: Msg) -> impl Future> + '_ { self::msg(&self.chain, msg) } @@ -252,6 +305,40 @@ impl LightClientBase for CometblsMinimal { Self { chain } } + fn channel( + &self, + channel_id: unionlabs::id::ChannelId, + port_id: unionlabs::id::PortId, + at: HeightOf, + ) -> impl Future + '_ { + read_ibc_state::, _, _>( + &self.chain, + ChannelEndPath { + port_id, + channel_id, + }, + at.revision_height(), + ) + } + + fn connection( + &self, + connection_id: unionlabs::id::ConnectionId, + at: HeightOf, + ) -> impl Future< + Output = ConnectionEnd< + Self::ClientId, + ::ClientId, + String, + >, + > + '_ { + read_ibc_state::, _, _>( + &self.chain, + ConnectionPath { connection_id }, + at.revision_height(), + ) + } + fn query_client_state( &self, client_id: ::ClientId, @@ -266,11 +353,21 @@ impl LightClient for CometblsMinimal { type BaseCounterparty = Self::Counterparty; type Data = CometblsDataMsg; - type Fetch = CometblsFetchMsg; + type Fetch = CometblsFetchMsg; type Aggregate = CometblsAggregateMsg; type MsgError = TxSubmitError; + fn proof(&self, msg: FetchStateProof) -> RelayerMsg { + fetch( + self.chain.chain_id(), + LightClientSpecificFetch::(CometblsFetchMsg::FetchGetProof(GetProof { + path: msg.path, + height: msg.at, + })), + ) + } + fn msg(&self, msg: Msg) -> impl Future> + '_ { self::msg(&self.chain, msg) } @@ -287,6 +384,29 @@ impl LightClient for CometblsMinimal { } } +async fn read_ibc_state( + evm: &Evm, + p: P, + at: u64, +) -> P::Output +where + Counterparty: Chain, + C: ChainSpec, + P: IbcPath, Counterparty> + + EthereumStateRead< + C, + Counterparty, + Encoded = <<

>::EthCall as EthCallExt>::Return as TupleToOption>::Inner, + > + 'static, + ::Return: TupleToOption, +{ + evm.read_ibc_state(p.into_eth_call(), at) + .await + .unwrap() + .map(|x| P::decode_ibc_state(x)) + .unwrap() +} + fn generate_counterparty_updates( evm: &Evm, update_info: FetchUpdateHeaders, @@ -295,11 +415,11 @@ where C: ChainSpec, L: LightClient< HostChain = Evm, - Fetch = CometblsFetchMsg, + Fetch = CometblsFetchMsg, Data = CometblsDataMsg, Aggregate = CometblsAggregateMsg, >, - LightClientSpecificFetch: From>, + LightClientSpecificFetch: From>, AnyLightClientIdentified: From)>, AnyLightClientIdentified: From)>, { @@ -492,7 +612,7 @@ try_from_relayer_msg! { DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize, derive_more::Display, )] #[serde(bound(serialize = "", deserialize = ""))] -pub enum CometblsFetchMsg { +pub enum CometblsFetchMsg>, C: ChainSpec> { #[display(fmt = "FetchFinalityUpdate")] FetchFinalityUpdate(PhantomData), #[display(fmt = "FetchLightClientUpdates")] @@ -505,6 +625,8 @@ pub enum CometblsFetchMsg { FetchAccountUpdate(FetchAccountUpdate), #[display(fmt = "FetchBeaconGenesis")] FetchBeaconGenesis(FetchBeaconGenesis), + #[display(fmt = "FetchGetProof::{}", "_0.path")] + FetchGetProof(GetProof), } #[derive( @@ -724,7 +846,7 @@ pub struct LightClientUpdates(pub Vec>); impl DoAggregate for CometblsAggregateMsg where C: ChainSpec, - L: LightClient, Aggregate = Self, Fetch = CometblsFetchMsg>, + L: LightClient, Aggregate = Self, Fetch = CometblsFetchMsg>, Identified>: TryFrom + Into, @@ -877,7 +999,7 @@ where C: ChainSpec, L: LightClient< HostChain = Evm, - Fetch = CometblsFetchMsg, + Fetch = CometblsFetchMsg, Aggregate = CometblsAggregateMsg, >, AnyLightClientIdentified: From)>, @@ -1123,10 +1245,10 @@ async fn query_client_state( Any::try_from_proto_bytes(&client_state_bytes).unwrap() } -async fn do_fetch(evm: &Evm, msg: CometblsFetchMsg) -> Vec +async fn do_fetch(evm: &Evm, msg: CometblsFetchMsg) -> Vec where C: ChainSpec, - L: LightClient, Fetch = CometblsFetchMsg, Data = CometblsDataMsg>, + L: LightClient, Fetch = CometblsFetchMsg, Data = CometblsDataMsg>, LightClientSpecificData: From>, AnyLightClientIdentified: From)>, { @@ -1252,6 +1374,98 @@ where __marker: PhantomData, }) } + CometblsFetchMsg::FetchGetProof(get_proof) => { + let execution_height = evm.execution_height(get_proof.height).await; + + let path = get_proof.path.to_string(); + + let location = keccak256( + keccak256(path.as_bytes()) + .into_iter() + .chain(U256::from(0).encode()) + .collect::>(), + ); + + let proof = evm + .provider + .get_proof( + evm.readonly_ibc_handler.address(), + vec![location.into()], + Some(execution_height.into()), + ) + .await + .unwrap(); + + tracing::info!(?proof); + + let proof = match <[_; 1]>::try_from(proof.storage_proof) { + Ok([proof]) => proof, + Err(invalid) => { + panic!("received invalid response from eth_getProof, expected length of 1 but got `{invalid:#?}`"); + } + }; + + let proof = ethereum_v1::StorageProof { + proofs: [ethereum_v1::Proof { + key: proof.key.to_fixed_bytes().to_vec(), + // REVIEW(benluelo): Make sure this encoding works + value: proof.value.encode(), + proof: proof + .proof + .into_iter() + .map(|bytes| bytes.to_vec()) + .collect(), + }] + .to_vec(), + } + .encode_to_vec(); + + return [match get_proof.path { + unionlabs::proof::Path::ClientStatePath(_) => data::( + evm.chain_id, + ClientStateProof { + proof, + height: get_proof.height, + }, + ), + unionlabs::proof::Path::ClientConsensusStatePath(_) => data::( + evm.chain_id, + ClientConsensusStateProof { + proof, + height: get_proof.height, + }, + ), + unionlabs::proof::Path::ConnectionPath(_) => data::( + evm.chain_id, + ConnectionProof { + proof, + height: get_proof.height, + }, + ), + unionlabs::proof::Path::ChannelEndPath(_) => data::( + evm.chain_id, + ChannelEndProof { + proof, + height: get_proof.height, + }, + ), + unionlabs::proof::Path::CommitmentPath(_) => data::( + evm.chain_id, + CommitmentProof { + proof, + height: get_proof.height, + }, + ), + unionlabs::proof::Path::AcknowledgementPath(_) => data::( + evm.chain_id, + AcknowledgementProof { + proof, + height: get_proof.height, + }, + ), + }] + .into(); + } }; [data::(evm.chain_id, LightClientSpecificData::from(msg))].into() @@ -1273,21 +1487,12 @@ where &self, path: P, at: Height, - ) -> impl Future, Counterparty>>::Output>> + '_ { + ) -> impl Future> + '_ { async move { let execution_height = self.execution_height(at).await; - let ret = self - .read_ibc_state(path.clone().into_eth_call(), execution_height) - .await - .unwrap() - .map(|x| P::decode_ibc_state(x)) - .unwrap(); - let path = path.to_string(); - tracing::info!(path, ?execution_height); - let location = keccak256( keccak256(path.as_bytes()) .into_iter() @@ -1310,13 +1515,11 @@ where let proof = match <[_; 1]>::try_from(proof.storage_proof) { Ok([proof]) => proof, Err(invalid) => { - panic!("received invalid response from eth_getProof, expected length of 1 but got {invalid:#?}"); + panic!("received invalid response from eth_getProof, expected length of 1 but got `{invalid:#?}`"); } }; - StateProof { - state: ret, - proof: ethereum_v1::StorageProof { + ethereum_v1::StorageProof { proofs: [ethereum_v1::Proof { key: proof.key.to_fixed_bytes().to_vec(), // REVIEW(benluelo): Make sure this encoding works @@ -1329,14 +1532,27 @@ where }] .to_vec(), } - .encode_to_vec(), - // REVIEW: Beacon or execution? - proof_height: at, - } + .encode_to_vec() } } } +#[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, serde::Serialize, serde::Deserialize)] +#[serde(bound(serialize = "", deserialize = ""))] +pub struct GetProof>> { + path: unionlabs::proof::Path< + ::ClientId, + as Chain>::Height, + >, + height: as Chain>::Height, +} + +// pub struct AnyGetProof>> { +// __marker: PhantomData (C, L)>, +// } + +// type _AnyGetProof = Path2>; + trait EthereumStateRead: IbcPath, Counterparty> where Counterparty: Chain, @@ -1605,7 +1821,7 @@ where C: ChainSpec, L: LightClient< HostChain = Evm, - Fetch = CometblsFetchMsg, + Fetch = CometblsFetchMsg, Aggregate = CometblsAggregateMsg, >, Identified>: @@ -1675,7 +1891,7 @@ where C: ChainSpec, L: LightClient< HostChain = Evm, - Fetch = CometblsFetchMsg, + Fetch = CometblsFetchMsg, Aggregate = CometblsAggregateMsg, >, diff --git a/voyager/src/chain/proof.rs b/voyager/src/chain/proof.rs index 702942e1df..febd658aed 100644 --- a/voyager/src/chain/proof.rs +++ b/voyager/src/chain/proof.rs @@ -1,9 +1,5 @@ -use std::fmt::Debug; - use futures::Future; -use serde::{Deserialize, Serialize}; use unionlabs::{ - ibc::core::client::height::Height, proof::{ AcknowledgementPath, ChannelEndPath, ClientConsensusStatePath, ClientStatePath, CommitmentPath, ConnectionPath, IbcPath, @@ -11,33 +7,8 @@ use unionlabs::{ traits::Chain, }; -pub trait IbcStateRead>: Chain + Sized -where - StateProof: Debug + Serialize, -{ - fn state_proof( - &self, - path: P, - at: Self::Height, - ) -> impl Future> + '_; -} - -#[derive(Clone, PartialEq, Serialize, Deserialize)] -pub struct StateProof { - pub state: State, - #[serde(with = "::serde_utils::hex_string")] - pub proof: Vec, - pub proof_height: Height, -} - -impl Debug for StateProof { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("StateProof") - .field("state", &self.state) - .field("proof", &serde_utils::to_hex(&self.proof)) - .field("proof_height", &self.proof_height) - .finish() - } +pub trait IbcStateRead>: Chain + Sized { + fn state_proof(&self, path: P, at: Self::Height) -> impl Future> + '_; } pub trait IbcStateReadPaths: diff --git a/voyager/src/chain/union.rs b/voyager/src/chain/union.rs index 6c20ec6935..dc0b9bc931 100644 --- a/voyager/src/chain/union.rs +++ b/voyager/src/chain/union.rs @@ -25,7 +25,10 @@ use unionlabs::{ ethereum::{Address, H256, H512}, ethereum_consts_traits::{ChainSpec, Mainnet, Minimal}, ibc::{ - core::client::{height::Height, msg_update_client::MsgUpdateClient}, + core::{ + client::{height::Height, msg_update_client::MsgUpdateClient}, + connection::connection_end::ConnectionEnd, + }, google::protobuf::{any::Any, timestamp::Timestamp}, lightclients::{cometbls, ethereum, wasm}, }, @@ -53,22 +56,27 @@ use unionlabs::{ use crate::{ chain::{ evm::{CometblsMainnet, CometblsMinimal}, - proof::StateProof, - try_from_relayer_msg, Chain, ClientStateOf, ConsensusStateOf, HeightOf, IbcStateRead, - LightClient, LightClientBase, QueryHeight, + try_from_relayer_msg, Chain, ChainOf, ClientStateOf, ConsensusStateOf, HeightOf, + IbcStateRead, LightClient, LightClientBase, QueryHeight, }, msg::{ aggregate::{Aggregate, LightClientSpecificAggregate}, data, - data::{Data, LightClientSpecificData}, + data::{ + AcknowledgementProof, ChannelEndProof, ClientConsensusStateProof, ClientStateProof, + CommitmentProof, ConnectionProof, Data, LightClientSpecificData, + }, defer_relative, fetch, - fetch::{Fetch, FetchTrustedClientState, FetchUpdateHeaders, LightClientSpecificFetch}, + fetch::{ + Fetch, FetchStateProof, FetchTrustedClientState, FetchUpdateHeaders, + LightClientSpecificFetch, + }, identified, msg::{Msg, MsgUpdateClientData}, seq, wait, wait::WaitForBlock, AggregateData, AggregateReceiver, AnyLcMsg, AnyLightClientIdentified, DoAggregate, - Identified, LcMsg, RelayerMsg, + Identified, LcMsg, PathOf, RelayerMsg, }, queue::aggregate_data::{do_aggregate, UseAggregate}, }; @@ -114,17 +122,64 @@ impl LightClientBase for EthereumMinimal { { query_client_state::(&self.chain, client_id, height) } + + fn channel( + &self, + channel_id: unionlabs::id::ChannelId, + port_id: unionlabs::id::PortId, + at: HeightOf, + ) -> impl Future + '_ { + read_ibc_state::, _>( + &self.chain, + ChannelEndPath { + port_id, + channel_id, + }, + at, + ) + } + + fn connection( + &self, + connection_id: unionlabs::id::ConnectionId, + at: HeightOf, + ) -> impl Future< + Output = ConnectionEnd< + Self::ClientId, + ::ClientId, + String, + >, + > + '_ { + read_ibc_state::, _>( + &self.chain, + ConnectionPath { connection_id }, + at, + ) + } } impl LightClient for EthereumMinimal { type BaseCounterparty = Self::Counterparty; type Data = EthereumDataMsg; - type Fetch = EthereumFetchMsg; + type Fetch = EthereumFetchMsg; type Aggregate = EthereumAggregateMsg; type MsgError = BroadcastTxCommitError; + fn proof(&self, msg: FetchStateProof) -> RelayerMsg { + seq([ + wait::(self.chain.chain_id(), WaitForBlock(msg.at.increment())), + fetch::( + self.chain.chain_id(), + LightClientSpecificFetch(EthereumFetchMsg::AbciQuery(FetchAbciQuery { + path: msg.path, + height: msg.at, + })), + ), + ]) + } + fn msg(&self, msg: Msg) -> impl Future> + '_ { self::msg::(self.chain.clone(), msg) } @@ -166,17 +221,64 @@ impl LightClientBase for EthereumMainnet { { query_client_state::(&self.chain, client_id, height) } + + fn channel( + &self, + channel_id: unionlabs::id::ChannelId, + port_id: unionlabs::id::PortId, + at: HeightOf, + ) -> impl Future + '_ { + read_ibc_state::, _>( + &self.chain, + ChannelEndPath { + port_id, + channel_id, + }, + at, + ) + } + + fn connection( + &self, + connection_id: unionlabs::id::ConnectionId, + at: HeightOf, + ) -> impl Future< + Output = ConnectionEnd< + Self::ClientId, + ::ClientId, + String, + >, + > + '_ { + read_ibc_state::, _>( + &self.chain, + ConnectionPath { connection_id }, + at, + ) + } } impl LightClient for EthereumMainnet { type BaseCounterparty = Self::Counterparty; type Data = EthereumDataMsg; - type Fetch = EthereumFetchMsg; + type Fetch = EthereumFetchMsg; type Aggregate = EthereumAggregateMsg; type MsgError = BroadcastTxCommitError; + fn proof(&self, msg: FetchStateProof) -> RelayerMsg { + seq([ + wait::(self.chain.chain_id(), WaitForBlock(msg.at.increment())), + fetch::( + self.chain.chain_id(), + LightClientSpecificFetch(EthereumFetchMsg::AbciQuery(FetchAbciQuery { + path: msg.path, + height: msg.at, + })), + ), + ]) + } + fn msg(&self, msg: Msg) -> impl Future> + '_ { self::msg(self.chain.clone(), msg) } @@ -193,10 +295,10 @@ impl LightClient for EthereumMainnet { } } -async fn do_fetch(union: &Union, msg: EthereumFetchMsg) -> Vec +async fn do_fetch(union: &Union, msg: EthereumFetchMsg) -> Vec where C: ChainSpec, - L: LightClient, Data = EthereumDataMsg>, + L: LightClient, Data = EthereumDataMsg>, AnyLightClientIdentified: From)>, AggregateData: From)>, AggregateReceiver: From)>, @@ -437,6 +539,63 @@ where } } } + EthereumFetchMsg::AbciQuery(FetchAbciQuery { path, height }) => { + let mut client = + protos::cosmos::base::tendermint::v1beta1::service_client::ServiceClient::connect( + union.grpc_url.clone(), + ) + .await + .unwrap(); + + let query_result = client + .abci_query(AbciQueryRequest { + data: path.to_string().into_bytes(), + path: "store/ibc/key".to_string(), + height: i64::try_from(height.revision_height).unwrap() - 1_i64, + prove: true, + }) + .await + .unwrap() + .into_inner(); + + let proof = protos::ibc::core::commitment::v1::MerkleProof { + proofs: query_result + .proof_ops + .unwrap() + .ops + .into_iter() + .map(|op| { + protos::cosmos::ics23::v1::CommitmentProof::decode(op.data.as_slice()) + .unwrap() + }) + .collect::>(), + } + .encode_to_vec(); + + let height = *height; + [match path { + unionlabs::proof::Path::ClientStatePath(_) => { + data::(union.chain_id(), ClientStateProof { proof, height }) + } + unionlabs::proof::Path::ClientConsensusStatePath(_) => data::( + union.chain_id(), + ClientConsensusStateProof { proof, height }, + ), + unionlabs::proof::Path::ConnectionPath(_) => { + data::(union.chain_id(), ConnectionProof { proof, height }) + } + unionlabs::proof::Path::ChannelEndPath(_) => { + data::(union.chain_id(), ChannelEndProof { proof, height }) + } + unionlabs::proof::Path::CommitmentPath(_) => { + data::(union.chain_id(), CommitmentProof { proof, height }) + } + unionlabs::proof::Path::AcknowledgementPath(_) => { + data::(union.chain_id(), AcknowledgementProof { proof, height }) + } + }] + .into() + } } } @@ -449,7 +608,7 @@ where L: LightClient< HostChain = Union, Aggregate = EthereumAggregateMsg, - Fetch = EthereumFetchMsg, + Fetch = EthereumFetchMsg, >, L::Counterparty: LightClient>, AnyLightClientIdentified: From)>, @@ -529,7 +688,7 @@ pub enum EthereumDataMsg { )] #[serde(bound(serialize = "", deserialize = ""))] #[allow(clippy::large_enum_variant)] -pub enum EthereumFetchMsg { +pub enum EthereumFetchMsg, C: ChainSpec> { // FetchTrustedCommit { height: Height }, #[display(fmt = "FetchUntrustedCommit")] FetchUntrustedCommit(FetchUntrustedCommit), @@ -537,6 +696,8 @@ pub enum EthereumFetchMsg { FetchValidators(FetchValidators), #[display(fmt = "FetchProveRequest")] FetchProveRequest(FetchProveRequest), + #[display(fmt = "FetchAbciQuery")] + AbciQuery(FetchAbciQuery), } #[derive( @@ -647,7 +808,7 @@ where // REVIEW: Use trait alias here? L: LightClient< HostChain = Union, - Fetch = EthereumFetchMsg, + Fetch = EthereumFetchMsg, Aggregate = EthereumAggregateMsg, >, L::Counterparty: LightClient>, @@ -786,6 +947,13 @@ pub struct FetchProveRequest { pub __marker: PhantomData C>, } +#[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] +#[serde(bound(serialize = "", deserialize = ""))] +pub struct FetchAbciQuery> { + path: PathOf, + height: HeightOf, +} + #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] pub struct AggregateHeader @@ -988,7 +1156,7 @@ where ConsensusStateOf: TryFromProto, P: IbcPath + AbciStateRead + 'static, { - fn state_proof(&self, path: P, at: Height) -> impl Future> + '_ { + fn state_proof(&self, path: P, at: Height) -> impl Future> + '_ { async move { tracing::info!(%path, %at, "fetching state proof"); @@ -1003,43 +1171,48 @@ where .abci_query(AbciQueryRequest { data: path.to_string().into_bytes(), path: "store/ibc/key".to_string(), - height: i64::try_from(at.revision_height).unwrap() - 1_i64, + height: i64::try_from(at.revision_height).unwrap(), prove: true, }) .await .unwrap() .into_inner(); - // dbg!(&query_result); + let _state = P::from_abci_bytes(query_result.value); - let state = P::from_abci_bytes(query_result.value); - tracing::info!(?state, "fetched state proof"); - - StateProof { - state, - proof: protos::ibc::core::commitment::v1::MerkleProof { - proofs: query_result - .proof_ops - .unwrap() - .ops - .into_iter() - .map(|op| { - protos::cosmos::ics23::v1::CommitmentProof::decode(op.data.as_slice()) - .unwrap() - }) - .collect::>(), - } - .encode_to_vec(), - // NOTE: query_result.height == AbciQueryRequest.height, hence the increment - // we could use at.revision_height here as well, maybe add an assert? - proof_height: self - .make_height(query_result.height.try_into().unwrap()) - .increment(), - } + todo!() } } } +async fn read_ibc_state(union: &Union, path: P, at: HeightOf) -> P::Output +where + Counterparty: Chain, + ClientStateOf: TryFromProto, + ConsensusStateOf: TryFromProto, + P: IbcPath + AbciStateRead + 'static, +{ + let mut client = + protos::cosmos::base::tendermint::v1beta1::service_client::ServiceClient::connect( + union.grpc_url.clone(), + ) + .await + .unwrap(); + + let query_result = client + .abci_query(AbciQueryRequest { + data: path.to_string().into_bytes(), + path: "store/ibc/key".to_string(), + height: i64::try_from(at.revision_height).unwrap(), + prove: false, + }) + .await + .unwrap() + .into_inner(); + + P::from_abci_bytes(query_result.value) +} + fn tendermint_hash_to_h256(hash: tendermint::Hash) -> H256 { match hash { tendermint::Hash::Sha256(hash) => hash.into(), @@ -1059,7 +1232,7 @@ where // REVIEW: Use trait alias here? L: LightClient< HostChain = Union, - Fetch = EthereumFetchMsg, + Fetch = EthereumFetchMsg, Aggregate = EthereumAggregateMsg, >, L::Counterparty: LightClient>, @@ -1248,7 +1421,7 @@ where impl UseAggregate for Identified> where C: ChainSpec, - L: LightClient>, + L: LightClient>, // L::Counterparty: LightClient>, Identified>: TryFrom + Into, diff --git a/voyager/src/msg.rs b/voyager/src/msg.rs index d93cf591de..4e22f4997c 100644 --- a/voyager/src/msg.rs +++ b/voyager/src/msg.rs @@ -8,16 +8,18 @@ use std::{ use frame_support_procedural::{CloneNoBound, DebugNoBound, PartialEqNoBound}; use serde::{Deserialize, Serialize}; use unionlabs::{ - proof::IbcPath, + proof::{ + AcknowledgementPath, ChannelEndPath, ClientConsensusStatePath, ClientStatePath, + CommitmentPath, ConnectionPath, IbcPath, + }, traits::{Chain, ClientState}, }; use crate::{ chain::{ evm::{CometblsMainnet, CometblsMinimal}, - proof::StateProof, union::{EthereumMainnet, EthereumMinimal}, - LightClient, LightClientBase, + ChainOf, LightClient, LightClientBase, }, msg::{ aggregate::AnyAggregate, @@ -39,13 +41,6 @@ pub mod wait; pub type ChainIdOf = <<::HostChain as Chain>::SelfClientState as ClientState>::ChainId; -pub type StateProofOf = StateProof< - ::HostChain, - <::Counterparty as LightClientBase>::HostChain, - >>::Output, ->; - pub trait IntoRelayerMsg { fn into_relayer_msg(self) -> RelayerMsg; } @@ -679,8 +674,78 @@ pub mod aggregate { RecvPacket(AggregateRecvPacket), AckPacket(AggregateAckPacket), } + + // #[derive( + // DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize, derive_more::Display, + // )] + // #[serde(bound(serialize = "", deserialize = ""))] + // pub enum AggregateAnyStateProof { + // #[display(fmt = "{_0}")] + // ClientState( + // AggregateStateProof< + // L, + // ClientStatePath<::ClientId>, + // >, + // ), + // #[display(fmt = "{_0}")] + // ClientConsensusState( + // AggregateStateProof< + // L, + // ClientConsensusStatePath< + // as unionlabs::traits::Chain>::ClientId, + // HeightOf>, + // >, + // >, + // ), + // #[display(fmt = "{_0}")] + // Connection(AggregateStateProof), + // #[display(fmt = "{_0}")] + // ChannelEnd(AggregateStateProof), + // #[display(fmt = "{_0}")] + // Commitment(AggregateStateProof), + // #[display(fmt = "{_0}")] + // Acknowledgement(AggregateStateProof), + // } + + // #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] + // #[serde(bound(serialize = "", deserialize = ""))] + // pub struct AggregateStateProof> { + // height: HeightOf>, + // #[serde(skip)] + // pub __marker: PhantomData

, + // } +} + +pub trait IbcPathExt: IbcPath, ChainOf> { + type Data: TryFrom + Into; + type Proof: TryFrom + Into; } +pub trait AnyPath { + type Inner>>; +} + +pub enum Path2> { + ClientStatePath(P::Inner::ClientId>>), + ClientConsensusStatePath( + P::Inner< + ClientConsensusStatePath< + ::ClientId, + as Chain>::Height, + >, + >, + ), + ConnectionPath(P::Inner), + ChannelEndPath(P::Inner), + CommitmentPath(P::Inner), + AcknowledgementPath(P::Inner), +} + +pub type PathOf = unionlabs::proof::Path< + <::HostChain as Chain>::ClientId, + ::Counterparty> as Chain>::Height, +>; + pub trait AnyLightClient { type Inner: Debug + Display @@ -876,18 +941,18 @@ mod tests { msg::{ aggregate::{Aggregate, AggregateCreateClient, AnyAggregate}, data::Data, - event, + defer_relative, event, event::{Event, IbcEvent}, fetch, fetch::{ - AnyFetch, Fetch, FetchSelfClientState, FetchSelfConsensusState, + AnyFetch, Fetch, FetchConnectionEnd, FetchSelfClientState, FetchSelfConsensusState, FetchTrustedClientState, }, msg, msg::{ Msg, MsgChannelOpenInitData, MsgConnectionOpenInitData, MsgConnectionOpenTryData, }, - AggregateReceiver, AnyLcMsg, AnyMsg, Identified, RelayerMsg, + seq, AggregateReceiver, AnyLcMsg, AnyMsg, Identified, RelayerMsg, }, DELAY_PERIOD, }; @@ -1002,26 +1067,32 @@ mod tests { }, )); - print_json(RelayerMsg::Timeout { - timeout_timestamp: u64::MAX, - msg: Box::new(event::( - eth_chain_id, - crate::msg::event::Command::UpdateClient { - client_id: parse!("cometbls-0"), - counterparty_client_id: parse!("08-wasm-0"), - }, - )), + print_json(RelayerMsg::Repeat { + times: u64::MAX, + msg: Box::new(seq([ + defer_relative(30), + event::( + eth_chain_id, + crate::msg::event::Command::UpdateClient { + client_id: parse!("cometbls-0"), + counterparty_client_id: parse!("08-wasm-0"), + }, + ), + ])), }); - print_json(RelayerMsg::Timeout { - timeout_timestamp: u64::MAX, - msg: Box::new(event::( - union_chain_id.clone(), - crate::msg::event::Command::UpdateClient { - client_id: parse!("08-wasm-0"), - counterparty_client_id: parse!("cometbls-0"), - }, - )), + print_json(RelayerMsg::Repeat { + times: u64::MAX, + msg: Box::new(seq([ + defer_relative(30), + event::( + union_chain_id.clone(), + crate::msg::event::Command::UpdateClient { + client_id: parse!("08-wasm-0"), + counterparty_client_id: parse!("cometbls-0"), + }, + ), + ])), }); println!("\ncreate client msgs\n"); @@ -1104,6 +1175,13 @@ mod tests { // }, // }, // )))); + print_json(fetch::( + union_chain_id.clone(), + FetchConnectionEnd { + at: parse!("1-103"), + connection_id: parse!("connection-1"), + }, + )) } fn print_json(msg: T) { diff --git a/voyager/src/msg/data.rs b/voyager/src/msg/data.rs index 097db9e6c5..bcdceae830 100644 --- a/voyager/src/msg/data.rs +++ b/voyager/src/msg/data.rs @@ -2,24 +2,13 @@ use std::marker::PhantomData; use frame_support_procedural::{CloneNoBound, DebugNoBound, PartialEqNoBound}; use serde::{Deserialize, Serialize}; -use unionlabs::{ - self, - ibc::core::channel::channel::Channel, - proof::{ - AcknowledgementPath, ChannelEndPath, ClientConsensusStatePath, ClientStatePath, - CommitmentPath, ConnectionPath, - }, - traits::Chain, -}; +use unionlabs::{self, ibc::core::channel::channel::Channel}; use crate::{ chain::{ ChainOf, ClientStateOf, ConsensusStateOf, HeaderOf, HeightOf, LightClient, LightClientBase, }, - msg::{ - any_enum, fetch::FetchPacketAcknowledgement, identified, AnyLightClientIdentified, - StateProofOf, - }, + msg::{any_enum, fetch::FetchPacketAcknowledgement, identified, AnyLightClientIdentified}, }; any_enum! { @@ -34,6 +23,7 @@ any_enum! { PacketAcknowledgement(PacketAcknowledgement), TrustedClientState(TrustedClientState), + ClientStateProof(ClientStateProof), ClientConsensusStateProof(ClientConsensusStateProof), ConnectionProof(ConnectionProof), @@ -79,37 +69,51 @@ pub struct Header(pub HeaderOf); #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] -pub struct ClientStateProof( - pub StateProofOf as Chain>::ClientId>, L>, -); +pub struct ClientStateProof { + pub height: HeightOf>, + #[serde(with = "::serde_utils::hex_string")] + pub proof: Vec, +} #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] -pub struct ClientConsensusStateProof( - pub StateProofOf< - ClientConsensusStatePath< - as Chain>::ClientId, - as Chain>::Height, - >, - L, - >, -); +pub struct ClientConsensusStateProof { + pub height: HeightOf>, + #[serde(with = "::serde_utils::hex_string")] + pub proof: Vec, +} #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] -pub struct ConnectionProof(pub StateProofOf); +pub struct ConnectionProof { + pub height: HeightOf>, + #[serde(with = "::serde_utils::hex_string")] + pub proof: Vec, +} #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] -pub struct ChannelEndProof(pub StateProofOf); +pub struct ChannelEndProof { + pub height: HeightOf>, + #[serde(with = "::serde_utils::hex_string")] + pub proof: Vec, +} #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] -pub struct CommitmentProof(pub StateProofOf); +pub struct CommitmentProof { + pub height: HeightOf>, + #[serde(with = "::serde_utils::hex_string")] + pub proof: Vec, +} #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] -pub struct AcknowledgementProof(pub StateProofOf); +pub struct AcknowledgementProof { + pub height: HeightOf>, + #[serde(with = "::serde_utils::hex_string")] + pub proof: Vec, +} #[derive(DebugNoBound, CloneNoBound, PartialEqNoBound, Serialize, Deserialize)] #[serde(bound(serialize = "", deserialize = ""))] diff --git a/voyager/src/queue.rs b/voyager/src/queue.rs index 834aaeb11f..9e10a580db 100644 --- a/voyager/src/queue.rs +++ b/voyager/src/queue.rs @@ -55,10 +55,8 @@ use unionlabs::{ use crate::{ chain::{ evm::{CometblsMainnet, CometblsMinimal}, - proof::IbcStateRead, union::{EthereumMainnet, EthereumMinimal}, - AnyChain, AnyChainTryFromConfigError, ChainOf, HeightOf, LightClient, LightClientBase, - QueryHeight, + AnyChain, AnyChainTryFromConfigError, HeightOf, LightClient, LightClientBase, QueryHeight, }, config::Config, msg::{ @@ -98,7 +96,7 @@ use crate::{ AggregateData, AggregateReceiver, AnyLcMsg, AnyLightClientIdentified, ChainIdOf, DeferPoint, DoAggregate, Identified, LcMsg, RelayerMsg, }, - queue::aggregate_data::UseAggregate, + queue::aggregate_data::{IsAggregateData, UseAggregate}, DELAY_PERIOD, }; @@ -778,6 +776,7 @@ impl Worker { AnyLightClientIdentified: From)>, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, + AnyLightClientIdentified: From)>, // TODO: Remove once we no longer unwrap in handle_fetch <::ClientId as TryFrom< <::HostChain as Chain>::ClientId, @@ -793,6 +792,9 @@ impl Worker { LcMsg::Data(data) => { // TODO: Figure out a way to bubble it up to the top level + let data = + AnyLightClientIdentified::::from(Identified::new(msg.chain_id, data)); + tracing::error!( data = %serde_json::to_string(&data).unwrap(), "received data outside of an aggregation" @@ -913,18 +915,23 @@ where IbcEvent::SubmitEvidence(_) => unimplemented!(), IbcEvent::ConnectionOpenInit(init) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + wait::(l.chain().chain_id(), WaitForBlock(ibc_event.height)), RelayerMsg::Aggregate { data: [].into(), - queue: [mk_aggregate_update( - l.chain().chain_id(), - init.client_id.clone(), - init.counterparty_client_id.clone(), - ibc_event.height, - )] + queue: [ + // mk_aggregate_update( + // l.chain().chain_id(), + // init.client_id.clone(), + // init.counterparty_client_id.clone(), + // ibc_event.height, + // ) + mk_aggregate_wait_for_update( + l.chain().chain_id(), + init.client_id.clone(), + init.counterparty_client_id.clone(), + ibc_event.height, + ), + ] .into(), receiver: AggregateReceiver::from(Identified::new( l.chain().chain_id(), @@ -941,13 +948,13 @@ where ])] .into(), IbcEvent::ConnectionOpenTry(try_) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + // wait::( + // l.chain().chain_id(), + // WaitForBlock(ibc_event.height.increment()), + // ), RelayerMsg::Aggregate { data: [].into(), - queue: [mk_aggregate_update( + queue: [mk_aggregate_wait_for_update( l.chain().chain_id(), try_.client_id.clone(), try_.counterparty_client_id.clone(), @@ -969,13 +976,13 @@ where ])] .into(), IbcEvent::ConnectionOpenAck(ack) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + // wait::( + // l.chain().chain_id(), + // WaitForBlock(ibc_event.height.increment()), + // ), RelayerMsg::Aggregate { data: [].into(), - queue: [mk_aggregate_update( + queue: [mk_aggregate_wait_for_update( l.chain().chain_id(), ack.client_id.clone(), ack.counterparty_client_id.clone(), @@ -1003,10 +1010,10 @@ where } IbcEvent::ChannelOpenInit(init) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + // wait::( + // l.chain().chain_id(), + // WaitForBlock(ibc_event.height.increment()), + // ), RelayerMsg::Aggregate { data: [].into(), queue: [RelayerMsg::Aggregate { @@ -1014,7 +1021,7 @@ where queue: [fetch( l.chain().chain_id(), FetchChannelEnd { - at: ibc_event.height.increment(), + at: ibc_event.height, port_id: init.port_id.clone(), channel_id: init.channel_id.clone(), }, @@ -1024,7 +1031,7 @@ where l.chain().chain_id(), Aggregate::ConnectionFetchFromChannelEnd( AggregateConnectionFetchFromChannelEnd { - at: ibc_event.height.increment(), + at: ibc_event.height, }, ), )), @@ -1034,7 +1041,7 @@ where l.chain().chain_id(), Aggregate::ChannelHandshakeUpdateClient( AggregateChannelHandshakeUpdateClient { - update_to: ibc_event.height.increment(), + update_to: ibc_event.height, event_height: ibc_event.height, channel_handshake_event: ChannelHandshakeEvent::Init(init), }, @@ -1044,10 +1051,10 @@ where ])] .into(), IbcEvent::ChannelOpenTry(try_) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + // wait::( + // l.chain().chain_id(), + // WaitForBlock(ibc_event.height.increment()), + // ), RelayerMsg::Aggregate { data: [].into(), queue: [RelayerMsg::Aggregate { @@ -1055,7 +1062,7 @@ where queue: [fetch( l.chain().chain_id(), FetchChannelEnd { - at: ibc_event.height.increment(), + at: ibc_event.height, port_id: try_.port_id.clone(), channel_id: try_.channel_id.clone(), }, @@ -1065,7 +1072,7 @@ where l.chain().chain_id(), Aggregate::ConnectionFetchFromChannelEnd( AggregateConnectionFetchFromChannelEnd { - at: ibc_event.height.increment(), + at: ibc_event.height, }, ), )), @@ -1075,7 +1082,7 @@ where l.chain().chain_id(), Aggregate::ChannelHandshakeUpdateClient( AggregateChannelHandshakeUpdateClient { - update_to: ibc_event.height.increment(), + update_to: ibc_event.height, event_height: ibc_event.height, channel_handshake_event: ChannelHandshakeEvent::Try(try_), }, @@ -1085,10 +1092,10 @@ where ])] .into(), IbcEvent::ChannelOpenAck(ack) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + // wait::( + // l.chain().chain_id(), + // WaitForBlock(ibc_event.height.increment()), + // ), RelayerMsg::Aggregate { data: [].into(), queue: [RelayerMsg::Aggregate { @@ -1096,7 +1103,7 @@ where queue: [fetch( l.chain().chain_id(), FetchChannelEnd { - at: ibc_event.height.increment(), + at: ibc_event.height, port_id: ack.port_id.clone(), channel_id: ack.channel_id.clone(), }, @@ -1106,7 +1113,7 @@ where l.chain().chain_id(), Aggregate::ConnectionFetchFromChannelEnd( AggregateConnectionFetchFromChannelEnd { - at: ibc_event.height.increment(), + at: ibc_event.height, }, ), )), @@ -1116,7 +1123,7 @@ where l.chain().chain_id(), Aggregate::ChannelHandshakeUpdateClient( AggregateChannelHandshakeUpdateClient { - update_to: ibc_event.height.increment(), + update_to: ibc_event.height, event_height: ibc_event.height, channel_handshake_event: ChannelHandshakeEvent::Ack(ack), }, @@ -1133,10 +1140,10 @@ where } IbcEvent::RecvPacket(packet) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + // wait::( + // l.chain().chain_id(), + // WaitForBlock(ibc_event.height.increment()), + // ), RelayerMsg::Aggregate { data: [].into(), queue: [fetch( @@ -1150,7 +1157,7 @@ where receiver: AggregateReceiver::from(Identified::new( l.chain().chain_id(), Aggregate::PacketUpdateClient(AggregatePacketUpdateClient { - update_to: ibc_event.height.increment(), + update_to: ibc_event.height, event_height: ibc_event.height, block_hash: ibc_event.block_hash, packet_event: PacketEvent::Recv(packet), @@ -1160,10 +1167,10 @@ where ])] .into(), IbcEvent::SendPacket(packet) => [seq([ - wait::( - l.chain().chain_id(), - WaitForBlock(ibc_event.height.increment()), - ), + // wait::( + // l.chain().chain_id(), + // WaitForBlock(ibc_event.height.increment()), + // ), RelayerMsg::Aggregate { data: [].into(), queue: [fetch( @@ -1177,7 +1184,7 @@ where receiver: AggregateReceiver::from(Identified::new( l.chain().chain_id(), Aggregate::PacketUpdateClient(AggregatePacketUpdateClient { - update_to: ibc_event.height.increment(), + update_to: ibc_event.height, event_height: ibc_event.height, block_hash: ibc_event.block_hash, packet_event: PacketEvent::Send(packet), @@ -1226,35 +1233,11 @@ where } } -/// For updating a client, the information we have originally is: -/// -/// - `chain_id`: the id of the chain that the client to be updated is on -/// - `height`: the height to update *to* -/// - `client_id`: id of the client to update -/// - `counterparty_client_id`: id of the counterparty of the client to update -/// -/// Given this information, multiple aggregations are required: -/// -/// - given (`chain_id`, `client_id`), fetch the counterparty client's `chain_id` -/// (contained within the client's client state) -/// - `FetchLatestTrustedClientState`, aggregated down into `UpdateClientData`, -/// producing `UpdateClientWithCounterpartyChainIdData` -/// -/// - then, with (`counterparty_chain_id`, `counterparty_client_id`), fetch the latest -/// client state of the counterparty client (which contains the latest trusted height) -/// - `FetchLatestTrustedClientState`, aggregated down into -/// `UpdateClientWithCounterpartyChainIdData`, producing `FetchUpdateHeaders` -/// -/// - finally, with the latest client state, build the headers between -/// `latest_client_state..=update_to` (note that the client may be updated to a height -/// greater than `update_to`, but never less; as such the latest trusted height should -/// always be fetched whenever it's needed) -/// - `FetchUpdateHeaders`, which delegates to `L::generate_counterparty_updates` -fn mk_aggregate_update( +fn mk_aggregate_wait_for_update( chain_id: ChainIdOf, client_id: L::ClientId, counterparty_client_id: ::ClientId, - event_height: HeightOf>, + wait_for: HeightOf, ) -> RelayerMsg where AnyLightClientIdentified: From)>, @@ -1265,23 +1248,78 @@ where chain_id.clone(), FetchTrustedClientState { at: QueryHeight::Latest, - client_id: client_id.clone(), + client_id: client_id.clone().clone(), }, )] .into(), data: [].into(), receiver: AggregateReceiver::from(Identified::new( chain_id, - Aggregate::::UpdateClient(AggregateUpdateClient { - // Proof is only valid at N + 1 for tendermint - update_to: event_height.increment(), - client_id: client_id.clone(), + Aggregate::::WaitForTrustedHeight(AggregateWaitForTrustedHeight { + wait_for, + client_id, counterparty_client_id, }), )), } } +// /// For updating a client, the information we have originally is: +// /// +// /// - `chain_id`: the id of the chain that the client to be updated is on +// /// - `height`: the height to update *to* +// /// - `client_id`: id of the client to update +// /// - `counterparty_client_id`: id of the counterparty of the client to update +// /// +// /// Given this information, multiple aggregations are required: +// /// +// /// - given (`chain_id`, `client_id`), fetch the counterparty client's `chain_id` +// /// (contained within the client's client state) +// /// - `FetchLatestTrustedClientState`, aggregated down into `UpdateClientData`, +// /// producing `UpdateClientWithCounterpartyChainIdData` +// /// +// /// - then, with (`counterparty_chain_id`, `counterparty_client_id`), fetch the latest +// /// client state of the counterparty client (which contains the latest trusted height) +// /// - `FetchLatestTrustedClientState`, aggregated down into +// /// `UpdateClientWithCounterpartyChainIdData`, producing `FetchUpdateHeaders` +// /// +// /// - finally, with the latest client state, build the headers between +// /// `latest_client_state..=update_to` (note that the client may be updated to a height +// /// greater than `update_to`, but never less; as such the latest trusted height should +// /// always be fetched whenever it's needed) +// /// - `FetchUpdateHeaders`, which delegates to `L::generate_counterparty_updates` +// fn mk_aggregate_update( +// chain_id: ChainIdOf, +// client_id: L::ClientId, +// counterparty_client_id: ::ClientId, +// event_height: HeightOf>, +// ) -> RelayerMsg +// where +// AnyLightClientIdentified: From)>, +// AggregateReceiver: From)>, +// { +// RelayerMsg::Aggregate { +// queue: [fetch::( +// chain_id.clone(), +// FetchTrustedClientState { +// at: QueryHeight::Latest, +// client_id: client_id.clone(), +// }, +// )] +// .into(), +// data: [].into(), +// receiver: AggregateReceiver::from(Identified::new( +// chain_id, +// Aggregate::::UpdateClient(AggregateUpdateClient { +// // Proof is only valid at N + 1 for tendermint +// update_to: event_height.increment(), +// client_id: client_id.clone(), +// counterparty_client_id, +// }), +// )), +// } +// } + async fn handle_fetch(l: L, fetch: Fetch) -> Vec where AnyLightClientIdentified: From)>, @@ -1311,30 +1349,7 @@ where )] .into() } - Fetch::StateProof(FetchStateProof { at, path }) => [data( - l.chain().chain_id(), - match path { - proof::Path::ClientStatePath(path) => { - Data::ClientStateProof(ClientStateProof(l.chain().state_proof(path, at).await)) - } - proof::Path::ClientConsensusStatePath(path) => Data::ClientConsensusStateProof( - ClientConsensusStateProof(l.chain().state_proof(path, at).await), - ), - proof::Path::ConnectionPath(path) => { - Data::ConnectionProof(ConnectionProof(l.chain().state_proof(path, at).await)) - } - proof::Path::ChannelEndPath(path) => { - Data::ChannelEndProof(ChannelEndProof(l.chain().state_proof(path, at).await)) - } - proof::Path::CommitmentPath(path) => { - Data::CommitmentProof(CommitmentProof(l.chain().state_proof(path, at).await)) - } - proof::Path::AcknowledgementPath(path) => Data::AcknowledgementProof( - AcknowledgementProof(l.chain().state_proof(path, at).await), - ), - }, - )] - .into(), + Fetch::StateProof(msg) => [l.proof(msg)].into(), Fetch::SelfClientState(FetchSelfClientState { at: height }) => { // TODO: Split this into a separate query and aggregate let height = match height { @@ -1404,60 +1419,16 @@ where }) => [data( l.chain().chain_id(), ChannelEnd { - channel: l - .chain() - .state_proof( - proof::ChannelEndPath { - port_id, - channel_id, - }, - at, - ) - .map(|channel_end_proof| channel_end_proof.state) - .await, + channel: l.channel(channel_id, port_id, at).await, __marker: PhantomData, }, )] .into(), - Fetch::ConnectionEnd(FetchConnectionEnd { at, connection_id }) => { - [data( - l.chain().chain_id(), - ConnectionEnd( - l.chain() - .state_proof(proof::ConnectionPath { connection_id }, at) - .map(|connection_end_proof| { - unionlabs::ibc::core::connection::connection_end::ConnectionEnd::< - L::ClientId, - ::ClientId, - // NOTE: String used here since it may be empty; figure out a way to more strongly type this? - String, - > { - client_id: connection_end_proof.state.client_id.try_into().expect( - "state proof for a client should return it's own client id", - ), - versions: connection_end_proof.state.versions, - state: connection_end_proof.state.state, - counterparty: - unionlabs::ibc::core::connection::counterparty::Counterparty { - client_id: - <::ClientId>::try_from( - connection_end_proof.state.counterparty.client_id, - ) - .unwrap(), - connection_id: connection_end_proof - .state - .counterparty - .connection_id, - prefix: connection_end_proof.state.counterparty.prefix, - }, - delay_period: connection_end_proof.state.delay_period, - } - }) - .await, - ), - )] - .into() - } + Fetch::ConnectionEnd(FetchConnectionEnd { at, connection_id }) => [data( + l.chain().chain_id(), + ConnectionEnd(l.connection(connection_id, at).await), + )] + .into(), }; relayer_msg @@ -1567,34 +1538,22 @@ fn do_create( data: VecDeque, ) -> Vec where - identified!(TrustedClientState): - TryFrom + Into, - identified!(TrustedClientState): - TryFrom + Into, - - identified!(ClientStateProof): - TryFrom + Into, - identified!(ClientConsensusStateProof): - TryFrom + Into, - identified!(ConnectionProof): - TryFrom + Into, - identified!(ChannelEndProof): - TryFrom + Into, - identified!(CommitmentProof): - TryFrom + Into, - identified!(AcknowledgementProof): - TryFrom + Into, - - identified!(SelfClientState): - TryFrom + Into, - identified!(SelfConsensusState): - TryFrom + Into, - - identified!(ChannelEnd): TryFrom + Into, - identified!(ConnectionEnd): - TryFrom + Into, - identified!(PacketAcknowledgement): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(TrustedClientState): IsAggregateData, + + identified!(ClientStateProof): IsAggregateData, + identified!(ClientConsensusStateProof): IsAggregateData, + identified!(ConnectionProof): IsAggregateData, + identified!(ChannelEndProof): IsAggregateData, + identified!(CommitmentProof): IsAggregateData, + identified!(AcknowledgementProof): IsAggregateData, + + identified!(SelfClientState): IsAggregateData, + identified!(SelfConsensusState): IsAggregateData, + + identified!(ChannelEnd): IsAggregateData, + identified!(ConnectionEnd): IsAggregateData, + identified!(PacketAcknowledgement): IsAggregateData, AnyLightClientIdentified: From)>, AnyLightClientIdentified: From)>, @@ -1780,8 +1739,7 @@ where impl UseAggregate for identified!(AggregateChannelHandshakeUpdateClient) where - identified!(ConnectionEnd): - TryFrom + Into, + identified!(ConnectionEnd): IsAggregateData, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, { @@ -1827,10 +1785,10 @@ where RelayerMsg::Aggregate { data: [].into(), - queue: [mk_aggregate_update( + queue: [mk_aggregate_wait_for_update( this_chain_id.clone(), - connection.client_id.clone(), - connection.counterparty.client_id.clone(), + connection.client_id, + connection.counterparty.client_id, update_to, )] .into(), @@ -1844,8 +1802,7 @@ where impl UseAggregate for identified!(AggregatePacketUpdateClient) where - identified!(ConnectionEnd): - TryFrom + Into, + identified!(ConnectionEnd): IsAggregateData, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, { @@ -1886,28 +1843,29 @@ where ), }; + let agg = RelayerMsg::Aggregate { + queue: [fetch::( + this_chain_id.clone().clone(), + FetchTrustedClientState { + at: QueryHeight::Latest, + client_id: connection.client_id.clone().clone(), + }, + )] + .into(), + data: [].into(), + receiver: AggregateReceiver::from(Identified::new( + this_chain_id.clone(), + Aggregate::::WaitForTrustedHeight(AggregateWaitForTrustedHeight { + wait_for: update_to, + client_id: connection.client_id.clone().clone(), + counterparty_client_id: connection.counterparty.client_id.clone(), + }), + )), + }; + RelayerMsg::Aggregate { data: [].into(), - queue: [RelayerMsg::Aggregate { - queue: [fetch::( - this_chain_id.clone().clone(), - FetchTrustedClientState { - at: QueryHeight::Latest, - client_id: connection.client_id.clone().clone(), - }, - )] - .into(), - data: [].into(), - receiver: AggregateReceiver::from(Identified::new( - this_chain_id.clone(), - Aggregate::::WaitForTrustedHeight(AggregateWaitForTrustedHeight { - wait_for: update_to, - client_id: connection.client_id.clone().clone(), - counterparty_client_id: connection.counterparty.client_id.clone(), - }), - )), - }] - .into(), + queue: [agg].into(), receiver: AggregateReceiver::from(Identified::new(this_chain_id, event)), } } @@ -1915,7 +1873,7 @@ where impl UseAggregate for identified!(AggregateConnectionFetchFromChannelEnd) where - identified!(ChannelEnd): TryFrom + Into, + identified!(ChannelEnd): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![identified!(ChannelEnd)]; @@ -1947,8 +1905,7 @@ where impl UseAggregate for identified!(AggregateUpdateClientFromClientId) where - identified!(TrustedClientState): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, // AnyLightClientIdentified: From)>, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, @@ -2005,8 +1962,7 @@ where impl UseAggregate for identified!(AggregateUpdateClient) where - identified!(TrustedClientState): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, // AnyLightClientIdentified: From)>, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, @@ -2065,8 +2021,7 @@ where impl UseAggregate for identified!(AggregateUpdateClientWithCounterpartyChainId) where - identified!(TrustedClientState): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, { @@ -2116,8 +2071,7 @@ where impl UseAggregate for identified!(AggregateWaitForTrustedHeight) where - identified!(TrustedClientState): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, { @@ -2164,8 +2118,7 @@ where // TODO: Remove, unused impl UseAggregate for identified!(ConsensusStateProofAtLatestHeight) where - identified!(TrustedClientState): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, AnyLightClientIdentified: From)>, AggregateReceiver: From)>, { @@ -2203,8 +2156,7 @@ where impl UseAggregate for identified!(AggregateMsgAfterUpdate) where - identified!(TrustedClientState): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, AnyLightClientIdentified: From)>, AnyLightClientIdentified: From)>, AggregateData: From)>, @@ -2292,6 +2244,13 @@ where }), }, ), + fetch::( + this_chain_id.clone(), + FetchConnectionEnd { + at: trusted_client_state_fetched_at_height, + connection_id: event.connection_id.clone(), + }, + ), ] .into(), receiver: AggregateReceiver::from(Identified::new( @@ -2365,6 +2324,13 @@ where }), }, ), + fetch::( + this_chain_id.clone(), + FetchConnectionEnd { + at: trusted_client_state_fetched_at_height, + connection_id: event.connection_id.clone(), + }, + ), ] .into(), receiver: AggregateReceiver::from(Identified::new( @@ -2484,6 +2450,14 @@ where }), }, ), + fetch::( + this_chain_id.clone(), + FetchChannelEnd { + at: trusted_client_state_fetched_at_height, + port_id: event.port_id.clone(), + channel_id: event.channel_id.clone(), + }, + ), ] .into(), receiver: AggregateReceiver::from(Identified::new( @@ -2525,16 +2499,26 @@ where }), ))] .into(), - queue: [fetch::( - this_chain_id.clone(), - FetchStateProof { - at: trusted_client_state_fetched_at_height, - path: proof::Path::ChannelEndPath(ChannelEndPath { + queue: [ + fetch::( + this_chain_id.clone(), + FetchStateProof { + at: trusted_client_state_fetched_at_height, + path: proof::Path::ChannelEndPath(ChannelEndPath { + port_id: event.port_id.clone(), + channel_id: event.channel_id.clone(), + }), + }, + ), + fetch::( + this_chain_id.clone(), + FetchChannelEnd { + at: trusted_client_state_fetched_at_height, port_id: event.port_id.clone(), channel_id: event.channel_id.clone(), - }), - }, - )] + }, + ), + ] .into(), receiver: AggregateReceiver::from(Identified::new( this_chain_id, @@ -2574,16 +2558,26 @@ where }), ))] .into(), - queue: [fetch::( - this_chain_id.clone(), - FetchStateProof { - at: trusted_client_state_fetched_at_height, - path: proof::Path::ChannelEndPath(ChannelEndPath { + queue: [ + fetch::( + this_chain_id.clone(), + FetchStateProof { + at: trusted_client_state_fetched_at_height, + path: proof::Path::ChannelEndPath(ChannelEndPath { + port_id: event.port_id.clone(), + channel_id: event.channel_id.clone(), + }), + }, + ), + fetch::( + this_chain_id.clone(), + FetchChannelEnd { + at: trusted_client_state_fetched_at_height, port_id: event.port_id.clone(), channel_id: event.channel_id.clone(), - }), - }, - )] + }, + ), + ] .into(), receiver: AggregateReceiver::from(Identified::new( this_chain_id, @@ -2687,14 +2681,11 @@ where impl UseAggregate for identified!(AggregateConnectionOpenTry) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(ClientStateProof): - TryFrom + Into, - identified!(ClientConsensusStateProof): - TryFrom + Into, - identified!(ConnectionProof): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(ClientStateProof): IsAggregateData, + identified!(ClientConsensusStateProof): IsAggregateData, + identified!(ConnectionProof): IsAggregateData, + identified!(ConnectionEnd): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ @@ -2702,6 +2693,7 @@ where identified!(ClientStateProof), identified!(ClientConsensusStateProof), identified!(ConnectionProof), + identified!(ConnectionEnd), ]; fn aggregate( @@ -2724,36 +2716,42 @@ where }, Identified { chain_id: client_state_proof_chain_id, - data: ClientStateProof(client_state_proof) + data: ClientStateProof { + height: client_state_proof_height, + proof: client_state_proof, + } }, Identified { chain_id: consensus_state_proof_chain_id, - data: ClientConsensusStateProof(consensus_state_proof) + data: ClientConsensusStateProof { + height: consensus_state_proof_height, + proof: consensus_state_proof, + } }, Identified { chain_id: connection_proof_chain_id, - data: ConnectionProof(connection_proof) + data: ConnectionProof { + height: connection_proof_height, + proof: connection_proof, + } + }, + Identified { + chain_id: connection_end_chain_id, + data: ConnectionEnd(connection_end), }, ]: Self::AggregatedData, ) -> RelayerMsg { - assert_eq!(this_chain_id, trusted_client_state_chain_id); - - assert!( - consensus_state_proof.proof_height.revision_height - >= trusted_height.into_height().revision_height - ); - assert!( - client_state_proof.proof_height.revision_height - >= trusted_height.into_height().revision_height - ); + assert!(consensus_state_proof_height.revision_height() >= trusted_height.revision_height()); + assert!(client_state_proof_height.revision_height() >= trusted_height.revision_height()); let counterparty_chain_id: ChainIdOf = trusted_client_state.chain_id(); - // assert_eq!(counterparty_chain_id, client_updated_chain_id); + assert_eq!(trusted_client_state_chain_id, this_chain_id); assert_eq!(client_state_proof_chain_id, this_chain_id); assert_eq!(consensus_state_proof_chain_id, this_chain_id); assert_eq!(connection_proof_chain_id, this_chain_id); + assert_eq!(connection_end_chain_id, this_chain_id); let consensus_height = trusted_client_state.height(); @@ -2762,7 +2760,7 @@ where Msg::ConnectionOpenTry(MsgConnectionOpenTryData { msg: MsgConnectionOpenTry { client_id: event.counterparty_client_id, - client_state: client_state_proof.state, + client_state: trusted_client_state, counterparty: connection::counterparty::Counterparty { client_id: event.client_id, connection_id: event.connection_id, @@ -2771,12 +2769,11 @@ where }, }, delay_period: DELAY_PERIOD, - counterparty_versions: connection_proof.state.versions, - proof_height: connection_proof.proof_height.into(), - proof_init: connection_proof.proof, - proof_client: client_state_proof.proof, - proof_consensus: consensus_state_proof.proof, - // consensus_height: fetched_at, + counterparty_versions: connection_end.versions, + proof_height: connection_proof_height, + proof_init: connection_proof, + proof_client: client_state_proof, + proof_consensus: consensus_state_proof, consensus_height, }, }), @@ -2786,14 +2783,11 @@ where impl UseAggregate for identified!(AggregateConnectionOpenAck) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(ClientStateProof): - TryFrom + Into, - identified!(ClientConsensusStateProof): - TryFrom + Into, - identified!(ConnectionProof): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(ClientStateProof): IsAggregateData, + identified!(ClientConsensusStateProof): IsAggregateData, + identified!(ConnectionProof): IsAggregateData, + identified!(ConnectionEnd): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ @@ -2801,6 +2795,7 @@ where identified!(ClientStateProof), identified!(ClientConsensusStateProof), identified!(ConnectionProof), + identified!(ConnectionEnd), ]; fn aggregate( @@ -2823,36 +2818,41 @@ where }, Identified { chain_id: client_state_proof_chain_id, - data: ClientStateProof(client_state_proof) + data: ClientStateProof { + height: client_state_proof_height, + proof: client_state_proof, + } }, Identified { chain_id: consensus_state_proof_chain_id, - data: ClientConsensusStateProof(consensus_state_proof) + data: ClientConsensusStateProof { + height: consensus_state_proof_height, + proof: consensus_state_proof, + } }, Identified { chain_id: connection_proof_chain_id, - data: ConnectionProof(connection_proof) + data: ConnectionProof { + height: connection_proof_height, + proof: connection_proof, + } + }, + Identified { + chain_id: connection_end_chain_id, + data: ConnectionEnd(connection_end), }, ]: Self::AggregatedData, ) -> RelayerMsg { - assert_eq!(this_chain_id, trusted_client_state_chain_id); - - assert!( - consensus_state_proof.proof_height.revision_height - >= trusted_height.into_height().revision_height - ); - assert!( - client_state_proof.proof_height.revision_height - >= trusted_height.into_height().revision_height - ); + assert!(consensus_state_proof_height.revision_height() >= trusted_height.revision_height()); + assert!(client_state_proof_height.revision_height() >= trusted_height.revision_height()); let counterparty_chain_id: ChainIdOf = trusted_client_state.chain_id(); - // assert_eq!(counterparty_chain_id, client_updated_chain_id); - + assert_eq!(trusted_client_state_chain_id, this_chain_id); assert_eq!(client_state_proof_chain_id, this_chain_id); assert_eq!(consensus_state_proof_chain_id, this_chain_id); assert_eq!(connection_proof_chain_id, this_chain_id); + assert_eq!(connection_end_chain_id, this_chain_id); let consensus_height = trusted_client_state.height(); @@ -2863,13 +2863,12 @@ where connection_id: event.counterparty_connection_id, counterparty_connection_id: event.connection_id, // TODO: Figure out a way to not panic here, likely by encoding this invariant into the type somehow - version: connection_proof.state.versions[0].clone(), - client_state: client_state_proof.state, - proof_height: connection_proof.proof_height, - proof_try: connection_proof.proof, - proof_client: client_state_proof.proof, - proof_consensus: consensus_state_proof.proof, - // consensus_height: consensus_state_proof.proof_height, + version: connection_end.versions[0].clone(), + client_state: trusted_client_state, + proof_height: connection_proof_height.into(), + proof_try: connection_proof, + proof_client: client_state_proof, + proof_consensus: consensus_state_proof, consensus_height: consensus_height.into(), }, }), @@ -2879,14 +2878,10 @@ where impl UseAggregate for identified!(AggregateConnectionOpenConfirm) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(ClientStateProof): - TryFrom + Into, - identified!(ClientConsensusStateProof): - TryFrom + Into, - identified!(ConnectionProof): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(ClientStateProof): IsAggregateData, + identified!(ClientConsensusStateProof): IsAggregateData, + identified!(ConnectionProof): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ @@ -2914,23 +2909,24 @@ where }, Identified { chain_id: connection_proof_chain_id, - data: ConnectionProof(connection_proof) + data: ConnectionProof { + height: connection_proof_height, + proof: connection_proof + } }, ]: Self::AggregatedData, ) -> RelayerMsg { - assert_eq!(this_chain_id, trusted_client_state_chain_id); - let counterparty_chain_id: ChainIdOf = trusted_client_state.chain_id(); - // assert_eq!(counterparty_chain_id, client_updated_chain_id); + assert_eq!(trusted_client_state_chain_id, this_chain_id); assert_eq!(connection_proof_chain_id, this_chain_id); msg::( counterparty_chain_id, Msg::ConnectionOpenConfirm(MsgConnectionOpenConfirmData(MsgConnectionOpenConfirm { connection_id: event.counterparty_connection_id, - proof_height: connection_proof.proof_height.into(), - proof_ack: connection_proof.proof, + proof_height: connection_proof_height, + proof_ack: connection_proof, })), ) } @@ -2938,18 +2934,17 @@ where impl UseAggregate for identified!(AggregateChannelOpenTry) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(ChannelEndProof): - TryFrom + Into, - identified!(ConnectionEnd): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(ChannelEndProof): IsAggregateData, + identified!(ConnectionEnd): IsAggregateData, + identified!(ChannelEnd): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ identified!(TrustedClientState), identified!(ChannelEndProof), identified!(ConnectionEnd), + identified!(ChannelEnd), ]; fn aggregate( @@ -2972,12 +2967,22 @@ where }, Identified { chain_id: channel_proof_chain_id, - data: ChannelEndProof(channel_proof) + data: ChannelEndProof { + proof: channel_proof, + height: channel_proof_height + } }, Identified { chain_id: _connection_end_chain_id, data: ConnectionEnd(connection) }, + Identified { + chain_id: _channel_end_chain_id, + data: ChannelEnd { + channel, + __marker: _ + }, + }, ]: Self::AggregatedData, ) -> RelayerMsg { assert_eq!(this_chain_id, trusted_client_state_chain_id); @@ -2988,12 +2993,12 @@ where msg::( counterparty_chain_id, - Msg::ChannelOpenTry(MsgChannelOpenTryData { + MsgChannelOpenTryData { msg: MsgChannelOpenTry { - port_id: channel_proof.state.counterparty.port_id.clone(), + port_id: channel.counterparty.port_id.clone(), channel: Channel { state: channel::state::State::Tryopen, - ordering: channel_proof.state.ordering, + ordering: channel.ordering, counterparty: channel::counterparty::Counterparty { port_id: event.port_id.clone(), channel_id: event.channel_id.clone().to_string(), @@ -3007,26 +3012,26 @@ where }, // NOTE: Review behaviour here counterparty_version: event.version, - proof_init: channel_proof.proof, - proof_height: channel_proof.proof_height, + proof_init: channel_proof, + proof_height: channel_proof_height.into(), }, __marker: PhantomData, - }), + }, ) } } impl UseAggregate for identified!(AggregateChannelOpenAck) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(ChannelEndProof): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(ChannelEndProof): IsAggregateData, + identified!(ChannelEnd): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ identified!(TrustedClientState), identified!(ChannelEndProof), + identified!(ChannelEnd), ]; fn aggregate( @@ -3049,44 +3054,54 @@ where }, Identified { chain_id: channel_proof_chain_id, - data: ChannelEndProof(channel_proof) + data: ChannelEndProof { + height: channel_proof_height, + proof: channel_proof, + } + }, + Identified { + chain_id: channel_end_chain_id, + data: ChannelEnd { + channel, + __marker: _ + }, }, ]: Self::AggregatedData, ) -> RelayerMsg { - assert_eq!(this_chain_id, trusted_client_state_chain_id); - let counterparty_chain_id: ChainIdOf = trusted_client_state.chain_id(); + assert_eq!(trusted_client_state_chain_id, this_chain_id); assert_eq!(channel_proof_chain_id, this_chain_id); + assert_eq!(channel_end_chain_id, this_chain_id); msg::( counterparty_chain_id, - Msg::ChannelOpenAck(MsgChannelOpenAckData { + MsgChannelOpenAckData { msg: MsgChannelOpenAck { - port_id: channel_proof.state.counterparty.port_id.clone(), + port_id: channel.counterparty.port_id.clone(), channel_id: event.counterparty_channel_id, counterparty_channel_id: event.channel_id, counterparty_version: event.version, - proof_try: channel_proof.proof, - proof_height: channel_proof.proof_height, + proof_try: channel_proof, + proof_height: channel_proof_height.into(), }, __marker: PhantomData, - }), + }, ) } } impl UseAggregate for identified!(AggregateChannelOpenConfirm) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(ChannelEndProof): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(ChannelEndProof): IsAggregateData, + identified!(ChannelEnd): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ identified!(TrustedClientState), identified!(ChannelEndProof), + identified!(ChannelEnd), ]; fn aggregate( @@ -3109,36 +3124,45 @@ where }, Identified { chain_id: channel_proof_chain_id, - data: ChannelEndProof(channel_proof) + data: ChannelEndProof { + height: channel_proof_height, + proof: channel_proof, + } + }, + Identified { + chain_id: channel_end_chain_id, + data: ChannelEnd { + channel, + __marker: _ + }, }, ]: Self::AggregatedData, ) -> RelayerMsg { assert_eq!(this_chain_id, trusted_client_state_chain_id); assert_eq!(this_chain_id, channel_proof_chain_id); + assert_eq!(channel_end_chain_id, this_chain_id); let counterparty_chain_id: ChainIdOf = trusted_client_state.chain_id(); msg::( counterparty_chain_id, - Msg::ChannelOpenConfirm(MsgChannelOpenConfirmData { + MsgChannelOpenConfirmData { msg: MsgChannelOpenConfirm { - port_id: channel_proof.state.counterparty.port_id, + port_id: channel.counterparty.port_id, channel_id: event.counterparty_channel_id, - proof_ack: channel_proof.proof, - proof_height: channel_proof.proof_height, + proof_ack: channel_proof, + proof_height: channel_proof_height.into(), }, __marker: PhantomData, - }), + }, ) } } impl UseAggregate for identified!(AggregateRecvPacket) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(CommitmentProof): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(CommitmentProof): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ @@ -3166,7 +3190,10 @@ where }, Identified { chain_id: commitment_proof_chain_id, - data: CommitmentProof(commitment_proof) + data: CommitmentProof { + height: commitment_proof_height, + proof: commitment_proof + } }, ]: Self::AggregatedData, ) -> RelayerMsg { @@ -3177,9 +3204,8 @@ where msg::( counterparty_chain_id, - Msg::RecvPacket(MsgRecvPacketData { + MsgRecvPacketData { msg: MsgRecvPacket { - proof_height: commitment_proof.proof_height, packet: Packet { sequence: event.packet_sequence, source_port: event.packet_src_port, @@ -3190,22 +3216,20 @@ where timeout_height: event.packet_timeout_height, timeout_timestamp: event.packet_timeout_timestamp, }, - proof_commitment: commitment_proof.proof, + proof_commitment: commitment_proof, + proof_height: commitment_proof_height.into(), }, __marker: PhantomData, - }), + }, ) } } impl UseAggregate for identified!(AggregateAckPacket) where - identified!(TrustedClientState): - TryFrom + Into, - identified!(PacketAcknowledgement): - TryFrom + Into, - identified!(AcknowledgementProof): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, + identified!(PacketAcknowledgement): IsAggregateData, + identified!(AcknowledgementProof): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ @@ -3240,7 +3264,10 @@ where }, Identified { chain_id: commitment_proof_chain_id, - data: AcknowledgementProof(acknowledgement_proof) + data: AcknowledgementProof { + proof: acknowledgement_proof, + height: acknowledgement_proof_height + }, }, ]: Self::AggregatedData, ) -> RelayerMsg { @@ -3254,7 +3281,7 @@ where counterparty_chain_id, Msg::AckPacket(MsgAckPacketData { msg: MsgAcknowledgement { - proof_height: acknowledgement_proof.proof_height, + proof_height: acknowledgement_proof_height.into(), packet: Packet { sequence: event.packet_sequence, source_port: event.packet_src_port, @@ -3266,7 +3293,7 @@ where timeout_timestamp: event.packet_timeout_timestamp, }, acknowledgement: ack, - proof_acked: acknowledgement_proof.proof, + proof_acked: acknowledgement_proof, }, __marker: PhantomData, }), @@ -3276,8 +3303,7 @@ where impl UseAggregate for identified!(AggregateFetchCounterpartyStateProof) where - identified!(TrustedClientState): - TryFrom + Into, + identified!(TrustedClientState): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![identified!(TrustedClientState),]; @@ -3310,10 +3336,8 @@ where impl UseAggregate for identified!(AggregateCreateClient) where - identified!(SelfClientState): - TryFrom + Into, - identified!(SelfConsensusState): - TryFrom + Into, + identified!(SelfClientState): IsAggregateData, + identified!(SelfConsensusState): IsAggregateData, AnyLightClientIdentified: From)>, { type AggregatedData = HList![ diff --git a/voyager/src/queue/aggregate_data.rs b/voyager/src/queue/aggregate_data.rs index 122ff75c6a..860f030e61 100644 --- a/voyager/src/queue/aggregate_data.rs +++ b/voyager/src/queue/aggregate_data.rs @@ -4,12 +4,15 @@ use frunk::{HCons, HNil}; use crate::{ chain::LightClient, - msg::{AggregateData, RelayerMsg}, + msg::{data::AnyData, AnyLightClientIdentified, RelayerMsg}, }; +pub trait IsAggregateData = TryFrom, Error = AnyLightClientIdentified> + + Into>; + pub fn do_aggregate>( event: T, - data: VecDeque, + data: VecDeque>, ) -> RelayerMsg { // let data_json = serde_json::to_string(&data).expect("serialization should not fail"); @@ -92,7 +95,7 @@ impl HListTryFromIterator for HNil { } pub trait UseAggregate { - type AggregatedData: HListTryFromIterator; + type AggregatedData: HListTryFromIterator>; fn aggregate(this: Self, data: Self::AggregatedData) -> RelayerMsg; }