diff --git a/ibc-apps/ics20-transfer/src/module.rs b/ibc-apps/ics20-transfer/src/module.rs index 41d3016a4..9be18b84e 100644 --- a/ibc-apps/ics20-transfer/src/module.rs +++ b/ibc-apps/ics20-transfer/src/module.rs @@ -162,11 +162,11 @@ pub fn on_chan_close_confirm_execute( pub fn on_recv_packet_execute( ctx_b: &mut impl TokenTransferExecutionContext, packet: &Packet, -) -> (ModuleExtras, Acknowledgement) { +) -> (ModuleExtras, Option) { let Ok(data) = serde_json::from_slice::(&packet.data) else { let ack = AcknowledgementStatus::error(TokenTransferError::FailedToDeserializePacketData.into()); - return (ModuleExtras::empty(), ack.into()); + return (ModuleExtras::empty(), Some(ack.into())); }; let (mut extras, ack) = match process_recv_packet_execute(ctx_b, packet, data.clone()) { @@ -184,7 +184,7 @@ pub fn on_recv_packet_execute( }; extras.events.push(recv_event.into()); - (extras, ack.into()) + (extras, Some(ack.into())) } pub fn on_acknowledgement_packet_validate( diff --git a/ibc-apps/ics721-nft-transfer/src/module.rs b/ibc-apps/ics721-nft-transfer/src/module.rs index 53b45e7c3..dd4271a4c 100644 --- a/ibc-apps/ics721-nft-transfer/src/module.rs +++ b/ibc-apps/ics721-nft-transfer/src/module.rs @@ -162,11 +162,11 @@ pub fn on_chan_close_confirm_execute( pub fn on_recv_packet_execute( ctx_b: &mut impl NftTransferExecutionContext, packet: &Packet, -) -> (ModuleExtras, Acknowledgement) { +) -> (ModuleExtras, Option) { let Ok(data) = serde_json::from_slice::(&packet.data) else { let ack = AcknowledgementStatus::error(NftTransferError::FailedToDeserializePacketData.into()); - return (ModuleExtras::empty(), ack.into()); + return (ModuleExtras::empty(), Some(ack.into())); }; let (mut extras, ack) = match process_recv_packet_execute(ctx_b, packet, data.clone()) { @@ -187,7 +187,7 @@ pub fn on_recv_packet_execute( }; extras.events.push(recv_event.into()); - (extras, ack.into()) + (extras, Some(ack.into())) } pub fn on_acknowledgement_packet_validate( diff --git a/ibc-core/ics04-channel/src/handler/acknowledgement.rs b/ibc-core/ics04-channel/src/handler/acknowledgement.rs index fddea0d82..aae613068 100644 --- a/ibc-core/ics04-channel/src/handler/acknowledgement.rs +++ b/ibc-core/ics04-channel/src/handler/acknowledgement.rs @@ -1,19 +1,95 @@ +use ibc_core_channel_types::acknowledgement::Acknowledgement; use ibc_core_channel_types::channel::{Counterparty, Order, State as ChannelState}; use ibc_core_channel_types::commitment::{compute_ack_commitment, compute_packet_commitment}; use ibc_core_channel_types::error::ChannelError; -use ibc_core_channel_types::events::AcknowledgePacket; +use ibc_core_channel_types::events::{AcknowledgePacket, WriteAcknowledgement}; use ibc_core_channel_types::msgs::MsgAcknowledgement; +use ibc_core_channel_types::packet::{Packet, Receipt}; use ibc_core_client::context::prelude::*; use ibc_core_connection::delay::verify_conn_delay_passed; use ibc_core_connection::types::State as ConnectionState; use ibc_core_handler_types::events::{IbcEvent, MessageEvent}; use ibc_core_host::types::path::{ - AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, Path, SeqAckPath, + AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, Path, ReceiptPath, + SeqAckPath, SeqRecvPath, }; use ibc_core_host::{ExecutionContext, ValidationContext}; use ibc_core_router::module::Module; use ibc_primitives::prelude::*; +pub fn commit_packet_sequence_no( + ctx_b: &mut ExecCtx, + packet: &Packet, +) -> Result<(), ChannelError> +where + ExecCtx: ExecutionContext, +{ + let chan_end_path_on_b = ChannelEndPath::new(&packet.port_id_on_b, &packet.chan_id_on_b); + let chan_end_on_b = ctx_b.channel_end(&chan_end_path_on_b)?; + + // `recvPacket` core handler state changes + match chan_end_on_b.ordering { + Order::Unordered => { + let receipt_path_on_b = ReceiptPath { + port_id: packet.port_id_on_b.clone(), + channel_id: packet.chan_id_on_b.clone(), + sequence: packet.seq_on_a, + }; + + ctx_b.store_packet_receipt(&receipt_path_on_b, Receipt::Ok)?; + } + Order::Ordered => { + let seq_recv_path_on_b = SeqRecvPath::new(&packet.port_id_on_b, &packet.chan_id_on_b); + let next_seq_recv = ctx_b.get_next_sequence_recv(&seq_recv_path_on_b)?; + ctx_b.store_next_sequence_recv(&seq_recv_path_on_b, next_seq_recv.increment())?; + } + _ => {} + } + + Ok(()) +} + +pub fn commit_packet_acknowledgment( + ctx_b: &mut ExecCtx, + packet: &Packet, + acknowledgement: &Acknowledgement, +) -> Result<(), ChannelError> +where + ExecCtx: ExecutionContext, +{ + let ack_path_on_b = AckPath::new(&packet.port_id_on_b, &packet.chan_id_on_b, packet.seq_on_a); + + // `writeAcknowledgement` handler state changes + ctx_b.store_packet_acknowledgement(&ack_path_on_b, compute_ack_commitment(acknowledgement))?; + + Ok(()) +} + +pub fn emit_packet_acknowledgement_event( + ctx_b: &mut ExecCtx, + packet: Packet, + acknowledgement: Acknowledgement, +) -> Result<(), ChannelError> +where + ExecCtx: ExecutionContext, +{ + let chan_end_path_on_b = ChannelEndPath::new(&packet.port_id_on_b, &packet.chan_id_on_b); + let chan_end_on_b = ctx_b.channel_end(&chan_end_path_on_b)?; + let conn_id_on_b = &chan_end_on_b.connection_hops()[0]; + + ctx_b.log_message("success: packet write acknowledgement".to_string())?; + + let event = IbcEvent::WriteAcknowledgement(WriteAcknowledgement::new( + packet, + acknowledgement, + conn_id_on_b.clone(), + )); + ctx_b.emit_ibc_event(IbcEvent::Message(MessageEvent::Channel))?; + ctx_b.emit_ibc_event(event)?; + + Ok(()) +} + pub fn acknowledgement_packet_validate( ctx_a: &ValCtx, module: &dyn Module, diff --git a/ibc-core/ics04-channel/src/handler/recv_packet.rs b/ibc-core/ics04-channel/src/handler/recv_packet.rs index 60bf30199..4537802ac 100644 --- a/ibc-core/ics04-channel/src/handler/recv_packet.rs +++ b/ibc-core/ics04-channel/src/handler/recv_packet.rs @@ -1,9 +1,8 @@ use ibc_core_channel_types::channel::{Counterparty, Order, State as ChannelState}; -use ibc_core_channel_types::commitment::{compute_ack_commitment, compute_packet_commitment}; +use ibc_core_channel_types::commitment::compute_packet_commitment; use ibc_core_channel_types::error::ChannelError; -use ibc_core_channel_types::events::{ReceivePacket, WriteAcknowledgement}; +use ibc_core_channel_types::events::ReceivePacket; use ibc_core_channel_types::msgs::MsgRecvPacket; -use ibc_core_channel_types::packet::Receipt; use ibc_core_client::context::prelude::*; use ibc_core_connection::delay::verify_conn_delay_passed; use ibc_core_connection::types::State as ConnectionState; @@ -16,6 +15,10 @@ use ibc_core_host::{ExecutionContext, ValidationContext}; use ibc_core_router::module::Module; use ibc_primitives::prelude::*; +use super::acknowledgement::{ + commit_packet_acknowledgment, commit_packet_sequence_no, emit_packet_acknowledgement_event, +}; + pub fn recv_packet_validate(ctx_b: &ValCtx, msg: MsgRecvPacket) -> Result<(), ChannelError> where ValCtx: ValidationContext, @@ -70,42 +73,16 @@ where let (extras, acknowledgement) = module.on_recv_packet_execute(&msg.packet, &msg.signer); // state changes - { - // `recvPacket` core handler state changes - match chan_end_on_b.ordering { - Order::Unordered => { - let receipt_path_on_b = ReceiptPath { - port_id: msg.packet.port_id_on_b.clone(), - channel_id: msg.packet.chan_id_on_b.clone(), - sequence: msg.packet.seq_on_a, - }; + commit_packet_sequence_no(ctx_b, &msg.packet)?; - ctx_b.store_packet_receipt(&receipt_path_on_b, Receipt::Ok)?; - } - Order::Ordered => { - let seq_recv_path_on_b = - SeqRecvPath::new(&msg.packet.port_id_on_b, &msg.packet.chan_id_on_b); - let next_seq_recv = ctx_b.get_next_sequence_recv(&seq_recv_path_on_b)?; - ctx_b.store_next_sequence_recv(&seq_recv_path_on_b, next_seq_recv.increment())?; - } - _ => {} - } - let ack_path_on_b = AckPath::new( - &msg.packet.port_id_on_b, - &msg.packet.chan_id_on_b, - msg.packet.seq_on_a, - ); - // `writeAcknowledgement` handler state changes - ctx_b.store_packet_acknowledgement( - &ack_path_on_b, - compute_ack_commitment(&acknowledgement), - )?; + if let Some(acknowledgement) = acknowledgement.as_ref() { + commit_packet_acknowledgment(ctx_b, &msg.packet, acknowledgement)?; } // emit events and logs { + // receive packet events/logs ctx_b.log_message("success: packet receive".to_string())?; - ctx_b.log_message("success: packet write acknowledgement".to_string())?; let conn_id_on_b = &chan_end_on_b.connection_hops()[0]; let event = IbcEvent::ReceivePacket(ReceivePacket::new( @@ -115,14 +92,13 @@ where )); ctx_b.emit_ibc_event(IbcEvent::Message(MessageEvent::Channel))?; ctx_b.emit_ibc_event(event)?; - let event = IbcEvent::WriteAcknowledgement(WriteAcknowledgement::new( - msg.packet, - acknowledgement, - conn_id_on_b.clone(), - )); - ctx_b.emit_ibc_event(IbcEvent::Message(MessageEvent::Channel))?; - ctx_b.emit_ibc_event(event)?; + // write ack events/logs + if let Some(acknowledgement) = acknowledgement { + emit_packet_acknowledgement_event(ctx_b, msg.packet, acknowledgement)?; + } + + // module specific events/logs for module_event in extras.events { ctx_b.emit_ibc_event(IbcEvent::Module(module_event))?; } diff --git a/ibc-core/ics26-routing/src/module.rs b/ibc-core/ics26-routing/src/module.rs index a73d4f639..de6a3e3a5 100644 --- a/ibc-core/ics26-routing/src/module.rs +++ b/ibc-core/ics26-routing/src/module.rs @@ -127,7 +127,7 @@ pub trait Module: Debug { &mut self, packet: &Packet, relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement); + ) -> (ModuleExtras, Option); fn on_acknowledgement_packet_validate( &self, diff --git a/ibc-testkit/src/testapp/ibc/applications/nft_transfer/module.rs b/ibc-testkit/src/testapp/ibc/applications/nft_transfer/module.rs index df6a158a6..b7d1338d6 100644 --- a/ibc-testkit/src/testapp/ibc/applications/nft_transfer/module.rs +++ b/ibc-testkit/src/testapp/ibc/applications/nft_transfer/module.rs @@ -64,10 +64,10 @@ impl Module for DummyNftTransferModule { &mut self, _packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { ( ModuleExtras::empty(), - Acknowledgement::try_from(vec![1u8]).expect("Never fails"), + Some(Acknowledgement::try_from(vec![1u8]).expect("Never fails")), ) } diff --git a/ibc-testkit/src/testapp/ibc/applications/transfer/module.rs b/ibc-testkit/src/testapp/ibc/applications/transfer/module.rs index 289feb654..a85336e9a 100644 --- a/ibc-testkit/src/testapp/ibc/applications/transfer/module.rs +++ b/ibc-testkit/src/testapp/ibc/applications/transfer/module.rs @@ -64,10 +64,10 @@ impl Module for DummyTransferModule { &mut self, _packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { ( ModuleExtras::empty(), - Acknowledgement::try_from(vec![1u8]).expect("Never fails"), + Some(Acknowledgement::try_from(vec![1u8]).expect("Never fails")), ) } diff --git a/ibc-testkit/src/testapp/ibc/core/types.rs b/ibc-testkit/src/testapp/ibc/core/types.rs index a658cad91..63c878a25 100644 --- a/ibc-testkit/src/testapp/ibc/core/types.rs +++ b/ibc-testkit/src/testapp/ibc/core/types.rs @@ -279,12 +279,12 @@ mod tests { &mut self, _packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { self.counter += 1; ( ModuleExtras::empty(), - Acknowledgement::try_from(vec![1u8]).expect("Never fails"), + Some(Acknowledgement::try_from(vec![1u8]).expect("Never fails")), ) } @@ -379,10 +379,10 @@ mod tests { &mut self, _packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { ( ModuleExtras::empty(), - Acknowledgement::try_from(vec![1u8]).expect("Never fails"), + Some(Acknowledgement::try_from(vec![1u8]).expect("Never fails")), ) }