diff --git a/rs/dogecoin/ckdoge/minter/tests/tests.rs b/rs/dogecoin/ckdoge/minter/tests/tests.rs index 7fae5bb01b59..9560ce702c44 100644 --- a/rs/dogecoin/ckdoge/minter/tests/tests.rs +++ b/rs/dogecoin/ckdoge/minter/tests/tests.rs @@ -383,6 +383,7 @@ mod withdrawal { setup .withdrawal_flow() + .minter_await_fee_refresh() .ledger_approve_minter(account, RETRIEVE_DOGE_MIN_AMOUNT) .minter_retrieve_doge_with_approval( RETRIEVE_DOGE_MIN_AMOUNT, @@ -415,6 +416,7 @@ mod withdrawal { let withdrawal_flow = setup .withdrawal_flow() + .minter_await_fee_refresh() .ledger_approve_minter(account, RETRIEVE_DOGE_MIN_AMOUNT); setup.ledger().stop(); @@ -454,6 +456,7 @@ mod withdrawal { setup .withdrawal_flow() + .minter_await_fee_refresh() .ledger_approve_minter(account, RETRIEVE_DOGE_MIN_AMOUNT) .minter_retrieve_doge_with_approval( RETRIEVE_DOGE_MIN_AMOUNT, @@ -542,6 +545,7 @@ mod withdrawal { setup .withdrawal_flow() + .minter_await_fee_refresh() .ledger_approve_minter(account, withdrawal_amount) .minter_retrieve_doge_with_approval( withdrawal_amount, @@ -584,6 +588,7 @@ mod withdrawal { setup .withdrawal_flow() + .minter_await_fee_refresh() .ledger_approve_minter(account, withdrawal_amount) .minter_retrieve_doge_with_approval( withdrawal_amount, @@ -634,6 +639,8 @@ fn should_estimate_withdrawal_fee() { .minter_update_balance() .expect_mint(); + minter.await_fee_refresh(); + assert_eq!( estimate_withdrawal_fee_and_check(&minter, DOGE, 2), Err(EstimateWithdrawalFeeError::AmountTooLow { @@ -697,6 +704,7 @@ mod post_upgrade { setup .withdrawal_flow() + .minter_await_fee_refresh() .ledger_approve_minter(account, RETRIEVE_DOGE_MIN_AMOUNT) .minter_retrieve_doge_with_approval( RETRIEVE_DOGE_MIN_AMOUNT, diff --git a/rs/dogecoin/ckdoge/test_utils/src/flow/withdrawal.rs b/rs/dogecoin/ckdoge/test_utils/src/flow/withdrawal.rs index 45be16e56c69..320e6efdc6f9 100644 --- a/rs/dogecoin/ckdoge/test_utils/src/flow/withdrawal.rs +++ b/rs/dogecoin/ckdoge/test_utils/src/flow/withdrawal.rs @@ -28,7 +28,7 @@ use std::time::Duration; /// Entry point in the withdrawal flow /// -/// Step 1: approve the minter to burn user's funds +/// Step 1: await a refresh of the minter's median fee percentiles pub struct WithdrawalFlowStart { setup: S, } @@ -38,6 +38,21 @@ impl WithdrawalFlowStart { Self { setup } } + pub fn minter_await_fee_refresh(self) -> WithdrawalFlowApproval + where + S: AsRef, + { + self.setup.as_ref().minter().await_fee_refresh(); + WithdrawalFlowApproval { setup: self.setup } + } +} + +/// Step 2: approve the minter to burn user's funds +pub struct WithdrawalFlowApproval { + setup: S, +} + +impl WithdrawalFlowApproval { pub fn ledger_approve_minter(self, account: A, amount: u64) -> RetrieveDogeFlow where A: Into, diff --git a/rs/dogecoin/ckdoge/test_utils/src/lib.rs b/rs/dogecoin/ckdoge/test_utils/src/lib.rs index b6dba5818a64..762d58a4f683 100644 --- a/rs/dogecoin/ckdoge/test_utils/src/lib.rs +++ b/rs/dogecoin/ckdoge/test_utils/src/lib.rs @@ -48,6 +48,8 @@ pub const LEDGER_TRANSFER_FEE: u64 = DOGE / 100; const MAX_TIME_IN_QUEUE: Duration = Duration::from_secs(10); pub const MIN_CONFIRMATIONS: u32 = 60; pub const BLOCK_TIME: Duration = Duration::from_secs(60); +/// Must be at least the minter's `refresh_fee_percentiles_frequency`. +pub const FEE_PERCENTILES_REFRESH_INTERVAL: Duration = Duration::from_secs(360); pub struct Setup { pub env: Arc, diff --git a/rs/dogecoin/ckdoge/test_utils/src/minter.rs b/rs/dogecoin/ckdoge/test_utils/src/minter.rs index 7be9b6fc7153..4c18c3382f4f 100644 --- a/rs/dogecoin/ckdoge/test_utils/src/minter.rs +++ b/rs/dogecoin/ckdoge/test_utils/src/minter.rs @@ -1,5 +1,5 @@ use crate::events::MinterEventAssert; -use crate::{MAX_TIME_IN_QUEUE, NNS_ROOT_PRINCIPAL}; +use crate::{FEE_PERCENTILES_REFRESH_INTERVAL, MAX_TIME_IN_QUEUE, NNS_ROOT_PRINCIPAL}; use candid::{Decode, Encode, Principal}; use canlog::LogEntry; use ic_ckdoge_minter::{ @@ -163,6 +163,28 @@ impl MinterCanister { Decode!(&call_result, Result).unwrap() } + pub fn await_fee_refresh(&self) { + let refreshes_before = self.count_fee_percentile_refreshes(); + self.env + .advance_time(FEE_PERCENTILES_REFRESH_INTERVAL + Duration::from_secs(1)); + let max_ticks = 10; + for _ in 0..max_ticks { + self.env.tick(); + if self.count_fee_percentile_refreshes() > refreshes_before { + return; + } + } + dbg!(self.get_logs()); + panic!("BUG: minter did not refresh fee percentiles within {max_ticks} ticks"); + } + + fn count_fee_percentile_refreshes(&self) -> usize { + self.get_logs() + .iter() + .filter(|entry| entry.message.contains("update median fee per vbyte")) + .count() + } + pub fn retrieve_doge_status(&self, ledger_burn_index: u64) -> RetrieveDogeStatus { let call_result = self .env