From 60e5cf1f8a4dcada6a0a93b5612a898d555193c4 Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Thu, 10 Dec 2020 14:24:30 -0800 Subject: [PATCH 1/4] [docs] Add docs to the 'policy' module --- src/descriptor/mod.rs | 1 - src/descriptor/policy.rs | 47 +++++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index cae0654a..4a82df34 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -44,7 +44,6 @@ pub use miniscript::{ pub mod checksum; mod dsl; pub mod error; -#[allow(missing_docs)] // TODO add missing docs and remove this allow pub mod policy; #[allow(missing_docs)] // TODO add missing docs and remove this allow pub mod template; diff --git a/src/descriptor/policy.rs b/src/descriptor/policy.rs index a8e22586..37b18dd2 100644 --- a/src/descriptor/policy.rs +++ b/src/descriptor/policy.rs @@ -103,44 +103,65 @@ impl PKOrF { } } -/// An item that need to be satisfied +/// An item that needs to be satisfied #[derive(Debug, Clone, Serialize)] #[serde(tag = "type", rename_all = "UPPERCASE")] pub enum SatisfiableItem { // Leaves + /// Signature for a raw public key Signature(PKOrF), + /// Signature for an extended key fingerprint SignatureKey(PKOrF), + /// SHA256 preimage hash SHA256Preimage { + /// The digest value hash: sha256::Hash, }, + /// Double SHA256 preimage hash HASH256Preimage { + /// The digest value hash: sha256d::Hash, }, + /// RIPEMD160 preimage hash RIPEMD160Preimage { + /// The digest value hash: ripemd160::Hash, }, + /// SHA256 then RIPEMD160 preimage hash HASH160Preimage { + /// The digest value hash: hash160::Hash, }, + /// Absolute timeclock timestamp AbsoluteTimelock { + /// The timestamp value value: u32, }, + /// Relative timelock locktime RelativeTimelock { + /// The timelock value value: u32, }, + /// Multi-signature public keys with threshold count + Multisig { + /// The raw public key or extended key fingerprint + keys: Vec, + /// The required threshold count + threshold: usize, + }, // Complex item + /// Threshold items with threshold count Thresh { + /// The policy items items: Vec, - threshold: usize, - }, - Multisig { - keys: Vec, + /// The required threshold count threshold: usize, }, } impl SatisfiableItem { + /// Returns whether the [`SatisfiableItem`] is a leaf item pub fn is_leaf(&self) -> bool { !matches!(self, SatisfiableItem::Thresh { @@ -149,6 +170,7 @@ impl SatisfiableItem { }) } + /// Returns a unique id for the [`SatisfiableItem`] pub fn id(&self) -> String { get_checksum(&serde_json::to_string(self).expect("Failed to serialize a SatisfiableItem")) .expect("Failed to compute a SatisfiableItem id") @@ -213,7 +235,9 @@ fn mix(vec: Vec>) -> Vec> { answer } +/// 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 pub type FoldedConditionMap = BTreeMap, HashSet>; fn serialize_folded_cond_map( @@ -279,6 +303,7 @@ pub enum Satisfaction { } impl Satisfaction { + /// Returns whether the [`Satisfaction`] is a leaf item pub fn is_leaf(&self) -> bool { match self { Satisfaction::None | Satisfaction::Complete { .. } => true, @@ -363,7 +388,7 @@ impl Satisfaction { // since the previous step can turn one item of the iterator into multiple ones, we call flatten to expand them out .flatten() // .inspect(|x| println!("flat {:?}", x)) - // try to fold all the conditions for this specific combination of indexes/options. if they are not compatibile, 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, @@ -426,8 +451,10 @@ pub struct Policy { /// An extra condition that must be satisfied but that is out of control of the user #[derive(Hash, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default, Serialize)] pub struct Condition { + /// Optional CheckSequenceVerify condition #[serde(skip_serializing_if = "Option::is_none")] pub csv: Option, + /// Optional timelock condition #[serde(skip_serializing_if = "Option::is_none")] pub timelock: Option, } @@ -459,6 +486,7 @@ impl Condition { Ok(self) } + /// Returns `true` if there are no extra conditions to verify pub fn is_null(&self) -> bool { self.csv.is_none() && self.timelock.is_none() } @@ -467,12 +495,19 @@ impl Condition { /// Errors that can happen while extracting and manipulating policies #[derive(Debug)] pub enum PolicyError { + /// Not enough items are selected to satisfy a [`SatisfiableItem::Thresh`] NotEnoughItemsSelected(String), + /// Too many items are selected to satisfy a [`SatisfiableItem::Thresh`] TooManyItemsSelected(String), + /// Index out of range for an item to satisfy a [`SatisfiableItem::Thresh`] 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 MixedTimelockUnits, + /// Incompatible conditions (not currently used) IncompatibleConditions, } From 4e771d6546b049bf554ef5f18a92a61507a2b66c Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Sun, 13 Dec 2020 20:35:59 -0800 Subject: [PATCH 2/4] [docs] Add docs to the 'template' module --- src/descriptor/template.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/descriptor/template.rs b/src/descriptor/template.rs index 9dbbf153..48609c19 100644 --- a/src/descriptor/template.rs +++ b/src/descriptor/template.rs @@ -60,6 +60,7 @@ pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks); /// } /// ``` pub trait DescriptorTemplate { + /// Build the complete descriptor fn build(self) -> Result; } From 0f2dc05c0814e9857428bd0f2168e6ee13579d3d Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Sun, 13 Dec 2020 20:36:38 -0800 Subject: [PATCH 3/4] [docs] Add docs to the 'descriptor' module --- src/descriptor/error.rs | 14 +++++++------- src/descriptor/mod.rs | 5 ++--- src/descriptor/policy.rs | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/descriptor/error.rs b/src/descriptor/error.rs index 151487da..e470fea9 100644 --- a/src/descriptor/error.rs +++ b/src/descriptor/error.rs @@ -35,9 +35,9 @@ pub enum Error { InvalidHDKeyPath, //KeyParsingError(String), - #[allow(missing_docs)] + /// Error thrown while working with [`keys`](crate::keys) Key(crate::keys::KeyError), - #[allow(missing_docs)] + /// Error while extracting and manipulating policies Policy(crate::descriptor::policy::PolicyError), //InputIndexDoesntExist, @@ -47,15 +47,15 @@ pub enum Error { InvalidDescriptorCharacter(char), //CantDeriveWithMiniscript, - #[allow(missing_docs)] + /// BIP32 error BIP32(bitcoin::util::bip32::Error), - #[allow(missing_docs)] + /// Error during base58 decoding Base58(bitcoin::util::base58::Error), - #[allow(missing_docs)] + /// Key-related error PK(bitcoin::util::key::Error), - #[allow(missing_docs)] + /// Miniscript error Miniscript(miniscript::Error), - #[allow(missing_docs)] + /// Hex decoding error Hex(bitcoin::hashes::hex::Error), } diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 4a82df34..ec00133f 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -45,7 +45,6 @@ pub mod checksum; mod dsl; pub mod error; pub mod policy; -#[allow(missing_docs)] // TODO add missing docs and remove this allow pub mod template; pub use self::checksum::get_checksum; @@ -65,9 +64,9 @@ pub type ExtendedDescriptor = Descriptor; /// [`psbt::Output`]: bitcoin::util::psbt::Output pub type HDKeyPaths = BTreeMap; -#[allow(missing_docs)] // TODO add missing docs and remove this allow /// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`] pub trait ToWalletDescriptor { + /// Convert to wallet descriptor fn to_wallet_descriptor( self, network: Network, @@ -187,9 +186,9 @@ impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap, ValidNetworks) { } } -#[allow(missing_docs)] // TODO add missing docs and remove this allow /// Trait implemented on [`Descriptor`]s to add a method to extract the spending [`policy`] pub trait ExtractPolicy { + /// Extract the spending [`policy`] fn extract_policy( &self, signers: &SignersContainer, diff --git a/src/descriptor/policy.rs b/src/descriptor/policy.rs index 37b18dd2..d14d2da4 100644 --- a/src/descriptor/policy.rs +++ b/src/descriptor/policy.rs @@ -139,7 +139,7 @@ pub enum SatisfiableItem { }, /// Relative timelock locktime RelativeTimelock { - /// The timelock value + /// The locktime value value: u32, }, /// Multi-signature public keys with threshold count From f8d3cdca9ff6d8806bf9dd1d50351b81b545c724 Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Sun, 13 Dec 2020 21:04:17 -0800 Subject: [PATCH 4/4] [docs] Add experimental warning to compact_filters and policy modules --- src/blockchain/compact_filters/mod.rs | 2 ++ src/descriptor/policy.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/blockchain/compact_filters/mod.rs b/src/blockchain/compact_filters/mod.rs index b7ee67e1..89c2f4d9 100644 --- a/src/blockchain/compact_filters/mod.rs +++ b/src/blockchain/compact_filters/mod.rs @@ -37,6 +37,8 @@ //! connecting to a single peer at a time, optionally by opening multiple connections if it's //! desirable to use multiple threads at once to sync in parallel. //! +//! This is an **EXPERIMENTAL** feature, API and other major changes are expected. +//! //! ## Example //! //! ```no_run diff --git a/src/descriptor/policy.rs b/src/descriptor/policy.rs index d14d2da4..21d93b6c 100644 --- a/src/descriptor/policy.rs +++ b/src/descriptor/policy.rs @@ -27,6 +27,8 @@ //! This module implements the logic to extract and represent the spending policies of a descriptor //! in a more human-readable format. //! +//! This is an **EXPERIMENTAL** feature, API and other major changes are expected. +//! //! ## Example //! //! ```