From d0e59e41b9af969d9c73da817ef94300226f3825 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 3 Jul 2025 20:26:39 +0000 Subject: [PATCH 1/5] doc: fix broken link and stranded doccomment (The stranded doccomment was associated with commented-out code, but rustdoc was applying it to the nearest non-commented-out item. Just delete all the commented-out stuff since we're not going to reenable it in 12.x.) --- src/descriptor/mod.rs | 2 +- src/lib.rs | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index b1afc0dbd..3df15e0ad 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -648,7 +648,7 @@ impl Descriptor { /// See [`at_derivation_index`] and `[derived_descriptor`] for more documentation. /// /// [`at_derivation_index`]: Self::at_derivation_index - /// [`derived_descriptor`]: crate::DerivedDescriptor::derived_descriptor + /// [`derived_descriptor`]: crate::Descriptor::derived_descriptor /// /// # Errors /// diff --git a/src/lib.rs b/src/lib.rs index c1d576284..6f6218606 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -401,16 +401,6 @@ where T: Translator; } -/// Either a key or keyhash, but both contain Pk -// pub struct ForEach<'a, Pk: MiniscriptKey>(&'a Pk); - -// impl<'a, Pk: MiniscriptKey> ForEach<'a, Pk> { -// /// Convenience method to avoid distinguishing between keys and hashes when these are the same type -// pub fn as_key(&self) -> &'a Pk { -// self.0 -// } -// } - /// Trait describing the ability to iterate over every key pub trait ForEachKey { /// Run a predicate on every key in the descriptor, returning whether From 01bfd22cf17cb04a18b5045f66941bb31d87a61d Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 3 Jul 2025 20:30:39 +0000 Subject: [PATCH 2/5] clippy.toml: bump up large error threshold On 12.x apparently the "large error" (actually a copy of Self) returned by the plan API is a fair bit larger than it is on master, so we need to increase this threshold by a bunch. --- clippy.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy.toml b/clippy.toml index ab03a348e..b91802a81 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,3 +1,3 @@ msrv = "1.56.1" # plan API returns Self as an error type for an large-ish enum -large-error-threshold = 256 +large-error-threshold = 512 From 9efc345563947d85f963255b909fc634796fb499 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 3 Jul 2025 20:32:30 +0000 Subject: [PATCH 3/5] clippy: lifetime syntax stuff --- src/descriptor/tr.rs | 6 +++--- src/iter/mod.rs | 2 +- src/miniscript/iter.rs | 4 ++-- src/miniscript/lex.rs | 2 +- src/miniscript/mod.rs | 2 +- src/miniscript/satisfy.rs | 4 ++-- src/policy/concrete.rs | 2 +- src/policy/semantic.rs | 2 +- src/primitives/threshold.rs | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs index 9fc4d445d..faf943931 100644 --- a/src/descriptor/tr.rs +++ b/src/descriptor/tr.rs @@ -129,7 +129,7 @@ impl TapTree { /// Iterates over all miniscripts in DFS walk order compatible with the /// PSBT requirements (BIP 371). - pub fn iter(&self) -> TapTreeIter { TapTreeIter { stack: vec![(0, self)] } } + pub fn iter(&self) -> TapTreeIter<'_, Pk> { TapTreeIter { stack: vec![(0, self)] } } // Helper function to translate keys fn translate_helper(&self, t: &mut T) -> Result, TranslateErr> @@ -196,7 +196,7 @@ impl Tr { /// Iterate over all scripts in merkle tree. If there is no script path, the iterator /// yields [`None`] - pub fn iter_scripts(&self) -> TapTreeIter { + pub fn iter_scripts(&self) -> TapTreeIter<'_, Pk> { match self.tree { Some(ref t) => t.iter(), None => TapTreeIter { stack: vec![] }, @@ -565,7 +565,7 @@ impl fmt::Display for Tr { } // Helper function to parse string into miniscript tree form -fn parse_tr_tree(s: &str) -> Result { +fn parse_tr_tree(s: &str) -> Result, Error> { expression::check_valid_chars(s)?; if s.len() > 3 && &s[..3] == "tr(" && s.as_bytes()[s.len() - 1] == b')' { diff --git a/src/iter/mod.rs b/src/iter/mod.rs index e3fb12a9d..ce69277a0 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -17,7 +17,7 @@ pub use tree::{ use crate::sync::Arc; use crate::{Miniscript, MiniscriptKey, ScriptContext, Terminal}; -impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> TreeLike for &'a Miniscript { +impl TreeLike for &'_ Miniscript { fn as_node(&self) -> Tree { use Terminal::*; match self.node { diff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs index 175fbfe4a..8758ef2b0 100644 --- a/src/miniscript/iter.rs +++ b/src/miniscript/iter.rs @@ -18,12 +18,12 @@ impl Miniscript { /// Creates a new [Iter] iterator that will iterate over all [Miniscript] items within /// AST by traversing its branches. For the specific algorithm please see /// [Iter::next] function. - pub fn iter(&self) -> Iter { Iter::new(self) } + pub fn iter(&self) -> Iter<'_, Pk, Ctx> { Iter::new(self) } /// Creates a new [PkIter] iterator that will iterate over all plain public keys (and not /// key hash values) present in [Miniscript] items within AST by traversing all its branches. /// For the specific algorithm please see [PkIter::next] function. - pub fn iter_pk(&self) -> PkIter { PkIter::new(self) } + pub fn iter_pk(&self) -> PkIter<'_, Pk, Ctx> { PkIter::new(self) } /// Enumerates all child nodes of the current AST node (`self`) and returns a `Vec` referencing /// them. diff --git a/src/miniscript/lex.rs b/src/miniscript/lex.rs index 6184572dd..101be27f2 100644 --- a/src/miniscript/lex.rs +++ b/src/miniscript/lex.rs @@ -75,7 +75,7 @@ impl<'s> TokenIter<'s> { pub fn new(v: Vec>) -> TokenIter<'s> { TokenIter(v) } /// Look at the top at Iterator - pub fn peek(&self) -> Option<&'s Token> { self.0.last() } + pub fn peek(&self) -> Option<&'s Token<'_>> { self.0.last() } /// Push a value to the iterator /// This will be first value consumed by popun_ diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 6cc419823..e15c349bb 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -551,7 +551,7 @@ impl Miniscript { /// /// Returns the fragment name (right of the `:`) and a list of wrappers /// (left of the `:`). -fn split_expression_name(name: &str) -> Result<(&str, Cow), Error> { +fn split_expression_name(name: &str) -> Result<(&str, Cow<'_, str>), Error> { let mut aliased_wrap; let frag_name; let frag_wrap; diff --git a/src/miniscript/satisfy.rs b/src/miniscript/satisfy.rs index 2cdaac25c..0281d86dd 100644 --- a/src/miniscript/satisfy.rs +++ b/src/miniscript/satisfy.rs @@ -259,7 +259,7 @@ impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig! { impl Satisfier for HashMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)> } -impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &'a S { +impl> Satisfier for &'_ S { fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { (**self).lookup_ecdsa_sig(p) } @@ -319,7 +319,7 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &' fn check_after(&self, n: absolute::LockTime) -> bool { (**self).check_after(n) } } -impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &'a mut S { +impl> Satisfier for &'_ mut S { fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { (**self).lookup_ecdsa_sig(p) } diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index a07bf262a..6c4321326 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -1044,7 +1044,7 @@ fn generate_combination( ret } -impl<'a, Pk: MiniscriptKey> TreeLike for &'a Policy { +impl TreeLike for &'_ Policy { fn as_node(&self) -> Tree { use Policy::*; diff --git a/src/policy/semantic.rs b/src/policy/semantic.rs index cd7d61002..eb157fd7b 100644 --- a/src/policy/semantic.rs +++ b/src/policy/semantic.rs @@ -619,7 +619,7 @@ impl Policy { } } -impl<'a, Pk: MiniscriptKey> TreeLike for &'a Policy { +impl TreeLike for &'_ Policy { fn as_node(&self) -> Tree { use Policy::*; diff --git a/src/primitives/threshold.rs b/src/primitives/threshold.rs index daf440327..222c70966 100644 --- a/src/primitives/threshold.rs +++ b/src/primitives/threshold.rs @@ -211,7 +211,7 @@ impl Threshold { pub fn into_data(self) -> Vec { self.inner } /// Passthrough to an iterator on the underlying vector. - pub fn iter(&self) -> core::slice::Iter { self.inner.iter() } + pub fn iter(&self) -> core::slice::Iter<'_, T> { self.inner.iter() } } impl Threshold { From 22ce32a98c1fbd5270ae0ed08d6a7a4f56916788 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 3 Jul 2025 20:42:32 +0000 Subject: [PATCH 4/5] clippy: non-lifetime stuff --- src/miniscript/analyzable.rs | 14 ++++---------- src/miniscript/mod.rs | 2 +- src/policy/compiler.rs | 11 ++++------- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/miniscript/analyzable.rs b/src/miniscript/analyzable.rs index 8fe61867d..e8fa65cb7 100644 --- a/src/miniscript/analyzable.rs +++ b/src/miniscript/analyzable.rs @@ -17,11 +17,8 @@ use crate::{Miniscript, MiniscriptKey, ScriptContext, Terminal}; /// /// This allows parsing miniscripts if /// 1. It is unsafe(does not require a digital signature to spend it) -/// 2. It contains a unspendable path because of either -/// a. Resource limitations -/// b. Timelock Mixing -/// 3. The script is malleable and thereby some of satisfaction weight -/// guarantees are not satisfied. +/// 2. It contains a unspendable path because of either resource limitations or timelock mixing. +/// 3. The script is malleable and thereby some of satisfaction weight guarantees are not satisfied. /// 4. It has repeated public keys /// 5. raw pkh fragments without the pk. This could be obtained when parsing miniscript from script #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)] @@ -123,11 +120,8 @@ impl ExtParams { /// Possible reasons Miniscript guarantees can fail /// We currently mark Miniscript as Non-Analyzable if /// 1. It is unsafe(does not require a digital signature to spend it) -/// 2. It contains a unspendable path because of either -/// a. Resource limitations -/// b. Timelock Mixing -/// 3. The script is malleable and thereby some of satisfaction weight -/// guarantees are not satisfied. +/// 2. It contains a unspendable path because of either resource limitations or timelock mixing. +/// 3. The script is malleable and thereby some of satisfaction weight guarantees are not satisfied. /// 4. It has repeated publickeys #[derive(Debug, PartialEq)] pub enum AnalysisError { diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index e15c349bb..4523cad40 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -378,7 +378,7 @@ impl Miniscript { /// The type information and extra properties are implied by the AST. impl PartialOrd for Miniscript { fn partial_cmp(&self, other: &Miniscript) -> Option { - Some(self.node.cmp(&other.node)) + Some(self.cmp(other)) } } diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index d306da905..9242bc347 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -671,13 +671,10 @@ fn insert_elem( // Check whether the new element is worse than any existing element. If there // is an element which is a subtype of the current element and has better // cost, don't consider this element. - let is_worse = map - .iter() - .map(|(existing_key, existing_elem)| { - let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob); - existing_key.is_subtype(elem_key) && existing_elem_cost <= elem_cost - }) - .any(|x| x); + let is_worse = map.iter().any(|(existing_key, existing_elem)| { + let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob); + existing_key.is_subtype(elem_key) && existing_elem_cost <= elem_cost + }); if !is_worse { // If the element is not worse any element in the map, remove elements // whose subtype is the current element and have worse cost. From 2019e97ba4426f31491fc8dc5e0478383759bc6a Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 3 Jul 2025 20:42:32 +0000 Subject: [PATCH 5/5] ci: pin nightly compiler version Don't bother with the cronjob to update this. We'll just leave the nightly compiler version fixed forever on these old versions (or update it on an ad-hoc basis). --- .github/workflows/rust.yml | 29 +++++++++++++++++++++++++---- nightly-version | 1 + 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 nightly-version diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 033cc6d93..8e5d85b97 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -9,6 +9,17 @@ on: # yamllint disable-line rule:truthy name: Continuous integration jobs: + Prepare: + runs-on: ubuntu-24.04 + outputs: + nightly_version: ${{ steps.read_toolchain.outputs.nightly_version }} + steps: + - name: "Checkout repo" + uses: actions/checkout@v4 + - name: "Read nightly version" + id: read_toolchain + run: echo "nightly_version=$(cat nightly-version)" >> $GITHUB_OUTPUT + Stable: # 2 jobs, one per lock file. name: Test - stable toolchain runs-on: ubuntu-latest @@ -33,6 +44,7 @@ jobs: Nightly: # 2 jobs, one per lock file. name: Test - nightly toolchain + needs: Prepare runs-on: ubuntu-latest strategy: fail-fast: false @@ -47,7 +59,9 @@ jobs: repository: rust-bitcoin/rust-bitcoin-maintainer-tools path: maintainer-tools - name: "Select toolchain" - uses: dtolnay/rust-toolchain@nightly + uses: dtolnay/rust-toolchain@v1 + with: + toolchain: ${{ needs.Prepare.outputs.nightly_version }} - name: "Set dependencies" run: cp Cargo-${{ matrix.dep }}.lock Cargo.lock - name: "Run test script" @@ -79,6 +93,7 @@ jobs: Lint: name: Lint - nightly toolchain + needs: Prepare runs-on: ubuntu-latest strategy: fail-fast: false @@ -93,7 +108,9 @@ jobs: repository: rust-bitcoin/rust-bitcoin-maintainer-tools path: maintainer-tools - name: "Select toolchain" - uses: dtolnay/rust-toolchain@nightly + uses: dtolnay/rust-toolchain@v1 + with: + toolchain: ${{ needs.Prepare.outputs.nightly_version }} - name: "Install clippy" run: rustup component add clippy - name: "Set dependencies" @@ -125,6 +142,7 @@ jobs: Docsrs: name: Docs - nightly toolchain + needs: Prepare runs-on: ubuntu-latest strategy: fail-fast: false @@ -139,7 +157,9 @@ jobs: repository: rust-bitcoin/rust-bitcoin-maintainer-tools path: maintainer-tools - name: "Select toolchain" - uses: dtolnay/rust-toolchain@nightly + uses: dtolnay/rust-toolchain@v1 + with: + toolchain: ${{ needs.Prepare.outputs.nightly_version }} - name: "Set dependencies" run: cp Cargo-${{ matrix.dep }}.lock Cargo.lock - name: "Run test script" @@ -198,6 +218,7 @@ jobs: run: ./contrib/integration_test.sh Embedded: + needs: Prepare runs-on: ubuntu-latest steps: - name: Checkout @@ -208,7 +229,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: ${{ needs.Prepare.outputs.nightly_version }} override: true components: rust-src target: thumbv7m-none-eabi diff --git a/nightly-version b/nightly-version new file mode 100644 index 000000000..ba747383d --- /dev/null +++ b/nightly-version @@ -0,0 +1 @@ +nightly-2025-03-21