Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: calculate trace hash from both class ID and token ID #1032

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions ibc-apps/ics721-nft-transfer/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,13 @@ pub trait NftTransferValidationContext {
memo: &Memo,
) -> Result<(), NftTransferError>;

/// Returns a hash of the prefixed class ID.
/// Implement only if the host chain supports hashed class ID.
fn class_hash_string(&self, _class_id: &PrefixedClassId) -> Option<String> {
/// Returns a hash of the prefixed class ID and the token ID.
/// Implement only if the host chain supports hashed class ID and token ID.
fn token_hash_string(
&self,
_class_id: &PrefixedClassId,
_token_id: &TokenId,
) -> Option<String> {
None
}

Expand Down
24 changes: 12 additions & 12 deletions ibc-apps/ics721-nft-transfer/src/handler/on_recv_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ibc_core::router::types::module::ModuleExtras;

use crate::context::NftTransferExecutionContext;
use crate::types::error::NftTransferError;
use crate::types::events::ClassTraceEvent;
use crate::types::events::TokenTraceEvent;
use crate::types::packet::PacketData;
use crate::types::{is_receiver_chain_source, TracePrefix};

Expand Down Expand Up @@ -77,24 +77,24 @@ where
c
};

let extras = {
let class_trace_event = ClassTraceEvent {
trace_hash: ctx_b.class_hash_string(&class_id),
class: class_id.clone(),
};
ModuleExtras {
events: vec![class_trace_event.into()],
log: Vec::new(),
}
let mut extras = ModuleExtras {
events: vec![],
log: Vec::new(),
};

for ((token_id, token_uri), token_data) in data
.token_ids
.as_ref()
.0
.iter()
.zip(data.token_uris.iter())
.zip(data.token_data.iter())
{
let trace_event = TokenTraceEvent {
trace_hash: ctx_b.token_hash_string(&class_id, token_id),
class: class_id.clone(),
token: token_id.clone(),
};
extras.events.push(trace_event.into());

// Note: the validation is called before the execution.
// Refer to ICS-20 `process_recv_packet_execute()`.

Expand Down
3 changes: 3 additions & 0 deletions ibc-apps/ics721-nft-transfer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
#[cfg(any(test, feature = "std"))]
extern crate std;

#[cfg(feature = "serde")]
pub mod context;
#[cfg(feature = "serde")]
pub mod handler;
#[cfg(feature = "serde")]
pub mod module;

/// Re-exports the implementation of the IBC [Non-Fungible Token
Expand Down
25 changes: 15 additions & 10 deletions ibc-apps/ics721-nft-transfer/types/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use ibc_core::primitives::Signer;
use ibc_core::router::types::event::ModuleEvent;

use super::Memo;
use crate::{PrefixedClassId, TokenIds, MODULE_ID_STR};
use crate::{PrefixedClassId, TokenId, TokenIds, MODULE_ID_STR};

const EVENT_TYPE_PACKET: &str = "non_fungible_token_packet";
const EVENT_TYPE_TIMEOUT: &str = "timeout";
const EVENT_TYPE_CLASS_TRACE: &str = "class_trace";
const EVENT_TYPE_TOKEN_TRACE: &str = "token_trace";
const EVENT_TYPE_TRANSFER: &str = "ibc_nft_transfer";

/// Contains all events variants that can be emitted from the NFT transfer application
Expand All @@ -18,7 +18,7 @@ pub enum Event {
Ack(AckEvent),
AckStatus(AckStatusEvent),
Timeout(TimeoutEvent),
ClassTrace(ClassTraceEvent),
TokenTrace(TokenTraceEvent),
Transfer(TransferEvent),
}

Expand Down Expand Up @@ -144,17 +144,22 @@ impl From<TimeoutEvent> for ModuleEvent {
}

/// Event emitted in the `onRecvPacket` module callback when new tokens are minted
pub struct ClassTraceEvent {
pub struct TokenTraceEvent {
pub trace_hash: Option<String>,
pub class: PrefixedClassId,
pub token: TokenId,
}

impl From<ClassTraceEvent> for ModuleEvent {
fn from(ev: ClassTraceEvent) -> Self {
let ClassTraceEvent { trace_hash, class } = ev;
impl From<TokenTraceEvent> for ModuleEvent {
fn from(ev: TokenTraceEvent) -> Self {
let TokenTraceEvent {
trace_hash,
class,
token,
} = ev;
let mut ev = Self {
kind: EVENT_TYPE_CLASS_TRACE.to_string(),
attributes: vec![("class", class).into()],
kind: EVENT_TYPE_TOKEN_TRACE.to_string(),
attributes: vec![("class", class).into(), ("token", token).into()],
};
if let Some(hash) = trace_hash {
ev.attributes.push(("trace_hash", hash).into());
Expand Down Expand Up @@ -202,7 +207,7 @@ impl From<Event> for ModuleEvent {
Event::Ack(ev) => ev.into(),
Event::AckStatus(ev) => ev.into(),
Event::Timeout(ev) => ev.into(),
Event::ClassTrace(ev) => ev.into(),
Event::TokenTrace(ev) => ev.into(),
Event::Transfer(ev) => ev.into(),
}
}
Expand Down
Loading