Skip to content

Commit 33676d1

Browse files
committed
Merge #565: policy: Do a bunch of docs fixes
1bd3070 policy: Put some love into the rustdocs (Tobin C. Harding) 062d1b8 Remove duplicate docs (Tobin C. Harding) 0e4fa34 Move semantic/abstract docs to the semantic module (Tobin C. Harding) Pull request description: Three patches, the first two simple. The third is a bunch of mixed rustdoc fixes. Just sing out if this is too painful to review. I did this while attempting to understand the module better. ACKs for top commit: apoelstra: ACK 1bd3070 Tree-SHA512: 907f8301ed37076dbdfe4672d0a0c2b2286513af2de54ee5b8744d8bb07b99f85bf70b3a9c6b53688af2e6ce964856c2fc2ad58f3dff649aeb2546ed97fd3e75
2 parents a807ea4 + 1bd3070 commit 33676d1

File tree

4 files changed

+165
-192
lines changed

4 files changed

+165
-192
lines changed

src/policy/compiler.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{policy, Miniscript, MiniscriptKey, Terminal};
2424
type PolicyCache<Pk, Ctx> =
2525
BTreeMap<(Concrete<Pk>, OrdF64, Option<OrdF64>), BTreeMap<CompilationKey, AstElemExt<Pk, Ctx>>>;
2626

27-
///Ordered f64 for comparison
27+
/// Ordered f64 for comparison.
2828
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
2929
pub(crate) struct OrdF64(pub f64);
3030

@@ -36,7 +36,7 @@ impl Ord for OrdF64 {
3636
}
3737
}
3838

39-
/// Detailed Error type for Compiler
39+
/// Detailed error type for compiler.
4040
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
4141
pub enum CompilerError {
4242
/// Compiler has non-safe input policy.

src/policy/concrete.rs

+69-106
Original file line numberDiff line numberDiff line change
@@ -35,35 +35,35 @@ use crate::{errstr, AbsLockTime, Error, ForEachKey, MiniscriptKey, Translator};
3535
#[cfg(feature = "compiler")]
3636
const MAX_COMPILATION_LEAVES: usize = 1024;
3737

38-
/// Concrete policy which corresponds directly to a Miniscript structure,
38+
/// Concrete policy which corresponds directly to a miniscript structure,
3939
/// and whose disjunctions are annotated with satisfaction probabilities
40-
/// to assist the compiler
40+
/// to assist the compiler.
4141
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4242
pub enum Policy<Pk: MiniscriptKey> {
43-
/// Unsatisfiable
43+
/// Unsatisfiable.
4444
Unsatisfiable,
45-
/// Trivially satisfiable
45+
/// Trivially satisfiable.
4646
Trivial,
47-
/// A public key which must sign to satisfy the descriptor
47+
/// A public key which must sign to satisfy the descriptor.
4848
Key(Pk),
49-
/// An absolute locktime restriction
49+
/// An absolute locktime restriction.
5050
After(AbsLockTime),
51-
/// A relative locktime restriction
51+
/// A relative locktime restriction.
5252
Older(Sequence),
53-
/// A SHA256 whose preimage must be provided to satisfy the descriptor
53+
/// A SHA256 whose preimage must be provided to satisfy the descriptor.
5454
Sha256(Pk::Sha256),
55-
/// A SHA256d whose preimage must be provided to satisfy the descriptor
55+
/// A SHA256d whose preimage must be provided to satisfy the descriptor.
5656
Hash256(Pk::Hash256),
57-
/// A RIPEMD160 whose preimage must be provided to satisfy the descriptor
57+
/// A RIPEMD160 whose preimage must be provided to satisfy the descriptor.
5858
Ripemd160(Pk::Ripemd160),
59-
/// A HASH160 whose preimage must be provided to satisfy the descriptor
59+
/// A HASH160 whose preimage must be provided to satisfy the descriptor.
6060
Hash160(Pk::Hash160),
61-
/// A list of sub-policies, all of which must be satisfied
61+
/// A list of sub-policies, all of which must be satisfied.
6262
And(Vec<Policy<Pk>>),
6363
/// A list of sub-policies, one of which must be satisfied, along with
64-
/// relative probabilities for each one
64+
/// relative probabilities for each one.
6565
Or(Vec<(usize, Policy<Pk>)>),
66-
/// A set of descriptors, satisfactions must be provided for `k` of them
66+
/// A set of descriptors, satisfactions must be provided for `k` of them.
6767
Threshold(usize, Vec<Policy<Pk>>),
6868
}
6969

@@ -183,29 +183,28 @@ impl<Pk: MiniscriptKey> From<Policy<Pk>> for PolicyArc<Pk> {
183183
}
184184
}
185185

186-
/// Detailed Error type for Policies
186+
/// Detailed error type for concrete policies.
187187
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
188188
pub enum PolicyError {
189-
/// `And` fragments only support two args
189+
/// `And` fragments only support two args.
190190
NonBinaryArgAnd,
191-
/// `Or` fragments only support two args
191+
/// `Or` fragments only support two args.
192192
NonBinaryArgOr,
193-
/// `Thresh` fragment can only have `1<=k<=n`
193+
/// `Thresh` fragment can only have `1<=k<=n`.
194194
IncorrectThresh,
195-
/// `older` or `after` fragment can only have `n = 0`
195+
/// `older` or `after` fragment can only have `n = 0`.
196196
ZeroTime,
197-
/// `after` fragment can only have ` n < 2^31`
197+
/// `after` fragment can only have `n < 2^31`.
198198
TimeTooFar,
199-
/// Semantic Policy Error: `And` `Or` fragments must take args: k > 1
199+
/// Semantic Policy Error: `And` `Or` fragments must take args: `k > 1`.
200200
InsufficientArgsforAnd,
201-
/// Semantic Policy Error: `And` `Or` fragments must take args: k > 1
201+
/// Semantic policy error: `And` `Or` fragments must take args: `k > 1`.
202202
InsufficientArgsforOr,
203-
/// Entailment max terminals exceeded
203+
/// Entailment max terminals exceeded.
204204
EntailmentMaxTerminals,
205-
/// lifting error: Cannot lift policies that have
206-
/// a combination of height and timelocks.
205+
/// Cannot lift policies that have a combination of height and timelocks.
207206
HeightTimelockCombination,
208-
/// Duplicate Public Keys
207+
/// Duplicate Public Keys.
209208
DuplicatePubKeys,
210209
}
211210

@@ -278,8 +277,8 @@ impl error::Error for PolicyError {
278277
}
279278

280279
impl<Pk: MiniscriptKey> Policy<Pk> {
281-
/// Flatten the [`Policy`] tree structure into a Vector of tuple `(leaf script, leaf probability)`
282-
/// with leaf probabilities corresponding to odds for sub-branch in the policy.
280+
/// Flattens the [`Policy`] tree structure into a vector of tuples `(leaf script, leaf probability)`
281+
/// with leaf probabilities corresponding to odds for each sub-branch in the policy.
283282
/// We calculate the probability of selecting the sub-branch at every level and calculate the
284283
/// leaf probabilities as the probability of traversing through required branches to reach the
285284
/// leaf node, i.e. multiplication of the respective probabilities.
@@ -298,7 +297,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
298297
///
299298
/// ## Constraints
300299
///
301-
/// Since this splitting might lead to exponential blow-up, we constraint the number of
300+
/// Since this splitting might lead to exponential blow-up, we constrain the number of
302301
/// leaf-nodes to [`MAX_COMPILATION_LEAVES`].
303302
#[cfg(feature = "compiler")]
304303
fn to_tapleaf_prob_vec(&self, prob: f64) -> Vec<(f64, Policy<Pk>)> {
@@ -323,7 +322,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
323322
}
324323
}
325324

326-
/// Extract the internal_key from policy tree.
325+
/// Extracts the internal_key from this policy tree.
327326
#[cfg(feature = "compiler")]
328327
fn extract_key(self, unspendable_key: Option<Pk>) -> Result<(Pk, Policy<Pk>), Error> {
329328
let mut internal_key: Option<Pk> = None;
@@ -366,13 +365,14 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
366365
}
367366
}
368367

369-
/// Compile the [`Policy`] into a [`Descriptor::Tr`].
368+
/// Compiles the [`Policy`] into a [`Descriptor::Tr`].
370369
///
371370
/// ### TapTree compilation
372371
///
373-
/// The policy tree constructed by root-level disjunctions over [`Or`][`Policy::Or`] and
374-
/// [`Thresh`][`Policy::Threshold`](1, ..) which is flattened into a vector (with respective
372+
/// The policy tree constructed by root-level disjunctions over [`Policy::Or`] and
373+
/// [`Policy::Threshold`](1, ..) which is flattened into a vector (with respective
375374
/// probabilities derived from odds) of policies.
375+
///
376376
/// For example, the policy `thresh(1,or(pk(A),pk(B)),and(or(pk(C),pk(D)),pk(E)))` gives the
377377
/// vector `[pk(A),pk(B),and(or(pk(C),pk(D)),pk(E)))]`. Each policy in the vector is compiled
378378
/// into the respective miniscripts. A Huffman Tree is created from this vector which optimizes
@@ -424,7 +424,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
424424
/// ### TapTree compilation
425425
///
426426
/// The policy tree constructed by root-level disjunctions over [`Policy::Or`] and
427-
/// [`Policy::Threshold`] (k, ..n..) which is flattened into a vector (with respective
427+
/// [`Policy::Threshold`](k, ..n..) which is flattened into a vector (with respective
428428
/// probabilities derived from odds) of policies. For example, the policy
429429
/// `thresh(1,or(pk(A),pk(B)),and(or(pk(C),pk(D)),pk(E)))` gives the vector
430430
/// `[pk(A),pk(B),and(or(pk(C),pk(D)),pk(E)))]`.
@@ -437,8 +437,6 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
437437
/// enumeration or limits exceed. For a given [`Policy`], we maintain an [ordered
438438
/// set](`BTreeSet`) of `(prob, policy)` (ordered by probability) to maintain the list of
439439
/// enumerated sub-policies whose disjunction is isomorphic to initial policy (*invariant*).
440-
///
441-
/// [`Policy`]: crate::policy::concrete::Policy
442440
#[cfg(feature = "compiler")]
443441
pub fn compile_tr_private_experimental(
444442
&self,
@@ -480,16 +478,16 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
480478
}
481479
}
482480

483-
/// Compile the [`Policy`] into desc_ctx [`Descriptor`]
481+
/// Compiles the [`Policy`] into `desc_ctx` [`Descriptor`]
484482
///
485-
/// In case of [Tr][`DescriptorCtx::Tr`], `internal_key` is used for the Taproot comilation when
483+
/// In case of [`DescriptorCtx::Tr`], `internal_key` is used for the taproot compilation when
486484
/// no public key can be inferred from the given policy.
487485
///
488486
/// # NOTE:
489487
///
490-
/// It is **not recommended** to use policy as a stable identifier for a miniscript.
491-
/// You should use the policy compiler once, and then use the miniscript output as a stable identifier.
492-
/// See the compiler document in doc/compiler.md for more details.
488+
/// It is **not recommended** to use policy as a stable identifier for a miniscript. You should
489+
/// use the policy compiler once, and then use the miniscript output as a stable identifier. See
490+
/// the compiler document in [`doc/compiler.md`] for more details.
493491
#[cfg(feature = "compiler")]
494492
pub fn compile_to_descriptor<Ctx: ScriptContext>(
495493
&self,
@@ -511,13 +509,13 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
511509
}
512510
}
513511

514-
/// Compile the descriptor into an optimized `Miniscript` representation
512+
/// Compiles the descriptor into an optimized `Miniscript` representation.
515513
///
516514
/// # NOTE:
517515
///
518-
/// It is **not recommended** to use policy as a stable identifier for a miniscript.
519-
/// You should use the policy compiler once, and then use the miniscript output as a stable identifier.
520-
/// See the compiler document in doc/compiler.md for more details.
516+
/// It is **not recommended** to use policy as a stable identifier for a miniscript. You should
517+
/// use the policy compiler once, and then use the miniscript output as a stable identifier. See
518+
/// the compiler document in doc/compiler.md for more details.
521519
#[cfg(feature = "compiler")]
522520
pub fn compile<Ctx: ScriptContext>(&self) -> Result<Miniscript<Pk, Ctx>, CompilerError> {
523521
self.is_valid()?;
@@ -531,10 +529,11 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
531529

532530
#[cfg(feature = "compiler")]
533531
impl<Pk: MiniscriptKey> PolicyArc<Pk> {
534-
/// Given a [`Policy`], return a vector of policies whose disjunction is isomorphic to the initial one.
535-
/// This function is supposed to incrementally expand i.e. represent the policy as disjunction over
536-
/// sub-policies output by it. The probability calculations are similar as
537-
/// [to_tapleaf_prob_vec][`Policy::to_tapleaf_prob_vec`]
532+
/// Returns a vector of policies whose disjunction is isomorphic to the initial one.
533+
///
534+
/// This function is supposed to incrementally expand i.e. represent the policy as
535+
/// disjunction over sub-policies output by it. The probability calculations are similar
536+
/// to [`Policy::to_tapleaf_prob_vec`].
538537
#[cfg(feature = "compiler")]
539538
fn enumerate_pol(&self, prob: f64) -> Vec<(f64, Arc<Self>)> {
540539
match self {
@@ -563,8 +562,6 @@ impl<Pk: MiniscriptKey> PolicyArc<Pk> {
563562
/// enumeration or limits exceed. For a given [`Policy`], we maintain an [ordered
564563
/// set](`BTreeSet`) of `(prob, policy)` (ordered by probability) to maintain the list of
565564
/// enumerated sub-policies whose disjunction is isomorphic to initial policy (*invariant*).
566-
///
567-
/// [`Policy`]: crate::policy::concrete::Policy
568565
#[cfg(feature = "compiler")]
569566
fn enumerate_policy_tree(self, prob: f64) -> Vec<(f64, Arc<Self>)> {
570567
let mut tapleaf_prob_vec = BTreeSet::<(Reverse<OrdF64>, Arc<Self>)>::new();
@@ -689,49 +686,9 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
689686
}
690687
}
691688

692-
/// Convert a policy using one kind of public key to another
693-
/// type of public key
694-
///
695-
/// # Example
696-
///
697-
/// ```
698-
/// use miniscript::{bitcoin::PublicKey, policy::concrete::Policy, Translator, hash256};
699-
/// use std::str::FromStr;
700-
/// use miniscript::translate_hash_fail;
701-
/// use std::collections::HashMap;
702-
/// use miniscript::bitcoin::hashes::{sha256, hash160, ripemd160};
703-
/// let alice_key = "0270cf3c71f65a3d93d285d9149fddeeb638f87a2d4d8cf16c525f71c417439777";
704-
/// let bob_key = "02f43b15c50a436f5335dbea8a64dd3b4e63e34c3b50c42598acb5f4f336b5d2fb";
705-
/// let placeholder_policy = Policy::<String>::from_str("and(pk(alice_key),pk(bob_key))").unwrap();
706-
///
707-
/// // Information to translator abstract String type keys to concrete bitcoin::PublicKey.
708-
/// // In practice, wallets would map from String key names to BIP32 keys
709-
/// struct StrPkTranslator {
710-
/// pk_map: HashMap<String, bitcoin::PublicKey>
711-
/// }
712-
///
713-
/// // If we also wanted to provide mapping of other associated types(sha256, older etc),
714-
/// // we would use the general Translator Trait.
715-
/// impl Translator<String, bitcoin::PublicKey, ()> for StrPkTranslator {
716-
/// // Provides the translation public keys P -> Q
717-
/// fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, ()> {
718-
/// self.pk_map.get(pk).copied().ok_or(()) // Dummy Err
719-
/// }
720-
///
721-
/// // Fail for hash types
722-
/// translate_hash_fail!(String, bitcoin::PublicKey, ());
723-
/// }
689+
/// Converts a policy using one kind of public key to another type of public key.
724690
///
725-
/// let mut pk_map = HashMap::new();
726-
/// pk_map.insert(String::from("alice_key"), bitcoin::PublicKey::from_str(alice_key).unwrap());
727-
/// pk_map.insert(String::from("bob_key"), bitcoin::PublicKey::from_str(bob_key).unwrap());
728-
/// let mut t = StrPkTranslator { pk_map: pk_map };
729-
///
730-
/// let real_policy = placeholder_policy.translate_pk(&mut t).unwrap();
731-
///
732-
/// let expected_policy = Policy::from_str(&format!("and(pk({}),pk({}))", alice_key, bob_key)).unwrap();
733-
/// assert_eq!(real_policy, expected_policy);
734-
/// ```
691+
/// For example usage please see [`crate::policy::semantic::Policy::translate_pk`].
735692
pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
736693
where
737694
T: Translator<Pk, Q, E>,
@@ -773,7 +730,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
773730
}
774731
}
775732

776-
/// Translate `Concrete::Key(key)` to `Concrete::Unsatisfiable` when extracting TapKey
733+
/// Translates `Concrete::Key(key)` to `Concrete::Unsatisfiable` when extracting `TapKey`.
777734
pub fn translate_unsatisfiable_pk(self, key: &Pk) -> Policy<Pk> {
778735
match self {
779736
Policy::Key(ref k) if k.clone() == *key => Policy::Unsatisfiable,
@@ -797,7 +754,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
797754
}
798755
}
799756

800-
/// Get all keys in the policy
757+
/// Gets all keys in the policy.
801758
pub fn keys(&self) -> Vec<&Pk> {
802759
match *self {
803760
Policy::Key(ref pk) => vec![pk],
@@ -814,8 +771,8 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
814771
}
815772
}
816773

817-
/// Get the number of [TapLeaf][`TapTree::Leaf`] considering exhaustive root-level [OR][`Policy::Or`]
818-
/// and [Thresh][`Policy::Threshold`] disjunctions for the TapTree.
774+
/// Gets the number of [TapLeaf](`TapTree::Leaf`)s considering exhaustive root-level [`Policy::Or`]
775+
/// and [`Policy::Threshold`] disjunctions for the `TapTree`.
819776
#[cfg(feature = "compiler")]
820777
fn num_tap_leaves(&self) -> usize {
821778
match self {
@@ -827,7 +784,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
827784
}
828785
}
829786

830-
/// Check on the number of TapLeaves
787+
/// Does checks on the number of `TapLeaf`s.
831788
#[cfg(feature = "compiler")]
832789
fn check_num_tapleaves(&self) -> Result<(), Error> {
833790
if self.num_tap_leaves() > MAX_COMPILATION_LEAVES {
@@ -836,7 +793,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
836793
Ok(())
837794
}
838795

839-
/// Check whether the policy contains duplicate public keys
796+
/// Checks whether the policy contains duplicate public keys.
840797
pub fn check_duplicate_keys(&self) -> Result<(), PolicyError> {
841798
let pks = self.keys();
842799
let pks_len = pks.len();
@@ -851,8 +808,11 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
851808

852809
/// Checks whether the given concrete policy contains a combination of
853810
/// timelocks and heightlocks.
811+
///
812+
/// # Returns
813+
///
854814
/// Returns an error if there is at least one satisfaction that contains
855-
/// a combination of hieghtlock and timelock.
815+
/// a combination of heightlock and timelock.
856816
pub fn check_timelocks(&self) -> Result<(), PolicyError> {
857817
let timelocks = self.check_timelocks_helper();
858818
if timelocks.contains_combination {
@@ -962,11 +922,14 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
962922
_ => Ok(()),
963923
}
964924
}
965-
/// This returns whether any possible compilation of the policy could be
966-
/// compiled as non-malleable and safe. Note that this returns a tuple
967-
/// (safe, non-malleable) to avoid because the non-malleability depends on
968-
/// safety and we would like to cache results.
925+
926+
/// Checks if any possible compilation of the policy could be compiled
927+
/// as non-malleable and safe.
928+
///
929+
/// # Returns
969930
///
931+
/// Returns a tuple `(safe, non-malleable)` to avoid the fact that
932+
/// non-malleability depends on safety and we would like to cache results.
970933
pub fn is_safe_nonmalleable(&self) -> (bool, bool) {
971934
match *self {
972935
Policy::Unsatisfiable | Policy::Trivial => (true, true),
@@ -1232,7 +1195,7 @@ impl_from_tree!(
12321195
}
12331196
);
12341197

1235-
/// Create a Huffman Tree from compiled [Miniscript] nodes
1198+
/// Creates a Huffman Tree from compiled [`Miniscript`] nodes.
12361199
#[cfg(feature = "compiler")]
12371200
fn with_huffman_tree<Pk: MiniscriptKey>(
12381201
ms: Vec<(OrdF64, Miniscript<Pk, Tap>)>,
@@ -1263,7 +1226,7 @@ fn with_huffman_tree<Pk: MiniscriptKey>(
12631226
Ok(node)
12641227
}
12651228

1266-
/// Enumerate a [Thresh][`Policy::Threshold`](k, ..n..) into `n` different thresh.
1229+
/// Enumerates a [`Policy::Threshold(k, ..n..)`] into `n` different thresh's.
12671230
///
12681231
/// ## Strategy
12691232
///

0 commit comments

Comments
 (0)