Skip to content

Commit

Permalink
feat: complete packet protocol in both order or unorder channel
Browse files Browse the repository at this point in the history
  • Loading branch information
liyukun committed Aug 17, 2023
1 parent 9c01b0d commit ced573f
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 89 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jsonrpc-core = "18.0"
strum = { version = "0.24.1", features = ["derive"] }
lazy_static = "1.4.0"

ckb-ics-axon = { git = "https://github.com/synapseweb3/ckb-ics.git", rev = "ef124f9" }
ckb-ics-axon = { git = "https://github.com/synapseweb3/ckb-ics.git", rev = "cda7d4e" }
cstr_core = "0.2.6"
rlp = "0.5.2"

Expand Down
2 changes: 2 additions & 0 deletions crates/relayer/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub mod requests;
pub mod runtime;
pub mod tracking;

pub const SEC_TO_NANO: u64 = 1_000_000_000;

use serde::{de::Error, Deserialize, Serialize};

// NOTE(new): When adding a variant to `ChainType`, make sure to update
Expand Down
7 changes: 2 additions & 5 deletions crates/relayer/src/chain/axon/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,8 @@ use ibc_relayer_types::{
Height,
};

use super::{
contract,
utils::{to_timestamp, SEC_TO_NANO},
};
use crate::error::Error;
use super::{contract, utils::to_timestamp};
use crate::{chain::SEC_TO_NANO, error::Error};

fn into_ethers_client_id(value: Option<ClientId>) -> String {
match value {
Expand Down
3 changes: 1 addition & 2 deletions crates/relayer/src/chain/axon/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use ckb_ics_axon::proof::{
use rlp::Encodable;

use crate::{
chain::SEC_TO_NANO,
client_state::{AnyClientState, IdentifiedAnyClientState},
consensus_state::AnyConsensusState,
error::Error,
Expand All @@ -21,8 +22,6 @@ use ibc_relayer_types::{
timestamp::Timestamp,
};

pub const SEC_TO_NANO: u64 = 1_000_000_000;

pub fn to_timestamp(seconds: u64) -> Result<Timestamp, Error> {
Timestamp::from_nanoseconds(seconds * SEC_TO_NANO).map_err(convert_err)
}
Expand Down
10 changes: 5 additions & 5 deletions crates/relayer/src/chain/ckb4ibc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ use self::extractor::{extract_connections_from_tx, extract_ibc_packet_from_tx};
use self::message::{convert_msg_to_ckb_tx, CkbTxInfo, Converter, MsgToTxConverter};
use self::monitor::Ckb4IbcEventMonitor;
use self::utils::{
convert_port_id_to_array, get_channel_idx, get_dummy_merkle_proof, get_encoded_object,
convert_port_id_to_array, get_channel_number, get_dummy_merkle_proof, get_encoded_object,
get_search_key,
};

Expand Down Expand Up @@ -227,7 +227,7 @@ impl Ckb4IbcChain {
.hash_type(ScriptHashType::Type.into())
.args(
PacketArgs {
channel_id: get_channel_idx(channel_id)?,
channel_id: get_channel_number(channel_id)?,
port_id: port_id.as_str().as_bytes().try_into().unwrap(),
sequence,
}
Expand Down Expand Up @@ -281,7 +281,7 @@ impl Ckb4IbcChain {
let channel_args = ChannelArgs {
client_id,
open: is_open,
channel_id: get_channel_idx(&channel_id)?,
channel_id: get_channel_number(&channel_id)?,
port_id: convert_port_id_to_array(&port_id)?,
};
let script = Script::new_builder()
Expand Down Expand Up @@ -1004,7 +1004,7 @@ impl ChainEndpoint for Ckb4IbcChain {
} else {
Ok((
PacketArgs {
channel_id: get_channel_idx(&request.channel_id)?,
channel_id: get_channel_number(&request.channel_id)?,
port_id: ibc_packet
.packet
.source_port_id
Expand Down Expand Up @@ -1046,7 +1046,7 @@ impl ChainEndpoint for Ckb4IbcChain {
} else {
Ok((
PacketArgs {
channel_id: get_channel_idx(&request.channel_id)?,
channel_id: get_channel_number(&request.channel_id)?,
port_id: ibc_packet
.packet
.source_port_id
Expand Down
6 changes: 3 additions & 3 deletions crates/relayer/src/chain/ckb4ibc/message/chan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::str::FromStr;
use super::{CkbTxInfo, MsgToTxConverter, TxBuilder};
use crate::chain::ckb4ibc::utils::{
convert_port_id_to_array, convert_proof, extract_client_id_by_connection_id,
generate_channel_id, get_channel_capacity, get_channel_idx, get_channel_lock_script,
generate_channel_id, get_channel_capacity, get_channel_lock_script, get_channel_number,
get_client_id_from_channel, get_client_outpoint, get_connection_capacity,
get_connection_lock_script, get_encoded_object,
};
Expand Down Expand Up @@ -217,7 +217,7 @@ pub fn convert_chan_open_ack_to_tx<C: MsgToTxConverter>(
msg: MsgChannelOpenAck,
converter: &C,
) -> Result<CkbTxInfo, Error> {
let channel_idx = get_channel_idx(&msg.channel_id)?;
let channel_idx = get_channel_number(&msg.channel_id)?;
let old_channel = converter.get_ibc_channel(&msg.channel_id);
let counterparty_port_id = PortId::from_str(&old_channel.counterparty.port_id).unwrap();
let mut new_channel = old_channel.clone();
Expand Down Expand Up @@ -298,7 +298,7 @@ pub fn convert_chan_open_confirm_to_tx<C: MsgToTxConverter>(
let channel_args = ChannelArgs {
client_id: client_cell_type_args,
open: true,
channel_id: get_channel_idx(&msg.channel_id)?,
channel_id: get_channel_number(&msg.channel_id)?,
port_id: convert_port_id_to_array(&msg.port_id)?,
};

Expand Down
153 changes: 83 additions & 70 deletions crates/relayer/src/chain/ckb4ibc/message/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ckb_ics_axon::message::Envelope;
use ckb_ics_axon::message::MsgAckPacket as CkbMsgAckPacket;
use ckb_ics_axon::message::MsgRecvPacket as CkbMsgRecvPacket;
use ckb_ics_axon::message::MsgType;
use ckb_ics_axon::object::Packet as CkbPacket;
use ckb_ics_axon::object::{Ordering, Packet as CkbPacket};
use ckb_ics_axon::{ChannelArgs, PacketArgs};
use ckb_types::packed::BytesOpt;
use ibc_relayer_types::core::ics04_channel::msgs::acknowledgement::MsgAcknowledgement;
Expand All @@ -14,13 +14,14 @@ use ibc_relayer_types::core::ics04_channel::packet::Packet;

use super::{CkbTxInfo, MsgToTxConverter, TxBuilder};
use crate::chain::ckb4ibc::utils::{
convert_proof, extract_client_id_by_connection_id, get_channel_capacity, get_channel_idx,
get_channel_lock_script, get_client_outpoint, get_encoded_object, get_packet_capacity,
get_packet_lock_script,
convert_port_id_to_array, convert_proof, extract_client_id_by_connection_id,
get_channel_capacity, get_channel_lock_script, get_channel_number, get_client_outpoint,
get_encoded_object, get_packet_capacity, get_packet_lock_script,
};
use crate::chain::SEC_TO_NANO;
use crate::error::Error;

fn convert_ibc_packet(packet: Packet) -> CkbPacket {
fn convert_ibc_packet(packet: &Packet) -> CkbPacket {
let seq: u64 = packet.sequence.into();
let source_port_id = packet.source_port.to_string();
let source_channel_id = packet.source_channel.to_string();
Expand All @@ -32,147 +33,159 @@ fn convert_ibc_packet(packet: Packet) -> CkbPacket {
source_channel_id,
destination_port_id,
destination_channel_id,
data: packet.data,
data: packet.data.clone(),
timeout_height: packet.timeout_height.commitment_revision_height(),
timeout_timestamp: packet.timeout_timestamp.nanoseconds() / 100000, // use second as unit
timeout_timestamp: packet.timeout_timestamp.nanoseconds() / SEC_TO_NANO,
}
}

pub fn convert_ack_packet_to_tx<C: MsgToTxConverter>(
msg: MsgAcknowledgement,
pub fn convert_recv_packet_to_tx<C: MsgToTxConverter>(
msg: MsgRecvPacket,
converter: &C,
) -> Result<CkbTxInfo, Error> {
let channel_id = msg.packet.source_channel.clone();
let channel_id = msg.packet.destination_channel.clone();
let old_channel_end = converter.get_ibc_channel(&channel_id);
let mut new_channel_end = old_channel_end.clone();
new_channel_end.sequence.next_sequence_acks += 1;
let old_channel = get_encoded_object(old_channel_end);
let new_channel = get_encoded_object(new_channel_end.clone());

let ckb_msg = CkbMsgAckPacket {
let packet = convert_ibc_packet(&msg.packet);
match old_channel_end.order {
Ordering::Ordered => new_channel_end.sequence.next_sequence_recvs += 1,
Ordering::Unordered => {
new_channel_end
.sequence
.received_sequences
.push(packet.sequence);
}
Ordering::Unknown => return Err(Error::other("channel ordering must be Order or Unorder")),
}

let recv_packet = CkbMsgRecvPacket {
proofs: convert_proof(msg.proofs)?,
acknowledgement: msg.acknowledgement.as_ref().to_vec(),
};
let envelope = Envelope {
msg_type: MsgType::MsgAckPacket,
content: rlp::encode(&ckb_msg).to_vec(),
msg_type: MsgType::MsgRecvPacket,
content: rlp::encode(&recv_packet).to_vec(),
};
let port_id = msg.packet.source_port.clone();

let channel_input = converter.get_ibc_channel_input(&channel_id, &msg.packet.source_port);
let sequence = msg.packet.sequence;
let packet = convert_ibc_packet(msg.packet);
let seq = packet.sequence;
let new_ibc_packet = IbcPacket {
packet,
tx_hash: None,
status: PacketStatus::Ack,
let port_id = convert_port_id_to_array(&msg.packet.destination_port)?;
let channel_number = get_channel_number(&channel_id)?;
let packet_args = PacketArgs {
channel_id: channel_number,
port_id,
sequence: packet.sequence,
};
let new_packet = get_encoded_object(new_ibc_packet);
let old_ibc_packet_input =
converter.get_packet_cell_input(channel_id.clone(), port_id.clone(), sequence);
let channel_idx = get_channel_idx(&channel_id)?;
let port_id_in_args: [u8; 32] = port_id.as_bytes().try_into().unwrap();

let (client_cell_type_args, client_id) =
extract_client_id_by_connection_id(&new_channel_end.connection_hops[0], converter)?;
let channel_args = ChannelArgs {
client_id: client_cell_type_args,
open: true,
channel_id: channel_idx,
port_id: port_id_in_args,
};
let packet_args = PacketArgs {
channel_id: channel_idx,
port_id: port_id_in_args,
sequence: seq,
channel_id: channel_number,
port_id,
};

let old_channel = get_encoded_object(old_channel_end);
let new_channel = get_encoded_object(new_channel_end);
let ibc_packet = get_encoded_object(IbcPacket {
packet,
tx_hash: None,
status: PacketStatus::Recv,
});

let channel_input = converter.get_ibc_channel_input(&channel_id, &msg.packet.source_port);
let channel_lock = get_channel_lock_script(converter, channel_args.to_args());
let packet_lock = get_packet_lock_script(converter, packet_args.to_args());

let packed_tx = TxBuilder::default()
.cell_dep(get_client_outpoint(converter, &client_id)?)
.cell_dep(converter.get_chan_contract_outpoint())
.input(channel_input)
.input(old_ibc_packet_input)
// TODO: fetch useless packet cell as input to save capacity
// .input()
.output(channel_lock, get_channel_capacity(), new_channel.data)
.output(packet_lock, get_packet_capacity(), new_packet.data)
.output(packet_lock, get_packet_capacity(), ibc_packet.data)
.witness(old_channel.witness, new_channel.witness)
.witness(BytesOpt::default(), new_packet.witness)
.witness(BytesOpt::default(), ibc_packet.witness)
.build();

Ok(CkbTxInfo {
unsigned_tx: Some(packed_tx),
envelope,
input_capacity: CHANNEL_CELL_CAPACITY + PACKET_CELL_CAPACITY,
input_capacity: PACKET_CELL_CAPACITY,
event: None,
})
}

pub fn convert_recv_packet_to_tx<C: MsgToTxConverter>(
msg: MsgRecvPacket,
pub fn convert_ack_packet_to_tx<C: MsgToTxConverter>(
msg: MsgAcknowledgement,
converter: &C,
) -> Result<CkbTxInfo, Error> {
let channel_id = msg.packet.destination_channel.clone();
let channel_id = msg.packet.source_channel.clone();
let old_channel_end = converter.get_ibc_channel(&channel_id);
let mut new_channel_end = old_channel_end.clone();
new_channel_end.sequence.next_sequence_recvs += 1;

match old_channel_end.order {
Ordering::Ordered => new_channel_end.sequence.next_sequence_acks += 1,
Ordering::Unordered => {}
Ordering::Unknown => return Err(Error::other("channel ordering must be Order or Unorder")),
}

let old_channel = get_encoded_object(old_channel_end);
let new_channel = get_encoded_object(new_channel_end.clone());

let ckb_msg = CkbMsgRecvPacket {
let ack_packet = CkbMsgAckPacket {
proofs: convert_proof(msg.proofs)?,
acknowledgement: msg.acknowledgement.as_ref().to_vec(),
};
let envelope = Envelope {
msg_type: MsgType::MsgRecvPacket,
content: rlp::encode(&ckb_msg).to_vec(),
msg_type: MsgType::MsgAckPacket,
content: rlp::encode(&ack_packet).to_vec(),
};
let port_id = msg.packet.destination_port.clone();

let channel_input = converter.get_ibc_channel_input(&channel_id, &msg.packet.source_port);
let packet = convert_ibc_packet(msg.packet);
let seq = packet.sequence;
let ibc_packet = IbcPacket {
let channel_number = get_channel_number(&channel_id)?;
let packet = convert_ibc_packet(&msg.packet);
let port_id = convert_port_id_to_array(&msg.packet.source_port)?;
let packet_args = PacketArgs {
sequence: packet.sequence,
channel_id: channel_number,
port_id,
};

let new_packet = get_encoded_object(IbcPacket {
packet,
tx_hash: None,
status: PacketStatus::Recv,
};
let packet = get_encoded_object(ibc_packet);
let channel_idx = get_channel_idx(&channel_id)?;
let port_id_in_args: [u8; 32] = port_id.as_str().as_bytes().try_into().unwrap();
status: PacketStatus::Ack,
});
let channel_input = converter.get_ibc_channel_input(&channel_id, &msg.packet.source_port);
let old_packet =
converter.get_packet_cell_input(channel_id, msg.packet.source_port, msg.packet.sequence);

let (client_cell_type_args, client_id) =
extract_client_id_by_connection_id(&new_channel_end.connection_hops[0], converter)?;
let channel_args = ChannelArgs {
client_id: client_cell_type_args,
open: true,
channel_id: channel_idx,
port_id: port_id_in_args,
};
let packet_args = PacketArgs {
channel_id: channel_idx,
port_id: port_id_in_args,
sequence: seq,
channel_id: channel_number,
port_id,
};

let channel_lock = get_channel_lock_script(converter, channel_args.to_args());
let packet_lock = get_packet_lock_script(converter, packet_args.to_args());

let packed_tx = TxBuilder::default()
.cell_dep(get_client_outpoint(converter, &client_id)?)
.cell_dep(converter.get_chan_contract_outpoint())
.input(channel_input)
.input(old_packet)
.output(channel_lock, get_channel_capacity(), new_channel.data)
.output(packet_lock, get_packet_capacity(), packet.data)
.output(packet_lock, get_packet_capacity(), new_packet.data)
.witness(old_channel.witness, new_channel.witness)
.witness(BytesOpt::default(), packet.witness)
.witness(BytesOpt::default(), new_packet.witness)
.build();

Ok(CkbTxInfo {
unsigned_tx: Some(packed_tx),
envelope,
input_capacity: PACKET_CELL_CAPACITY,
input_capacity: CHANNEL_CELL_CAPACITY + PACKET_CELL_CAPACITY,
event: None,
})
}
2 changes: 1 addition & 1 deletion crates/relayer/src/chain/ckb4ibc/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn get_script_hash(type_args: &H256) -> Byte32 {
script.calc_script_hash()
}

pub fn get_channel_idx(id: &ChannelId) -> Result<u16, Error> {
pub fn get_channel_number(id: &ChannelId) -> Result<u16, Error> {
let s = id.as_str();
let result = s
.strip_prefix(CHANNEL_ID_PREFIX)
Expand Down
Loading

0 comments on commit ced573f

Please sign in to comment.