From 2b777485fa1ee34a3d347acde9fcaaf5fbbf8e53 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Mon, 5 Apr 2021 14:58:36 +0200 Subject: [PATCH 1/3] policy: introduce p2p constants from the reference implementation This introduces some constants defined by Bitcoin Core which as a consequence define some network rules in a new 'policy' module. Only some were picked, which are very unlikely to change. Nonetheless a Warning has been put in the module documentation. Script-level constants are left into rust-miniscript where they are already defined (src/miniscript/limits.rs). --- src/blockdata/constants.rs | 3 ++- src/lib.rs | 1 + src/policy/mod.rs | 54 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/policy/mod.rs diff --git a/src/blockdata/constants.rs b/src/blockdata/constants.rs index a7108d53..8458b95b 100644 --- a/src/blockdata/constants.rs +++ b/src/blockdata/constants.rs @@ -46,7 +46,8 @@ pub const MAX_BLOCK_WEIGHT: u32 = 4_000_000; pub const MIN_TRANSACTION_WEIGHT: u32 = 4 * 60; /// The factor that non-witness serialization data is multiplied by during weight calculation pub const WITNESS_SCALE_FACTOR: usize = 4; - +/// The maximum allowed number of signature check operations in a block +pub const MAX_BLOCK_SIGOPS_COST: i64 = 80_000; /// In Bitcoind this is insanely described as ~((u256)0 >> 32) pub fn max_target(_: Network) -> Uint256 { diff --git a/src/lib.rs b/src/lib.rs index 26bf991e..71395090 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,6 +68,7 @@ pub mod blockdata; pub mod util; pub mod consensus; pub mod hash_types; +pub mod policy; pub use hash_types::*; pub use blockdata::block::Block; diff --git a/src/policy/mod.rs b/src/policy/mod.rs new file mode 100644 index 00000000..e6cdc26e --- /dev/null +++ b/src/policy/mod.rs @@ -0,0 +1,54 @@ +// Rust Bitcoin Library +// Written in 2014 by +// Andrew Poelstra +// +// To the extent possible under law, the author(s) have dedicated all +// copyright and related and neighboring rights to this software to +// the public domain worldwide. This software is distributed without +// any warranty. +// +// You should have received a copy of the CC0 Public Domain Dedication +// along with this software. +// If not, see . +// + +//! Policy +//! +//! This module exposes some constants and functions used in the reference implementation and which +//! as a consequence defines some network rules. +//! +//! # *Warning* +//! While the constants present in this module are very unlikely to change, they do not define +//! Bitcoin. As such they must not be relied upon as if they were consensus rules. +//! +//! These values were taken from bitcoind v0.21.1 (194b9b8792d9b0798fdb570b79fa51f1d1f5ebaf). + +use super::blockdata::constants::MAX_BLOCK_SIGOPS_COST; + +/// Maximum weight of a transaction for it to be relayed by most nodes on the network +pub const MAX_STANDARD_TX_WEIGHT: u32 = 400_000; + +/// Minimum non-witness size for a standard transaction (1 segwit input + 1 P2WPKH output = 82 bytes) +pub const MIN_STANDARD_TX_NONWITNESS_SIZE: u32 = 82; + +/// Maximum number of sigops in a standard tx. +pub const MAX_STANDARD_TX_SIGOPS_COST: u32 = MAX_BLOCK_SIGOPS_COST as u32 / 5; + +/// The minimum incremental *feerate* (despite the name), in sats per virtual kilobyte for RBF. +pub const DEFAULT_INCREMENTAL_RELAY_FEE: u32 = 1_000; + +/// The number of bytes equivalent per signature operation. Affects transaction relay through the +/// virtual size computation. +pub const DEFAULT_BYTES_PER_SIGOP: u32 = 20; + +/// The minimum feerate, in sats per kilo-virtualbyte, for defining dust. An output is considered +/// dust if spending it under this feerate would cost more in fee. +pub const DUST_RELAY_TX_FEE: u32 = 3_000; + +/// Minimum feerate, in sats per virtual kilobyte, for a transaction to be relayed by most nodes on +/// the network. +pub const DEFAULT_MIN_RELAY_TX_FEE: u32 = 1_000; + +/// Default number of hours for an unconfirmed transaction to expire in most of the network nodes' +/// mempools. +pub const DEFAULT_MEMPOOL_EXPIRY: u32 = 336; From 2e9d62a9c7ea7b992bd21585b386ddad9ff94d55 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 12 May 2021 21:10:18 +0200 Subject: [PATCH 2/3] blockdata/script: use policy's constant in dust computation Signed-off-by: Antoine Poinsot --- src/blockdata/script.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/blockdata/script.rs b/src/blockdata/script.rs index 42ceb6b6..8d7aa83f 100644 --- a/src/blockdata/script.rs +++ b/src/blockdata/script.rs @@ -33,6 +33,7 @@ use hash_types::{PubkeyHash, WPubkeyHash, ScriptHash, WScriptHash}; use blockdata::opcodes; use consensus::{encode, Decodable, Encodable}; use hashes::{Hash, hex}; +use policy::DUST_RELAY_TX_FEE; #[cfg(feature="bitcoinconsensus")] use bitcoinconsensus; #[cfg(feature="bitcoinconsensus")] use std::convert; #[cfg(feature="bitcoinconsensus")] use OutPoint; @@ -412,7 +413,7 @@ impl Script { // This must never be lower than Bitcoin Core's GetDustThreshold() (as of v0.21) as it may // otherwise allow users to create transactions which likely can never be // broadcasted/confirmed. - 3 * // The default dust relay fee is 3000 satoshi/kB (ie 3 sat/vByte) + DUST_RELAY_TX_FEE as u64 / 1000 * // The default dust relay fee is 3000 satoshi/kB (ie 3 sat/vByte) if self.is_op_return() { 0 } else if self.is_witness_program() { From 7345aa60d9486dd4dffd8aa9e4d7fbbd52057a55 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 12 May 2021 21:33:19 +0200 Subject: [PATCH 3/3] policy: add a function to get the virtual transaction size It's very useful to Bitcoin applications, and especially "L2" ones, to effectively compute feerates. Currently (and this is very unlikely to change) bitcoind nodes compute the virtual size as a rounded-up division of the size in witness units by 4, with a penalty for transactions that are essentially >5% full of sigops. Signed-off-by: Antoine Poinsot --- src/policy/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/policy/mod.rs b/src/policy/mod.rs index e6cdc26e..02efa58b 100644 --- a/src/policy/mod.rs +++ b/src/policy/mod.rs @@ -23,7 +23,8 @@ //! //! These values were taken from bitcoind v0.21.1 (194b9b8792d9b0798fdb570b79fa51f1d1f5ebaf). -use super::blockdata::constants::MAX_BLOCK_SIGOPS_COST; +use super::blockdata::constants::{MAX_BLOCK_SIGOPS_COST, WITNESS_SCALE_FACTOR}; +use std::cmp; /// Maximum weight of a transaction for it to be relayed by most nodes on the network pub const MAX_STANDARD_TX_WEIGHT: u32 = 400_000; @@ -52,3 +53,9 @@ pub const DEFAULT_MIN_RELAY_TX_FEE: u32 = 1_000; /// Default number of hours for an unconfirmed transaction to expire in most of the network nodes' /// mempools. pub const DEFAULT_MEMPOOL_EXPIRY: u32 = 336; + +/// The virtual transaction size, as computed by default by bitcoind node. +pub fn get_virtual_tx_size(weight: i64, n_sigops: i64) -> i64 { + (cmp::max(weight, n_sigops * DEFAULT_BYTES_PER_SIGOP as i64) + WITNESS_SCALE_FACTOR as i64 - 1) + / WITNESS_SCALE_FACTOR as i64 +}