mirror of
https://github.com/serai-dex/serai.git
synced 2024-11-16 17:07:35 +00:00
Bitcoin Dust constant justification, median_fee fn
This commit is contained in:
parent
e5113c333e
commit
83c41eccd4
2 changed files with 62 additions and 9 deletions
|
@ -315,6 +315,34 @@ impl Bitcoin {
|
|||
}
|
||||
}
|
||||
|
||||
// This function panics on a node which doesn't follow the Bitcoin protocol, which is deemed fine
|
||||
async fn median_fee(&self, block: &Block) -> Result<Fee, NetworkError> {
|
||||
let mut fees = vec![];
|
||||
if block.txdata.len() > 1 {
|
||||
for tx in &block.txdata[1 ..] {
|
||||
let mut in_value = 0;
|
||||
for input in &tx.input {
|
||||
let mut input_tx = input.previous_output.txid.to_raw_hash().to_byte_array();
|
||||
input_tx.reverse();
|
||||
in_value += self.get_transaction(&input_tx).await?.output
|
||||
[usize::try_from(input.previous_output.vout).unwrap()]
|
||||
.value;
|
||||
}
|
||||
let out = tx.output.iter().map(|output| output.value).sum::<u64>();
|
||||
fees.push((in_value - out) / tx.weight().to_wu());
|
||||
}
|
||||
}
|
||||
fees.sort();
|
||||
// Prefer the higher fee
|
||||
let fee = fees.get(fees.len() / 2).cloned().unwrap_or(0);
|
||||
|
||||
// The DUST constant documentation details a 5000 sat/kilo-vbyte minimum fee policy.
|
||||
// 5000 sat/kilo-vbyte is 5000 sat/4-kilo-weight (1250 sat/kilo-weight).
|
||||
// Since bitcoin-serai takes fee per weight, use a minimum of 2
|
||||
// (the ceil div of 1250 by 1000)
|
||||
Ok(Fee(fee.max(2)))
|
||||
}
|
||||
|
||||
async fn make_signable_transaction(
|
||||
&self,
|
||||
block_number: usize,
|
||||
|
@ -325,12 +353,7 @@ impl Bitcoin {
|
|||
) -> Result<Option<BSignableTransaction>, NetworkError> {
|
||||
// TODO2: Use an fee representative of several blocks, cached inside Self
|
||||
let block_for_fee = self.get_block(block_number).await?;
|
||||
let median_fee = || {
|
||||
// TODO
|
||||
let _ = block_for_fee;
|
||||
Fee(2)
|
||||
};
|
||||
let fee = median_fee();
|
||||
let fee = self.median_fee(&block_for_fee).await?;
|
||||
|
||||
let payments = payments
|
||||
.iter()
|
||||
|
@ -392,9 +415,35 @@ impl Network for Bitcoin {
|
|||
const ESTIMATED_BLOCK_TIME_IN_SECONDS: usize = 600;
|
||||
const CONFIRMATIONS: usize = 6;
|
||||
|
||||
// 0.0001 BTC, 10,000 satoshis
|
||||
#[allow(clippy::inconsistent_digit_grouping)]
|
||||
const DUST: u64 = 1_00_000_000 / 10_000;
|
||||
/*
|
||||
A Taproot input is:
|
||||
- 36 bytes for the OutPoint
|
||||
- 0 bytes for the script (+1 byte for the length)
|
||||
- 4 bytes for the sequence
|
||||
Per https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format
|
||||
|
||||
There's also:
|
||||
- 1 byte for the witness length
|
||||
- 1 byte for the signature length
|
||||
- 64 bytes for the signature
|
||||
which have the SegWit discount.
|
||||
|
||||
(4 * (36 + 1 + 4)) + (1 + 1 + 64) = 164 + 66 = 230 weight units
|
||||
230 ceil div 4 = 57 vbytes
|
||||
|
||||
Bitcoin defines multiple minimum feerate constants *per kilo-vbyte*. Currently, these are
|
||||
1000 and 3000. Since these are solely relay rules, and may be raised, we use a
|
||||
5000 sat/kilo-vbyte minimum fee rate.
|
||||
|
||||
5000 sat/kilo-vbyte = 5 sat/vbyte
|
||||
5 * 57 = 285 sats/spent-output
|
||||
|
||||
Even if an output took 100 bytes (it should be just ~29-43), taking 400 weight units, adding
|
||||
100 vbytes, tripling the transaction size, then the sats/tx would be < 1000.
|
||||
|
||||
Increase by an order of magnitude, 10,000 satoshis.
|
||||
*/
|
||||
const DUST: u64 = 10_000;
|
||||
|
||||
// Bitcoin has a max weight of 400,000 (MAX_STANDARD_TX_WEIGHT)
|
||||
// A non-SegWit TX will have 4 weight units per byte, leaving a max size of 100,000 bytes
|
||||
|
|
|
@ -272,6 +272,10 @@ pub trait Network: 'static + Send + Sync + Clone + PartialEq + Eq + Debug {
|
|||
const MAX_OUTPUTS: usize;
|
||||
|
||||
/// Minimum output value which will be handled.
|
||||
///
|
||||
/// For any received output, there's the cost to spend the output. This value MUST exceed the
|
||||
/// cost to spend said output, and should by a notable margin (not just 2x, yet an order of
|
||||
/// magnitude).
|
||||
const DUST: u64;
|
||||
|
||||
/// Tweak keys for this network.
|
||||
|
|
Loading…
Reference in a new issue