diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 42afd7e3..ace7e2cf 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -20,7 +20,7 @@ of the PR were done in a specific way --> * [ ] I've signed all my commits * [ ] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) -* [ ] I ran `cargo fmt` and `cargo clippy` before committing +* [ ] I ran `cargo +nightly fmt` and `cargo clippy` before committing #### New Features: diff --git a/.github/workflows/cont_integration.yml b/.github/workflows/cont_integration.yml index 7b3bb715..ef34fa32 100644 --- a/.github/workflows/cont_integration.yml +++ b/.github/workflows/cont_integration.yml @@ -111,7 +111,6 @@ jobs: run: cargo check --target wasm32-unknown-unknown --no-default-features --features miniscript/no-std,bdk_chain/hashbrown fmt: - needs: prepare name: Rust fmt runs-on: ubuntu-latest steps: @@ -122,12 +121,12 @@ jobs: - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: - toolchain: ${{ needs.prepare.outputs.rust_version }} + toolchain: nightly override: true profile: minimal components: rustfmt - name: Check fmt - run: cargo fmt --all -- --config format_code_in_doc_comments=true --check + run: cargo fmt --all --check clippy_check: needs: prepare diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..505d959b --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +comment_width = 100 +format_code_in_doc_comments = true +wrap_comments = true diff --git a/wallet/examples/compiler.rs b/wallet/examples/compiler.rs index bf43f3de..86fb6774 100644 --- a/wallet/examples/compiler.rs +++ b/wallet/examples/compiler.rs @@ -25,9 +25,9 @@ use bdk_wallet::{KeychainKind, Wallet}; /// Miniscript policy is a high level abstraction of spending conditions. Defined in the /// rust-miniscript library here https://docs.rs/miniscript/7.0.0/miniscript/policy/index.html -/// rust-miniscript provides a `compile()` function that can be used to compile any miniscript policy -/// into a descriptor. This descriptor then in turn can be used in bdk a fully functioning wallet -/// can be derived from the policy. +/// rust-miniscript provides a `compile()` function that can be used to compile any miniscript +/// policy into a descriptor. This descriptor then in turn can be used in bdk a fully functioning +/// wallet can be derived from the policy. /// /// This example demonstrates the interaction between a bdk wallet and miniscript policy. #[allow(clippy::print_stdout)] diff --git a/wallet/examples/policy.rs b/wallet/examples/policy.rs index 2b55a2eb..4ceb47b7 100644 --- a/wallet/examples/policy.rs +++ b/wallet/examples/policy.rs @@ -20,11 +20,11 @@ use bdk_wallet::signer::SignersContainer; /// /// Policy is higher abstraction representation of the wallet descriptor spending condition. /// This is useful to express complex miniscript spending conditions into more human readable form. -/// The resulting `Policy` structure can be used to derive spending conditions the wallet is capable -/// to spend from. +/// The resulting `Policy` structure can be used to derive spending conditions the wallet is +/// capable to spend from. /// -/// This example demos a Policy output for a 2of2 multisig between between 2 parties, where the wallet holds -/// one of the Extend Private key. +/// This example demos a Policy output for a 2of2 multisig between between 2 parties, where the +/// wallet holds one of the Extend Private key. #[allow(clippy::print_stdout)] fn main() -> Result<(), Box> { let secp = bitcoin::secp256k1::Secp256k1::new(); diff --git a/wallet/src/descriptor/checksum.rs b/wallet/src/descriptor/checksum.rs index 7b770910..cd2305b9 100644 --- a/wallet/src/descriptor/checksum.rs +++ b/wallet/src/descriptor/checksum.rs @@ -19,7 +19,8 @@ use alloc::string::String; use miniscript::descriptor::checksum::desc_checksum; -/// Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation +/// Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string +/// from the calculation pub fn calc_checksum(desc: &str) -> Result { if let Some(split) = desc.split_once('#') { let og_checksum = split.1; diff --git a/wallet/src/descriptor/dsl.rs b/wallet/src/descriptor/dsl.rs index caec8cdb..0bce9510 100644 --- a/wallet/src/descriptor/dsl.rs +++ b/wallet/src/descriptor/dsl.rs @@ -404,7 +404,8 @@ macro_rules! apply_modifier { /// Macro to write full descriptors with code /// /// This macro expands to a `Result` of -/// [`DescriptorTemplateOut`](super::template::DescriptorTemplateOut) and [`DescriptorError`](crate::descriptor::DescriptorError) +/// [`DescriptorTemplateOut`](super::template::DescriptorTemplateOut) and +/// [`DescriptorError`](crate::descriptor::DescriptorError) /// /// The syntax is very similar to the normal descriptor syntax, with the exception that modifiers /// cannot be grouped together. For instance, a descriptor fragment like `sdv:older(144)` has to be @@ -429,9 +430,10 @@ macro_rules! apply_modifier { /// /// ------- /// -/// 2-of-3 that becomes a 1-of-3 after a timelock has expired. Both `descriptor_a` and `descriptor_b` are equivalent: the first -/// syntax is more suitable for a fixed number of items known at compile time, while the other accepts a -/// [`Vec`] of items, which makes it more suitable for writing dynamic descriptors. +/// 2-of-3 that becomes a 1-of-3 after a timelock has expired. Both `descriptor_a` and +/// `descriptor_b` are equivalent: the first syntax is more suitable for a fixed number of items +/// known at compile time, while the other accepts a [`Vec`] of items, which makes it more suitable +/// for writing dynamic descriptors. /// /// They both produce the descriptor: `wsh(thresh(2,pk(...),s:pk(...),sndv:older(...)))` /// @@ -672,8 +674,9 @@ macro_rules! fragment_internal { /// Macro to write descriptor fragments with code /// -/// This macro will be expanded to an object of type `Result<(Miniscript, KeyMap, ValidNetworks), DescriptorError>`. It allows writing -/// fragments of larger descriptors that can be pieced together using `fragment!(thresh_vec(m, ...))`. +/// This macro will be expanded to an object of type `Result<(Miniscript, +/// KeyMap, ValidNetworks), DescriptorError>`. It allows writing fragments of larger descriptors +/// that can be pieced together using `fragment!(thresh_vec(m, ...))`. /// /// The syntax to write macro fragment is the same as documented for the [`descriptor`] macro. #[macro_export] @@ -846,11 +849,13 @@ mod test { } } - // - at least one of each "type" of operator; i.e. one modifier, one leaf_opcode, one leaf_opcode_value, etc. + // - at least one of each "type" of operator; i.e. one modifier, one leaf_opcode, one + // leaf_opcode_value, etc. // - mixing up key types that implement IntoDescriptorKey in multi() or thresh() // expected script for pk and bare manually created - // expected addresses created with `bitcoin-cli getdescriptorinfo` (for hash) and `bitcoin-cli deriveaddresses` + // expected addresses created with `bitcoin-cli getdescriptorinfo` (for hash) and `bitcoin-cli + // deriveaddresses` #[test] fn test_fixed_legacy_descriptors() { @@ -1105,7 +1110,8 @@ mod test { ); } - // - verify the valid_networks returned is correctly computed based on the keys present in the descriptor + // - verify the valid_networks returned is correctly computed based on the keys present in the + // descriptor #[test] fn test_valid_networks() { let xprv = bip32::Xpriv::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); @@ -1162,7 +1168,8 @@ mod test { assert_eq!(key_map.get(&key3).unwrap().to_string(), "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf/10/20/30/40/*"); } - // - verify the ScriptContext is correctly validated (i.e. passing a type that only impl IntoDescriptorKey to a pkh() descriptor should throw a compilation error + // - verify the ScriptContext is correctly validated (i.e. passing a type that only impl + // IntoDescriptorKey to a pkh() descriptor should throw a compilation error #[test] fn test_script_context_validation() { // this compiles @@ -1174,8 +1181,9 @@ mod test { assert_eq!(desc.to_string(), "pkh(tpubD6NzVbkrYhZ4WR7a4vY1VT3khMJMeAxVsfq9TBJyJWrNk247zCJtV7AWf6UJP7rAVsn8NNKdJi3gFyKPTmWZS9iukb91xbn2HbFSMQm2igY/0/*)#yrnz9pp2"); // as expected this does not compile due to invalid context - //let desc_key:DescriptorKey = (xprv, path.clone()).into_descriptor_key().unwrap(); - //let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap(); + //let desc_key:DescriptorKey = (xprv, + // path.clone()).into_descriptor_key().unwrap(); let (desc, _key_map, + // _valid_networks) = descriptor!(pkh(desc_key)).unwrap(); } #[test] diff --git a/wallet/src/descriptor/mod.rs b/wallet/src/descriptor/mod.rs index f5ef5957..26f5ae16 100644 --- a/wallet/src/descriptor/mod.rs +++ b/wallet/src/descriptor/mod.rs @@ -69,7 +69,8 @@ pub type HdKeyPaths = BTreeMap; /// [`psbt::Output`]: bitcoin::psbt::Output pub type TapKeyOrigins = BTreeMap, KeySource)>; -/// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`] +/// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by +/// a wallet in a specific [`Network`] pub trait IntoWalletDescriptor { /// Convert to wallet descriptor fn into_wallet_descriptor( @@ -460,10 +461,11 @@ impl DescriptorMeta for ExtendedDescriptor { // using `for_any_key` should make this stop as soon as we return `true` self.for_any_key(|key| { if let DescriptorPublicKey::XPub(xpub) = key { - // Check if the key matches one entry in our `key_origins`. If it does, `matches()` will - // return the "prefix" that matched, so we remove that prefix from the full path - // found in `key_origins` and save it in `derive_path`. We expect this to be a derivation - // path of length 1 if the key is `wildcard` and an empty path otherwise. + // Check if the key matches one entry in our `key_origins`. If it does, `matches()` + // will return the "prefix" that matched, so we remove that prefix + // from the full path found in `key_origins` and save it in + // `derive_path`. We expect this to be a derivation path of length 1 + // if the key is `wildcard` and an empty path otherwise. let root_fingerprint = xpub.root_fingerprint(secp); let derive_path = key_origins .get_key_value(&root_fingerprint) @@ -478,10 +480,11 @@ impl DescriptorMeta for ExtendedDescriptor { .cloned() .collect::(); - // `derive_path` only contains the replacement index for the wildcard, if present, or - // an empty path for fixed descriptors. To verify the key we also need the normal steps - // that come before the wildcard, so we take them directly from `xpub` and then append - // the final index + // `derive_path` only contains the replacement index for the wildcard, if + // present, or an empty path for fixed descriptors. + // To verify the key we also need the normal steps + // that come before the wildcard, so we take them directly from `xpub` and + // then append the final index if verify_key( xpub, &xpub.derivation_path.extend(derive_path.clone()), diff --git a/wallet/src/descriptor/policy.rs b/wallet/src/descriptor/policy.rs index 6fb4013f..4250ed34 100644 --- a/wallet/src/descriptor/policy.rs +++ b/wallet/src/descriptor/policy.rs @@ -237,7 +237,8 @@ fn mix(vec: Vec>) -> Vec> { /// Type for a map of sets of [`Condition`] items keyed by each set's index pub type ConditionMap = BTreeMap>; -/// Type for a map of folded sets of [`Condition`] items keyed by a vector of the combined set's indexes +/// Type for a map of folded sets of [`Condition`] items keyed by a vector of the combined set's +/// indexes pub type FoldedConditionMap = BTreeMap, HashSet>; fn serialize_folded_cond_map( @@ -363,14 +364,18 @@ impl Satisfaction { if items.len() >= *m { let mut map = BTreeMap::new(); let indexes = combinations(items, *m); - // `indexes` at this point is a Vec>, with the "n choose k" of items (m of n) + // `indexes` at this point is a Vec>, with the "n choose k" of items (m + // of n) indexes .into_iter() // .inspect(|x| println!("--- orig --- {:?}", x)) - // we map each of the combinations of elements into a tuple of ([chosen items], [conditions]). unfortunately, those items have potentially more than one - // condition (think about ORs), so we also use `mix` to expand those, i.e. [[0], [1, 2]] becomes [[0, 1], [0, 2]]. This is necessary to make sure that we + // we map each of the combinations of elements into a tuple of ([chosen items], + // [conditions]). unfortunately, those items have potentially more than one + // condition (think about ORs), so we also use `mix` to expand those, i.e. [[0], + // [1, 2]] becomes [[0, 1], [0, 2]]. This is necessary to make sure that we // consider every possible options and check whether or not they are compatible. - // since this step can turn one item of the iterator into multiple ones, we use `flat_map()` to expand them out + // since this step can turn one item of the iterator into multiple ones, we use + // `flat_map()` to expand them out .flat_map(|i_vec| { mix(i_vec .iter() @@ -386,7 +391,8 @@ impl Satisfaction { .collect::, Vec)>>() }) // .inspect(|x| println!("flat {:?}", x)) - // try to fold all the conditions for this specific combination of indexes/options. if they are not compatible, try_fold will be Err + // try to fold all the conditions for this specific combination of + // indexes/options. if they are not compatible, try_fold will be Err .map(|(key, val)| { ( key, @@ -503,15 +509,18 @@ impl Condition { /// Errors that can happen while extracting and manipulating policies #[derive(Debug, PartialEq, Eq)] pub enum PolicyError { - /// Not enough items are selected to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`] + /// Not enough items are selected to satisfy a [`SatisfiableItem::Thresh`] or a + /// [`SatisfiableItem::Multisig`] NotEnoughItemsSelected(String), - /// Index out of range for an item to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`] + /// Index out of range for an item to satisfy a [`SatisfiableItem::Thresh`] or a + /// [`SatisfiableItem::Multisig`] IndexOutOfRange(usize), /// Can not add to an item that is [`Satisfaction::None`] or [`Satisfaction::Complete`] AddOnLeaf, /// Can not add to an item that is [`Satisfaction::PartialComplete`] AddOnPartialComplete, - /// Can not merge CSV or timelock values unless both are less than or both are equal or greater than 500_000_000 + /// Can not merge CSV or timelock values unless both are less than or both are equal or greater + /// than 500_000_000 MixedTimelockUnits, /// Incompatible conditions (not currently used) IncompatibleConditions, @@ -642,8 +651,8 @@ impl Policy { /// create a transaction /// /// What this means is that for some spending policies the user should select which paths in - /// the tree it intends to satisfy while signing, because the transaction must be created differently based - /// on that. + /// the tree it intends to satisfy while signing, because the transaction must be created + /// differently based on that. pub fn requires_path(&self) -> bool { self.get_condition(&BTreeMap::new()).is_err() } @@ -1063,7 +1072,8 @@ pub enum BuildSatisfaction<'a> { /// Current blockchain height current_height: u32, /// The highest confirmation height between the inputs - /// CSV should consider different inputs, but we consider the worst condition for the tx as whole + /// CSV should consider different inputs, but we consider the worst condition for the tx as + /// whole input_max_height: u32, }, } @@ -1633,6 +1643,7 @@ mod test { ); } + #[rustfmt::skip] #[test] fn test_extract_satisfaction_timelock() { //const PSBT_POLICY_CONSIDER_TIMELOCK_NOT_EXPIRED: &str = "cHNidP8BAFMBAAAAAdld52uJFGT7Yde0YZdSVh2vL020Zm2exadH5R4GSNScAAAAAAD/////ATrcAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASvI3AAAAAAAACIAILhzvvcBzw/Zfnc9ispRK0PCahxn1F6RHXTZAmw5tqNPAQVSdmNSsmlofCEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42Zsusk3whAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIrJNShyIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAAA"; diff --git a/wallet/src/descriptor/template.rs b/wallet/src/descriptor/template.rs index ee9ec9ae..6a8ad686 100644 --- a/wallet/src/descriptor/template.rs +++ b/wallet/src/descriptor/template.rs @@ -25,7 +25,8 @@ use crate::keys::{DerivableKey, IntoDescriptorKey, ValidNetworks}; use crate::wallet::utils::SecpCtx; use crate::{descriptor, KeychainKind}; -/// Type alias for the return type of [`DescriptorTemplate`], [`descriptor!`](crate::descriptor!) and others +/// Type alias for the return type of [`DescriptorTemplate`], [`descriptor!`](crate::descriptor!) +/// and others pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks); /// Trait for descriptor templates that can be built into a full descriptor @@ -210,7 +211,8 @@ impl> DescriptorTemplate for P2TR { /// BIP44 template. Expands to `pkh(key/44'/{0,1}'/0'/{0,1}/*)` /// -/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`). +/// Since there are hardened derivation steps, this template requires a private derivable key +/// (generally a `xprv`/`tprv`). /// /// See [`Bip44Public`] for a template that can work with a `xpub`/`tpub`. /// @@ -242,7 +244,8 @@ impl> DescriptorTemplate for Bip44 { /// BIP44 public template. Expands to `pkh(key/{0,1}/*)` /// -/// This assumes that the key used has already been derived with `m/44'/0'/0'` for Mainnet or `m/44'/1'/0'` for Testnet. +/// This assumes that the key used has already been derived with `m/44'/0'/0'` for Mainnet or +/// `m/44'/1'/0'` for Testnet. /// /// This template requires the parent fingerprint to populate correctly the metadata of PSBTs. /// @@ -284,7 +287,8 @@ impl> DescriptorTemplate for Bip44Public { /// BIP49 template. Expands to `sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))` /// -/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`). +/// Since there are hardened derivation steps, this template requires a private derivable key +/// (generally a `xprv`/`tprv`). /// /// See [`Bip49Public`] for a template that can work with a `xpub`/`tpub`. /// @@ -319,7 +323,8 @@ impl> DescriptorTemplate for Bip49 { /// BIP49 public template. Expands to `sh(wpkh(key/{0,1}/*))` /// -/// This assumes that the key used has already been derived with `m/49'/0'/0'` for Mainnet or `m/49'/1'/0'` for Testnet. +/// This assumes that the key used has already been derived with `m/49'/0'/0'` for Mainnet or +/// `m/49'/1'/0'` for Testnet. /// /// This template requires the parent fingerprint to populate correctly the metadata of PSBTs. /// @@ -361,7 +366,8 @@ impl> DescriptorTemplate for Bip49Public { /// BIP84 template. Expands to `wpkh(key/84'/{0,1}'/0'/{0,1}/*)` /// -/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`). +/// Since there are hardened derivation steps, this template requires a private derivable key +/// (generally a `xprv`/`tprv`). /// /// See [`Bip84Public`] for a template that can work with a `xpub`/`tpub`. /// @@ -396,7 +402,8 @@ impl> DescriptorTemplate for Bip84 { /// BIP84 public template. Expands to `wpkh(key/{0,1}/*)` /// -/// This assumes that the key used has already been derived with `m/84'/0'/0'` for Mainnet or `m/84'/1'/0'` for Testnet. +/// This assumes that the key used has already been derived with `m/84'/0'/0'` for Mainnet or +/// `m/84'/1'/0'` for Testnet. /// /// This template requires the parent fingerprint to populate correctly the metadata of PSBTs. /// @@ -438,7 +445,8 @@ impl> DescriptorTemplate for Bip84Public { /// BIP86 template. Expands to `tr(key/86'/{0,1}'/0'/{0,1}/*)` /// -/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`). +/// Since there are hardened derivation steps, this template requires a private derivable key +/// (generally a `xprv`/`tprv`). /// /// See [`Bip86Public`] for a template that can work with a `xpub`/`tpub`. /// @@ -473,7 +481,8 @@ impl> DescriptorTemplate for Bip86 { /// BIP86 public template. Expands to `tr(key/{0,1}/*)` /// -/// This assumes that the key used has already been derived with `m/86'/0'/0'` for Mainnet or `m/86'/1'/0'` for Testnet. +/// This assumes that the key used has already been derived with `m/86'/0'/0'` for Mainnet or +/// `m/86'/1'/0'` for Testnet. /// /// This template requires the parent fingerprint to populate correctly the metadata of PSBTs. /// diff --git a/wallet/src/keys/mod.rs b/wallet/src/keys/mod.rs index eac37496..a91401be 100644 --- a/wallet/src/keys/mod.rs +++ b/wallet/src/keys/mod.rs @@ -105,9 +105,10 @@ impl DescriptorKey { } } - // This method is used internally by `bdk_wallet::fragment!` and `bdk_wallet::descriptor!`. It has to be - // public because it is effectively called by external crates once the macros are expanded, - // but since it is not meant to be part of the public api we hide it from the docs. + // This method is used internally by `bdk_wallet::fragment!` and `bdk_wallet::descriptor!`. It + // has to be public because it is effectively called by external crates once the macros are + // expanded, but since it is not meant to be part of the public api we hide it from the + // docs. #[doc(hidden)] pub fn extract( self, @@ -281,8 +282,8 @@ impl ExtScriptContext for Ctx { /// } /// ``` /// -/// Key type that can only work within [`miniscript::Segwitv0`] context. Only the specialized version -/// of the trait is implemented. +/// Key type that can only work within [`miniscript::Segwitv0`] context. Only the specialized +/// version of the trait is implemented. /// /// This example deliberately fails to compile, to demonstrate how the compiler can catch when keys /// are misused. In this case, the "segwit-only" key is used to build a `pkh()` descriptor, which @@ -662,7 +663,8 @@ pub trait GeneratableKey: Sized { /// Trait that allows generating a key with the default options /// -/// This trait is automatically implemented if the [`GeneratableKey::Options`] implements [`Default`]. +/// This trait is automatically implemented if the [`GeneratableKey::Options`] implements +/// [`Default`]. pub trait GeneratableDefaultOptions: GeneratableKey where Ctx: ScriptContext, diff --git a/wallet/src/psbt/mod.rs b/wallet/src/psbt/mod.rs index 9b3aea84..5f05b7b8 100644 --- a/wallet/src/psbt/mod.rs +++ b/wallet/src/psbt/mod.rs @@ -21,7 +21,8 @@ use bitcoin::TxOut; /// Trait to add functions to extract utxos and calculate fees. pub trait PsbtUtils { - /// Get the `TxOut` for the specified input index, if it doesn't exist in the PSBT `None` is returned. + /// Get the `TxOut` for the specified input index, if it doesn't exist in the PSBT `None` is + /// returned. fn get_utxo_for(&self, input_index: usize) -> Option; /// The total transaction fee amount, sum of input amounts minus sum of output amounts, in sats. diff --git a/wallet/src/types.rs b/wallet/src/types.rs index 54ddfa26..76d8871c 100644 --- a/wallet/src/types.rs +++ b/wallet/src/types.rs @@ -69,7 +69,8 @@ pub struct LocalOutput { #[derive(Debug, Clone, PartialEq, Eq)] pub struct WeightedUtxo { /// The weight of the witness data and `scriptSig` expressed in [weight units]. This is used to - /// properly maintain the feerate when adding this input to a transaction during coin selection. + /// properly maintain the feerate when adding this input to a transaction during coin + /// selection. /// /// [weight units]: https://en.bitcoin.it/wiki/Weight_units pub satisfaction_weight: Weight, diff --git a/wallet/src/wallet/changeset.rs b/wallet/src/wallet/changeset.rs index 571173ee..ebfdb9fb 100644 --- a/wallet/src/wallet/changeset.rs +++ b/wallet/src/wallet/changeset.rs @@ -14,23 +14,23 @@ type IndexedTxGraphChangeSet = /// The change set is responsible for transmiting data between the persistent storage layer and the /// core library components. Specifically, it serves two primary functions: /// -/// 1) Recording incremental changes to the in-memory representation that need to be persisted -/// to disk +/// 1) Recording incremental changes to the in-memory representation that need to be persisted to +/// disk /// 2) Applying aggregate changes from the persistence layer to the in-memory representation at -/// startup +/// startup /// /// ## Contract /// /// The change set maintains and enforces the following properties: /// /// * Change sets must implement [`Serialize`] and [`Deserialize`] to meet the definition from -/// above. +/// above. /// * Change sets must implement [`Default`] as a way of instantiating new empty objects. /// * Change sets must implement [`Merge`] so that many instances can be aggregated into a single -/// instance. +/// instance. /// * A change set is composed of a number of individual "sub-change sets" that adhere to the same -/// rules as above. This is for increased modularity and portability. For example the core -/// modules each have their own change set (`tx_graph`, `local_chain`, etc). +/// rules as above. This is for increased modularity and portability. For example the core modules +/// each have their own change set (`tx_graph`, `local_chain`, etc). /// /// ## Members and required fields /// diff --git a/wallet/src/wallet/coin_selection.rs b/wallet/src/wallet/coin_selection.rs index e5654fb4..352d9438 100644 --- a/wallet/src/wallet/coin_selection.rs +++ b/wallet/src/wallet/coin_selection.rs @@ -204,14 +204,15 @@ pub trait CoinSelectionAlgorithm: core::fmt::Debug { /// Perform the coin selection /// /// - `required_utxos`: the utxos that must be spent regardless of `target_amount` with their - /// weight cost + /// weight cost /// - `optional_utxos`: the remaining available utxos to satisfy `target_amount` with their - /// weight cost + /// weight cost /// - `fee_rate`: fee rate to use - /// - `target_amount`: the outgoing amount and the fees already accumulated from adding - /// outputs and transaction’s header. + /// - `target_amount`: the outgoing amount and the fees already accumulated from adding outputs + /// and transaction’s header. /// - `drain_script`: the script to use in case of change - /// - `rand`: random number generated used by some coin selection algorithms such as [`SingleRandomDraw`] + /// - `rand`: random number generated used by some coin selection algorithms such as + /// [`SingleRandomDraw`] fn coin_select( &self, required_utxos: Vec, @@ -254,10 +255,11 @@ impl CoinSelectionAlgorithm for LargestFirstCoinSelection { } } -/// OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the selected coins next +/// OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the +/// selected coins next /// -/// This coin selection algorithm sorts the available UTXOs by blockheight and then picks them starting -/// from the oldest ones until the required amount is reached. +/// This coin selection algorithm sorts the available UTXOs by blockheight and then picks them +/// starting from the oldest ones until the required amount is reached. #[derive(Debug, Default, Clone, Copy)] pub struct OldestFirstCoinSelection; @@ -407,8 +409,8 @@ pub struct BranchAndBoundCoinSelection { /// Error returned by branch and bound coin selection. #[derive(Debug)] enum BnbError { - /// Branch and bound coin selection tries to avoid needing a change by finding the right inputs for - /// the desired outputs plus fee, if there is not such combination this error is thrown + /// Branch and bound coin selection tries to avoid needing a change by finding the right inputs + /// for the desired outputs plus fee, if there is not such combination this error is thrown NoExactMatch, /// Branch and bound coin selection possible attempts with sufficiently big UTXO set could grow /// exponentially, thus a limit is set, and when hit, this error is thrown @@ -608,15 +610,17 @@ impl BranchAndBoundCoinSelection { // Backtracking, moving backwards if backtrack { - // Walk backwards to find the last included UTXO that still needs to have its omission branch traversed. + // Walk backwards to find the last included UTXO that still needs to have its + // omission branch traversed. while let Some(false) = current_selection.last() { current_selection.pop(); curr_available_value += optional_utxos[current_selection.len()].effective_value; } if current_selection.last_mut().is_none() { - // We have walked back to the first utxo and no branch is untraversed. All solutions searched - // If best selection is empty, then there's no exact match + // We have walked back to the first utxo and no branch is untraversed. All + // solutions searched If best selection is empty, then + // there's no exact match if best_selection.is_empty() { return Err(BnbError::NoExactMatch); } diff --git a/wallet/src/wallet/mod.rs b/wallet/src/wallet/mod.rs index 277df8c0..34b6d8fb 100644 --- a/wallet/src/wallet/mod.rs +++ b/wallet/src/wallet/mod.rs @@ -84,8 +84,8 @@ pub use utils::IsDust; /// A Bitcoin wallet /// -/// The `Wallet` acts as a way of coherently interfacing with output descriptors and related transactions. -/// Its main components are: +/// The `Wallet` acts as a way of coherently interfacing with output descriptors and related +/// transactions. Its main components are: /// /// 1. output *descriptors* from which it can derive addresses. /// 2. [`signer`]s that can contribute signatures to addresses instantiated from the descriptors. @@ -735,7 +735,8 @@ impl Wallet { /// derivation index that hasn't been used in a transaction. /// /// This will attempt to reveal a new address if all previously revealed addresses have - /// been used, in which case the returned address will be the same as calling [`Wallet::reveal_next_address`]. + /// been used, in which case the returned address will be the same as calling + /// [`Wallet::reveal_next_address`]. /// /// **WARNING**: To avoid address reuse you must persist the changes resulting from one or more /// calls to this method before closing the wallet. See [`Wallet::reveal_next_address`]. @@ -914,7 +915,8 @@ impl Wallet { self.stage.merge(additions.into()); } - /// Calculates the fee of a given transaction. Returns [`Amount::ZERO`] if `tx` is a coinbase transaction. + /// Calculates the fee of a given transaction. Returns [`Amount::ZERO`] if `tx` is a coinbase + /// transaction. /// /// To calculate the fee for a [`Transaction`] with inputs not owned by this wallet you must /// manually insert the TxOut(s) into the tx graph using the [`insert_txout`] function. @@ -947,8 +949,8 @@ impl Wallet { /// Calculate the [`FeeRate`] for a given transaction. /// - /// To calculate the fee rate for a [`Transaction`] with inputs not owned by this wallet you must - /// manually insert the TxOut(s) into the tx graph using the [`insert_txout`] function. + /// To calculate the fee rate for a [`Transaction`] with inputs not owned by this wallet you + /// must manually insert the TxOut(s) into the tx graph using the [`insert_txout`] function. /// /// Note `tx` does not have to be in the graph for this to work. /// @@ -1117,8 +1119,8 @@ impl Wallet { txs } - /// Return the balance, separated into available, trusted-pending, untrusted-pending and immature - /// values. + /// Return the balance, separated into available, trusted-pending, untrusted-pending and + /// immature values. pub fn balance(&self) -> Balance { self.indexed_graph.graph().balance( &self.chain, @@ -1195,7 +1197,8 @@ impl Wallet { /// Start building a transaction. /// - /// This returns a blank [`TxBuilder`] from which you can specify the parameters for the transaction. + /// This returns a blank [`TxBuilder`] from which you can specify the parameters for the + /// transaction. /// /// ## Example /// @@ -1251,8 +1254,8 @@ impl Wallet { }) .transpose()?; - // The policy allows spending external outputs, but it requires a policy path that hasn't been - // provided + // The policy allows spending external outputs, but it requires a policy path that hasn't + // been provided if params.change_policy != tx_builder::ChangeSpendPolicy::OnlyChange && external_policy.requires_path() && params.external_policy_path.is_none() @@ -1327,7 +1330,8 @@ impl Wallet { match requirements.timelock { // No requirement, just use the fee_sniping_height None => fee_sniping_height, - // There's a block-based requirement, but the value is lower than the fee_sniping_height + // There's a block-based requirement, but the value is lower than the + // fee_sniping_height Some(value @ absolute::LockTime::Blocks(_)) if value < fee_sniping_height => { fee_sniping_height } @@ -1745,7 +1749,8 @@ impl Wallet { } /// Sign a transaction with all the wallet's signers, in the order specified by every signer's - /// [`SignerOrdering`]. This function returns the `Result` type with an encapsulated `bool` that has the value true if the PSBT was finalized, or false otherwise. + /// [`SignerOrdering`]. This function returns the `Result` type with an encapsulated `bool` that + /// has the value true if the PSBT was finalized, or false otherwise. /// /// The [`SignOptions`] can be used to tweak the behavior of the software signers, and the way /// the transaction is finalized at the end. Note that it can't be guaranteed that *every* @@ -1777,8 +1782,8 @@ impl Wallet { self.update_psbt_with_descriptor(psbt) .map_err(SignerError::MiniscriptPsbt)?; - // If we aren't allowed to use `witness_utxo`, ensure that every input (except p2tr and finalized ones) - // has the `non_witness_utxo` + // If we aren't allowed to use `witness_utxo`, ensure that every input (except p2tr and + // finalized ones) has the `non_witness_utxo` if !sign_options.trust_witness_utxo && psbt .inputs @@ -1904,8 +1909,8 @@ impl Wallet { // - Try to derive the descriptor by looking at the txout. If it's in our database, we // know exactly which `keychain` to use, and which derivation index it is - // - If that fails, try to derive it by looking at the psbt input: the complete logic - // is in `src/descriptor/mod.rs`, but it will basically look at `bip32_derivation`, + // - If that fails, try to derive it by looking at the psbt input: the complete logic is + // in `src/descriptor/mod.rs`, but it will basically look at `bip32_derivation`, // `redeem_script` and `witness_script` to determine the right derivation // - If that also fails, it will try it on the internal descriptor, if present let desc = psbt @@ -1968,13 +1973,14 @@ impl Wallet { &self.secp } - /// The derivation index of this wallet. It will return `None` if it has not derived any addresses. - /// Otherwise, it will return the index of the highest address it has derived. + /// The derivation index of this wallet. It will return `None` if it has not derived any + /// addresses. Otherwise, it will return the index of the highest address it has derived. pub fn derivation_index(&self, keychain: KeychainKind) -> Option { self.indexed_graph.index.last_revealed_index(keychain) } - /// The index of the next address that you would get if you were to ask the wallet for a new address + /// The index of the next address that you would get if you were to ask the wallet for a new + /// address pub fn next_derivation_index(&self, keychain: KeychainKind) -> u32 { self.indexed_graph .index @@ -2031,10 +2037,11 @@ impl Wallet { .is_mature(current_height) .then(|| new_local_utxo(k, i, full_txo)) }) - // only process UTxOs not selected manually, they will be considered later in the chain - // NOTE: this avoid UTxOs in both required and optional list + // only process UTxOs not selected manually, they will be considered later in the + // chain NOTE: this avoid UTxOs in both required and optional list .filter(|may_spend| !params.utxos.contains_key(&may_spend.outpoint)) - // only add to optional UTxOs those which satisfy the change policy if we reuse change + // only add to optional UTxOs those which satisfy the change policy if we reuse + // change .filter(|local_output| { self.keychains().count() == 1 || params.change_policy.is_satisfied_by(local_output) diff --git a/wallet/src/wallet/persisted.rs b/wallet/src/wallet/persisted.rs index 71236989..2144d7f0 100644 --- a/wallet/src/wallet/persisted.rs +++ b/wallet/src/wallet/persisted.rs @@ -59,9 +59,10 @@ type FutureResult<'a, T, E> = Pin> + Send + /// For a blocking version, use [`WalletPersister`]. /// /// Associated functions of this trait should not be called directly, and the trait is designed so -/// that associated functions are hard to find (since they are not methods!). [`AsyncWalletPersister`] is -/// used by [`PersistedWallet`] (a light wrapper around [`Wallet`]) which enforces some level of -/// safety. Refer to [`PersistedWallet`] for more about the safety checks. +/// that associated functions are hard to find (since they are not methods!). +/// [`AsyncWalletPersister`] is used by [`PersistedWallet`] (a light wrapper around [`Wallet`]) +/// which enforces some level of safety. Refer to [`PersistedWallet`] for more about the safety +/// checks. pub trait AsyncWalletPersister { /// Error type of the persister. type Error; @@ -112,11 +113,11 @@ pub trait AsyncWalletPersister { /// /// * Ensure the persister is initialized before data is persisted. /// * Ensure there were no previously persisted wallet data before creating a fresh wallet and -/// persisting it. +/// persisting it. /// * Only clear the staged changes of [`Wallet`] after persisting succeeds. /// * Ensure the wallet is persisted to the same `P` type as when created/loaded. Note that this is -/// not completely fool-proof as you can have multiple instances of the same `P` type that are -/// connected to different databases. +/// not completely fool-proof as you can have multiple instances of the same `P` type that are +/// connected to different databases. #[derive(Debug)] pub struct PersistedWallet

{ inner: Wallet, diff --git a/wallet/src/wallet/signer.rs b/wallet/src/wallet/signer.rs index f9a1b741..2af6b966 100644 --- a/wallet/src/wallet/signer.rs +++ b/wallet/src/wallet/signer.rs @@ -240,8 +240,8 @@ impl Deref for SignerWrapper { pub trait SignerCommon: fmt::Debug + Send + Sync { /// Return the [`SignerId`] for this signer /// - /// The [`SignerId`] can be used to lookup a signer in the [`Wallet`](crate::Wallet)'s signers map or to - /// compare two signers. + /// The [`SignerId`] can be used to lookup a signer in the [`Wallet`](crate::Wallet)'s signers + /// map or to compare two signers. fn id(&self, secp: &SecpCtx) -> SignerId; /// Return the secret key for the signer @@ -256,9 +256,9 @@ pub trait SignerCommon: fmt::Debug + Send + Sync { /// PSBT Input signer /// -/// This trait can be implemented to provide custom signers to the wallet. If the signer supports signing -/// individual inputs, this trait should be implemented and BDK will provide automatically an implementation -/// for [`TransactionSigner`]. +/// This trait can be implemented to provide custom signers to the wallet. If the signer supports +/// signing individual inputs, this trait should be implemented and BDK will provide automatically +/// an implementation for [`TransactionSigner`]. pub trait InputSigner: SignerCommon { /// Sign a single psbt input fn sign_input( @@ -272,8 +272,8 @@ pub trait InputSigner: SignerCommon { /// PSBT signer /// -/// This trait can be implemented when the signer can't sign inputs individually, but signs the whole transaction -/// at once. +/// This trait can be implemented when the signer can't sign inputs individually, but signs the +/// whole transaction at once. pub trait TransactionSigner: SignerCommon { /// Sign all the inputs of the psbt fn sign_transaction( @@ -766,8 +766,8 @@ pub struct SignOptions { /// a transaction /// /// The wallet will only "use" a timelock to satisfy the spending policy of an input if the - /// timelock height has already been reached. This option allows overriding the "current height" to let the - /// wallet use timelocks in the future to spend a coin. + /// timelock height has already been reached. This option allows overriding the "current + /// height" to let the wallet use timelocks in the future to spend a coin. pub assume_height: Option, /// Whether the signer should use the `sighash_type` set in the PSBT when signing, no matter diff --git a/wallet/src/wallet/tx_builder.rs b/wallet/src/wallet/tx_builder.rs index 7d693761..4c350fbf 100644 --- a/wallet/src/wallet/tx_builder.rs +++ b/wallet/src/wallet/tx_builder.rs @@ -100,7 +100,8 @@ use crate::{KeychainKind, LocalOutput, Utxo, WeightedUtxo}; /// ``` /// /// At the moment [`coin_selection`] is an exception to the rule as it consumes `self`. -/// This means it is usually best to call [`coin_selection`] on the return value of `build_tx` before assigning it. +/// This means it is usually best to call [`coin_selection`] on the return value of `build_tx` +/// before assigning it. /// /// For further examples see [this module](super::tx_builder)'s documentation; /// @@ -202,16 +203,17 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// /// An example of when the policy path is needed is the following descriptor: /// `wsh(thresh(2,pk(A),sj:and_v(v:pk(B),n:older(6)),snj:and_v(v:pk(C),after(630000))))`, - /// derived from the miniscript policy `thresh(2,pk(A),and(pk(B),older(6)),and(pk(C),after(630000)))`. - /// It declares three descriptor fragments, and at the top level it uses `thresh()` to - /// ensure that at least two of them are satisfied. The individual fragments are: + /// derived from the miniscript policy + /// `thresh(2,pk(A),and(pk(B),older(6)),and(pk(C),after(630000)))`. It declares three + /// descriptor fragments, and at the top level it uses `thresh()` to ensure that at least + /// two of them are satisfied. The individual fragments are: /// /// 1. `pk(A)` /// 2. `and(pk(B),older(6))` /// 3. `and(pk(C),after(630000))` /// - /// When those conditions are combined in pairs, it's clear that the transaction needs to be created - /// differently depending on how the user intends to satisfy the policy afterwards: + /// When those conditions are combined in pairs, it's clear that the transaction needs to be + /// created differently depending on how the user intends to satisfy the policy afterwards: /// /// * If fragments `1` and `2` are used, the transaction will need to use a specific /// `n_sequence` in order to spend an `OP_CSV` branch. @@ -269,7 +271,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// Add the list of outpoints to the internal list of UTXOs that **must** be spent. /// - /// If an error occurs while adding any of the UTXOs then none of them are added and the error is returned. + /// If an error occurs while adding any of the UTXOs then none of them are added and the error + /// is returned. /// /// These have priority over the "unspendable" utxos, meaning that if a utxo is present both in /// the "utxos" and the "unspendable" list, it will be spent. @@ -321,7 +324,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// /// 1. `outpoint`: To add it to the raw transaction. /// 2. `psbt_input`: To know the value. - /// 3. `satisfaction_weight`: To know how much weight/vbytes the input will add to the transaction for fee calculation. + /// 3. `satisfaction_weight`: To know how much weight/vbytes the input will add to the + /// transaction for fee calculation. /// /// There are several security concerns about adding foreign UTXOs that application /// developers should consider. First, how do you know the value of the input is correct? If a @@ -343,9 +347,9 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// /// This is an **EXPERIMENTAL** feature, API and other major changes are expected. /// - /// In order to use [`Wallet::calculate_fee`] or [`Wallet::calculate_fee_rate`] for a transaction - /// created with foreign UTXO(s) you must manually insert the corresponding TxOut(s) into the tx - /// graph using the [`Wallet::insert_txout`] function. + /// In order to use [`Wallet::calculate_fee`] or [`Wallet::calculate_fee_rate`] for a + /// transaction created with foreign UTXO(s) you must manually insert the corresponding + /// TxOut(s) into the tx graph using the [`Wallet::insert_txout`] function. /// /// # Errors /// @@ -375,7 +379,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { ) } - /// Same as [add_foreign_utxo](TxBuilder::add_foreign_utxo) but allows to set the nSequence value. + /// Same as [add_foreign_utxo](TxBuilder::add_foreign_utxo) but allows to set the nSequence + /// value. pub fn add_foreign_utxo_with_sequence( &mut self, outpoint: OutPoint, @@ -513,8 +518,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { self } - /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::psbt::Input::witness_utxo) field when spending from - /// SegWit descriptors. + /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::psbt::Input::witness_utxo) field + /// when spending from SegWit descriptors. /// /// This reduces the size of the PSBT, but some signers might reject them due to the lack of /// the `non_witness_utxo`. @@ -542,7 +547,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { self } - /// Spend all the available inputs. This respects filters like [`TxBuilder::unspendable`] and the change policy. + /// Spend all the available inputs. This respects filters like [`TxBuilder::unspendable`] and + /// the change policy. pub fn drain_wallet(&mut self) -> &mut Self { self.params.drain_wallet = true; self @@ -552,7 +558,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// /// Overrides the [`CoinSelectionAlgorithm`]. /// - /// Note that this function consumes the builder and returns it so it is usually best to put this as the first call on the builder. + /// Note that this function consumes the builder and returns it so it is usually best to put + /// this as the first call on the builder. pub fn coin_selection(self, coin_selection: P) -> TxBuilder<'a, P> { TxBuilder { wallet: self.wallet, @@ -573,12 +580,12 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// Set the current blockchain height. /// /// This will be used to: - /// 1. Set the nLockTime for preventing fee sniping. - /// **Note**: This will be ignored if you manually specify a nlocktime using [`TxBuilder::nlocktime`]. - /// 2. Decide whether coinbase outputs are mature or not. If the coinbase outputs are not - /// mature at spending height, which is `current_height` + 1, we ignore them in the coin - /// selection. If you want to create a transaction that spends immature coinbase inputs, - /// manually add them using [`TxBuilder::add_utxos`]. + /// 1. Set the nLockTime for preventing fee sniping. **Note**: This will be ignored if you + /// manually specify a nlocktime using [`TxBuilder::nlocktime`]. + /// 2. Decide whether coinbase outputs are mature or not. If the coinbase outputs are not mature + /// at spending height, which is `current_height` + 1, we ignore them in the coin selection. + /// If you want to create a transaction that spends immature coinbase inputs, manually add + /// them using [`TxBuilder::add_utxos`]. /// /// In both cases, if you don't provide a current height, we use the last sync height. pub fn current_height(&mut self, height: u32) -> &mut Self { @@ -589,7 +596,8 @@ impl<'a, Cs> TxBuilder<'a, Cs> { /// Set whether or not the dust limit is checked. /// - /// **Note**: by avoiding a dust limit check you may end up with a transaction that is non-standard. + /// **Note**: by avoiding a dust limit check you may end up with a transaction that is + /// non-standard. pub fn allow_dust(&mut self, allow_dust: bool) -> &mut Self { self.params.allow_dust = allow_dust; self diff --git a/wallet/tests/wallet.rs b/wallet/tests/wallet.rs index e7fe88d1..fc6bf165 100644 --- a/wallet/tests/wallet.rs +++ b/wallet/tests/wallet.rs @@ -37,11 +37,10 @@ fn parse_descriptor(s: &str) -> (Descriptor, KeyMap) { } // The satisfaction size of a P2WPKH is 112 WU = -// 1 (elements in witness) + 1 (OP_PUSH) + 33 (pk) + 1 (OP_PUSH) + 72 (signature + sighash) + 1*4 (script len) -// On the witness itself, we have to push once for the pk (33WU) and once for signature + sighash (72WU), for -// a total of 105 WU. -// Here, we push just once for simplicity, so we have to add an extra byte for the missing -// OP_PUSH. +// 1 (elements in witness) + 1 (OP_PUSH) + 33 (pk) + 1 (OP_PUSH) + 72 (signature + sighash) + 1*4 +// (script len) On the witness itself, we have to push once for the pk (33WU) and once for signature +// + sighash (72WU), for a total of 105 WU. Here, we push just once for simplicity, so we have to +// add an extra byte for the missing OP_PUSH. const P2WPKH_FAKE_WITNESS_SIZE: usize = 106; const DB_MAGIC: &[u8] = &[0x21, 0x24, 0x48]; @@ -377,8 +376,8 @@ fn test_get_funded_wallet_balance() { let (wallet, _) = get_funded_wallet_wpkh(); // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 - // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 - // sats are the transaction fee. + // to a foreign address and one returning 50_000 back to the wallet as change. The remaining + // 1000 sats are the transaction fee. assert_eq!(wallet.balance().confirmed, Amount::from_sat(50_000)); } @@ -396,8 +395,8 @@ fn test_get_funded_wallet_sent_and_received() { let (sent, received) = wallet.sent_and_received(&tx); // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 - // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 - // sats are the transaction fee. + // to a foreign address and one returning 50_000 back to the wallet as change. The remaining + // 1000 sats are the transaction fee. assert_eq!(sent.to_sat(), 76_000); assert_eq!(received.to_sat(), 50_000); } @@ -410,8 +409,8 @@ fn test_get_funded_wallet_tx_fees() { let tx_fee = wallet.calculate_fee(&tx).expect("transaction fee"); // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 - // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 - // sats are the transaction fee. + // to a foreign address and one returning 50_000 back to the wallet as change. The remaining + // 1000 sats are the transaction fee. assert_eq!(tx_fee, Amount::from_sat(1000)) } @@ -425,8 +424,8 @@ fn test_get_funded_wallet_tx_fee_rate() { .expect("transaction fee rate"); // The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000 - // to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000 - // sats are the transaction fee. + // to a foreign address and one returning 50_000 back to the wallet as change. The remaining + // 1000 sats are the transaction fee. // tx weight = 452 wu, as vbytes = (452 + 3) / 4 = 113 // fee_rate (sats per kwu) = fee / weight = 1000sat / 0.452kwu = 2212 @@ -3877,8 +3876,8 @@ fn test_spend_coinbase() { // to be included in block h + [100 = COINBASE_MATURITY] or higher. // Tx elibible to be included in the next block will be accepted in the mempool, used in block // templates and relayed on the network. - // Miners may include such tx in a block when their chaintip is at h + [99 = COINBASE_MATURITY - 1]. - // This means these coins are available for selection at height h + 99. + // Miners may include such tx in a block when their chaintip is at h + [99 = COINBASE_MATURITY - + // 1]. This means these coins are available for selection at height h + 99. // // By https://bitcoin.stackexchange.com/a/119017 let not_yet_mature_time = confirmation_height + COINBASE_MATURITY - 2; @@ -4095,9 +4094,10 @@ fn test_taproot_load_descriptor_duplicated_keys() { ); } -/// In dev mode this test panics, but in release mode, or if the `debug_panic` in `TxOutIndex::replenish_inner_index` -/// is commented out, there is no panic and the balance is calculated correctly. See issue [#1483] -/// and PR [#1486] for discussion on mixing non-wildcard and wildcard descriptors. +/// In dev mode this test panics, but in release mode, or if the `debug_panic` in +/// `TxOutIndex::replenish_inner_index` is commented out, there is no panic and the balance is +/// calculated correctly. See issue [#1483] and PR [#1486] for discussion on mixing non-wildcard and +/// wildcard descriptors. /// /// [#1483]: https://github.com/bitcoindevkit/bdk/issues/1483 /// [#1486]: https://github.com/bitcoindevkit/bdk/pull/1486 @@ -4134,7 +4134,8 @@ fn test_keychains_with_overlapping_spks() { } #[test] -/// The wallet should re-use previously allocated change addresses when the tx using them is cancelled +/// The wallet should re-use previously allocated change addresses when the tx using them is +/// cancelled fn test_tx_cancellation() { macro_rules! new_tx { ($wallet:expr) => {{