From 439caddbf7f2e36d0da904f8948d4652328a9f1f Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 12:15:53 +0400 Subject: [PATCH 1/8] Post events at the execution level and horde them in the inspector --- core/src/engine/inspector.rs | 111 ++++---- core/src/events.rs | 8 +- core/src/intents/token_diff.rs | 19 +- core/src/intents/tokens.rs | 67 +++-- defuse/src/contract/intents/execute.rs | 222 +++++----------- defuse/src/contract/intents/simulate.rs | 327 ++++++++++++------------ 6 files changed, 354 insertions(+), 400 deletions(-) diff --git a/core/src/engine/inspector.rs b/core/src/engine/inspector.rs index 370ad37d..7ef72c71 100644 --- a/core/src/engine/inspector.rs +++ b/core/src/engine/inspector.rs @@ -1,68 +1,63 @@ -use crate::error::Result; -use crate::{ - Deadline, - intents::{ - token_diff::TokenDiff, - tokens::{FtWithdraw, MtWithdraw, NativeWithdraw, NftWithdraw, StorageDeposit, Transfer}, - }, - tokens::Amounts, -}; +use crate::Deadline; +use crate::events::DefuseEvent; use impl_tools::autoimpl; use near_sdk::{AccountIdRef, CryptoHash}; #[autoimpl(for &mut T, Box)] pub trait Inspector { - fn on_deadline(&mut self, deadline: Deadline); - - fn on_transfer( - &mut self, - sender_id: &AccountIdRef, - transfer: &Transfer, - intent_hash: CryptoHash, - ) -> Result<()>; - - fn on_token_diff( - &mut self, - owner_id: &AccountIdRef, - token_diff: &TokenDiff, - fees_collected: &Amounts, - intent_hash: CryptoHash, - ) -> Result<()>; - - fn on_ft_withdraw( - &mut self, - owner_id: &AccountIdRef, - ft_withdraw: &FtWithdraw, - intent_hash: CryptoHash, - ) -> Result<()>; + fn emit_event(&mut self, event: DefuseEvent<'_>); - fn on_nft_withdraw( - &mut self, - owner_id: &AccountIdRef, - nft_withdraw: &NftWithdraw, - intent_hash: CryptoHash, - ) -> Result<()>; - - fn on_mt_withdraw( - &mut self, - owner_id: &AccountIdRef, - mt_withdraw: &MtWithdraw, - intent_hash: CryptoHash, - ) -> Result<()>; - - fn on_native_withdraw( - &mut self, - owner_id: &AccountIdRef, - native_withdraw: &NativeWithdraw, - intent_hash: CryptoHash, - ) -> Result<()>; + fn on_deadline(&mut self, deadline: Deadline); - fn on_storage_deposit( - &mut self, - owner_id: &AccountIdRef, - storage_deposit: &StorageDeposit, - intent_hash: CryptoHash, - ) -> Result<()>; + // fn on_transfer( + // &mut self, + // sender_id: &AccountIdRef, + // transfer: &Transfer, + // intent_hash: CryptoHash, + // ) -> Result<()>; + + // fn on_token_diff( + // &mut self, + // owner_id: &AccountIdRef, + // token_diff: &TokenDiff, + // fees_collected: &Amounts, + // intent_hash: CryptoHash, + // ) -> Result<()>; + + // fn on_ft_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // ft_withdraw: &FtWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()>; + + // fn on_nft_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // nft_withdraw: &NftWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()>; + + // fn on_mt_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // mt_withdraw: &MtWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()>; + + // fn on_native_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // native_withdraw: &NativeWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()>; + + // fn on_storage_deposit( + // &mut self, + // owner_id: &AccountIdRef, + // storage_deposit: &StorageDeposit, + // intent_hash: CryptoHash, + // ) -> Result<()>; fn on_intent_executed(&mut self, signer_id: &AccountIdRef, hash: CryptoHash); } diff --git a/core/src/events.rs b/core/src/events.rs index 6dd90484..4f816b8e 100644 --- a/core/src/events.rs +++ b/core/src/events.rs @@ -1,8 +1,3 @@ -use std::borrow::Cow; - -use derive_more::derive::From; -use near_sdk::{near, serde::Deserialize}; - use crate::{ accounts::{AccountEvent, PublicKeyEvent}, fees::{FeeChangedEvent, FeeCollectorChangedEvent}, @@ -12,6 +7,9 @@ use crate::{ tokens::{FtWithdraw, MtWithdraw, NativeWithdraw, NftWithdraw, StorageDeposit, Transfer}, }, }; +use derive_more::derive::From; +use near_sdk::{near, serde::Deserialize}; +use std::borrow::Cow; #[must_use = "make sure to `.emit()` this event"] #[near(event_json(standard = "dip4"))] diff --git a/core/src/intents/token_diff.rs b/core/src/intents/token_diff.rs index b127e426..cf49b976 100644 --- a/core/src/intents/token_diff.rs +++ b/core/src/intents/token_diff.rs @@ -7,12 +7,14 @@ use serde_with::{DisplayFromStr, serde_as}; use crate::{ DefuseError, Result, + accounts::AccountEvent, engine::{Engine, Inspector, State, StateView}, + events::DefuseEvent, fees::Pips, tokens::{Amounts, TokenId}, }; -use super::ExecutableIntent; +use super::{ExecutableIntent, IntentEvent}; pub type TokenDeltas = Amounts>; @@ -84,9 +86,18 @@ impl ExecutableIntent for TokenDiff { } } - engine - .inspector - .on_token_diff(signer_id, &self, &fees_collected, intent_hash)?; + let event = DefuseEvent::TokenDiff(Cow::Owned(vec![IntentEvent::new( + AccountEvent::new( + signer_id, + TokenDiffEvent { + diff: Cow::Borrowed(&self), + fees_collected: fees_collected.clone(), + }, + ), + intent_hash, + )])); + + engine.inspector.emit_event(event); // deposit fees to collector if !fees_collected.is_empty() { diff --git a/core/src/intents/tokens.rs b/core/src/intents/tokens.rs index d25a8bd6..8e949a81 100644 --- a/core/src/intents/tokens.rs +++ b/core/src/intents/tokens.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::{borrow::Cow, collections::BTreeMap}; use near_contract_standards::non_fungible_token; use near_sdk::{AccountId, AccountIdRef, CryptoHash, NearToken, json_types::U128, near}; @@ -6,11 +6,13 @@ use serde_with::{DisplayFromStr, serde_as}; use crate::{ DefuseError, Result, + accounts::AccountEvent, engine::{Engine, Inspector, State}, + events::DefuseEvent, tokens::Amounts, }; -use super::ExecutableIntent; +use super::{ExecutableIntent, IntentEvent}; #[cfg_attr( all(feature = "abi", not(target_arch = "wasm32")), @@ -47,9 +49,13 @@ impl ExecutableIntent for Transfer { if sender_id == self.receiver_id || self.tokens.is_empty() { return Err(DefuseError::InvalidIntent); } - engine - .inspector - .on_transfer(sender_id, &self, intent_hash)?; + let event = DefuseEvent::Transfer(Cow::Owned(vec![IntentEvent::new( + AccountEvent::new(sender_id, Cow::Borrowed(&self)), + intent_hash, + )])); + + engine.inspector.emit_event(event); + engine .state .internal_sub_balance(sender_id, self.tokens.clone())?; @@ -95,9 +101,13 @@ impl ExecutableIntent for FtWithdraw { S: State, I: Inspector, { - engine - .inspector - .on_ft_withdraw(owner_id, &self, intent_hash)?; + let event = DefuseEvent::FtWithdraw(Cow::Owned(vec![IntentEvent::new( + AccountEvent::new(owner_id, Cow::Borrowed(&self)), + intent_hash, + )])); + + engine.inspector.emit_event(event); + engine.state.ft_withdraw(owner_id, self) } } @@ -137,9 +147,13 @@ impl ExecutableIntent for NftWithdraw { S: State, I: Inspector, { - engine - .inspector - .on_nft_withdraw(owner_id, &self, intent_hash)?; + let event = DefuseEvent::NftWithdraw(Cow::Owned(vec![IntentEvent::new( + AccountEvent::new(owner_id, Cow::Borrowed(&self)), + intent_hash, + )])); + + engine.inspector.emit_event(event); + engine.state.nft_withdraw(owner_id, self) } } @@ -170,6 +184,7 @@ pub struct MtWithdraw { #[serde(default, skip_serializing_if = "Option::is_none")] pub storage_deposit: Option, } + impl ExecutableIntent for MtWithdraw { #[inline] fn execute_intent( @@ -182,9 +197,13 @@ impl ExecutableIntent for MtWithdraw { S: State, I: Inspector, { - engine - .inspector - .on_mt_withdraw(owner_id, &self, intent_hash)?; + let event = DefuseEvent::MtWithdraw(Cow::Owned(vec![IntentEvent::new( + AccountEvent::new(owner_id, Cow::Borrowed(&self)), + intent_hash, + )])); + + engine.inspector.emit_event(event); + engine.state.mt_withdraw(owner_id, self) } } @@ -212,9 +231,13 @@ impl ExecutableIntent for NativeWithdraw { S: State, I: Inspector, { - engine - .inspector - .on_native_withdraw(owner_id, &self, intent_hash)?; + let event = DefuseEvent::NativeWithdraw(Cow::Owned(vec![IntentEvent::new( + AccountEvent::new(owner_id, Cow::Borrowed(&self)), + intent_hash, + )])); + + engine.inspector.emit_event(event); + engine.state.native_withdraw(owner_id, self) } } @@ -250,9 +273,13 @@ impl ExecutableIntent for StorageDeposit { S: State, I: Inspector, { - engine - .inspector - .on_storage_deposit(owner_id, &self, intent_hash)?; + let event = DefuseEvent::StorageDeposit(Cow::Owned(vec![IntentEvent::new( + AccountEvent::new(owner_id, Cow::Borrowed(&self)), + intent_hash, + )])); + + engine.inspector.emit_event(event); + engine.state.storage_deposit(owner_id, self) } } diff --git a/defuse/src/contract/intents/execute.rs b/defuse/src/contract/intents/execute.rs index 81e29cba..c60ced64 100644 --- a/defuse/src/contract/intents/execute.rs +++ b/defuse/src/contract/intents/execute.rs @@ -1,19 +1,8 @@ -use std::borrow::Cow; - -use defuse_core::error::Result; use defuse_core::{ - Deadline, - accounts::AccountEvent, - engine::Inspector, - events::DefuseEvent, - intents::{ - IntentEvent, - token_diff::{TokenDiff, TokenDiffEvent}, - tokens::{FtWithdraw, MtWithdraw, NativeWithdraw, NftWithdraw, StorageDeposit, Transfer}, - }, - tokens::Amounts, + Deadline, accounts::AccountEvent, engine::Inspector, events::DefuseEvent, intents::IntentEvent, }; use near_sdk::{AccountIdRef, CryptoHash}; +use std::borrow::Cow; #[derive(Debug, Default)] pub struct ExecuteInspector { @@ -22,149 +11,78 @@ pub struct ExecuteInspector { impl Inspector for ExecuteInspector { #[inline] - fn on_deadline(&mut self, _deadline: Deadline) {} - - #[inline] - fn on_transfer( - &mut self, - sender_id: &AccountIdRef, - transfer: &Transfer, - intent_hash: CryptoHash, - ) -> Result<()> { - DefuseEvent::Transfer( - [IntentEvent::new( - AccountEvent::new(sender_id, Cow::Borrowed(transfer)), - intent_hash, - )] - .as_slice() - .into(), - ) - .emit(); - - Ok(()) + fn emit_event(&mut self, event: DefuseEvent<'_>) { + event.emit(); } #[inline] - fn on_token_diff( - &mut self, - owner_id: &AccountIdRef, - token_diff: &TokenDiff, - fees_collected: &Amounts, - intent_hash: CryptoHash, - ) -> Result<()> { - DefuseEvent::TokenDiff( - [IntentEvent::new( - AccountEvent::new( - owner_id, - TokenDiffEvent { - diff: Cow::Borrowed(token_diff), - fees_collected: fees_collected.clone(), - }, - ), - intent_hash, - )] - .as_slice() - .into(), - ) - .emit(); - - Ok(()) - } - - fn on_ft_withdraw( - &mut self, - owner_id: &AccountIdRef, - ft_withdraw: &FtWithdraw, - intent_hash: CryptoHash, - ) -> Result<()> { - DefuseEvent::FtWithdraw( - [IntentEvent::new( - AccountEvent::new(owner_id, Cow::Borrowed(ft_withdraw)), - intent_hash, - )] - .as_slice() - .into(), - ) - .emit(); - - Ok(()) - } - - fn on_nft_withdraw( - &mut self, - owner_id: &AccountIdRef, - nft_withdraw: &NftWithdraw, - intent_hash: CryptoHash, - ) -> Result<()> { - DefuseEvent::NftWithdraw( - [IntentEvent::new( - AccountEvent::new(owner_id, Cow::Borrowed(nft_withdraw)), - intent_hash, - )] - .as_slice() - .into(), - ) - .emit(); - - Ok(()) - } - - fn on_mt_withdraw( - &mut self, - owner_id: &AccountIdRef, - mt_withdraw: &MtWithdraw, - intent_hash: CryptoHash, - ) -> Result<()> { - DefuseEvent::MtWithdraw( - [IntentEvent::new( - AccountEvent::new(owner_id, Cow::Borrowed(mt_withdraw)), - intent_hash, - )] - .as_slice() - .into(), - ) - .emit(); - - Ok(()) - } - - fn on_native_withdraw( - &mut self, - owner_id: &AccountIdRef, - native_withdraw: &NativeWithdraw, - intent_hash: CryptoHash, - ) -> Result<()> { - DefuseEvent::NativeWithdraw( - [IntentEvent::new( - AccountEvent::new(owner_id, Cow::Borrowed(native_withdraw)), - intent_hash, - )] - .as_slice() - .into(), - ) - .emit(); - - Ok(()) - } - - fn on_storage_deposit( - &mut self, - owner_id: &AccountIdRef, - storage_deposit: &StorageDeposit, - intent_hash: CryptoHash, - ) -> Result<()> { - DefuseEvent::StorageDeposit( - [IntentEvent::new( - AccountEvent::new(owner_id, Cow::Borrowed(storage_deposit)), - intent_hash, - )] - .as_slice() - .into(), - ) - .emit(); + fn on_deadline(&mut self, _deadline: Deadline) {} - Ok(()) - } + // #[inline] + // fn on_transfer( + // &mut self, + // sender_id: &AccountIdRef, + // transfer: &Transfer, + // intent_hash: CryptoHash, + // ) -> Result<()> { + // Ok(()) + // } + + // #[inline] + // fn on_token_diff( + // &mut self, + // owner_id: &AccountIdRef, + // token_diff: &TokenDiff, + // fees_collected: &Amounts, + // intent_hash: CryptoHash, + // ) -> Result<()> { + // Ok(()) + // } + + // fn on_ft_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // ft_withdraw: &FtWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()> { + // Ok(()) + // } + + // fn on_nft_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // nft_withdraw: &NftWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()> { + // Ok(()) + // } + + // fn on_mt_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // mt_withdraw: &MtWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()> { + // Ok(()) + // } + + // fn on_native_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // native_withdraw: &NativeWithdraw, + // intent_hash: CryptoHash, + // ) -> Result<()> { + // Ok(()) + // } + + // fn on_storage_deposit( + // &mut self, + // owner_id: &AccountIdRef, + // storage_deposit: &StorageDeposit, + // intent_hash: CryptoHash, + // ) -> Result<()> { + // Ok(()) + // } #[inline] fn on_intent_executed(&mut self, signer_id: &AccountIdRef, intent_hash: CryptoHash) { diff --git a/defuse/src/contract/intents/simulate.rs b/defuse/src/contract/intents/simulate.rs index 8e58ca2d..28a1b68d 100644 --- a/defuse/src/contract/intents/simulate.rs +++ b/defuse/src/contract/intents/simulate.rs @@ -1,30 +1,28 @@ -use std::collections::HashMap; - -use defuse_core::DefuseError; -use defuse_core::error::Result; +use defuse_core::events::DefuseEvent; use defuse_core::{ Deadline, accounts::AccountEvent, engine::Inspector, intents::{ IntentEvent, - token_diff::{TokenDeltas, TokenDiff}, - tokens::{FtWithdraw, MtWithdraw, NativeWithdraw, NftWithdraw, StorageDeposit, Transfer}, + token_diff::TokenDeltas, + tokens::{FtWithdraw, MtWithdraw, NftWithdraw}, }, - tokens::{Amounts, TokenId}, }; -use defuse_map_utils::cleanup::DefaultMap; use defuse_near_utils::UnwrapOrPanicError; -use near_sdk::{AccountId, AccountIdRef, CryptoHash, require}; +use near_sdk::{AccountId, AccountIdRef, CryptoHash, serde_json}; +use std::collections::HashMap; pub struct SimulateInspector { pub intents_executed: Vec>>, pub min_deadline: Deadline, pub balance_diff: HashMap, + #[allow(dead_code)] // FIXME: remove pub wnear_id: AccountId, pub ft_withdrawals: Option>, pub nft_withdrawals: Option>, pub mt_withdrawals: Option>, + pub events_emitted: Vec, } impl SimulateInspector { @@ -37,169 +35,176 @@ impl SimulateInspector { ft_withdrawals: None, nft_withdrawals: None, mt_withdrawals: None, + events_emitted: Vec::new(), } } } impl Inspector for SimulateInspector { #[inline] - fn on_deadline(&mut self, deadline: Deadline) { - self.min_deadline = self.min_deadline.min(deadline); + fn emit_event(&mut self, event: DefuseEvent<'_>) { + self.events_emitted + .push(serde_json::to_string(&event).unwrap_or_panic_display()); } #[inline] - fn on_transfer( - &mut self, - sender_id: &AccountIdRef, - transfer: &Transfer, - _intent_hash: CryptoHash, - ) -> Result<()> { - for (token_id, transfer_amount) in &transfer.tokens { - self.balance_diff - .entry_or_default(sender_id.to_owned()) - .sub(token_id.clone(), *transfer_amount) - .ok_or(DefuseError::BalanceOverflow)?; - - self.balance_diff - .entry_or_default(transfer.receiver_id.clone()) - .add(token_id.clone(), *transfer_amount) - .ok_or(DefuseError::BalanceOverflow)?; - } - - Ok(()) - } - - #[inline] - fn on_token_diff( - &mut self, - owner_id: &AccountIdRef, - token_diff: &TokenDiff, - _fees_collected: &Amounts, - _intent_hash: CryptoHash, - ) -> Result<()> { - for (token_id, delta) in &token_diff.diff { - if *delta >= 0 { - self.balance_diff - .entry_or_default(owner_id.to_owned()) - .add( - token_id.clone(), - (*delta).try_into().unwrap_or_panic_display(), - ) - .ok_or(DefuseError::BalanceOverflow)?; - } else { - self.balance_diff - .entry_or_default(owner_id.to_owned()) - .sub( - token_id.clone(), - (-delta).try_into().unwrap_or_panic_display(), - ) - .ok_or(DefuseError::BalanceOverflow)?; - } - } - - Ok(()) - } - - fn on_ft_withdraw( - &mut self, - owner_id: &AccountIdRef, - ft_withdraw: &FtWithdraw, - _intent_hash: CryptoHash, - ) -> Result<()> { - self.balance_diff - .entry_or_default(owner_id.to_owned()) - .sub( - TokenId::Nep141(ft_withdraw.token.clone()), - ft_withdraw.amount.0, - ) - .ok_or(DefuseError::BalanceOverflow)?; - - self.ft_withdrawals - .get_or_insert(Vec::new()) - .push(ft_withdraw.clone()); - - Ok(()) - } - - fn on_nft_withdraw( - &mut self, - owner_id: &AccountIdRef, - nft_withdraw: &NftWithdraw, - _intent_hash: CryptoHash, - ) -> Result<()> { - self.balance_diff - .entry_or_default(owner_id.to_owned()) - .sub( - TokenId::Nep171(nft_withdraw.token.clone(), nft_withdraw.token_id.clone()), - 1, - ) - .ok_or(DefuseError::BalanceOverflow)?; - - self.nft_withdrawals - .get_or_insert(Vec::new()) - .push(nft_withdraw.clone()); - - Ok(()) - } - - fn on_mt_withdraw( - &mut self, - owner_id: &AccountIdRef, - mt_withdraw: &MtWithdraw, - _intent_hash: CryptoHash, - ) -> Result<()> { - require!( - mt_withdraw.amounts.len() != mt_withdraw.token_ids.len(), - "Invalid mt_withdraw() call. List of tokens and amounts don't match in length." - ); - - for (token_id, transfer_amount) in - mt_withdraw.token_ids.iter().zip(mt_withdraw.amounts.iter()) - { - let token_id: TokenId = token_id.parse().unwrap_or_panic_display(); - - self.balance_diff - .entry_or_default(owner_id.to_owned()) - .sub(token_id, transfer_amount.0) - .ok_or(DefuseError::BalanceOverflow)?; - } - - self.mt_withdrawals - .get_or_insert(Vec::new()) - .push(mt_withdraw.clone()); - - Ok(()) - } - - fn on_native_withdraw( - &mut self, - owner_id: &AccountIdRef, - native_withdraw: &NativeWithdraw, - _intent_hash: CryptoHash, - ) -> Result<()> { - let wnear = TokenId::Nep141(self.wnear_id.clone()); - self.balance_diff - .entry_or_default(owner_id.to_owned()) - .sub(wnear, native_withdraw.amount.as_yoctonear()) - .ok_or(DefuseError::BalanceOverflow)?; - - Ok(()) + fn on_deadline(&mut self, deadline: Deadline) { + self.min_deadline = self.min_deadline.min(deadline); } - fn on_storage_deposit( - &mut self, - owner_id: &AccountIdRef, - storage_deposit: &StorageDeposit, - _intent_hash: CryptoHash, - ) -> Result<()> { - let wnear = TokenId::Nep141(self.wnear_id.clone()); - self.balance_diff - .entry_or_default(owner_id.to_owned()) - .sub(wnear, storage_deposit.amount.as_yoctonear()) - .ok_or(DefuseError::BalanceOverflow)?; - - Ok(()) - } + // #[inline] + // fn on_transfer( + // &mut self, + // sender_id: &AccountIdRef, + // transfer: &Transfer, + // _intent_hash: CryptoHash, + // ) -> Result<()> { + // for (token_id, transfer_amount) in &transfer.tokens { + // self.balance_diff + // .entry_or_default(sender_id.to_owned()) + // .sub(token_id.clone(), *transfer_amount) + // .ok_or(DefuseError::BalanceOverflow)?; + + // self.balance_diff + // .entry_or_default(transfer.receiver_id.clone()) + // .add(token_id.clone(), *transfer_amount) + // .ok_or(DefuseError::BalanceOverflow)?; + // } + + // Ok(()) + // } + + // #[inline] + // fn on_token_diff( + // &mut self, + // owner_id: &AccountIdRef, + // token_diff: &TokenDiff, + // _fees_collected: &Amounts, + // _intent_hash: CryptoHash, + // ) -> Result<()> { + // for (token_id, delta) in &token_diff.diff { + // if *delta >= 0 { + // self.balance_diff + // .entry_or_default(owner_id.to_owned()) + // .add( + // token_id.clone(), + // (*delta).try_into().unwrap_or_panic_display(), + // ) + // .ok_or(DefuseError::BalanceOverflow)?; + // } else { + // self.balance_diff + // .entry_or_default(owner_id.to_owned()) + // .sub( + // token_id.clone(), + // (-delta).try_into().unwrap_or_panic_display(), + // ) + // .ok_or(DefuseError::BalanceOverflow)?; + // } + // } + + // Ok(()) + // } + + // fn on_ft_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // ft_withdraw: &FtWithdraw, + // _intent_hash: CryptoHash, + // ) -> Result<()> { + // self.balance_diff + // .entry_or_default(owner_id.to_owned()) + // .sub( + // TokenId::Nep141(ft_withdraw.token.clone()), + // ft_withdraw.amount.0, + // ) + // .ok_or(DefuseError::BalanceOverflow)?; + + // self.ft_withdrawals + // .get_or_insert(Vec::new()) + // .push(ft_withdraw.clone()); + + // Ok(()) + // } + + // fn on_nft_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // nft_withdraw: &NftWithdraw, + // _intent_hash: CryptoHash, + // ) -> Result<()> { + // self.balance_diff + // .entry_or_default(owner_id.to_owned()) + // .sub( + // TokenId::Nep171(nft_withdraw.token.clone(), nft_withdraw.token_id.clone()), + // 1, + // ) + // .ok_or(DefuseError::BalanceOverflow)?; + + // self.nft_withdrawals + // .get_or_insert(Vec::new()) + // .push(nft_withdraw.clone()); + + // Ok(()) + // } + + // fn on_mt_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // mt_withdraw: &MtWithdraw, + // _intent_hash: CryptoHash, + // ) -> Result<()> { + // require!( + // mt_withdraw.amounts.len() != mt_withdraw.token_ids.len(), + // "Invalid mt_withdraw() call. List of tokens and amounts don't match in length." + // ); + + // for (token_id, transfer_amount) in + // mt_withdraw.token_ids.iter().zip(mt_withdraw.amounts.iter()) + // { + // let token_id: TokenId = token_id.parse().unwrap_or_panic_display(); + + // self.balance_diff + // .entry_or_default(owner_id.to_owned()) + // .sub(token_id, transfer_amount.0) + // .ok_or(DefuseError::BalanceOverflow)?; + // } + + // self.mt_withdrawals + // .get_or_insert(Vec::new()) + // .push(mt_withdraw.clone()); + + // Ok(()) + // } + + // fn on_native_withdraw( + // &mut self, + // owner_id: &AccountIdRef, + // native_withdraw: &NativeWithdraw, + // _intent_hash: CryptoHash, + // ) -> Result<()> { + // let wnear = TokenId::Nep141(self.wnear_id.clone()); + // self.balance_diff + // .entry_or_default(owner_id.to_owned()) + // .sub(wnear, native_withdraw.amount.as_yoctonear()) + // .ok_or(DefuseError::BalanceOverflow)?; + + // Ok(()) + // } + + // fn on_storage_deposit( + // &mut self, + // owner_id: &AccountIdRef, + // storage_deposit: &StorageDeposit, + // _intent_hash: CryptoHash, + // ) -> Result<()> { + // let wnear = TokenId::Nep141(self.wnear_id.clone()); + // self.balance_diff + // .entry_or_default(owner_id.to_owned()) + // .sub(wnear, storage_deposit.amount.as_yoctonear()) + // .ok_or(DefuseError::BalanceOverflow)?; + + // Ok(()) + // } #[inline] fn on_intent_executed(&mut self, signer_id: &AccountIdRef, intent_hash: CryptoHash) { From a65fee63a8e44ac1ffc738fe42e422d18df6a231 Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 12:22:49 +0400 Subject: [PATCH 2/8] Minor --- defuse/src/contract/intents/execute.rs | 66 ---------- defuse/src/contract/intents/simulate.rs | 154 ------------------------ 2 files changed, 220 deletions(-) diff --git a/defuse/src/contract/intents/execute.rs b/defuse/src/contract/intents/execute.rs index c60ced64..9f8aa99a 100644 --- a/defuse/src/contract/intents/execute.rs +++ b/defuse/src/contract/intents/execute.rs @@ -18,72 +18,6 @@ impl Inspector for ExecuteInspector { #[inline] fn on_deadline(&mut self, _deadline: Deadline) {} - // #[inline] - // fn on_transfer( - // &mut self, - // sender_id: &AccountIdRef, - // transfer: &Transfer, - // intent_hash: CryptoHash, - // ) -> Result<()> { - // Ok(()) - // } - - // #[inline] - // fn on_token_diff( - // &mut self, - // owner_id: &AccountIdRef, - // token_diff: &TokenDiff, - // fees_collected: &Amounts, - // intent_hash: CryptoHash, - // ) -> Result<()> { - // Ok(()) - // } - - // fn on_ft_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // ft_withdraw: &FtWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()> { - // Ok(()) - // } - - // fn on_nft_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // nft_withdraw: &NftWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()> { - // Ok(()) - // } - - // fn on_mt_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // mt_withdraw: &MtWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()> { - // Ok(()) - // } - - // fn on_native_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // native_withdraw: &NativeWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()> { - // Ok(()) - // } - - // fn on_storage_deposit( - // &mut self, - // owner_id: &AccountIdRef, - // storage_deposit: &StorageDeposit, - // intent_hash: CryptoHash, - // ) -> Result<()> { - // Ok(()) - // } - #[inline] fn on_intent_executed(&mut self, signer_id: &AccountIdRef, intent_hash: CryptoHash) { self.intents_executed.push(IntentEvent::new( diff --git a/defuse/src/contract/intents/simulate.rs b/defuse/src/contract/intents/simulate.rs index 28a1b68d..ef0b1428 100644 --- a/defuse/src/contract/intents/simulate.rs +++ b/defuse/src/contract/intents/simulate.rs @@ -52,160 +52,6 @@ impl Inspector for SimulateInspector { self.min_deadline = self.min_deadline.min(deadline); } - // #[inline] - // fn on_transfer( - // &mut self, - // sender_id: &AccountIdRef, - // transfer: &Transfer, - // _intent_hash: CryptoHash, - // ) -> Result<()> { - // for (token_id, transfer_amount) in &transfer.tokens { - // self.balance_diff - // .entry_or_default(sender_id.to_owned()) - // .sub(token_id.clone(), *transfer_amount) - // .ok_or(DefuseError::BalanceOverflow)?; - - // self.balance_diff - // .entry_or_default(transfer.receiver_id.clone()) - // .add(token_id.clone(), *transfer_amount) - // .ok_or(DefuseError::BalanceOverflow)?; - // } - - // Ok(()) - // } - - // #[inline] - // fn on_token_diff( - // &mut self, - // owner_id: &AccountIdRef, - // token_diff: &TokenDiff, - // _fees_collected: &Amounts, - // _intent_hash: CryptoHash, - // ) -> Result<()> { - // for (token_id, delta) in &token_diff.diff { - // if *delta >= 0 { - // self.balance_diff - // .entry_or_default(owner_id.to_owned()) - // .add( - // token_id.clone(), - // (*delta).try_into().unwrap_or_panic_display(), - // ) - // .ok_or(DefuseError::BalanceOverflow)?; - // } else { - // self.balance_diff - // .entry_or_default(owner_id.to_owned()) - // .sub( - // token_id.clone(), - // (-delta).try_into().unwrap_or_panic_display(), - // ) - // .ok_or(DefuseError::BalanceOverflow)?; - // } - // } - - // Ok(()) - // } - - // fn on_ft_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // ft_withdraw: &FtWithdraw, - // _intent_hash: CryptoHash, - // ) -> Result<()> { - // self.balance_diff - // .entry_or_default(owner_id.to_owned()) - // .sub( - // TokenId::Nep141(ft_withdraw.token.clone()), - // ft_withdraw.amount.0, - // ) - // .ok_or(DefuseError::BalanceOverflow)?; - - // self.ft_withdrawals - // .get_or_insert(Vec::new()) - // .push(ft_withdraw.clone()); - - // Ok(()) - // } - - // fn on_nft_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // nft_withdraw: &NftWithdraw, - // _intent_hash: CryptoHash, - // ) -> Result<()> { - // self.balance_diff - // .entry_or_default(owner_id.to_owned()) - // .sub( - // TokenId::Nep171(nft_withdraw.token.clone(), nft_withdraw.token_id.clone()), - // 1, - // ) - // .ok_or(DefuseError::BalanceOverflow)?; - - // self.nft_withdrawals - // .get_or_insert(Vec::new()) - // .push(nft_withdraw.clone()); - - // Ok(()) - // } - - // fn on_mt_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // mt_withdraw: &MtWithdraw, - // _intent_hash: CryptoHash, - // ) -> Result<()> { - // require!( - // mt_withdraw.amounts.len() != mt_withdraw.token_ids.len(), - // "Invalid mt_withdraw() call. List of tokens and amounts don't match in length." - // ); - - // for (token_id, transfer_amount) in - // mt_withdraw.token_ids.iter().zip(mt_withdraw.amounts.iter()) - // { - // let token_id: TokenId = token_id.parse().unwrap_or_panic_display(); - - // self.balance_diff - // .entry_or_default(owner_id.to_owned()) - // .sub(token_id, transfer_amount.0) - // .ok_or(DefuseError::BalanceOverflow)?; - // } - - // self.mt_withdrawals - // .get_or_insert(Vec::new()) - // .push(mt_withdraw.clone()); - - // Ok(()) - // } - - // fn on_native_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // native_withdraw: &NativeWithdraw, - // _intent_hash: CryptoHash, - // ) -> Result<()> { - // let wnear = TokenId::Nep141(self.wnear_id.clone()); - // self.balance_diff - // .entry_or_default(owner_id.to_owned()) - // .sub(wnear, native_withdraw.amount.as_yoctonear()) - // .ok_or(DefuseError::BalanceOverflow)?; - - // Ok(()) - // } - - // fn on_storage_deposit( - // &mut self, - // owner_id: &AccountIdRef, - // storage_deposit: &StorageDeposit, - // _intent_hash: CryptoHash, - // ) -> Result<()> { - // let wnear = TokenId::Nep141(self.wnear_id.clone()); - // self.balance_diff - // .entry_or_default(owner_id.to_owned()) - // .sub(wnear, storage_deposit.amount.as_yoctonear()) - // .ok_or(DefuseError::BalanceOverflow)?; - - // Ok(()) - // } - #[inline] fn on_intent_executed(&mut self, signer_id: &AccountIdRef, intent_hash: CryptoHash) { self.intents_executed.push(IntentEvent::new( From 75c680a7ffa3e1052d89e80112637a7ff72a07bd Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 12:22:58 +0400 Subject: [PATCH 3/8] Minor --- core/src/engine/inspector.rs | 50 ------------------------------------ 1 file changed, 50 deletions(-) diff --git a/core/src/engine/inspector.rs b/core/src/engine/inspector.rs index 7ef72c71..d1921723 100644 --- a/core/src/engine/inspector.rs +++ b/core/src/engine/inspector.rs @@ -9,55 +9,5 @@ pub trait Inspector { fn on_deadline(&mut self, deadline: Deadline); - // fn on_transfer( - // &mut self, - // sender_id: &AccountIdRef, - // transfer: &Transfer, - // intent_hash: CryptoHash, - // ) -> Result<()>; - - // fn on_token_diff( - // &mut self, - // owner_id: &AccountIdRef, - // token_diff: &TokenDiff, - // fees_collected: &Amounts, - // intent_hash: CryptoHash, - // ) -> Result<()>; - - // fn on_ft_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // ft_withdraw: &FtWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()>; - - // fn on_nft_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // nft_withdraw: &NftWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()>; - - // fn on_mt_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // mt_withdraw: &MtWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()>; - - // fn on_native_withdraw( - // &mut self, - // owner_id: &AccountIdRef, - // native_withdraw: &NativeWithdraw, - // intent_hash: CryptoHash, - // ) -> Result<()>; - - // fn on_storage_deposit( - // &mut self, - // owner_id: &AccountIdRef, - // storage_deposit: &StorageDeposit, - // intent_hash: CryptoHash, - // ) -> Result<()>; - fn on_intent_executed(&mut self, signer_id: &AccountIdRef, hash: CryptoHash); } From 5933fb3497ab6b46846501efa6b51d411e22b83c Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 16:00:08 +0400 Subject: [PATCH 4/8] Get rid of withdrawal objects --- defuse/src/contract/intents/mod.rs | 5 +---- defuse/src/contract/intents/simulate.rs | 19 +++---------------- defuse/src/intents.rs | 11 +---------- tests/src/tests/defuse/intents/ft_withdraw.rs | 7 ++++--- 4 files changed, 9 insertions(+), 33 deletions(-) diff --git a/defuse/src/contract/intents/mod.rs b/defuse/src/contract/intents/mod.rs index 8c8f5eb7..0a2f2cba 100644 --- a/defuse/src/contract/intents/mod.rs +++ b/defuse/src/contract/intents/mod.rs @@ -35,7 +35,7 @@ impl Intents for Contract { #[pause(name = "intents")] #[inline] fn simulate_intents(&self, signed: Vec) -> SimulationOutput { - let mut inspector = SimulateInspector::new(self.wnear_id.clone()); + let mut inspector = SimulateInspector::default(); let engine = Engine::new(self.cached(), &mut inspector); let invariant_violated = match engine.execute_signed_intents(signed) { @@ -51,9 +51,6 @@ impl Intents for Contract { invariant_violated, state: StateOutput { fee: self.fee() }, balance_diff: inspector.balance_diff, - ft_withdrawals: inspector.ft_withdrawals, - nft_withdrawals: inspector.nft_withdrawals, - mt_withdrawals: inspector.mt_withdrawals, } } } diff --git a/defuse/src/contract/intents/simulate.rs b/defuse/src/contract/intents/simulate.rs index ef0b1428..2f289b97 100644 --- a/defuse/src/contract/intents/simulate.rs +++ b/defuse/src/contract/intents/simulate.rs @@ -3,11 +3,7 @@ use defuse_core::{ Deadline, accounts::AccountEvent, engine::Inspector, - intents::{ - IntentEvent, - token_diff::TokenDeltas, - tokens::{FtWithdraw, MtWithdraw, NftWithdraw}, - }, + intents::{IntentEvent, token_diff::TokenDeltas}, }; use defuse_near_utils::UnwrapOrPanicError; use near_sdk::{AccountId, AccountIdRef, CryptoHash, serde_json}; @@ -17,24 +13,15 @@ pub struct SimulateInspector { pub intents_executed: Vec>>, pub min_deadline: Deadline, pub balance_diff: HashMap, - #[allow(dead_code)] // FIXME: remove - pub wnear_id: AccountId, - pub ft_withdrawals: Option>, - pub nft_withdrawals: Option>, - pub mt_withdrawals: Option>, pub events_emitted: Vec, } -impl SimulateInspector { - pub fn new(wnear_id: AccountId) -> Self { +impl Default for SimulateInspector { + fn default() -> Self { Self { intents_executed: Vec::new(), min_deadline: Deadline::MAX, balance_diff: HashMap::default(), - wnear_id, - ft_withdrawals: None, - nft_withdrawals: None, - mt_withdrawals: None, events_emitted: Vec::new(), } } diff --git a/defuse/src/intents.rs b/defuse/src/intents.rs index 9e7f84dc..72763a36 100644 --- a/defuse/src/intents.rs +++ b/defuse/src/intents.rs @@ -5,11 +5,7 @@ use defuse_core::{ accounts::AccountEvent, engine::deltas::InvariantViolated, fees::Pips, - intents::{ - IntentEvent, - token_diff::TokenDeltas, - tokens::{FtWithdraw, MtWithdraw, NftWithdraw}, - }, + intents::{IntentEvent, token_diff::TokenDeltas}, payload::multi::MultiPayload, }; @@ -53,11 +49,6 @@ pub struct SimulationOutput { /// All changes in balances after simulating the intent pub balance_diff: HashMap, - - /// Explicit withdrawal requests - pub ft_withdrawals: Option>, - pub nft_withdrawals: Option>, - pub mt_withdrawals: Option>, } impl SimulationOutput { diff --git a/tests/src/tests/defuse/intents/ft_withdraw.rs b/tests/src/tests/defuse/intents/ft_withdraw.rs index 3425d57d..54ca2b6d 100644 --- a/tests/src/tests/defuse/intents/ft_withdraw.rs +++ b/tests/src/tests/defuse/intents/ft_withdraw.rs @@ -278,9 +278,10 @@ async fn test_ft_withdraw_intent_msg( .collect::>() ) ); - assert_eq!(sim_out.ft_withdrawals, Some(vec![withdraw_intent])); - assert!(sim_out.nft_withdrawals.is_none()); - assert!(sim_out.mt_withdrawals.is_none()); + // FIXME: consider testing events + // assert_eq!(sim_out.ft_withdrawals, Some(vec![withdraw_intent])); + // assert!(sim_out.nft_withdrawals.is_none()); + // assert!(sim_out.mt_withdrawals.is_none()); env.defuse.execute_intents(intents).await.unwrap(); From cf61fd1f7f4ed6d75b4dbe1d0bc4028fd05cd3e5 Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 16:13:57 +0400 Subject: [PATCH 5/8] Minor refactor --- core/src/engine/inspector.rs | 2 +- core/src/intents/token_diff.rs | 2 +- core/src/intents/tokens.rs | 12 ++++++------ defuse/src/contract/intents/execute.rs | 2 +- defuse/src/contract/intents/simulate.rs | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/engine/inspector.rs b/core/src/engine/inspector.rs index d1921723..1660ae1c 100644 --- a/core/src/engine/inspector.rs +++ b/core/src/engine/inspector.rs @@ -5,7 +5,7 @@ use near_sdk::{AccountIdRef, CryptoHash}; #[autoimpl(for &mut T, Box)] pub trait Inspector { - fn emit_event(&mut self, event: DefuseEvent<'_>); + fn on_event(&mut self, event: DefuseEvent<'_>); fn on_deadline(&mut self, deadline: Deadline); diff --git a/core/src/intents/token_diff.rs b/core/src/intents/token_diff.rs index cf49b976..597f3ea5 100644 --- a/core/src/intents/token_diff.rs +++ b/core/src/intents/token_diff.rs @@ -97,7 +97,7 @@ impl ExecutableIntent for TokenDiff { intent_hash, )])); - engine.inspector.emit_event(event); + engine.inspector.on_event(event); // deposit fees to collector if !fees_collected.is_empty() { diff --git a/core/src/intents/tokens.rs b/core/src/intents/tokens.rs index 8e949a81..2d0044e8 100644 --- a/core/src/intents/tokens.rs +++ b/core/src/intents/tokens.rs @@ -54,7 +54,7 @@ impl ExecutableIntent for Transfer { intent_hash, )])); - engine.inspector.emit_event(event); + engine.inspector.on_event(event); engine .state @@ -106,7 +106,7 @@ impl ExecutableIntent for FtWithdraw { intent_hash, )])); - engine.inspector.emit_event(event); + engine.inspector.on_event(event); engine.state.ft_withdraw(owner_id, self) } @@ -152,7 +152,7 @@ impl ExecutableIntent for NftWithdraw { intent_hash, )])); - engine.inspector.emit_event(event); + engine.inspector.on_event(event); engine.state.nft_withdraw(owner_id, self) } @@ -202,7 +202,7 @@ impl ExecutableIntent for MtWithdraw { intent_hash, )])); - engine.inspector.emit_event(event); + engine.inspector.on_event(event); engine.state.mt_withdraw(owner_id, self) } @@ -236,7 +236,7 @@ impl ExecutableIntent for NativeWithdraw { intent_hash, )])); - engine.inspector.emit_event(event); + engine.inspector.on_event(event); engine.state.native_withdraw(owner_id, self) } @@ -278,7 +278,7 @@ impl ExecutableIntent for StorageDeposit { intent_hash, )])); - engine.inspector.emit_event(event); + engine.inspector.on_event(event); engine.state.storage_deposit(owner_id, self) } diff --git a/defuse/src/contract/intents/execute.rs b/defuse/src/contract/intents/execute.rs index 9f8aa99a..4cba102b 100644 --- a/defuse/src/contract/intents/execute.rs +++ b/defuse/src/contract/intents/execute.rs @@ -11,7 +11,7 @@ pub struct ExecuteInspector { impl Inspector for ExecuteInspector { #[inline] - fn emit_event(&mut self, event: DefuseEvent<'_>) { + fn on_event(&mut self, event: DefuseEvent<'_>) { event.emit(); } diff --git a/defuse/src/contract/intents/simulate.rs b/defuse/src/contract/intents/simulate.rs index 2f289b97..30cf0401 100644 --- a/defuse/src/contract/intents/simulate.rs +++ b/defuse/src/contract/intents/simulate.rs @@ -29,7 +29,7 @@ impl Default for SimulateInspector { impl Inspector for SimulateInspector { #[inline] - fn emit_event(&mut self, event: DefuseEvent<'_>) { + fn on_event(&mut self, event: DefuseEvent<'_>) { self.events_emitted .push(serde_json::to_string(&event).unwrap_or_panic_display()); } From 02b4f8ae56303c194ae744563a5b94f1d5194cf8 Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 16:45:23 +0400 Subject: [PATCH 6/8] Use serde_json::Value instead of String in SimulateInspector --- core/src/engine/inspector.rs | 3 +-- defuse/src/contract/intents/simulate.rs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/engine/inspector.rs b/core/src/engine/inspector.rs index 1660ae1c..d25393fe 100644 --- a/core/src/engine/inspector.rs +++ b/core/src/engine/inspector.rs @@ -1,5 +1,4 @@ -use crate::Deadline; -use crate::events::DefuseEvent; +use crate::{Deadline, events::DefuseEvent}; use impl_tools::autoimpl; use near_sdk::{AccountIdRef, CryptoHash}; diff --git a/defuse/src/contract/intents/simulate.rs b/defuse/src/contract/intents/simulate.rs index 30cf0401..24582224 100644 --- a/defuse/src/contract/intents/simulate.rs +++ b/defuse/src/contract/intents/simulate.rs @@ -13,7 +13,7 @@ pub struct SimulateInspector { pub intents_executed: Vec>>, pub min_deadline: Deadline, pub balance_diff: HashMap, - pub events_emitted: Vec, + pub events_emitted: Vec, } impl Default for SimulateInspector { @@ -31,7 +31,7 @@ impl Inspector for SimulateInspector { #[inline] fn on_event(&mut self, event: DefuseEvent<'_>) { self.events_emitted - .push(serde_json::to_string(&event).unwrap_or_panic_display()); + .push(serde_json::to_value(&event).unwrap_or_panic_display()); } #[inline] From d3714c7e7f7d949ea7d487ff6c0cef94162958be Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 16:45:37 +0400 Subject: [PATCH 7/8] Minor --- tests/src/tests/defuse/intents/ft_withdraw.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/src/tests/defuse/intents/ft_withdraw.rs b/tests/src/tests/defuse/intents/ft_withdraw.rs index 54ca2b6d..d24019fd 100644 --- a/tests/src/tests/defuse/intents/ft_withdraw.rs +++ b/tests/src/tests/defuse/intents/ft_withdraw.rs @@ -278,10 +278,6 @@ async fn test_ft_withdraw_intent_msg( .collect::>() ) ); - // FIXME: consider testing events - // assert_eq!(sim_out.ft_withdrawals, Some(vec![withdraw_intent])); - // assert!(sim_out.nft_withdrawals.is_none()); - // assert!(sim_out.mt_withdrawals.is_none()); env.defuse.execute_intents(intents).await.unwrap(); From 2a69d8a1a5d9c5bc8dd89e06a048134b7ce18390 Mon Sep 17 00:00:00 2001 From: BonelessImpl Date: Fri, 16 May 2025 16:59:29 +0400 Subject: [PATCH 8/8] Use encompassing event --- core/src/engine/inspector.rs | 4 ++-- core/src/events.rs | 19 +++++++++++++++++++ core/src/intents/token_diff.rs | 2 +- core/src/intents/tokens.rs | 12 ++++++------ defuse/src/contract/intents/execute.rs | 8 ++++++-- defuse/src/contract/intents/simulate.rs | 4 ++-- 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/core/src/engine/inspector.rs b/core/src/engine/inspector.rs index d25393fe..3d119863 100644 --- a/core/src/engine/inspector.rs +++ b/core/src/engine/inspector.rs @@ -1,10 +1,10 @@ -use crate::{Deadline, events::DefuseEvent}; +use crate::{Deadline, events::Event}; use impl_tools::autoimpl; use near_sdk::{AccountIdRef, CryptoHash}; #[autoimpl(for &mut T, Box)] pub trait Inspector { - fn on_event(&mut self, event: DefuseEvent<'_>); + fn on_event(&mut self, event: Event<'_>); fn on_deadline(&mut self, deadline: Deadline); diff --git a/core/src/events.rs b/core/src/events.rs index 4f816b8e..543106c3 100644 --- a/core/src/events.rs +++ b/core/src/events.rs @@ -7,10 +7,29 @@ use crate::{ tokens::{FtWithdraw, MtWithdraw, NativeWithdraw, NftWithdraw, StorageDeposit, Transfer}, }, }; +use defuse_nep245::MtEvent; use derive_more::derive::From; use near_sdk::{near, serde::Deserialize}; use std::borrow::Cow; +#[must_use = "make sure to `.emit()` this event"] +#[near(serializers = [json])] +#[derive(Debug, Clone, From)] +#[serde(untagged)] +pub enum Event<'a> { + Dip4(DefuseEvent<'a>), + Nep245(MtEvent<'a>), +} + +impl Event<'_> { + pub fn emit(&self) { + match self { + Self::Dip4(event) => event.emit(), + Self::Nep245(event) => event.emit(), + } + } +} + #[must_use = "make sure to `.emit()` this event"] #[near(event_json(standard = "dip4"))] #[derive(Debug, Clone, Deserialize, From)] diff --git a/core/src/intents/token_diff.rs b/core/src/intents/token_diff.rs index 597f3ea5..96319d1f 100644 --- a/core/src/intents/token_diff.rs +++ b/core/src/intents/token_diff.rs @@ -97,7 +97,7 @@ impl ExecutableIntent for TokenDiff { intent_hash, )])); - engine.inspector.on_event(event); + engine.inspector.on_event(event.into()); // deposit fees to collector if !fees_collected.is_empty() { diff --git a/core/src/intents/tokens.rs b/core/src/intents/tokens.rs index 2d0044e8..799b5ba0 100644 --- a/core/src/intents/tokens.rs +++ b/core/src/intents/tokens.rs @@ -54,7 +54,7 @@ impl ExecutableIntent for Transfer { intent_hash, )])); - engine.inspector.on_event(event); + engine.inspector.on_event(event.into()); engine .state @@ -106,7 +106,7 @@ impl ExecutableIntent for FtWithdraw { intent_hash, )])); - engine.inspector.on_event(event); + engine.inspector.on_event(event.into()); engine.state.ft_withdraw(owner_id, self) } @@ -152,7 +152,7 @@ impl ExecutableIntent for NftWithdraw { intent_hash, )])); - engine.inspector.on_event(event); + engine.inspector.on_event(event.into()); engine.state.nft_withdraw(owner_id, self) } @@ -202,7 +202,7 @@ impl ExecutableIntent for MtWithdraw { intent_hash, )])); - engine.inspector.on_event(event); + engine.inspector.on_event(event.into()); engine.state.mt_withdraw(owner_id, self) } @@ -236,7 +236,7 @@ impl ExecutableIntent for NativeWithdraw { intent_hash, )])); - engine.inspector.on_event(event); + engine.inspector.on_event(event.into()); engine.state.native_withdraw(owner_id, self) } @@ -278,7 +278,7 @@ impl ExecutableIntent for StorageDeposit { intent_hash, )])); - engine.inspector.on_event(event); + engine.inspector.on_event(event.into()); engine.state.storage_deposit(owner_id, self) } diff --git a/defuse/src/contract/intents/execute.rs b/defuse/src/contract/intents/execute.rs index 4cba102b..42fc1650 100644 --- a/defuse/src/contract/intents/execute.rs +++ b/defuse/src/contract/intents/execute.rs @@ -1,5 +1,9 @@ use defuse_core::{ - Deadline, accounts::AccountEvent, engine::Inspector, events::DefuseEvent, intents::IntentEvent, + Deadline, + accounts::AccountEvent, + engine::Inspector, + events::{DefuseEvent, Event}, + intents::IntentEvent, }; use near_sdk::{AccountIdRef, CryptoHash}; use std::borrow::Cow; @@ -11,7 +15,7 @@ pub struct ExecuteInspector { impl Inspector for ExecuteInspector { #[inline] - fn on_event(&mut self, event: DefuseEvent<'_>) { + fn on_event(&mut self, event: Event<'_>) { event.emit(); } diff --git a/defuse/src/contract/intents/simulate.rs b/defuse/src/contract/intents/simulate.rs index 24582224..fc624801 100644 --- a/defuse/src/contract/intents/simulate.rs +++ b/defuse/src/contract/intents/simulate.rs @@ -1,4 +1,4 @@ -use defuse_core::events::DefuseEvent; +use defuse_core::events::Event; use defuse_core::{ Deadline, accounts::AccountEvent, @@ -29,7 +29,7 @@ impl Default for SimulateInspector { impl Inspector for SimulateInspector { #[inline] - fn on_event(&mut self, event: DefuseEvent<'_>) { + fn on_event(&mut self, event: Event<'_>) { self.events_emitted .push(serde_json::to_value(&event).unwrap_or_panic_display()); }