-
Notifications
You must be signed in to change notification settings - Fork 370
fix(ckdoge): use correct transaction fees #7660
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
Merged
+462
−142
Merged
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
71f30cb
DEFI-2458: fee estimator
gregorydemay 711a989
DEFI-2458: store last_median_fee_per_vbyte
gregorydemay f016eae
DEFI-2458: instantiate FeeEstimator from CanisterRuntime
gregorydemay fbde32f
DEFI-2458: copied Bitcoin implementation for DogecoinFeeEstimator
gregorydemay 9144be0
DEFI-2458: evalue minter fee
gregorydemay 9bf8241
DEFI-2458: evaluate transaction fees
gregorydemay ec83e2e
DEFI-2458: use FeeEstimator to build transactions
gregorydemay 1f4949b
DEFI-2458: CanisterRuntime generic over type of FeeEstimator
gregorydemay bd0939e
DEFI-2458: clean-up
gregorydemay d78c33d
DEFI-2458: Dogecoin evaluate_transaction_fee
gregorydemay ab4cc47
DEFI-2458: fix minimum_withrawal_amount
gregorydemay 725391f
DEFI-2458: unit test for Dogecoin minimum_withrawal_amount
gregorydemay a2df781
DEFI-2458: rename
gregorydemay 03bb227
Merge branch 'master' into gdemay/DEFI-2458-ckdoge-tx-fees
gregorydemay 95acd65
DEFI-2548: docs estimate_median_fee
gregorydemay b980924
DEFI-2548: rename associated type
gregorydemay 7f4cdf2
DEFI-2548: DUST_LIMIT constant
gregorydemay fc8bbdc
DEFI-2548: clean-up evaluate_minter_fee
gregorydemay 8da1f30
DEFI-2548: rename build_bitcoin_unsigned_transaction
gregorydemay a84220e
DEFi-2458: fix system test
gregorydemay 415ab61
DEFI-2548: formatting
gregorydemay 6b23f0b
DEFI-2548: typos
gregorydemay 3daf88c
DEFI-2548: docs BitcoinFeeEstimator
gregorydemay b3bf7fb
DEFI-2548: docs PER_REQUEST_SIZE_BOUND
gregorydemay 69fc403
DEFI-2548: remove comment
gregorydemay 257eb2a
DEFI-2548: change Dogecoin Regtest dust limit
gregorydemay 2a38b95
Merge branch 'master' into gdemay/DEFI-2458-ckdoge-tx-fees
gregorydemay File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| use crate::state::CkBtcMinterState; | ||
| use crate::tx::UnsignedTransaction; | ||
| use crate::{Network, fake_sign}; | ||
| use ic_btc_interface::{MillisatoshiPerByte, Satoshi}; | ||
| use std::cmp::max; | ||
|
|
||
| pub trait FeeEstimator { | ||
| fn estimate_median_fee( | ||
gregorydemay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| &self, | ||
| fee_percentiles: &[MillisatoshiPerByte], | ||
| ) -> Option<MillisatoshiPerByte>; | ||
|
|
||
| /// Evaluate the fee necessary to cover the minter's cycles consumption. | ||
| fn evaluate_minter_fee(&self, num_inputs: u64, num_outputs: u64) -> Satoshi; | ||
|
|
||
| /// Evaluate transaction fee with the given fee rate (in milli base unit per vbyte/byte) | ||
| fn evaluate_transaction_fee(&self, tx: &UnsignedTransaction, fee_rate: u64) -> u64; | ||
|
|
||
| /// Compute a new minimum withdrawal amount based on the current fee rate | ||
| fn fee_based_minimum_withrawal_amount(&self, median_fee: MillisatoshiPerByte) -> Satoshi; | ||
| } | ||
|
|
||
| pub struct BitcoinFeeEstimator { | ||
| network: Network, | ||
| retrieve_btc_min_amount: u64, | ||
| check_fee: u64, | ||
gregorydemay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| impl BitcoinFeeEstimator { | ||
| pub fn new(network: Network, retrieve_btc_min_amount: u64, check_fee: u64) -> Self { | ||
| Self { | ||
| network, | ||
| retrieve_btc_min_amount, | ||
| check_fee, | ||
| } | ||
| } | ||
|
|
||
| pub fn from_state(state: &CkBtcMinterState) -> Self { | ||
| Self::new( | ||
| state.btc_network, | ||
| state.retrieve_btc_min_amount, | ||
| state.check_fee, | ||
| ) | ||
| } | ||
|
|
||
| /// An estimated fee per vbyte of 142 millistatoshis per vbyte was selected around 2025.06.21 01:09:50 UTC | ||
gregorydemay marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// for Bitcoin Mainnet, whereas the median fee around that time should have been 2_000. | ||
| /// Until we know the root cause, we ensure that the estimated fee has a meaningful minimum value. | ||
| const fn minimum_fee_per_vbyte(&self) -> MillisatoshiPerByte { | ||
gregorydemay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| match &self.network { | ||
| Network::Mainnet => 1_500, | ||
| Network::Testnet => 1_000, | ||
| Network::Regtest => 0, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl FeeEstimator for BitcoinFeeEstimator { | ||
| fn estimate_median_fee( | ||
| &self, | ||
| fee_percentiles: &[MillisatoshiPerByte], | ||
| ) -> Option<MillisatoshiPerByte> { | ||
| /// The default fee we use on regtest networks. | ||
| const DEFAULT_REGTEST_FEE: MillisatoshiPerByte = 5_000; | ||
|
|
||
| let median_fee = match &self.network { | ||
| Network::Mainnet | Network::Testnet => { | ||
| if fee_percentiles.len() < 100 { | ||
| return None; | ||
| } | ||
| Some(fee_percentiles[50]) | ||
| } | ||
| Network::Regtest => Some(DEFAULT_REGTEST_FEE), | ||
gregorydemay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
| median_fee.map(|f| f.max(self.minimum_fee_per_vbyte())) | ||
| } | ||
|
|
||
| fn evaluate_minter_fee(&self, num_inputs: u64, num_outputs: u64) -> u64 { | ||
gregorydemay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const MINTER_FEE_PER_INPUT: u64 = 146; | ||
| const MINTER_FEE_PER_OUTPUT: u64 = 4; | ||
| const MINTER_FEE_CONSTANT: u64 = 26; | ||
| const MINTER_ADDRESS_DUST_LIMIT: Satoshi = 300; | ||
|
|
||
| max( | ||
| MINTER_FEE_PER_INPUT * num_inputs | ||
| + MINTER_FEE_PER_OUTPUT * num_outputs | ||
| + MINTER_FEE_CONSTANT, | ||
| MINTER_ADDRESS_DUST_LIMIT, | ||
| ) | ||
| } | ||
|
|
||
| /// Returns the minimum withdrawal amount based on the current median fee rate (in millisatoshi per byte). | ||
| /// The returned amount is in satoshi. | ||
| fn fee_based_minimum_withrawal_amount(&self, median_fee: MillisatoshiPerByte) -> Satoshi { | ||
gregorydemay marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| match self.network { | ||
| Network::Mainnet | Network::Testnet => { | ||
| const PER_REQUEST_RBF_BOUND: u64 = 22_100; | ||
| const PER_REQUEST_VSIZE_BOUND: u64 = 221; | ||
| const PER_REQUEST_MINTER_FEE_BOUND: u64 = 305; | ||
|
|
||
| let median_fee_rate = median_fee / 1_000; | ||
| ((PER_REQUEST_RBF_BOUND | ||
| + PER_REQUEST_VSIZE_BOUND * median_fee_rate | ||
| + PER_REQUEST_MINTER_FEE_BOUND | ||
| + self.check_fee) | ||
| / 50_000) //TODO DEFI-2187: adjust increment of minimum withdrawal amount to be a multiple of retrieve_btc_min_amount/2 | ||
| * 50_000 | ||
| + self.retrieve_btc_min_amount | ||
| } | ||
| Network::Regtest => self.retrieve_btc_min_amount, | ||
| } | ||
| } | ||
|
|
||
| fn evaluate_transaction_fee( | ||
| &self, | ||
| unsigned_tx: &UnsignedTransaction, | ||
| fee_per_vbyte: u64, | ||
| ) -> u64 { | ||
| let tx_vsize = fake_sign(unsigned_tx).vsize(); | ||
| (tx_vsize as u64 * fee_per_vbyte) / 1000 | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.