From 1abe148c04e03d88c7f28eed0fd96e54120101e0 Mon Sep 17 00:00:00 2001 From: benluelo Date: Tue, 26 Nov 2024 18:28:11 +0000 Subject: [PATCH] wip --- Cargo.lock | 1 + cosmwasm/union-ibc/core/msg/src/query.rs | 4 + cosmwasm/union-ibc/core/src/contract.rs | 37 ++++++++- evm/contracts/core/04-channel/IBCPacket.sol | 4 +- lib/ibc-solidity/src/lib.rs | 24 ++++++ lib/voyager-message/src/ibc_union.rs | 9 ++- .../state/cosmos-sdk-union/src/main.rs | 46 +++++++++-- voyager/plugins/transaction-batch/Cargo.toml | 1 + voyager/plugins/transaction-batch/src/main.rs | 76 +++++++++++-------- .../plugins/transaction/ethereum/src/main.rs | 24 +++--- 10 files changed, 170 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 420bc17936..7415398151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13707,6 +13707,7 @@ dependencies = [ name = "voyager-plugin-transaction-batch" version = "0.1.0" dependencies = [ + "alloy", "cometbft-rpc", "dashmap 5.5.3", "either", diff --git a/cosmwasm/union-ibc/core/msg/src/query.rs b/cosmwasm/union-ibc/core/msg/src/query.rs index f0833ab9d2..5ebd1a0686 100644 --- a/cosmwasm/union-ibc/core/msg/src/query.rs +++ b/cosmwasm/union-ibc/core/msg/src/query.rs @@ -1,3 +1,5 @@ +use unionlabs::hash::H256; + #[derive(serde::Serialize, serde::Deserialize)] #[serde(deny_unknown_fields, rename_all = "snake_case")] pub enum QueryMsg { @@ -10,4 +12,6 @@ pub enum QueryMsg { GetConnection { connection_id: u32 }, GetChannel { channel_id: u32 }, GetChannels { contract: String }, + GetBatchPackets { channel_id: u32, batch_hash: H256 }, + GetBatchReceipts { channel_id: u32, batch_hash: H256 }, } diff --git a/cosmwasm/union-ibc/core/src/contract.rs b/cosmwasm/union-ibc/core/src/contract.rs index 43fda37e99..bb7be3d4a6 100644 --- a/cosmwasm/union-ibc/core/src/contract.rs +++ b/cosmwasm/union-ibc/core/src/contract.rs @@ -25,7 +25,7 @@ use union_ibc_msg::{ use unionlabs::{ ethereum::keccak256, hash::{hash_v2::HexPrefixed, H256}, - ics24::ethabi::COMMITMENT_MAGIC, + ics24::ethabi::{BatchPacketsPath, BatchReceiptsPath, COMMITMENT_MAGIC}, }; use crate::{ @@ -1518,6 +1518,13 @@ fn store_commit(deps: DepsMut, key: &H256, value: &H256) -> Result<(), ContractE Ok(()) } +fn read_commit(deps: Deps, key: &H256) -> Option { + deps.storage.get(key.as_ref()).map(|bz| { + bz.try_into() + .expect("H256 is the only value ever written to this storage; qed;") + }) +} + fn save_connection( deps: DepsMut, connection_id: u32, @@ -1664,6 +1671,34 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { + let commit = read_commit( + deps, + &BatchPacketsPath { + channel_id, + batch_hash, + } + .key(), + ); + Ok(to_json_binary(&commit)?) + } + QueryMsg::GetBatchReceipts { + channel_id, + batch_hash, + } => { + let commit = read_commit( + deps, + &BatchReceiptsPath { + channel_id, + batch_hash, + } + .key(), + ); + Ok(to_json_binary(&commit)?) + } } } diff --git a/evm/contracts/core/04-channel/IBCPacket.sol b/evm/contracts/core/04-channel/IBCPacket.sol index 1d305bd980..dbbc092539 100644 --- a/evm/contracts/core/04-channel/IBCPacket.sol +++ b/evm/contracts/core/04-channel/IBCPacket.sol @@ -206,11 +206,11 @@ abstract contract IBCPacketImpl is IBCStore, IIBCPacket { if (!intent) { bytes32 proofCommitmentKey; if (l == 1) { - proofCommitmentKey = IBCCommitment.batchReceiptsCommitmentKey( + proofCommitmentKey = IBCCommitment.batchPacketsCommitmentKey( sourceChannel, IBCPacketLib.commitPacket(packets[0]) ); } else { - proofCommitmentKey = IBCCommitment.batchReceiptsCommitmentKey( + proofCommitmentKey = IBCCommitment.batchPacketsCommitmentKey( sourceChannel, IBCPacketLib.commitPackets(packets) ); } diff --git a/lib/ibc-solidity/src/lib.rs b/lib/ibc-solidity/src/lib.rs index 1aeb85314f..8e21c0ef98 100644 --- a/lib/ibc-solidity/src/lib.rs +++ b/lib/ibc-solidity/src/lib.rs @@ -762,3 +762,27 @@ impl Clone for ibc::Ibc::IbcEvents { } } } + +#[cfg(test)] +mod tests { + use alloy::{ + primitives::{bytes, keccak256}, + sol_types::SolValue, + }; + + use crate::ibc::Packet; + + #[test] + fn packet_hash() { + dbg!(keccak256( + Packet { + source_channel: 2, + destination_channel: 6, + data: bytes!("0000000000000000000000000000000000000000000000000000000000000000"), + timeout_height: 0, + timeout_timestamp: 1733628077574130799 + } + .abi_encode_params() + )); + } +} diff --git a/lib/voyager-message/src/ibc_union.rs b/lib/voyager-message/src/ibc_union.rs index 154982982b..201a424d5f 100644 --- a/lib/voyager-message/src/ibc_union.rs +++ b/lib/voyager-message/src/ibc_union.rs @@ -1,5 +1,5 @@ use enumorph::Enumorph; -use ibc_solidity::ibc::{Channel, Connection}; +use ibc_solidity::ibc::{Channel, Connection, Packet}; use serde::{Deserialize, Serialize}; use unionlabs::{ bytes::Bytes, @@ -243,7 +243,12 @@ pub struct MsgChannelCloseInit {} pub struct MsgChannelCloseConfirm {} #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct MsgPacketRecv {} +pub struct MsgPacketRecv { + pub packets: Vec, + pub relayer_msgs: Vec, + pub proof: Bytes, + pub proof_height: u64, +} #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct MsgPacketAcknowledgement {} diff --git a/voyager/modules/state/cosmos-sdk-union/src/main.rs b/voyager/modules/state/cosmos-sdk-union/src/main.rs index 79c9ec92cb..ef301f07cb 100644 --- a/voyager/modules/state/cosmos-sdk-union/src/main.rs +++ b/voyager/modules/state/cosmos-sdk-union/src/main.rs @@ -3,7 +3,7 @@ use std::{ error::Error, fmt::{Debug, Display}, - num::{NonZeroU64, ParseIntError}, + num::ParseIntError, sync::Arc, }; @@ -223,16 +223,44 @@ impl Module { Ok(channel) } - #[instrument(skip_all, fields(chain_id = %self.chain_id, %height, %channel_id))] - async fn query_channel(&self, height: Height, channel_id: u32) -> RpcResult> { - let channel = self - .query_smart::<_, Channel>( - &union_ibc_msg::query::QueryMsg::GetChannel { channel_id }, + #[instrument(skip_all, fields(chain_id = %self.chain_id, %height, %channel_id, %batch_hash))] + async fn query_batch_packets( + &self, + height: Height, + channel_id: u32, + batch_hash: H256, + ) -> RpcResult> { + let commitment = self + .query_smart::<_, Option>( + &union_ibc_msg::query::QueryMsg::GetBatchPackets { + channel_id, + batch_hash, + }, Some(height), ) .await?; - Ok(channel) + Ok(commitment.flatten()) + } + + #[instrument(skip_all, fields(chain_id = %self.chain_id, %height, %channel_id, %batch_hash))] + async fn query_batch_receipts( + &self, + height: Height, + channel_id: u32, + batch_hash: H256, + ) -> RpcResult> { + let commitment = self + .query_smart::<_, Option>( + &union_ibc_msg::query::QueryMsg::GetBatchReceipts { + channel_id, + batch_hash, + }, + Some(height), + ) + .await?; + + Ok(commitment.flatten()) } } @@ -290,6 +318,10 @@ impl StateModuleServer for Module { .query_batch_packets(at, path.channel_id, path.batch_hash) .await .map(into_value), + Path::BatchReceipts(path) => self + .query_batch_receipts(at, path.channel_id, path.batch_hash) + .await + .map(into_value), } } diff --git a/voyager/plugins/transaction-batch/Cargo.toml b/voyager/plugins/transaction-batch/Cargo.toml index b0d759f7b6..eb2b2fdab6 100644 --- a/voyager/plugins/transaction-batch/Cargo.toml +++ b/voyager/plugins/transaction-batch/Cargo.toml @@ -4,6 +4,7 @@ name = "voyager-plugin-transaction-batch" version = "0.1.0" [dependencies] +alloy = { workspace = true, features = ["sol-types"] } cometbft-rpc = { workspace = true } dashmap = { workspace = true } either = { workspace = true } diff --git a/voyager/plugins/transaction-batch/src/main.rs b/voyager/plugins/transaction-batch/src/main.rs index b91140cabc..adc6089144 100644 --- a/voyager/plugins/transaction-batch/src/main.rs +++ b/voyager/plugins/transaction-batch/src/main.rs @@ -6,8 +6,10 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; +use alloy::sol_types::SolValue; use either::Either; use futures::{stream::FuturesOrdered, StreamExt, TryFutureExt, TryStreamExt}; +use ibc_solidity::ibc::Packet; use itertools::Itertools; use jsonrpsee::{ core::{async_trait, RpcResult}, @@ -18,6 +20,7 @@ use serde::{Deserialize, Serialize}; use tracing::{debug, error, instrument, trace, warn}; use unionlabs::{ bytes::Bytes, + ethereum::keccak256, ibc::core::{ client::height::Height, commitment::merkle_prefix::MerklePrefix, @@ -823,38 +826,47 @@ async fn do_make_msg_union( } EventUnion::SendPacket(event) => { - // let proof_try = voyager_client - // .query_ibc_proof( - // origin_chain_id, - // QueryHeight::Specific(origin_chain_proof_height), - // unionlabs::ics24::ethabi::BatchPacketsPath { - // channel_id: event.channel_id, - // batch_hash: (), - // }, - // ) - // .await?; - - // let client_info = voyager_client - // .client_info::(target_chain_id, event.connection.counterparty_client_id) - // .await?; - - // let encoded_proof_ack = voyager_client - // .encode_proof::( - // client_info.client_type, - // client_info.ibc_interface, - // proof_try.proof, - // ) - // .await?; - - // Ok(data(IbcDatagram::new::(ibc_union::IbcMsg::from( - // ibc_union::MsgChannelOpenConfirm { - // channel_id: event.counterparty_channel_id, - // proof_ack: encoded_proof_ack, - // proof_height: origin_chain_proof_height.height(), - // }, - // )))) - - todo!() + let packet = Packet { + source_channel: event.packet.source_channel.channel_id, + destination_channel: event.packet.destination_channel.channel_id, + data: event.packet_data.into(), + timeout_height: event.packet.timeout_height, + timeout_timestamp: event.packet.timeout_timestamp, + }; + let proof_try = voyager_client + .query_ibc_proof( + origin_chain_id, + QueryHeight::Specific(origin_chain_proof_height), + unionlabs::ics24::ethabi::BatchPacketsPath { + channel_id: event.packet.source_channel.channel_id, + batch_hash: keccak256(packet.abi_encode_params()), + }, + ) + .await?; + + let client_info = voyager_client + .client_info::( + target_chain_id, + event.packet.destination_channel.connection.client_id, + ) + .await?; + + let encoded_proof_commitment = voyager_client + .encode_proof::( + client_info.client_type, + client_info.ibc_interface, + proof_try.proof, + ) + .await?; + + Ok(data(IbcDatagram::new::(ibc_union::IbcMsg::from( + ibc_union::MsgPacketRecv { + packets: vec![packet], + relayer_msgs: vec![vec![].into()], + proof: encoded_proof_commitment, + proof_height: origin_chain_proof_height.height(), + }, + )))) } // EventUnion::ChannelOpenTry(event) => { diff --git a/voyager/plugins/transaction/ethereum/src/main.rs b/voyager/plugins/transaction/ethereum/src/main.rs index e80079d37c..18ee4e9eb5 100644 --- a/voyager/plugins/transaction/ethereum/src/main.rs +++ b/voyager/plugins/transaction/ethereum/src/main.rs @@ -624,18 +624,18 @@ fn process_msgs>( }) .clear_decoder(), ), - // IbcMsg::RecvPacket(data) => ( - // msg, - // ibc_handler - // .recvPacket(MsgPacketRecv { - // packets: vec![convert_packet(data.packet)?], - // proof: data.proof_commitment.into(), - // proofHeight: data.proof_height.height(), - // relayer: relayer.into(), - // relayerMsgs: vec![], - // }) - // .clear_decoder(), - // ), + IbcMsg::PacketRecv(data) => ( + msg, + ibc_handler + .recvPacket(ibc::MsgPacketRecv { + packets: data.packets, + proof: data.proof.into(), + proof_height: data.proof_height, + relayer: relayer.into(), + relayer_msgs: data.relayer_msgs.into_iter().map(Into::into).collect(), + }) + .clear_decoder(), + ), // IbcMsg::AcknowledgePacket(data) => ( // msg, // ibc_handler