-
Notifications
You must be signed in to change notification settings - Fork 19
Feat/mt resolve deposit tests #198
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # cargo-audit configuration | ||
| # https://docs.rs/cargo-audit/latest/cargo_audit/config/ | ||
|
|
||
| [advisories] | ||
| # Ignore the lru unsound advisory - it comes from near-vm-runner which is | ||
| # locked to lru ^0.12.3 and cannot be updated to the fixed 0.16.3 version. | ||
| # The advisory relates to IterMut's Stacked Borrows violation, which does | ||
| # not affect our usage as we don't use IterMut directly. | ||
| # Tracked: https://github.com/near/nearcore/issues/XXXXX (upstream) | ||
| ignore = ["RUSTSEC-2026-0002"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -162,7 +162,8 @@ jobs: | |
| with: | ||
| cache: false | ||
| - name: Install cargo-audit | ||
| run: cargo install cargo-audit --version "^0.21" --locked | ||
| # Require 0.22+ for CVSS 4.0 support (advisory-db now contains CVSS 4.0 entries) | ||
| run: cargo install cargo-audit --version "^0.22" --locked | ||
| - uses: rustsec/[email protected] | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,11 @@ | ||
| use super::TokenId; | ||
| use derive_more::derive::From; | ||
| use near_sdk::{AccountIdRef, json_types::U128, near, serde::Deserialize}; | ||
| use near_sdk::{AccountIdRef, AsNep297Event, json_types::U128, near, serde::Deserialize}; | ||
| use std::borrow::Cow; | ||
|
|
||
| /// NEAR protocol limit for log messages (16 KiB) | ||
| pub const TOTAL_LOG_LENGTH_LIMIT: usize = 16384; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe move it to |
||
|
|
||
| #[must_use = "make sure to `.emit()` this event"] | ||
| #[near(event_json(standard = "nep245"))] | ||
| #[derive(Debug, Clone, Deserialize, From)] | ||
|
|
@@ -53,6 +56,29 @@ pub struct MtTransferEvent<'a> { | |
| pub memo: Option<Cow<'a, str>>, | ||
| } | ||
|
|
||
| impl MtTransferEvent<'_> { | ||
| /// Calculate the size of a refund event log for this transfer. | ||
| /// Creates a new event with swapped owner IDs and "refund" memo. | ||
| #[must_use] | ||
| pub fn refund_log_size(&self) -> usize { | ||
| MtEvent::MtTransfer( | ||
| [MtTransferEvent { | ||
| authorized_id: None, | ||
| old_owner_id: self.new_owner_id.clone(), | ||
| new_owner_id: self.old_owner_id.clone(), | ||
| token_ids: self.token_ids.clone(), | ||
| amounts: self.amounts.clone(), | ||
| memo: Some("refund".into()), | ||
| }] | ||
| .as_slice() | ||
| .into(), | ||
| ) | ||
| .to_nep297_event() | ||
| .to_event_log() | ||
| .len() | ||
| } | ||
| } | ||
|
|
||
| /// A trait that's used to make it possible to call `emit()` on the enum | ||
| /// arms' contents without having to explicitly construct the enum `MtEvent` itself | ||
| pub trait MtEventEmit<'a>: Into<MtEvent<'a>> { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,12 +4,20 @@ pub mod helpers; | |
| pub mod tx; | ||
|
|
||
| use std::sync::{ | ||
| Arc, | ||
| Arc, Mutex, | ||
| atomic::{AtomicUsize, Ordering}, | ||
| }; | ||
| use tokio::sync::OnceCell; | ||
|
|
||
| pub use account::{Account, SigningAccount}; | ||
| pub use extensions::{ | ||
| ft::{FtExt, FtViewExt}, | ||
| mt::{MtExt, MtViewExt}, | ||
| storage_management::{StorageManagementExt, StorageViewExt}, | ||
| wnear::{WNearDeployerExt, WNearExt}, | ||
| }; | ||
| pub use helpers::*; | ||
| pub use tx::{FnCallBuilder, TxBuilder}; | ||
|
|
||
| pub use anyhow; | ||
| use impl_tools::autoimpl; | ||
|
|
@@ -22,7 +30,6 @@ use near_api::{NetworkConfig, RPCEndpoint, Signer, signer::generate_secret_key}; | |
| use near_sandbox::{GenesisAccount, SandboxConfig}; | ||
| use near_sdk::{AccountId, AccountIdRef, NearToken}; | ||
| use rstest::fixture; | ||
| use tokio::sync::OnceCell; | ||
| use tracing::instrument; | ||
|
|
||
| #[autoimpl(Deref using self.root)] | ||
|
|
@@ -81,28 +88,54 @@ impl Sandbox { | |
| pub fn sandbox(&self) -> &near_sandbox::Sandbox { | ||
| self.sandbox.as_ref() | ||
| } | ||
|
|
||
| pub async fn fast_forward(&self, blocks: u64) { | ||
| self.sandbox.fast_forward(blocks).await.unwrap(); | ||
| } | ||
| } | ||
|
|
||
| /// Shared sandbox instance for test fixtures. | ||
| /// Using `OnceCell<Mutex<Option<...>>>` allows async init and taking ownership in atexit. | ||
| static SHARED_SANDBOX: OnceCell<Mutex<Option<Sandbox>>> = OnceCell::const_new(); | ||
|
|
||
| extern "C" fn cleanup_sandbox() { | ||
| if let Some(mutex) = SHARED_SANDBOX.get() { | ||
| if let Ok(mut guard) = mutex.lock() { | ||
| drop(guard.take()); | ||
| } | ||
| } | ||
|
Comment on lines
+97
to
+106
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very cool! Though, I thought there is a second reason for it not to be killed: PS: wrapping in
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tried, but
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tokio::process::Command::kill_on_drop() could help but since its kept in static variable, the value is never dropped ...
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Okay, then maybe get rid of As for kill_on_drop: since you're touching this part of code, can you also evaluate if tokio_shared_rt would help here?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oncecell guaranteeds that it will initialize sandbox only once, but yeah since we are only setting it bac to none after tests are finished it should be fine to live without it
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fyi: confirmed that near-sandbox is killed in case of successful execution and on ctrl+c
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually oncecell is quite helpful here due to get_or_init functionatliy. otherwise you need to manually lock the mutex, then there is async call to create sandbox and you dont want to keep mutex locked between await points so the implementation becomes ugly and complicated IMO. so i decided to keep oncecell since its semantically comaptible with what we want => initialize sanbox only once per test run (binary call) |
||
| } | ||
|
|
||
| #[fixture] | ||
| #[instrument] | ||
| pub async fn sandbox(#[default(NearToken::from_near(100_000))] amount: NearToken) -> Sandbox { | ||
| const SHARED_ROOT: &AccountIdRef = AccountIdRef::new_or_panic("test"); | ||
|
|
||
| static SHARED_SANDBOX: OnceCell<Sandbox> = OnceCell::const_new(); | ||
| static SUB_COUNTER: AtomicUsize = AtomicUsize::new(0); | ||
|
|
||
| let shared = SHARED_SANDBOX | ||
| .get_or_init(|| Sandbox::new(SHARED_ROOT)) | ||
| let mutex = SHARED_SANDBOX | ||
| .get_or_init(|| async { | ||
| unsafe { | ||
| libc::atexit(cleanup_sandbox); | ||
| } | ||
| Mutex::new(Some(Sandbox::new(SHARED_ROOT).await)) | ||
| }) | ||
| .await; | ||
|
|
||
| let (sandbox_arc, root_account) = mutex | ||
| .lock() | ||
| .unwrap() | ||
| .as_ref() | ||
| .map(|shared| (shared.sandbox.clone(), shared.root.clone())) | ||
| .unwrap(); | ||
|
|
||
| Sandbox { | ||
| root: shared | ||
| root: root_account | ||
| .generate_subaccount( | ||
| SUB_COUNTER.fetch_add(1, Ordering::Relaxed).to_string(), | ||
| amount, | ||
| ) | ||
| .await | ||
| .unwrap(), | ||
| sandbox: shared.sandbox.clone(), | ||
| sandbox: sandbox_arc, | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe avoid spending gas on serializing twice?