Merge bitcoindevkit/bdk#1448: bump(deps): upgrade rust bitcoin
to 0.32.0
, miniscript
to 0.12.0
and others
11200810d048abb8deb3c7961ca93c68011d41fd chore(wallet): rm dup code (志宇) 2a4564097bd70905ed9fa21b92cdf074a72f878e deps(bdk): bump `bitcoin` to `0.32.0`, miniscript to `12.0.0` (Leonardo Lima) Pull request description: fixes #1422 <!-- You can erase any parts of this template not applicable to your Pull Request. --> ### Description This PR focuses on upgrading the `rust-bitcoin` and `miniscript` versions, to `0.32.0` and `0.12.0`, respectively. It also bumps the versions of other BDK ecosystem crates that also rely on both `rust-bitcoin` and `miniscript`, being: - electrum-client https://github.com/bitcoindevkit/rust-electrum-client/pull/133 - esplora-client https://github.com/bitcoindevkit/rust-esplora-client/pull/85 - hwi https://github.com/bitcoindevkit/rust-hwi/pull/99 <ins>I structured the PR in multiple commits, with closed scope, being one for each BDK crate being upgraded, and one for each kind of fix and upgrade required, it seems like a lot of commits (**that should be squashed before merging**), but I think it'll make it easier during review phase.</ins> In summary I can already mention some of the main changes: - using `compute_txid()` instead of deprecated `txid()` - using `minimal_non_dust()` instead of `dust_value()` - using the renamed `signature` and `sighash_type` fields - using proper `sighash::P2wpkhError`, `sighash::TaprootError` instead of older `sighash::Error` - conversion from `Network` to new expected `NetworkKind` #1465 - conversion from the new `Weight` type to current expected `usize` #1466 - using `.into()` to convert from AbsLockTime and `RelLockTime` to `absolute::LockTime` and `relative::LockTime` - using Message::from_digest() instead of relying on deprecated `ThirtyTwoByteHash` trait. - updating the miniscript policy and dsl to proper expect and handle new `Threshold` type, instead of the previous two parameters. <!-- Describe the purpose of this PR, what's being adding and/or fixed --> ### Notes to the reviewers <ins>Again, I structured the PR in multiple commits, with closed scope, being one for each BDK crate being upgraded, and one for each kind of fix and upgrade required, it seems like a lot of commits (**that should be squashed before merging**), but I think it'll make it easier during review phase.</ins> It should definitely be carefully reviewed, especially the last commits for the wallet crate scope, the ones with the semantic `fix(wallet)`. I would also appreciate if @tcharding reviewed it, as he gave a try in the past (#1400 ), and I relied on some of it for the policy part of it, other rust-bitcoin maintainers reviews are a definitely welcome 😁 <!-- In this section you can include notes directed to the reviewers, like explaining why some parts of the PR were done in a specific way --> ### Changelog notice > // TODO(@oleonardolima): Do another pass and double check the changes - Use `compute_txid()` instead of deprecated `txid()` - Use `minimal_non_dust()` instead of `dust_value()` - Use `signature` and `sighash_type` fields, instead of previous `sig` and `hash_type` - Use `sighash::P2wpkhError`, and `sighash::TaprootError` instead of older `sighash::Error` - Converts from `Network` to `NetworkKind`, where expected - Converts from `Weight` type to current used `usize` - Use `.into()` to convert from `AbsLockTime` and `RelLockTime` to `absolute::LockTime` and `relative::LockTime` - Remove use of deprecated `ThirtyTwoByteHash` trait, use `Message::from_digest()` - Update the miniscript policy and dsl macros to proper expect and handle new `Threshold` type, instead of the previous two parameters. <!-- Notice the release manager should include in the release tag message changelog --> <!-- See https://keepachangelog.com/en/1.0.0/ for examples --> ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [ ] I've added tests for the new feature * [ ] I've added docs for the new feature #### Bugfixes: * [ ] This pull request breaks the existing API * [ ] I've added tests to reproduce the issue which are now passing * [ ] I'm linking the issue being fixed by this PR ACKs for top commit: notmandatory: ACK 11200810d048abb8deb3c7961ca93c68011d41fd Tree-SHA512: ba1ab64603b41014d3f0866d846167f77d31959ca6f1d9c3181d5e543964f5d772e05651d63935ba7bbffeba41a66868d27de4c32129739b9ca50f3bbaf9f2a1
This commit is contained in:
commit
3b040a7ee6
10
.github/workflows/cont_integration.yml
vendored
10
.github/workflows/cont_integration.yml
vendored
@ -58,15 +58,15 @@ jobs:
|
||||
- name: Check bdk_chain
|
||||
working-directory: ./crates/chain
|
||||
# TODO "--target thumbv6m-none-eabi" should work but currently does not
|
||||
run: cargo check --no-default-features --features bitcoin/no-std,miniscript/no-std,hashbrown
|
||||
run: cargo check --no-default-features --features miniscript/no-std,hashbrown
|
||||
- name: Check bdk wallet
|
||||
working-directory: ./crates/wallet
|
||||
# TODO "--target thumbv6m-none-eabi" should work but currently does not
|
||||
run: cargo check --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown
|
||||
run: cargo check --no-default-features --features miniscript/no-std,bdk_chain/hashbrown
|
||||
- name: Check esplora
|
||||
working-directory: ./crates/esplora
|
||||
# TODO "--target thumbv6m-none-eabi" should work but currently does not
|
||||
run: cargo check --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown
|
||||
run: cargo check --no-default-features --features miniscript/no-std,bdk_chain/hashbrown
|
||||
|
||||
check-wasm:
|
||||
name: Check WASM
|
||||
@ -92,10 +92,10 @@ jobs:
|
||||
uses: Swatinem/rust-cache@v2.2.1
|
||||
- name: Check bdk wallet
|
||||
working-directory: ./crates/wallet
|
||||
run: cargo check --target wasm32-unknown-unknown --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown,dev-getrandom-wasm
|
||||
run: cargo check --target wasm32-unknown-unknown --no-default-features --features miniscript/no-std,bdk_chain/hashbrown,dev-getrandom-wasm
|
||||
- name: Check esplora
|
||||
working-directory: ./crates/esplora
|
||||
run: cargo check --target wasm32-unknown-unknown --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown,async
|
||||
run: cargo check --target wasm32-unknown-unknown --no-default-features --features miniscript/no-std,bdk_chain/hashbrown,async
|
||||
|
||||
fmt:
|
||||
name: Rust fmt
|
||||
|
@ -13,9 +13,8 @@ readme = "README.md"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
# For no-std, remember to enable the bitcoin/no-std feature
|
||||
bitcoin = { version = "0.31", default-features = false }
|
||||
bitcoincore-rpc = { version = "0.18" }
|
||||
bitcoin = { version = "0.32.0", default-features = false }
|
||||
bitcoincore-rpc = { version = "0.19.0" }
|
||||
bdk_chain = { path = "../chain", version = "0.15", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -197,7 +197,7 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
|
||||
.graph
|
||||
.txs
|
||||
.iter()
|
||||
.map(|tx| tx.txid())
|
||||
.map(|tx| tx.compute_txid())
|
||||
.collect::<BTreeSet<Txid>>(),
|
||||
exp_txids,
|
||||
"changeset should have the 3 mempool transactions",
|
||||
@ -440,7 +440,7 @@ fn mempool_avoids_re_emission() -> anyhow::Result<()> {
|
||||
let emitted_txids = emitter
|
||||
.mempool()?
|
||||
.into_iter()
|
||||
.map(|(tx, _)| tx.txid())
|
||||
.map(|(tx, _)| tx.compute_txid())
|
||||
.collect::<BTreeSet<Txid>>();
|
||||
assert_eq!(
|
||||
emitted_txids, exp_txids,
|
||||
@ -509,7 +509,7 @@ fn mempool_re_emits_if_tx_introduction_height_not_reached() -> anyhow::Result<()
|
||||
emitter
|
||||
.mempool()?
|
||||
.into_iter()
|
||||
.map(|(tx, _)| tx.txid())
|
||||
.map(|(tx, _)| tx.compute_txid())
|
||||
.collect::<BTreeSet<_>>(),
|
||||
tx_introductions.iter().map(|&(_, txid)| txid).collect(),
|
||||
"first mempool emission should include all txs",
|
||||
@ -518,7 +518,7 @@ fn mempool_re_emits_if_tx_introduction_height_not_reached() -> anyhow::Result<()
|
||||
emitter
|
||||
.mempool()?
|
||||
.into_iter()
|
||||
.map(|(tx, _)| tx.txid())
|
||||
.map(|(tx, _)| tx.compute_txid())
|
||||
.collect::<BTreeSet<_>>(),
|
||||
tx_introductions.iter().map(|&(_, txid)| txid).collect(),
|
||||
"second mempool emission should still include all txs",
|
||||
@ -538,7 +538,7 @@ fn mempool_re_emits_if_tx_introduction_height_not_reached() -> anyhow::Result<()
|
||||
let emitted_txids = emitter
|
||||
.mempool()?
|
||||
.into_iter()
|
||||
.map(|(tx, _)| tx.txid())
|
||||
.map(|(tx, _)| tx.compute_txid())
|
||||
.collect::<BTreeSet<_>>();
|
||||
assert_eq!(
|
||||
emitted_txids, exp_txids,
|
||||
@ -596,7 +596,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
|
||||
emitter
|
||||
.mempool()?
|
||||
.into_iter()
|
||||
.map(|(tx, _)| tx.txid())
|
||||
.map(|(tx, _)| tx.compute_txid())
|
||||
.collect::<BTreeSet<_>>(),
|
||||
env.rpc_client()
|
||||
.get_raw_mempool()?
|
||||
@ -633,7 +633,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
|
||||
let mempool = emitter
|
||||
.mempool()?
|
||||
.into_iter()
|
||||
.map(|(tx, _)| tx.txid())
|
||||
.map(|(tx, _)| tx.compute_txid())
|
||||
.collect::<BTreeSet<_>>();
|
||||
let exp_mempool = tx_introductions
|
||||
.iter()
|
||||
@ -648,7 +648,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
|
||||
let mempool = emitter
|
||||
.mempool()?
|
||||
.into_iter()
|
||||
.map(|(tx, _)| tx.txid())
|
||||
.map(|(tx, _)| tx.compute_txid())
|
||||
.collect::<BTreeSet<_>>();
|
||||
let exp_mempool = tx_introductions
|
||||
.iter()
|
||||
|
@ -13,13 +13,12 @@ readme = "README.md"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
# For no-std, remember to enable the bitcoin/no-std feature
|
||||
bitcoin = { version = "0.31.0", default-features = false }
|
||||
bitcoin = { version = "0.32.0", default-features = false }
|
||||
serde_crate = { package = "serde", version = "1", optional = true, features = ["derive", "rc"] }
|
||||
|
||||
# Use hashbrown as a feature flag to have HashSet and HashMap from it.
|
||||
hashbrown = { version = "0.9.1", optional = true, features = ["serde"] }
|
||||
miniscript = { version = "11.0.0", optional = true, default-features = false }
|
||||
miniscript = { version = "12.0.0", optional = true, default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8"
|
||||
|
@ -31,7 +31,7 @@ impl DescriptorExt for Descriptor<DescriptorPublicKey> {
|
||||
self.at_derivation_index(0)
|
||||
.expect("descriptor can't have hardened derivation")
|
||||
.script_pubkey()
|
||||
.dust_value()
|
||||
.minimal_non_dust()
|
||||
.to_sat()
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ where
|
||||
let mut graph = tx_graph::ChangeSet::default();
|
||||
for (tx, anchors) in txs {
|
||||
if self.index.is_tx_relevant(tx) {
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
graph.append(self.graph.insert_tx(tx.clone()));
|
||||
for anchor in anchors {
|
||||
graph.append(self.graph.insert_anchor(txid, anchor));
|
||||
@ -234,7 +234,7 @@ where
|
||||
for (tx_pos, tx) in block.txdata.iter().enumerate() {
|
||||
changeset.indexer.append(self.index.index_tx(tx));
|
||||
if self.index.is_tx_relevant(tx) {
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
let anchor = A::from_block_position(block, block_id, tx_pos);
|
||||
changeset.graph.append(self.graph.insert_tx(tx.clone()));
|
||||
changeset
|
||||
@ -261,7 +261,7 @@ where
|
||||
let mut graph = tx_graph::ChangeSet::default();
|
||||
for (tx_pos, tx) in block.txdata.iter().enumerate() {
|
||||
let anchor = A::from_block_position(&block, block_id, tx_pos);
|
||||
graph.append(self.graph.insert_anchor(tx.txid(), anchor));
|
||||
graph.append(self.graph.insert_anchor(tx.compute_txid(), anchor));
|
||||
graph.append(self.graph.insert_tx(tx.clone()));
|
||||
}
|
||||
let indexer = self.index_tx_graph_changeset(&graph);
|
||||
|
@ -251,7 +251,7 @@ impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
|
||||
fn index_tx(&mut self, tx: &bitcoin::Transaction) -> Self::ChangeSet {
|
||||
let mut changeset = super::ChangeSet::<K>::default();
|
||||
for (op, txout) in tx.output.iter().enumerate() {
|
||||
changeset.append(self.index_txout(OutPoint::new(tx.txid(), op as u32), txout));
|
||||
changeset.append(self.index_txout(OutPoint::new(tx.compute_txid(), op as u32), txout));
|
||||
}
|
||||
changeset
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ impl<I: Clone + Ord> SpkTxOutIndex<I> {
|
||||
/// 2. When getting new data from the chain, you usually scan it before incorporating it into your chain state.
|
||||
pub fn scan(&mut self, tx: &Transaction) -> BTreeSet<I> {
|
||||
let mut scanned_indices = BTreeSet::new();
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
for (i, txout) in tx.output.iter().enumerate() {
|
||||
let op = OutPoint::new(txid, i as u32);
|
||||
if let Some(spk_i) = self.scan_txout(op, txout) {
|
||||
|
@ -43,7 +43,7 @@ use alloc::vec::Vec;
|
||||
/// let mut graph_a = TxGraph::<BlockId>::default();
|
||||
/// let _ = graph_a.insert_tx(tx.clone());
|
||||
/// graph_a.insert_anchor(
|
||||
/// tx.txid(),
|
||||
/// tx.compute_txid(),
|
||||
/// BlockId {
|
||||
/// height: 1,
|
||||
/// hash: Hash::hash("first".as_bytes()),
|
||||
@ -58,7 +58,7 @@ use alloc::vec::Vec;
|
||||
/// let mut graph_b = TxGraph::<ConfirmationHeightAnchor>::default();
|
||||
/// let _ = graph_b.insert_tx(tx.clone());
|
||||
/// graph_b.insert_anchor(
|
||||
/// tx.txid(),
|
||||
/// tx.compute_txid(),
|
||||
/// ConfirmationHeightAnchor {
|
||||
/// anchor_block: BlockId {
|
||||
/// height: 2,
|
||||
@ -76,7 +76,7 @@ use alloc::vec::Vec;
|
||||
/// let mut graph_c = TxGraph::<ConfirmationTimeHeightAnchor>::default();
|
||||
/// let _ = graph_c.insert_tx(tx.clone());
|
||||
/// graph_c.insert_anchor(
|
||||
/// tx.txid(),
|
||||
/// tx.compute_txid(),
|
||||
/// ConfirmationTimeHeightAnchor {
|
||||
/// anchor_block: BlockId {
|
||||
/// height: 2,
|
||||
|
@ -445,7 +445,7 @@ impl<A> TxGraph<A> {
|
||||
&'g self,
|
||||
tx: &'g Transaction,
|
||||
) -> impl Iterator<Item = (usize, Txid)> + '_ {
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
tx.input
|
||||
.iter()
|
||||
.enumerate()
|
||||
@ -516,9 +516,10 @@ impl<A: Clone + Ord> TxGraph<A> {
|
||||
pub fn insert_tx<T: Into<Arc<Transaction>>>(&mut self, tx: T) -> ChangeSet<A> {
|
||||
let tx = tx.into();
|
||||
let mut update = Self::default();
|
||||
update
|
||||
.txs
|
||||
.insert(tx.txid(), (TxNodeInternal::Whole(tx), BTreeSet::new(), 0));
|
||||
update.txs.insert(
|
||||
tx.compute_txid(),
|
||||
(TxNodeInternal::Whole(tx), BTreeSet::new(), 0),
|
||||
);
|
||||
self.apply_update(update)
|
||||
}
|
||||
|
||||
@ -533,7 +534,7 @@ impl<A: Clone + Ord> TxGraph<A> {
|
||||
) -> ChangeSet<A> {
|
||||
let mut changeset = ChangeSet::<A>::default();
|
||||
for (tx, seen_at) in txs {
|
||||
changeset.append(self.insert_seen_at(tx.txid(), seen_at));
|
||||
changeset.append(self.insert_seen_at(tx.compute_txid(), seen_at));
|
||||
changeset.append(self.insert_tx(tx));
|
||||
}
|
||||
changeset
|
||||
@ -642,7 +643,7 @@ impl<A: Clone + Ord> TxGraph<A> {
|
||||
pub fn apply_changeset(&mut self, changeset: ChangeSet<A>) {
|
||||
for wrapped_tx in changeset.txs {
|
||||
let tx = wrapped_tx.as_ref();
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
|
||||
tx.input
|
||||
.iter()
|
||||
@ -660,7 +661,7 @@ impl<A: Clone + Ord> TxGraph<A> {
|
||||
}
|
||||
Some((TxNodeInternal::Whole(tx), _, _)) => {
|
||||
debug_assert_eq!(
|
||||
tx.as_ref().txid(),
|
||||
tx.as_ref().compute_txid(),
|
||||
txid,
|
||||
"tx should produce txid that is same as key"
|
||||
);
|
||||
@ -825,7 +826,7 @@ impl<A: Anchor> TxGraph<A> {
|
||||
// resulting array will also include `tx`
|
||||
let unconfirmed_ancestor_txs =
|
||||
TxAncestors::new_include_root(self, tx.clone(), |_, ancestor_tx: Arc<Transaction>| {
|
||||
let tx_node = self.get_tx_node(ancestor_tx.as_ref().txid())?;
|
||||
let tx_node = self.get_tx_node(ancestor_tx.as_ref().compute_txid())?;
|
||||
// We're filtering the ancestors to keep only the unconfirmed ones (= no anchors in
|
||||
// the best chain)
|
||||
for block in tx_node.anchors {
|
||||
@ -843,7 +844,7 @@ impl<A: Anchor> TxGraph<A> {
|
||||
// and our unconf descendants' last seen.
|
||||
let unconfirmed_descendants_txs = TxDescendants::new_include_root(
|
||||
self,
|
||||
tx.as_ref().txid(),
|
||||
tx.as_ref().compute_txid(),
|
||||
|_, descendant_txid: Txid| {
|
||||
let tx_node = self.get_tx_node(descendant_txid)?;
|
||||
// We're filtering the ancestors to keep only the unconfirmed ones (= no anchors in
|
||||
@ -884,7 +885,7 @@ impl<A: Anchor> TxGraph<A> {
|
||||
return Ok(None);
|
||||
}
|
||||
if conflicting_tx.last_seen_unconfirmed == *last_seen
|
||||
&& conflicting_tx.as_ref().txid() > tx.as_ref().txid()
|
||||
&& conflicting_tx.as_ref().compute_txid() > tx.as_ref().compute_txid()
|
||||
{
|
||||
// Conflicting tx has priority if txid of conflicting tx > txid of original tx
|
||||
return Ok(None);
|
||||
@ -1255,7 +1256,7 @@ impl<A> ChangeSet<A> {
|
||||
tx.output
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(move |(vout, txout)| (OutPoint::new(tx.txid(), vout as _), txout))
|
||||
.map(move |(vout, txout)| (OutPoint::new(tx.compute_txid(), vout as _), txout))
|
||||
})
|
||||
.chain(self.txouts.iter().map(|(op, txout)| (*op, txout)))
|
||||
}
|
||||
|
@ -125,14 +125,14 @@ pub fn init_graph<'a, A: Anchor + Clone + 'a>(
|
||||
.collect(),
|
||||
};
|
||||
|
||||
tx_ids.insert(tx_tmp.tx_name, tx.txid());
|
||||
tx_ids.insert(tx_tmp.tx_name, tx.compute_txid());
|
||||
spk_index.scan(&tx);
|
||||
let _ = graph.insert_tx(tx.clone());
|
||||
for anchor in tx_tmp.anchors.iter() {
|
||||
let _ = graph.insert_anchor(tx.txid(), anchor.clone());
|
||||
let _ = graph.insert_anchor(tx.compute_txid(), anchor.clone());
|
||||
}
|
||||
if let Some(seen_at) = tx_tmp.last_seen {
|
||||
let _ = graph.insert_seen_at(tx.txid(), seen_at);
|
||||
let _ = graph.insert_seen_at(tx.compute_txid(), seen_at);
|
||||
}
|
||||
}
|
||||
(graph, spk_index, tx_ids)
|
||||
|
@ -52,7 +52,7 @@ fn insert_relevant_txs() {
|
||||
|
||||
let tx_b = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_a.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_a.compute_txid(), 0),
|
||||
..Default::default()
|
||||
}],
|
||||
..common::new_tx(1)
|
||||
@ -60,7 +60,7 @@ fn insert_relevant_txs() {
|
||||
|
||||
let tx_c = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_a.txid(), 1),
|
||||
previous_output: OutPoint::new(tx_a.compute_txid(), 1),
|
||||
..Default::default()
|
||||
}],
|
||||
..common::new_tx(2)
|
||||
@ -196,7 +196,7 @@ fn test_list_owned_txouts() {
|
||||
// tx3 spends tx2 and gives a change back in trusted keychain. Confirmed at Block 2.
|
||||
let tx3 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx2.txid(), 0),
|
||||
previous_output: OutPoint::new(tx2.compute_txid(), 0),
|
||||
..Default::default()
|
||||
}],
|
||||
output: vec![TxOut {
|
||||
@ -340,16 +340,22 @@ fn test_list_owned_txouts() {
|
||||
balance,
|
||||
) = fetch(0, &graph);
|
||||
|
||||
assert_eq!(confirmed_txouts_txid, [tx1.txid()].into());
|
||||
assert_eq!(confirmed_txouts_txid, [tx1.compute_txid()].into());
|
||||
assert_eq!(
|
||||
unconfirmed_txouts_txid,
|
||||
[tx2.txid(), tx3.txid(), tx4.txid(), tx5.txid()].into()
|
||||
[
|
||||
tx2.compute_txid(),
|
||||
tx3.compute_txid(),
|
||||
tx4.compute_txid(),
|
||||
tx5.compute_txid()
|
||||
]
|
||||
.into()
|
||||
);
|
||||
|
||||
assert_eq!(confirmed_utxos_txid, [tx1.txid()].into());
|
||||
assert_eq!(confirmed_utxos_txid, [tx1.compute_txid()].into());
|
||||
assert_eq!(
|
||||
unconfirmed_utxos_txid,
|
||||
[tx3.txid(), tx4.txid(), tx5.txid()].into()
|
||||
[tx3.compute_txid(), tx4.compute_txid(), tx5.compute_txid()].into()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -374,17 +380,20 @@ fn test_list_owned_txouts() {
|
||||
) = fetch(1, &graph);
|
||||
|
||||
// tx2 gets into confirmed txout set
|
||||
assert_eq!(confirmed_txouts_txid, [tx1.txid(), tx2.txid()].into());
|
||||
assert_eq!(
|
||||
confirmed_txouts_txid,
|
||||
[tx1.compute_txid(), tx2.compute_txid()].into()
|
||||
);
|
||||
assert_eq!(
|
||||
unconfirmed_txouts_txid,
|
||||
[tx3.txid(), tx4.txid(), tx5.txid()].into()
|
||||
[tx3.compute_txid(), tx4.compute_txid(), tx5.compute_txid()].into()
|
||||
);
|
||||
|
||||
// tx2 doesn't get into confirmed utxos set
|
||||
assert_eq!(confirmed_utxos_txid, [tx1.txid()].into());
|
||||
assert_eq!(confirmed_utxos_txid, [tx1.compute_txid()].into());
|
||||
assert_eq!(
|
||||
unconfirmed_utxos_txid,
|
||||
[tx3.txid(), tx4.txid(), tx5.txid()].into()
|
||||
[tx3.compute_txid(), tx4.compute_txid(), tx5.compute_txid()].into()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -411,13 +420,22 @@ fn test_list_owned_txouts() {
|
||||
// tx3 now gets into the confirmed txout set
|
||||
assert_eq!(
|
||||
confirmed_txouts_txid,
|
||||
[tx1.txid(), tx2.txid(), tx3.txid()].into()
|
||||
[tx1.compute_txid(), tx2.compute_txid(), tx3.compute_txid()].into()
|
||||
);
|
||||
assert_eq!(
|
||||
unconfirmed_txouts_txid,
|
||||
[tx4.compute_txid(), tx5.compute_txid()].into()
|
||||
);
|
||||
assert_eq!(unconfirmed_txouts_txid, [tx4.txid(), tx5.txid()].into());
|
||||
|
||||
// tx3 also gets into confirmed utxo set
|
||||
assert_eq!(confirmed_utxos_txid, [tx1.txid(), tx3.txid()].into());
|
||||
assert_eq!(unconfirmed_utxos_txid, [tx4.txid(), tx5.txid()].into());
|
||||
assert_eq!(
|
||||
confirmed_utxos_txid,
|
||||
[tx1.compute_txid(), tx3.compute_txid()].into()
|
||||
);
|
||||
assert_eq!(
|
||||
unconfirmed_utxos_txid,
|
||||
[tx4.compute_txid(), tx5.compute_txid()].into()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
balance,
|
||||
@ -442,12 +460,21 @@ fn test_list_owned_txouts() {
|
||||
|
||||
assert_eq!(
|
||||
confirmed_txouts_txid,
|
||||
[tx1.txid(), tx2.txid(), tx3.txid()].into()
|
||||
[tx1.compute_txid(), tx2.compute_txid(), tx3.compute_txid()].into()
|
||||
);
|
||||
assert_eq!(
|
||||
unconfirmed_txouts_txid,
|
||||
[tx4.compute_txid(), tx5.compute_txid()].into()
|
||||
);
|
||||
assert_eq!(unconfirmed_txouts_txid, [tx4.txid(), tx5.txid()].into());
|
||||
|
||||
assert_eq!(confirmed_utxos_txid, [tx1.txid(), tx3.txid()].into());
|
||||
assert_eq!(unconfirmed_utxos_txid, [tx4.txid(), tx5.txid()].into());
|
||||
assert_eq!(
|
||||
confirmed_utxos_txid,
|
||||
[tx1.compute_txid(), tx3.compute_txid()].into()
|
||||
);
|
||||
assert_eq!(
|
||||
unconfirmed_utxos_txid,
|
||||
[tx4.compute_txid(), tx5.compute_txid()].into()
|
||||
);
|
||||
|
||||
// Coinbase is still immature
|
||||
assert_eq!(
|
||||
|
@ -47,7 +47,7 @@ fn spk_txout_sent_and_received() {
|
||||
lock_time: absolute::LockTime::ZERO,
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint {
|
||||
txid: tx1.txid(),
|
||||
txid: tx1.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
..Default::default()
|
||||
|
@ -130,11 +130,11 @@ fn insert_txouts() {
|
||||
|
||||
// Mark it as confirmed.
|
||||
assert_eq!(
|
||||
graph.insert_anchor(update_txs.txid(), conf_anchor),
|
||||
graph.insert_anchor(update_txs.compute_txid(), conf_anchor),
|
||||
ChangeSet {
|
||||
txs: [].into(),
|
||||
txouts: [].into(),
|
||||
anchors: [(conf_anchor, update_txs.txid())].into(),
|
||||
anchors: [(conf_anchor, update_txs.compute_txid())].into(),
|
||||
last_seen: [].into()
|
||||
}
|
||||
);
|
||||
@ -149,7 +149,11 @@ fn insert_txouts() {
|
||||
ChangeSet {
|
||||
txs: [Arc::new(update_txs.clone())].into(),
|
||||
txouts: update_ops.clone().into(),
|
||||
anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(),
|
||||
anchors: [
|
||||
(conf_anchor, update_txs.compute_txid()),
|
||||
(unconf_anchor, h!("tx2"))
|
||||
]
|
||||
.into(),
|
||||
last_seen: [(h!("tx2"), 1000000)].into()
|
||||
}
|
||||
);
|
||||
@ -183,7 +187,9 @@ fn insert_txouts() {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
graph.tx_outputs(update_txs.txid()).expect("should exists"),
|
||||
graph
|
||||
.tx_outputs(update_txs.compute_txid())
|
||||
.expect("should exists"),
|
||||
[(
|
||||
0u32,
|
||||
&TxOut {
|
||||
@ -200,7 +206,11 @@ fn insert_txouts() {
|
||||
ChangeSet {
|
||||
txs: [Arc::new(update_txs.clone())].into(),
|
||||
txouts: update_ops.into_iter().chain(original_ops).collect(),
|
||||
anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(),
|
||||
anchors: [
|
||||
(conf_anchor, update_txs.compute_txid()),
|
||||
(unconf_anchor, h!("tx2"))
|
||||
]
|
||||
.into(),
|
||||
last_seen: [(h!("tx2"), 1000000)].into()
|
||||
}
|
||||
);
|
||||
@ -235,7 +245,7 @@ fn insert_tx_graph_keeps_track_of_spend() {
|
||||
};
|
||||
|
||||
let op = OutPoint {
|
||||
txid: tx1.txid(),
|
||||
txid: tx1.compute_txid(),
|
||||
vout: 0,
|
||||
};
|
||||
|
||||
@ -261,7 +271,7 @@ fn insert_tx_graph_keeps_track_of_spend() {
|
||||
|
||||
assert_eq!(
|
||||
graph1.outspends(op),
|
||||
&iter::once(tx2.txid()).collect::<HashSet<_>>()
|
||||
&iter::once(tx2.compute_txid()).collect::<HashSet<_>>()
|
||||
);
|
||||
assert_eq!(graph2.outspends(op), graph1.outspends(op));
|
||||
}
|
||||
@ -281,7 +291,9 @@ fn insert_tx_can_retrieve_full_tx_from_graph() {
|
||||
let mut graph = TxGraph::<()>::default();
|
||||
let _ = graph.insert_tx(tx.clone());
|
||||
assert_eq!(
|
||||
graph.get_tx(tx.txid()).map(|tx| tx.as_ref().clone()),
|
||||
graph
|
||||
.get_tx(tx.compute_txid())
|
||||
.map(|tx| tx.as_ref().clone()),
|
||||
Some(tx)
|
||||
);
|
||||
}
|
||||
@ -301,7 +313,7 @@ fn insert_tx_displaces_txouts() {
|
||||
|
||||
let changeset = tx_graph.insert_txout(
|
||||
OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
TxOut {
|
||||
@ -314,7 +326,7 @@ fn insert_tx_displaces_txouts() {
|
||||
|
||||
let _ = tx_graph.insert_txout(
|
||||
OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
TxOut {
|
||||
@ -328,7 +340,7 @@ fn insert_tx_displaces_txouts() {
|
||||
assert_eq!(
|
||||
tx_graph
|
||||
.get_txout(OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0
|
||||
})
|
||||
.unwrap()
|
||||
@ -337,7 +349,7 @@ fn insert_tx_displaces_txouts() {
|
||||
);
|
||||
assert_eq!(
|
||||
tx_graph.get_txout(OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 1
|
||||
}),
|
||||
None
|
||||
@ -361,7 +373,7 @@ fn insert_txout_does_not_displace_tx() {
|
||||
|
||||
let _ = tx_graph.insert_txout(
|
||||
OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
TxOut {
|
||||
@ -372,7 +384,7 @@ fn insert_txout_does_not_displace_tx() {
|
||||
|
||||
let _ = tx_graph.insert_txout(
|
||||
OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
TxOut {
|
||||
@ -384,7 +396,7 @@ fn insert_txout_does_not_displace_tx() {
|
||||
assert_eq!(
|
||||
tx_graph
|
||||
.get_txout(OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0
|
||||
})
|
||||
.unwrap()
|
||||
@ -393,7 +405,7 @@ fn insert_txout_does_not_displace_tx() {
|
||||
);
|
||||
assert_eq!(
|
||||
tx_graph.get_txout(OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 1
|
||||
}),
|
||||
None
|
||||
@ -443,14 +455,14 @@ fn test_calculate_fee() {
|
||||
input: vec![
|
||||
TxIn {
|
||||
previous_output: OutPoint {
|
||||
txid: intx1.txid(),
|
||||
txid: intx1.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
TxIn {
|
||||
previous_output: OutPoint {
|
||||
txid: intx2.txid(),
|
||||
txid: intx2.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
..Default::default()
|
||||
@ -543,7 +555,7 @@ fn test_walk_ancestors() {
|
||||
// tx_b0 spends tx_a0
|
||||
let tx_b0 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_a0.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_a0.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL, TxOut::NULL],
|
||||
@ -553,7 +565,7 @@ fn test_walk_ancestors() {
|
||||
// tx_b1 spends tx_a0
|
||||
let tx_b1 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_a0.txid(), 1),
|
||||
previous_output: OutPoint::new(tx_a0.compute_txid(), 1),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -572,7 +584,7 @@ fn test_walk_ancestors() {
|
||||
// tx_c0 spends tx_b0
|
||||
let tx_c0 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_b0.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_b0.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -582,7 +594,7 @@ fn test_walk_ancestors() {
|
||||
// tx_c1 spends tx_b0
|
||||
let tx_c1 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_b0.txid(), 1),
|
||||
previous_output: OutPoint::new(tx_b0.compute_txid(), 1),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -593,11 +605,11 @@ fn test_walk_ancestors() {
|
||||
let tx_c2 = Transaction {
|
||||
input: vec![
|
||||
TxIn {
|
||||
previous_output: OutPoint::new(tx_b1.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_b1.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
},
|
||||
TxIn {
|
||||
previous_output: OutPoint::new(tx_b2.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_b2.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
},
|
||||
],
|
||||
@ -617,7 +629,7 @@ fn test_walk_ancestors() {
|
||||
// tx_d0 spends tx_c1
|
||||
let tx_d0 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_c1.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_c1.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -628,11 +640,11 @@ fn test_walk_ancestors() {
|
||||
let tx_d1 = Transaction {
|
||||
input: vec![
|
||||
TxIn {
|
||||
previous_output: OutPoint::new(tx_c2.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_c2.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
},
|
||||
TxIn {
|
||||
previous_output: OutPoint::new(tx_c3.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_c3.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
},
|
||||
],
|
||||
@ -643,7 +655,7 @@ fn test_walk_ancestors() {
|
||||
// tx_e0 spends tx_d1
|
||||
let tx_e0 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_d1.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_d1.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -665,7 +677,7 @@ fn test_walk_ancestors() {
|
||||
]);
|
||||
|
||||
[&tx_a0, &tx_b1].iter().for_each(|&tx| {
|
||||
let changeset = graph.insert_anchor(tx.txid(), tip.block_id());
|
||||
let changeset = graph.insert_anchor(tx.compute_txid(), tip.block_id());
|
||||
assert!(!changeset.is_empty());
|
||||
});
|
||||
|
||||
@ -682,7 +694,7 @@ fn test_walk_ancestors() {
|
||||
// Only traverse unconfirmed ancestors of tx_e0 this time
|
||||
graph
|
||||
.walk_ancestors(tx_e0.clone(), |depth, tx| {
|
||||
let tx_node = graph.get_tx_node(tx.txid())?;
|
||||
let tx_node = graph.get_tx_node(tx.compute_txid())?;
|
||||
for block in tx_node.anchors {
|
||||
match local_chain.is_block_in_chain(block.anchor_block(), tip.block_id()) {
|
||||
Ok(Some(true)) => return None,
|
||||
@ -746,15 +758,15 @@ fn test_conflicting_descendants() {
|
||||
// tx_b spends tx_a
|
||||
let tx_b = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_a.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_a.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
..common::new_tx(2)
|
||||
};
|
||||
|
||||
let txid_a = tx_a.txid();
|
||||
let txid_b = tx_b.txid();
|
||||
let txid_a = tx_a.compute_txid();
|
||||
let txid_b = tx_b.compute_txid();
|
||||
|
||||
let mut graph = TxGraph::<()>::default();
|
||||
let _ = graph.insert_tx(tx_a);
|
||||
@ -778,7 +790,7 @@ fn test_descendants_no_repeat() {
|
||||
let txs_b = (0..3)
|
||||
.map(|vout| Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_a.txid(), vout),
|
||||
previous_output: OutPoint::new(tx_a.compute_txid(), vout),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -789,7 +801,7 @@ fn test_descendants_no_repeat() {
|
||||
let txs_c = (0..2)
|
||||
.map(|vout| Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(txs_b[vout as usize].txid(), vout),
|
||||
previous_output: OutPoint::new(txs_b[vout as usize].compute_txid(), vout),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -800,11 +812,11 @@ fn test_descendants_no_repeat() {
|
||||
let tx_d = Transaction {
|
||||
input: vec![
|
||||
TxIn {
|
||||
previous_output: OutPoint::new(txs_c[0].txid(), 0),
|
||||
previous_output: OutPoint::new(txs_c[0].compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
},
|
||||
TxIn {
|
||||
previous_output: OutPoint::new(txs_c[1].txid(), 0),
|
||||
previous_output: OutPoint::new(txs_c[1].compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
},
|
||||
],
|
||||
@ -814,7 +826,7 @@ fn test_descendants_no_repeat() {
|
||||
|
||||
let tx_e = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_d.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_d.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![TxOut::NULL],
|
||||
@ -848,11 +860,11 @@ fn test_descendants_no_repeat() {
|
||||
.chain(core::iter::once(&tx_e))
|
||||
{
|
||||
let _ = graph.insert_tx(tx.clone());
|
||||
expected_txids.push(tx.txid());
|
||||
expected_txids.push(tx.compute_txid());
|
||||
}
|
||||
|
||||
let descendants = graph
|
||||
.walk_descendants(tx_a.txid(), |_, txid| Some(txid))
|
||||
.walk_descendants(tx_a.compute_txid(), |_, txid| Some(txid))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(descendants, expected_txids);
|
||||
@ -888,7 +900,7 @@ fn test_chain_spends() {
|
||||
// The first confirmed transaction spends vout: 0. And is confirmed at block 98.
|
||||
let tx_1 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_0.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_0.compute_txid(), 0),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![
|
||||
@ -907,7 +919,7 @@ fn test_chain_spends() {
|
||||
// The second transactions spends vout:1, and is unconfirmed.
|
||||
let tx_2 = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_0.txid(), 1),
|
||||
previous_output: OutPoint::new(tx_0.compute_txid(), 1),
|
||||
..TxIn::default()
|
||||
}],
|
||||
output: vec![
|
||||
@ -931,7 +943,7 @@ fn test_chain_spends() {
|
||||
|
||||
for (ht, tx) in [(95, &tx_0), (98, &tx_1)] {
|
||||
let _ = graph.insert_anchor(
|
||||
tx.txid(),
|
||||
tx.compute_txid(),
|
||||
ConfirmationHeightAnchor {
|
||||
anchor_block: tip.block_id(),
|
||||
confirmation_height: ht,
|
||||
@ -941,19 +953,23 @@ fn test_chain_spends() {
|
||||
|
||||
// Assert that confirmed spends are returned correctly.
|
||||
assert_eq!(
|
||||
graph.get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 0)),
|
||||
graph.get_chain_spend(
|
||||
&local_chain,
|
||||
tip.block_id(),
|
||||
OutPoint::new(tx_0.compute_txid(), 0)
|
||||
),
|
||||
Some((
|
||||
ChainPosition::Confirmed(&ConfirmationHeightAnchor {
|
||||
anchor_block: tip.block_id(),
|
||||
confirmation_height: 98
|
||||
}),
|
||||
tx_1.txid(),
|
||||
tx_1.compute_txid(),
|
||||
)),
|
||||
);
|
||||
|
||||
// Check if chain position is returned correctly.
|
||||
assert_eq!(
|
||||
graph.get_chain_position(&local_chain, tip.block_id(), tx_0.txid()),
|
||||
graph.get_chain_position(&local_chain, tip.block_id(), tx_0.compute_txid()),
|
||||
// Some(ObservedAs::Confirmed(&local_chain.get_block(95).expect("block expected"))),
|
||||
Some(ChainPosition::Confirmed(&ConfirmationHeightAnchor {
|
||||
anchor_block: tip.block_id(),
|
||||
@ -963,25 +979,33 @@ fn test_chain_spends() {
|
||||
|
||||
// Even if unconfirmed tx has a last_seen of 0, it can still be part of a chain spend.
|
||||
assert_eq!(
|
||||
graph.get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 1)),
|
||||
Some((ChainPosition::Unconfirmed(0), tx_2.txid())),
|
||||
graph.get_chain_spend(
|
||||
&local_chain,
|
||||
tip.block_id(),
|
||||
OutPoint::new(tx_0.compute_txid(), 1)
|
||||
),
|
||||
Some((ChainPosition::Unconfirmed(0), tx_2.compute_txid())),
|
||||
);
|
||||
|
||||
// Mark the unconfirmed as seen and check correct ObservedAs status is returned.
|
||||
let _ = graph.insert_seen_at(tx_2.txid(), 1234567);
|
||||
let _ = graph.insert_seen_at(tx_2.compute_txid(), 1234567);
|
||||
|
||||
// Check chain spend returned correctly.
|
||||
assert_eq!(
|
||||
graph
|
||||
.get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 1))
|
||||
.get_chain_spend(
|
||||
&local_chain,
|
||||
tip.block_id(),
|
||||
OutPoint::new(tx_0.compute_txid(), 1)
|
||||
)
|
||||
.unwrap(),
|
||||
(ChainPosition::Unconfirmed(1234567), tx_2.txid())
|
||||
(ChainPosition::Unconfirmed(1234567), tx_2.compute_txid())
|
||||
);
|
||||
|
||||
// A conflicting transaction that conflicts with tx_1.
|
||||
let tx_1_conflict = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_0.txid(), 0),
|
||||
previous_output: OutPoint::new(tx_0.compute_txid(), 0),
|
||||
..Default::default()
|
||||
}],
|
||||
..common::new_tx(0)
|
||||
@ -990,13 +1014,13 @@ fn test_chain_spends() {
|
||||
|
||||
// Because this tx conflicts with an already confirmed transaction, chain position should return none.
|
||||
assert!(graph
|
||||
.get_chain_position(&local_chain, tip.block_id(), tx_1_conflict.txid())
|
||||
.get_chain_position(&local_chain, tip.block_id(), tx_1_conflict.compute_txid())
|
||||
.is_none());
|
||||
|
||||
// Another conflicting tx that conflicts with tx_2.
|
||||
let tx_2_conflict = Transaction {
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint::new(tx_0.txid(), 1),
|
||||
previous_output: OutPoint::new(tx_0.compute_txid(), 1),
|
||||
..Default::default()
|
||||
}],
|
||||
..common::new_tx(0)
|
||||
@ -1004,12 +1028,12 @@ fn test_chain_spends() {
|
||||
|
||||
// Insert in graph and mark it as seen.
|
||||
let _ = graph.insert_tx(tx_2_conflict.clone());
|
||||
let _ = graph.insert_seen_at(tx_2_conflict.txid(), 1234568);
|
||||
let _ = graph.insert_seen_at(tx_2_conflict.compute_txid(), 1234568);
|
||||
|
||||
// This should return a valid observation with correct last seen.
|
||||
assert_eq!(
|
||||
graph
|
||||
.get_chain_position(&local_chain, tip.block_id(), tx_2_conflict.txid())
|
||||
.get_chain_position(&local_chain, tip.block_id(), tx_2_conflict.compute_txid())
|
||||
.expect("position expected"),
|
||||
ChainPosition::Unconfirmed(1234568)
|
||||
);
|
||||
@ -1017,14 +1041,21 @@ fn test_chain_spends() {
|
||||
// Chain_spend now catches the new transaction as the spend.
|
||||
assert_eq!(
|
||||
graph
|
||||
.get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 1))
|
||||
.get_chain_spend(
|
||||
&local_chain,
|
||||
tip.block_id(),
|
||||
OutPoint::new(tx_0.compute_txid(), 1)
|
||||
)
|
||||
.expect("expect observation"),
|
||||
(ChainPosition::Unconfirmed(1234568), tx_2_conflict.txid())
|
||||
(
|
||||
ChainPosition::Unconfirmed(1234568),
|
||||
tx_2_conflict.compute_txid()
|
||||
)
|
||||
);
|
||||
|
||||
// Chain position of the `tx_2` is now none, as it is older than `tx_2_conflict`
|
||||
assert!(graph
|
||||
.get_chain_position(&local_chain, tip.block_id(), tx_2.txid())
|
||||
.get_chain_position(&local_chain, tip.block_id(), tx_2.compute_txid())
|
||||
.is_none());
|
||||
}
|
||||
|
||||
@ -1065,7 +1096,7 @@ fn test_changeset_last_seen_append() {
|
||||
fn update_last_seen_unconfirmed() {
|
||||
let mut graph = TxGraph::<()>::default();
|
||||
let tx = new_tx(0);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
|
||||
// insert a new tx
|
||||
// initially we have a last_seen of 0, and no anchors
|
||||
|
@ -13,7 +13,7 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
bdk_chain = { path = "../chain", version = "0.15.0" }
|
||||
electrum-client = { version = "0.19" }
|
||||
electrum-client = { version = "0.20" }
|
||||
#rustls = { version = "=0.21.1", optional = true, features = ["dangerous_configuration"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -310,7 +310,7 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
|
||||
Some(txout) => txout,
|
||||
None => continue,
|
||||
};
|
||||
debug_assert_eq!(op_tx.txid(), op_txid);
|
||||
debug_assert_eq!(op_tx.compute_txid(), op_txid);
|
||||
|
||||
// attempt to find the following transactions (alongside their chain positions), and
|
||||
// add to our sparsechain `update`:
|
||||
|
@ -13,13 +13,12 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
bdk_chain = { path = "../chain", version = "0.15.0", default-features = false }
|
||||
esplora-client = { version = "0.7.0", default-features = false }
|
||||
esplora-client = { version = "0.8.0", default-features = false }
|
||||
async-trait = { version = "0.1.66", optional = true }
|
||||
futures = { version = "0.3.26", optional = true }
|
||||
|
||||
# use these dependencies if you need to enable their /no-std features
|
||||
bitcoin = { version = "0.31.0", optional = true, default-features = false }
|
||||
miniscript = { version = "11.0.0", optional = true, default-features = false }
|
||||
bitcoin = { version = "0.32.0", optional = true, default-features = false }
|
||||
miniscript = { version = "12.0.0", optional = true, default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
bdk_testenv = { path = "../testenv", default-features = false }
|
||||
@ -27,7 +26,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
|
||||
|
||||
[features]
|
||||
default = ["std", "async-https", "blocking-https-rustls"]
|
||||
std = ["bdk_chain/std"]
|
||||
std = ["bdk_chain/std", "miniscript?/std"]
|
||||
async = ["async-trait", "futures", "esplora-client/async"]
|
||||
async-https = ["async", "esplora-client/async-https"]
|
||||
async-https-rustls = ["async", "esplora-client/async-https-rustls"]
|
||||
|
@ -10,4 +10,4 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
bdk_wallet = { path = "../wallet", version = "1.0.0-alpha.12" }
|
||||
hwi = { version = "0.8.0", features = [ "miniscript"] }
|
||||
hwi = { version = "0.9.0", features = [ "miniscript"] }
|
||||
|
@ -303,7 +303,7 @@ impl<K, A> Store<K, A> {
|
||||
let insert_tx_stmt = &mut db_transaction
|
||||
.prepare_cached("INSERT INTO tx (txid, whole_tx) VALUES (:txid, :whole_tx) ON CONFLICT (txid) DO UPDATE SET whole_tx = :whole_tx WHERE txid = :txid")
|
||||
.expect("insert or update tx whole_tx statement");
|
||||
let txid = tx.txid().to_string();
|
||||
let txid = tx.compute_txid().to_string();
|
||||
let whole_tx = serialize(&tx);
|
||||
insert_tx_stmt
|
||||
.execute(named_params! {":txid": txid, ":whole_tx": whole_tx })
|
||||
@ -685,9 +685,9 @@ mod test {
|
||||
let tx2_hex = Vec::<u8>::from_hex("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0432e7494d010e062f503253482fffffffff0100f2052a010000002321038a7f6ef1c8ca0c588aa53fa860128077c9e6c11e6830f4d7ee4e763a56b7718fac00000000").unwrap();
|
||||
let tx2: Arc<Transaction> = Arc::new(deserialize(tx2_hex.as_slice()).unwrap());
|
||||
|
||||
let outpoint0_0 = OutPoint::new(tx0.txid(), 0);
|
||||
let outpoint0_0 = OutPoint::new(tx0.compute_txid(), 0);
|
||||
let txout0_0 = tx0.output.first().unwrap().clone();
|
||||
let outpoint1_0 = OutPoint::new(tx1.txid(), 0);
|
||||
let outpoint1_0 = OutPoint::new(tx1.compute_txid(), 0);
|
||||
let txout1_0 = tx1.output.first().unwrap().clone();
|
||||
|
||||
let anchor1 = anchor_fn(1, 1296667328, block_hash_1);
|
||||
@ -696,11 +696,11 @@ mod test {
|
||||
let tx_graph_changeset = tx_graph::ChangeSet::<A> {
|
||||
txs: [tx0.clone(), tx1.clone()].into(),
|
||||
txouts: [(outpoint0_0, txout0_0), (outpoint1_0, txout1_0)].into(),
|
||||
anchors: [(anchor1, tx0.txid()), (anchor1, tx1.txid())].into(),
|
||||
anchors: [(anchor1, tx0.compute_txid()), (anchor1, tx1.compute_txid())].into(),
|
||||
last_seen: [
|
||||
(tx0.txid(), 1598918400),
|
||||
(tx1.txid(), 1598919121),
|
||||
(tx2.txid(), 1608919121),
|
||||
(tx0.compute_txid(), 1598918400),
|
||||
(tx1.compute_txid(), 1598919121),
|
||||
(tx2.compute_txid(), 1608919121),
|
||||
]
|
||||
.into(),
|
||||
};
|
||||
@ -730,7 +730,7 @@ mod test {
|
||||
txs: [tx2.clone()].into(),
|
||||
txouts: BTreeMap::default(),
|
||||
anchors: BTreeSet::default(),
|
||||
last_seen: [(tx2.txid(), 1708919121)].into(),
|
||||
last_seen: [(tx2.compute_txid(), 1708919121)].into(),
|
||||
};
|
||||
|
||||
let graph_changeset2: indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<Keychain>> =
|
||||
@ -749,7 +749,7 @@ mod test {
|
||||
let tx_graph_changeset3 = tx_graph::ChangeSet::<A> {
|
||||
txs: BTreeSet::default(),
|
||||
txouts: BTreeMap::default(),
|
||||
anchors: [(anchor2, tx0.txid()), (anchor2, tx1.txid())].into(),
|
||||
anchors: [(anchor2, tx0.compute_txid()), (anchor2, tx1.compute_txid())].into(),
|
||||
last_seen: BTreeMap::default(),
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
bdk_chain = { path = "../chain", version = "0.15", default-features = false }
|
||||
electrsd = { version= "0.27.1", features = ["bitcoind_25_0", "esplora_a33e97e1", "legacy"] }
|
||||
electrsd = { version = "0.28.0", features = ["bitcoind_25_0", "esplora_a33e97e1", "legacy"] }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
@ -15,8 +15,8 @@ rust-version = "1.63"
|
||||
[dependencies]
|
||||
anyhow = { version = "1", default-features = false }
|
||||
rand = "^0.8"
|
||||
miniscript = { version = "11.0.0", features = ["serde"], default-features = false }
|
||||
bitcoin = { version = "0.31.0", features = ["serde", "base64", "rand-std"], default-features = false }
|
||||
miniscript = { version = "12.0.0", features = ["serde"], default-features = false }
|
||||
bitcoin = { version = "0.32.0", features = ["serde", "base64", "rand-std"], default-features = false }
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = { version = "^1.0" }
|
||||
bdk_chain = { path = "../chain", version = "0.15.0", features = ["miniscript", "serde"], default-features = false }
|
||||
|
@ -703,10 +703,10 @@ macro_rules! fragment {
|
||||
$crate::keys::make_pkh($key, &secp)
|
||||
});
|
||||
( after ( $value:expr ) ) => ({
|
||||
$crate::impl_leaf_opcode_value!(After, $crate::miniscript::AbsLockTime::from_consensus($value))
|
||||
$crate::impl_leaf_opcode_value!(After, $crate::miniscript::AbsLockTime::from_consensus($value).expect("valid `AbsLockTime`"))
|
||||
});
|
||||
( older ( $value:expr ) ) => ({
|
||||
$crate::impl_leaf_opcode_value!(Older, $crate::bitcoin::Sequence($value)) // TODO!!
|
||||
$crate::impl_leaf_opcode_value!(Older, $crate::miniscript::RelLockTime::from_consensus($value).expect("valid `RelLockTime`")) // TODO!!
|
||||
});
|
||||
( sha256 ( $hash:expr ) ) => ({
|
||||
$crate::impl_leaf_opcode_value!(Sha256, $hash)
|
||||
@ -757,7 +757,8 @@ macro_rules! fragment {
|
||||
(keys_acc, net_acc)
|
||||
});
|
||||
|
||||
$crate::impl_leaf_opcode_value_two!(Thresh, $thresh, items)
|
||||
let thresh = $crate::miniscript::Threshold::new($thresh, items).expect("valid threshold and pks collection");
|
||||
$crate::impl_leaf_opcode_value!(Thresh, thresh)
|
||||
.map(|(minisc, _, _)| (minisc, key_maps, valid_networks))
|
||||
});
|
||||
( thresh ( $thresh:expr, $( $inner:tt )* ) ) => ({
|
||||
@ -769,7 +770,12 @@ macro_rules! fragment {
|
||||
( multi_vec ( $thresh:expr, $keys:expr ) ) => ({
|
||||
let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
|
||||
|
||||
$crate::keys::make_multi($thresh, $crate::miniscript::Terminal::Multi, $keys, &secp)
|
||||
let fun = |k, pks| {
|
||||
let thresh = $crate::miniscript::Threshold::new(k, pks).expect("valid threshold and pks collection");
|
||||
$crate::miniscript::Terminal::Multi(thresh)
|
||||
};
|
||||
|
||||
$crate::keys::make_multi($thresh, fun, $keys, &secp)
|
||||
});
|
||||
( multi ( $thresh:expr $(, $key:expr )+ ) ) => ({
|
||||
$crate::group_multi_keys!( $( $key ),* )
|
||||
@ -778,7 +784,12 @@ macro_rules! fragment {
|
||||
( multi_a_vec ( $thresh:expr, $keys:expr ) ) => ({
|
||||
let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
|
||||
|
||||
$crate::keys::make_multi($thresh, $crate::miniscript::Terminal::MultiA, $keys, &secp)
|
||||
let fun = |k, pks| {
|
||||
let thresh = $crate::miniscript::Threshold::new(k, pks).expect("valid threshold and pks collection");
|
||||
$crate::miniscript::Terminal::MultiA(thresh)
|
||||
};
|
||||
|
||||
$crate::keys::make_multi($thresh, fun, $keys, &secp)
|
||||
});
|
||||
( multi_a ( $thresh:expr $(, $key:expr )+ ) ) => ({
|
||||
$crate::group_multi_keys!( $( $key ),* )
|
||||
|
@ -37,7 +37,7 @@ pub enum Error {
|
||||
/// Error during base58 decoding
|
||||
Base58(bitcoin::base58::Error),
|
||||
/// Key-related error
|
||||
Pk(bitcoin::key::Error),
|
||||
Pk(bitcoin::key::ParsePublicKeyError),
|
||||
/// Miniscript error
|
||||
Miniscript(miniscript::Error),
|
||||
/// Hex decoding error
|
||||
@ -103,8 +103,8 @@ impl From<bitcoin::base58::Error> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::key::Error> for Error {
|
||||
fn from(err: bitcoin::key::Error) -> Self {
|
||||
impl From<bitcoin::key::ParsePublicKeyError> for Error {
|
||||
fn from(err: bitcoin::key::ParsePublicKeyError) -> Self {
|
||||
Error::Pk(err)
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ impl IntoWalletDescriptor for DescriptorTemplateOut {
|
||||
let pk = match pk {
|
||||
DescriptorPublicKey::XPub(ref xpub) => {
|
||||
let mut xpub = xpub.clone();
|
||||
xpub.xkey.network = self.network;
|
||||
xpub.xkey.network = self.network.into();
|
||||
|
||||
DescriptorPublicKey::XPub(xpub)
|
||||
}
|
||||
@ -264,11 +264,11 @@ impl IntoWalletDescriptor for DescriptorTemplateOut {
|
||||
.map(|(mut k, mut v)| {
|
||||
match (&mut k, &mut v) {
|
||||
(DescriptorPublicKey::XPub(xpub), DescriptorSecretKey::XPrv(xprv)) => {
|
||||
xpub.xkey.network = network;
|
||||
xprv.xkey.network = network;
|
||||
xpub.xkey.network = network.into();
|
||||
xprv.xkey.network = network.into();
|
||||
}
|
||||
(_, DescriptorSecretKey::Single(key)) => {
|
||||
key.key.network = network;
|
||||
key.key.network = network.into();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -606,8 +606,8 @@ mod test {
|
||||
use assert_matches::assert_matches;
|
||||
use bitcoin::hex::FromHex;
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
use bitcoin::ScriptBuf;
|
||||
use bitcoin::{bip32, Psbt};
|
||||
use bitcoin::{NetworkKind, ScriptBuf};
|
||||
|
||||
use super::*;
|
||||
use crate::psbt::PsbtUtils;
|
||||
@ -743,7 +743,7 @@ mod test {
|
||||
.unwrap();
|
||||
|
||||
let mut xprv_testnet = xprv;
|
||||
xprv_testnet.network = Network::Testnet;
|
||||
xprv_testnet.network = NetworkKind::Test;
|
||||
|
||||
let xpub_testnet = bip32::Xpub::from_priv(&secp, &xprv_testnet);
|
||||
let desc_pubkey = DescriptorPublicKey::XPub(DescriptorXKey {
|
||||
|
@ -40,6 +40,7 @@ use crate::collections::{BTreeMap, HashSet, VecDeque};
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::cmp::max;
|
||||
use miniscript::miniscript::limits::{MAX_PUBKEYS_IN_CHECKSIGADD, MAX_PUBKEYS_PER_MULTISIG};
|
||||
|
||||
use core::fmt;
|
||||
|
||||
@ -48,12 +49,12 @@ use serde::{Serialize, Serializer};
|
||||
|
||||
use bitcoin::bip32::Fingerprint;
|
||||
use bitcoin::hashes::{hash160, ripemd160, sha256};
|
||||
use bitcoin::{absolute, key::XOnlyPublicKey, PublicKey, Sequence};
|
||||
use bitcoin::{absolute, key::XOnlyPublicKey, relative, PublicKey, Sequence};
|
||||
|
||||
use miniscript::descriptor::{
|
||||
DescriptorPublicKey, ShInner, SinglePub, SinglePubKey, SortedMultiVec, WshInner,
|
||||
};
|
||||
use miniscript::hash256;
|
||||
use miniscript::{hash256, Threshold};
|
||||
use miniscript::{
|
||||
Descriptor, Miniscript, Satisfier, ScriptContext, SigType, Terminal, ToPublicKey,
|
||||
};
|
||||
@ -137,7 +138,7 @@ pub enum SatisfiableItem {
|
||||
/// Relative timelock locktime
|
||||
RelativeTimelock {
|
||||
/// The timelock value
|
||||
value: Sequence,
|
||||
value: relative::LockTime,
|
||||
},
|
||||
/// Multi-signature public keys with threshold count
|
||||
Multisig {
|
||||
@ -586,30 +587,25 @@ impl Policy {
|
||||
Ok(Some(policy))
|
||||
}
|
||||
|
||||
fn make_multisig<Ctx: ScriptContext + 'static>(
|
||||
keys: &[DescriptorPublicKey],
|
||||
fn make_multi<Ctx: ScriptContext + 'static, const MAX: usize>(
|
||||
threshold: &Threshold<DescriptorPublicKey, MAX>,
|
||||
signers: &SignersContainer,
|
||||
build_sat: BuildSatisfaction,
|
||||
threshold: usize,
|
||||
sorted: bool,
|
||||
secp: &SecpCtx,
|
||||
) -> Result<Option<Policy>, PolicyError> {
|
||||
if threshold == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let parsed_keys = keys.iter().map(|k| PkOrF::from_key(k, secp)).collect();
|
||||
let parsed_keys = threshold.iter().map(|k| PkOrF::from_key(k, secp)).collect();
|
||||
|
||||
let mut contribution = Satisfaction::Partial {
|
||||
n: keys.len(),
|
||||
m: threshold,
|
||||
n: threshold.n(),
|
||||
m: threshold.k(),
|
||||
items: vec![],
|
||||
conditions: Default::default(),
|
||||
sorted: Some(sorted),
|
||||
};
|
||||
let mut satisfaction = contribution.clone();
|
||||
|
||||
for (index, key) in keys.iter().enumerate() {
|
||||
for (index, key) in threshold.iter().enumerate() {
|
||||
if signers.find(signer_id(key, secp)).is_some() {
|
||||
contribution.add(
|
||||
&Satisfaction::Complete {
|
||||
@ -618,7 +614,6 @@ impl Policy {
|
||||
index,
|
||||
)?;
|
||||
}
|
||||
|
||||
if let Some(psbt) = build_sat.psbt() {
|
||||
if Ctx::find_signature(psbt, key, secp) {
|
||||
satisfaction.add(
|
||||
@ -635,12 +630,11 @@ impl Policy {
|
||||
|
||||
let mut policy: Policy = SatisfiableItem::Multisig {
|
||||
keys: parsed_keys,
|
||||
threshold,
|
||||
threshold: threshold.k(),
|
||||
}
|
||||
.into();
|
||||
policy.contribution = contribution;
|
||||
policy.satisfaction = satisfaction;
|
||||
|
||||
Ok(Some(policy))
|
||||
}
|
||||
|
||||
@ -725,7 +719,7 @@ impl Policy {
|
||||
timelock: Some(*value),
|
||||
}),
|
||||
SatisfiableItem::RelativeTimelock { value } => Ok(Condition {
|
||||
csv: Some(*value),
|
||||
csv: Some((*value).into()),
|
||||
timelock: None,
|
||||
}),
|
||||
_ => Ok(Condition::default()),
|
||||
@ -952,11 +946,14 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
|
||||
Some(policy)
|
||||
}
|
||||
Terminal::Older(value) => {
|
||||
let mut policy: Policy = SatisfiableItem::RelativeTimelock { value: *value }.into();
|
||||
let mut policy: Policy = SatisfiableItem::RelativeTimelock {
|
||||
value: (*value).into(),
|
||||
}
|
||||
.into();
|
||||
policy.contribution = Satisfaction::Complete {
|
||||
condition: Condition {
|
||||
timelock: None,
|
||||
csv: Some(*value),
|
||||
csv: Some((*value).into()),
|
||||
},
|
||||
};
|
||||
if let BuildSatisfaction::PsbtTimelocks {
|
||||
@ -966,9 +963,11 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
|
||||
} = build_sat
|
||||
{
|
||||
let older = Older::new(Some(current_height), Some(input_max_height), false);
|
||||
let older_sat = Satisfier::<bitcoin::PublicKey>::check_older(&older, *value);
|
||||
let inputs_sat = psbt_inputs_sat(psbt)
|
||||
.all(|sat| Satisfier::<bitcoin::PublicKey>::check_older(&sat, *value));
|
||||
let older_sat =
|
||||
Satisfier::<bitcoin::PublicKey>::check_older(&older, (*value).into());
|
||||
let inputs_sat = psbt_inputs_sat(psbt).all(|sat| {
|
||||
Satisfier::<bitcoin::PublicKey>::check_older(&sat, (*value).into())
|
||||
});
|
||||
if older_sat && inputs_sat {
|
||||
policy.satisfaction = policy.contribution.clone();
|
||||
}
|
||||
@ -986,9 +985,12 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
|
||||
Terminal::Hash160(hash) => {
|
||||
Some(SatisfiableItem::Hash160Preimage { hash: *hash }.into())
|
||||
}
|
||||
Terminal::Multi(k, pks) | Terminal::MultiA(k, pks) => {
|
||||
Policy::make_multisig::<Ctx>(pks, signers, build_sat, *k, false, secp)?
|
||||
}
|
||||
Terminal::Multi(threshold) => Policy::make_multi::<Ctx, MAX_PUBKEYS_PER_MULTISIG>(
|
||||
threshold, signers, build_sat, false, secp,
|
||||
)?,
|
||||
Terminal::MultiA(threshold) => Policy::make_multi::<Ctx, MAX_PUBKEYS_IN_CHECKSIGADD>(
|
||||
threshold, signers, build_sat, false, secp,
|
||||
)?,
|
||||
// Identities
|
||||
Terminal::Alt(inner)
|
||||
| Terminal::Swap(inner)
|
||||
@ -1016,8 +1018,9 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
|
||||
a.extract_policy(signers, build_sat, secp)?,
|
||||
b.extract_policy(signers, build_sat, secp)?,
|
||||
)?,
|
||||
Terminal::Thresh(k, nodes) => {
|
||||
let mut threshold = *k;
|
||||
Terminal::Thresh(threshold) => {
|
||||
let mut k = threshold.k();
|
||||
let nodes = threshold.data();
|
||||
let mapped: Vec<_> = nodes
|
||||
.iter()
|
||||
.map(|n| n.extract_policy(signers, build_sat, secp))
|
||||
@ -1027,13 +1030,13 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
|
||||
.collect();
|
||||
|
||||
if mapped.len() < nodes.len() {
|
||||
threshold = match threshold.checked_sub(nodes.len() - mapped.len()) {
|
||||
k = match k.checked_sub(nodes.len() - mapped.len()) {
|
||||
None => return Ok(None),
|
||||
Some(x) => x,
|
||||
};
|
||||
}
|
||||
|
||||
Policy::make_thresh(mapped, threshold)?
|
||||
Policy::make_thresh(mapped, k)?
|
||||
}
|
||||
|
||||
// Unsupported
|
||||
@ -1087,13 +1090,10 @@ impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
|
||||
build_sat: BuildSatisfaction,
|
||||
secp: &SecpCtx,
|
||||
) -> Result<Option<Policy>, Error> {
|
||||
Ok(Policy::make_multisig::<Ctx>(
|
||||
keys.pks.as_ref(),
|
||||
signers,
|
||||
build_sat,
|
||||
keys.k,
|
||||
true,
|
||||
secp,
|
||||
let threshold = Threshold::new(keys.k(), keys.pks().to_vec())
|
||||
.expect("valid threshold and pks collection");
|
||||
Ok(Policy::make_multi::<Ctx, MAX_PUBKEYS_PER_MULTISIG>(
|
||||
&threshold, signers, build_sat, true, secp,
|
||||
)?)
|
||||
}
|
||||
|
||||
|
@ -583,7 +583,7 @@ mod test {
|
||||
use bitcoin::bip32::ChildNumber::{self, Hardened};
|
||||
|
||||
let xprvkey = bitcoin::bip32::Xpriv::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
|
||||
assert_eq!(Network::Bitcoin, xprvkey.network);
|
||||
assert!(xprvkey.network.is_mainnet());
|
||||
let xdesc = Bip44(xprvkey, KeychainKind::Internal)
|
||||
.build(Network::Bitcoin)
|
||||
.unwrap();
|
||||
@ -597,7 +597,7 @@ mod test {
|
||||
}
|
||||
|
||||
let tprvkey = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
|
||||
assert_eq!(Network::Testnet, tprvkey.network);
|
||||
assert!(!tprvkey.network.is_mainnet());
|
||||
let tdesc = Bip44(tprvkey, KeychainKind::Internal)
|
||||
.build(Network::Testnet)
|
||||
.unwrap();
|
||||
|
@ -336,7 +336,7 @@ impl<Ctx: ScriptContext> ExtendedKey<Ctx> {
|
||||
pub fn into_xprv(self, network: Network) -> Option<bip32::Xpriv> {
|
||||
match self {
|
||||
ExtendedKey::Private((mut xprv, _)) => {
|
||||
xprv.network = network;
|
||||
xprv.network = network.into();
|
||||
Some(xprv)
|
||||
}
|
||||
ExtendedKey::Public(_) => None,
|
||||
@ -355,7 +355,7 @@ impl<Ctx: ScriptContext> ExtendedKey<Ctx> {
|
||||
ExtendedKey::Public((xpub, _)) => xpub,
|
||||
};
|
||||
|
||||
xpub.network = network;
|
||||
xpub.network = network.into();
|
||||
xpub
|
||||
}
|
||||
}
|
||||
@ -402,7 +402,7 @@ impl<Ctx: ScriptContext> From<bip32::Xpriv> for ExtendedKey<Ctx> {
|
||||
/// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
|
||||
/// fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
|
||||
/// let xprv = bip32::Xpriv {
|
||||
/// network: self.network,
|
||||
/// network: self.network.into(),
|
||||
/// depth: 0,
|
||||
/// parent_fingerprint: bip32::Fingerprint::default(),
|
||||
/// private_key: self.key_data.inner,
|
||||
@ -434,7 +434,7 @@ impl<Ctx: ScriptContext> From<bip32::Xpriv> for ExtendedKey<Ctx> {
|
||||
/// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
|
||||
/// fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
|
||||
/// let xprv = bip32::Xpriv {
|
||||
/// network: bitcoin::Network::Bitcoin, // pick an arbitrary network here
|
||||
/// network: bitcoin::Network::Bitcoin.into(), // pick an arbitrary network here
|
||||
/// depth: 0,
|
||||
/// parent_fingerprint: bip32::Fingerprint::default(),
|
||||
/// private_key: self.key_data.inner,
|
||||
@ -717,7 +717,7 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey {
|
||||
let inner = secp256k1::SecretKey::from_slice(&entropy)?;
|
||||
let private_key = PrivateKey {
|
||||
compressed: options.compressed,
|
||||
network: Network::Bitcoin,
|
||||
network: Network::Bitcoin.into(),
|
||||
inner,
|
||||
};
|
||||
|
||||
@ -847,9 +847,7 @@ impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey {
|
||||
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
|
||||
let networks = match self {
|
||||
DescriptorPublicKey::Single(_) => any_network(),
|
||||
DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. })
|
||||
if xkey.network == Network::Bitcoin =>
|
||||
{
|
||||
DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. }) if xkey.network.is_mainnet() => {
|
||||
mainnet_network()
|
||||
}
|
||||
_ => test_networks(),
|
||||
@ -882,12 +880,8 @@ impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for XOnlyPublicKey {
|
||||
impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey {
|
||||
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
|
||||
let networks = match &self {
|
||||
DescriptorSecretKey::Single(sk) if sk.key.network == Network::Bitcoin => {
|
||||
mainnet_network()
|
||||
}
|
||||
DescriptorSecretKey::XPrv(DescriptorXKey { xkey, .. })
|
||||
if xkey.network == Network::Bitcoin =>
|
||||
{
|
||||
DescriptorSecretKey::Single(sk) if sk.key.network.is_mainnet() => mainnet_network(),
|
||||
DescriptorSecretKey::XPrv(DescriptorXKey { xkey, .. }) if xkey.network.is_mainnet() => {
|
||||
mainnet_network()
|
||||
}
|
||||
_ => test_networks(),
|
||||
@ -1003,6 +997,6 @@ pub mod test {
|
||||
.unwrap();
|
||||
let xprv = xkey.into_xprv(Network::Testnet).unwrap();
|
||||
|
||||
assert_eq!(xprv.network, Network::Testnet);
|
||||
assert_eq!(xprv.network, Network::Testnet.into());
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ pub fn decide_change(remaining_amount: u64, fee_rate: FeeRate, drain_script: &Sc
|
||||
let drain_val = remaining_amount.saturating_sub(change_fee);
|
||||
|
||||
if drain_val.is_dust(drain_script) {
|
||||
let dust_threshold = drain_script.dust_value().to_sat();
|
||||
let dust_threshold = drain_script.minimal_non_dust().to_sat();
|
||||
Excess::NoChange {
|
||||
dust_threshold,
|
||||
change_fee,
|
||||
|
@ -164,7 +164,7 @@ impl FullyNodedExport {
|
||||
fn check_ms<Ctx: ScriptContext>(
|
||||
terminal: &Terminal<String, Ctx>,
|
||||
) -> Result<(), &'static str> {
|
||||
if let Terminal::Multi(_, _) = terminal {
|
||||
if let Terminal::Multi(_) = terminal {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("The descriptor contains operators not supported by Bitcoin Core")
|
||||
|
@ -1177,7 +1177,7 @@ impl Wallet {
|
||||
};
|
||||
|
||||
let mut changeset = ChangeSet::default();
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
changeset.append(self.indexed_graph.insert_tx(tx).into());
|
||||
if let Some(anchor) = anchor {
|
||||
changeset.append(self.indexed_graph.insert_anchor(txid, anchor).into());
|
||||
@ -1478,10 +1478,7 @@ impl Wallet {
|
||||
let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
|
||||
|
||||
for (index, (script_pubkey, value)) in recipients.enumerate() {
|
||||
if !params.allow_dust
|
||||
&& value.is_dust(script_pubkey)
|
||||
&& !script_pubkey.is_provably_unspendable()
|
||||
{
|
||||
if !params.allow_dust && value.is_dust(script_pubkey) && !script_pubkey.is_op_return() {
|
||||
return Err(CreateTxError::OutputBelowDustLimit(index));
|
||||
}
|
||||
|
||||
@ -1635,7 +1632,7 @@ impl Wallet {
|
||||
/// let tx = psbt.clone().extract_tx().expect("tx");
|
||||
/// // broadcast tx but it's taking too long to confirm so we want to bump the fee
|
||||
/// let mut psbt = {
|
||||
/// let mut builder = wallet.build_fee_bump(tx.txid())?;
|
||||
/// let mut builder = wallet.build_fee_bump(tx.compute_txid())?;
|
||||
/// builder
|
||||
/// .fee_rate(FeeRate::from_sat_per_vb(5).expect("valid feerate"));
|
||||
/// builder.finish()?
|
||||
@ -1673,7 +1670,9 @@ impl Wallet {
|
||||
.iter()
|
||||
.any(|txin| txin.sequence.to_consensus_u32() <= 0xFFFFFFFD)
|
||||
{
|
||||
return Err(BuildFeeBumpError::IrreplaceableTransaction(tx.txid()));
|
||||
return Err(BuildFeeBumpError::IrreplaceableTransaction(
|
||||
tx.compute_txid(),
|
||||
));
|
||||
}
|
||||
|
||||
let fee = self
|
||||
@ -1704,7 +1703,8 @@ impl Wallet {
|
||||
let satisfaction_weight = self
|
||||
.get_descriptor_for_keychain(keychain)
|
||||
.max_weight_to_satisfy()
|
||||
.unwrap();
|
||||
.unwrap()
|
||||
.to_wu() as usize;
|
||||
WeightedUtxo {
|
||||
utxo: Utxo::Local(LocalOutput {
|
||||
outpoint: txin.previous_output,
|
||||
@ -2037,6 +2037,7 @@ impl Wallet {
|
||||
self.get_descriptor_for_keychain(keychain)
|
||||
.max_weight_to_satisfy()
|
||||
.unwrap()
|
||||
.to_wu() as usize
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
@ -91,7 +91,7 @@ use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpriv};
|
||||
use bitcoin::hashes::hash160;
|
||||
use bitcoin::secp256k1::Message;
|
||||
use bitcoin::sighash::{EcdsaSighashType, TapSighash, TapSighashType};
|
||||
use bitcoin::{ecdsa, psbt, sighash, taproot};
|
||||
use bitcoin::{ecdsa, psbt, sighash, taproot, transaction};
|
||||
use bitcoin::{key::TapTweak, key::XOnlyPublicKey, secp256k1};
|
||||
use bitcoin::{PrivateKey, Psbt, PublicKey};
|
||||
|
||||
@ -159,8 +159,12 @@ pub enum SignerError {
|
||||
NonStandardSighash,
|
||||
/// Invalid SIGHASH for the signing context in use
|
||||
InvalidSighash,
|
||||
/// Error while computing the hash to sign
|
||||
SighashError(sighash::Error),
|
||||
/// Error while computing the hash to sign a P2WPKH input.
|
||||
SighashP2wpkh(sighash::P2wpkhError),
|
||||
/// Error while computing the hash to sign a Taproot input.
|
||||
SighashTaproot(sighash::TaprootError),
|
||||
/// Error while computing the hash, out of bounds access on the transaction inputs.
|
||||
TxInputsIndexError(transaction::InputsIndexError),
|
||||
/// Miniscript PSBT error
|
||||
MiniscriptPsbt(MiniscriptPsbtError),
|
||||
/// To be used only by external libraries implementing [`InputSigner`] or
|
||||
@ -169,9 +173,21 @@ pub enum SignerError {
|
||||
External(String),
|
||||
}
|
||||
|
||||
impl From<sighash::Error> for SignerError {
|
||||
fn from(e: sighash::Error) -> Self {
|
||||
SignerError::SighashError(e)
|
||||
impl From<transaction::InputsIndexError> for SignerError {
|
||||
fn from(v: transaction::InputsIndexError) -> Self {
|
||||
Self::TxInputsIndexError(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<sighash::P2wpkhError> for SignerError {
|
||||
fn from(e: sighash::P2wpkhError) -> Self {
|
||||
Self::SighashP2wpkh(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<sighash::TaprootError> for SignerError {
|
||||
fn from(e: sighash::TaprootError) -> Self {
|
||||
Self::SighashTaproot(e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +205,9 @@ impl fmt::Display for SignerError {
|
||||
Self::MissingHdKeypath => write!(f, "Missing fingerprint and derivation path"),
|
||||
Self::NonStandardSighash => write!(f, "The psbt contains a non standard sighash"),
|
||||
Self::InvalidSighash => write!(f, "Invalid SIGHASH for the signing context in use"),
|
||||
Self::SighashError(err) => write!(f, "Error while computing the hash to sign: {}", err),
|
||||
Self::SighashP2wpkh(err) => write!(f, "Error while computing the hash to sign a P2WPKH input: {}", err),
|
||||
Self::SighashTaproot(err) => write!(f, "Error while computing the hash to sign a Taproot input: {}", err),
|
||||
Self::TxInputsIndexError(err) => write!(f, "Error while computing the hash, out of bounds access on the transaction inputs: {}", err),
|
||||
Self::MiniscriptPsbt(err) => write!(f, "Miniscript PSBT error: {}", err),
|
||||
Self::External(err) => write!(f, "{}", err),
|
||||
}
|
||||
@ -549,21 +567,24 @@ fn sign_psbt_ecdsa(
|
||||
secret_key: &secp256k1::SecretKey,
|
||||
pubkey: PublicKey,
|
||||
psbt_input: &mut psbt::Input,
|
||||
hash: impl bitcoin::hashes::Hash + bitcoin::secp256k1::ThirtyTwoByteHash,
|
||||
hash_ty: EcdsaSighashType,
|
||||
hash: impl bitcoin::hashes::Hash<Bytes = [u8; 32]>,
|
||||
sighash_type: EcdsaSighashType,
|
||||
secp: &SecpCtx,
|
||||
allow_grinding: bool,
|
||||
) {
|
||||
let msg = &Message::from(hash);
|
||||
let sig = if allow_grinding {
|
||||
let msg = &Message::from_digest(hash.to_byte_array());
|
||||
let signature = if allow_grinding {
|
||||
secp.sign_ecdsa_low_r(msg, secret_key)
|
||||
} else {
|
||||
secp.sign_ecdsa(msg, secret_key)
|
||||
};
|
||||
secp.verify_ecdsa(msg, &sig, &pubkey.inner)
|
||||
secp.verify_ecdsa(msg, &signature, &pubkey.inner)
|
||||
.expect("invalid or corrupted ecdsa signature");
|
||||
|
||||
let final_signature = ecdsa::Signature { sig, hash_ty };
|
||||
let final_signature = ecdsa::Signature {
|
||||
signature,
|
||||
sighash_type,
|
||||
};
|
||||
psbt_input.partial_sigs.insert(pubkey, final_signature);
|
||||
}
|
||||
|
||||
@ -574,7 +595,7 @@ fn sign_psbt_schnorr(
|
||||
leaf_hash: Option<taproot::TapLeafHash>,
|
||||
psbt_input: &mut psbt::Input,
|
||||
hash: TapSighash,
|
||||
hash_ty: TapSighashType,
|
||||
sighash_type: TapSighashType,
|
||||
secp: &SecpCtx,
|
||||
) {
|
||||
let keypair = secp256k1::Keypair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
|
||||
@ -586,11 +607,14 @@ fn sign_psbt_schnorr(
|
||||
};
|
||||
|
||||
let msg = &Message::from(hash);
|
||||
let sig = secp.sign_schnorr(msg, &keypair);
|
||||
secp.verify_schnorr(&sig, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
|
||||
let signature = secp.sign_schnorr(msg, &keypair);
|
||||
secp.verify_schnorr(&signature, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
|
||||
.expect("invalid or corrupted schnorr signature");
|
||||
|
||||
let final_signature = taproot::Signature { sig, hash_ty };
|
||||
let final_signature = taproot::Signature {
|
||||
signature,
|
||||
sighash_type,
|
||||
};
|
||||
|
||||
if let Some(lh) = leaf_hash {
|
||||
psbt_input
|
||||
@ -933,7 +957,7 @@ impl ComputeSighash for Segwitv0 {
|
||||
// Always try first with the non-witness utxo
|
||||
let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
|
||||
// Check the provided prev-tx
|
||||
if prev_tx.txid() != tx_input.previous_output.txid {
|
||||
if prev_tx.compute_txid() != tx_input.previous_output.txid {
|
||||
return Err(SignerError::InvalidNonWitnessUtxo);
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,9 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
|
||||
|
||||
for utxo in utxos {
|
||||
let descriptor = wallet.get_descriptor_for_keychain(utxo.keychain);
|
||||
let satisfaction_weight = descriptor.max_weight_to_satisfy().unwrap();
|
||||
|
||||
let satisfaction_weight =
|
||||
descriptor.max_weight_to_satisfy().unwrap().to_wu() as usize;
|
||||
self.params.utxos.push(WeightedUtxo {
|
||||
satisfaction_weight,
|
||||
utxo: Utxo::Local(utxo),
|
||||
@ -385,9 +387,9 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
|
||||
if psbt_input.witness_utxo.is_none() {
|
||||
match psbt_input.non_witness_utxo.as_ref() {
|
||||
Some(tx) => {
|
||||
if tx.txid() != outpoint.txid {
|
||||
if tx.compute_txid() != outpoint.txid {
|
||||
return Err(AddForeignUtxoError::InvalidTxid {
|
||||
input_txid: tx.txid(),
|
||||
input_txid: tx.compute_txid(),
|
||||
foreign_utxo: outpoint,
|
||||
});
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
// licenses.
|
||||
|
||||
use bitcoin::secp256k1::{All, Secp256k1};
|
||||
use bitcoin::{absolute, Script, Sequence};
|
||||
use bitcoin::{absolute, relative, Script, Sequence};
|
||||
|
||||
use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
|
||||
|
||||
@ -26,7 +26,7 @@ pub trait IsDust {
|
||||
|
||||
impl IsDust for u64 {
|
||||
fn is_dust(&self, script: &Script) -> bool {
|
||||
*self < script.dust_value().to_sat()
|
||||
*self < script.minimal_non_dust().to_sat()
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ impl Older {
|
||||
}
|
||||
|
||||
impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for Older {
|
||||
fn check_older(&self, n: Sequence) -> bool {
|
||||
fn check_older(&self, n: relative::LockTime) -> bool {
|
||||
if let Some(current_height) = self.current_height {
|
||||
// TODO: test >= / >
|
||||
current_height
|
||||
|
@ -46,7 +46,7 @@ pub fn get_funded_wallet_with_change(descriptor: &str, change: &str) -> (Wallet,
|
||||
lock_time: bitcoin::absolute::LockTime::ZERO,
|
||||
input: vec![TxIn {
|
||||
previous_output: OutPoint {
|
||||
txid: tx0.txid(),
|
||||
txid: tx0.compute_txid(),
|
||||
vout: 0,
|
||||
},
|
||||
script_sig: Default::default(),
|
||||
@ -96,7 +96,7 @@ pub fn get_funded_wallet_with_change(descriptor: &str, change: &str) -> (Wallet,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
(wallet, tx1.txid())
|
||||
(wallet, tx1.compute_txid())
|
||||
}
|
||||
|
||||
/// Return a fake wallet that appears to be funded for testing.
|
||||
|
@ -45,7 +45,7 @@ fn receive_output(wallet: &mut Wallet, value: u64, height: ConfirmationTime) ->
|
||||
wallet.insert_tx(tx.clone(), height).unwrap();
|
||||
|
||||
OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0,
|
||||
}
|
||||
}
|
||||
@ -1151,7 +1151,7 @@ fn test_create_tx_add_utxo() {
|
||||
builder
|
||||
.add_recipient(addr.script_pubkey(), Amount::from_sat(30_000))
|
||||
.add_utxo(OutPoint {
|
||||
txid: small_output_tx.txid(),
|
||||
txid: small_output_tx.compute_txid(),
|
||||
vout: 0,
|
||||
})
|
||||
.unwrap();
|
||||
@ -1202,7 +1202,7 @@ fn test_create_tx_manually_selected_insufficient() {
|
||||
builder
|
||||
.add_recipient(addr.script_pubkey(), Amount::from_sat(30_000))
|
||||
.add_utxo(OutPoint {
|
||||
txid: small_output_tx.txid(),
|
||||
txid: small_output_tx.compute_txid(),
|
||||
vout: 0,
|
||||
})
|
||||
.unwrap()
|
||||
@ -1306,8 +1306,6 @@ fn test_create_tx_policy_path_ignored_subtree_with_csv() {
|
||||
#[test]
|
||||
fn test_create_tx_global_xpubs_with_origin() {
|
||||
use bitcoin::bip32;
|
||||
use bitcoin::hex::FromHex;
|
||||
|
||||
let (mut wallet, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
|
||||
let addr = wallet.next_unused_address(KeychainKind::External).unwrap();
|
||||
let mut builder = wallet.build_tx();
|
||||
@ -1348,7 +1346,11 @@ fn test_add_foreign_utxo() {
|
||||
builder
|
||||
.add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
|
||||
.only_witness_utxo()
|
||||
.add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
|
||||
.add_foreign_utxo(
|
||||
utxo.outpoint,
|
||||
psbt_input,
|
||||
foreign_utxo_satisfaction.to_wu() as usize,
|
||||
)
|
||||
.unwrap();
|
||||
let mut psbt = builder.finish().unwrap();
|
||||
wallet1.insert_txout(utxo.outpoint, utxo.txout);
|
||||
@ -1399,7 +1401,7 @@ fn test_add_foreign_utxo() {
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "MissingTxOut([OutPoint { txid: 0x21d7fb1bceda00ab4069fc52d06baa13470803e9050edd16f5736e5d8c4925fd, vout: 0 }])"
|
||||
expected = "MissingTxOut([OutPoint { txid: 21d7fb1bceda00ab4069fc52d06baa13470803e9050edd16f5736e5d8c4925fd, vout: 0 }])"
|
||||
)]
|
||||
fn test_calculate_fee_with_missing_foreign_utxo() {
|
||||
let (mut wallet1, _) = get_funded_wallet_wpkh();
|
||||
@ -1424,7 +1426,11 @@ fn test_calculate_fee_with_missing_foreign_utxo() {
|
||||
builder
|
||||
.add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
|
||||
.only_witness_utxo()
|
||||
.add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
|
||||
.add_foreign_utxo(
|
||||
utxo.outpoint,
|
||||
psbt_input,
|
||||
foreign_utxo_satisfaction.to_wu() as usize,
|
||||
)
|
||||
.unwrap();
|
||||
let psbt = builder.finish().unwrap();
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
@ -1441,8 +1447,11 @@ fn test_add_foreign_utxo_invalid_psbt_input() {
|
||||
.unwrap();
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
let result =
|
||||
builder.add_foreign_utxo(outpoint, psbt::Input::default(), foreign_utxo_satisfaction);
|
||||
let result = builder.add_foreign_utxo(
|
||||
outpoint,
|
||||
psbt::Input::default(),
|
||||
foreign_utxo_satisfaction.to_wu() as usize,
|
||||
);
|
||||
assert!(matches!(result, Err(AddForeignUtxoError::MissingUtxo)));
|
||||
}
|
||||
|
||||
@ -1470,7 +1479,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
|
||||
non_witness_utxo: Some(tx1.as_ref().clone()),
|
||||
..Default::default()
|
||||
},
|
||||
satisfaction_weight
|
||||
satisfaction_weight.to_wu() as usize
|
||||
)
|
||||
.is_err(),
|
||||
"should fail when outpoint doesn't match psbt_input"
|
||||
@ -1483,7 +1492,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
|
||||
non_witness_utxo: Some(tx2.as_ref().clone()),
|
||||
..Default::default()
|
||||
},
|
||||
satisfaction_weight
|
||||
satisfaction_weight.to_wu() as usize
|
||||
)
|
||||
.is_ok(),
|
||||
"should be ok when outpoint does match psbt_input"
|
||||
@ -1515,7 +1524,11 @@ fn test_add_foreign_utxo_only_witness_utxo() {
|
||||
..Default::default()
|
||||
};
|
||||
builder
|
||||
.add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
|
||||
.add_foreign_utxo(
|
||||
utxo2.outpoint,
|
||||
psbt_input,
|
||||
satisfaction_weight.to_wu() as usize,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
builder.finish().is_err(),
|
||||
@ -1531,7 +1544,11 @@ fn test_add_foreign_utxo_only_witness_utxo() {
|
||||
};
|
||||
builder
|
||||
.only_witness_utxo()
|
||||
.add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
|
||||
.add_foreign_utxo(
|
||||
utxo2.outpoint,
|
||||
psbt_input,
|
||||
satisfaction_weight.to_wu() as usize,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
builder.finish().is_ok(),
|
||||
@ -1547,7 +1564,11 @@ fn test_add_foreign_utxo_only_witness_utxo() {
|
||||
..Default::default()
|
||||
};
|
||||
builder
|
||||
.add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
|
||||
.add_foreign_utxo(
|
||||
utxo2.outpoint,
|
||||
psbt_input,
|
||||
satisfaction_weight.to_wu() as usize,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
builder.finish().is_ok(),
|
||||
@ -1583,8 +1604,6 @@ fn test_create_tx_global_xpubs_origin_missing() {
|
||||
#[test]
|
||||
fn test_create_tx_global_xpubs_master_without_origin() {
|
||||
use bitcoin::bip32;
|
||||
use bitcoin::hex::FromHex;
|
||||
|
||||
let (mut wallet, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
|
||||
let addr = wallet.next_unused_address(KeychainKind::External).unwrap();
|
||||
let mut builder = wallet.build_tx();
|
||||
@ -1613,7 +1632,7 @@ fn test_bump_fee_irreplaceable_tx() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -1630,7 +1649,7 @@ fn test_bump_fee_confirmed_tx() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
|
||||
wallet
|
||||
.insert_tx(
|
||||
@ -1657,7 +1676,7 @@ fn test_bump_fee_low_fee_rate() {
|
||||
let feerate = psbt.fee_rate().unwrap();
|
||||
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
@ -1690,7 +1709,7 @@ fn test_bump_fee_low_abs() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
@ -1713,7 +1732,7 @@ fn test_bump_fee_zero_abs() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -1739,7 +1758,7 @@ fn test_bump_fee_reduce_change() {
|
||||
let original_fee = check_fee!(wallet, psbt);
|
||||
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -1837,7 +1856,7 @@ fn test_bump_fee_reduce_single_recipient() {
|
||||
let tx = psbt.clone().extract_tx().expect("failed to extract tx");
|
||||
let original_sent_received = wallet.sent_and_received(&tx);
|
||||
let original_fee = check_fee!(wallet, psbt);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -1885,7 +1904,7 @@ fn test_bump_fee_absolute_reduce_single_recipient() {
|
||||
let original_fee = check_fee!(wallet, psbt);
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let original_sent_received = wallet.sent_and_received(&tx);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -1949,7 +1968,7 @@ fn test_bump_fee_drain_wallet() {
|
||||
builder
|
||||
.drain_to(addr.script_pubkey())
|
||||
.add_utxo(OutPoint {
|
||||
txid: tx.txid(),
|
||||
txid: tx.compute_txid(),
|
||||
vout: 0,
|
||||
})
|
||||
.unwrap()
|
||||
@ -1959,7 +1978,7 @@ fn test_bump_fee_drain_wallet() {
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let original_sent_received = wallet.sent_and_received(&tx);
|
||||
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -2011,7 +2030,7 @@ fn test_bump_fee_remove_output_manually_selected_only() {
|
||||
)
|
||||
.unwrap();
|
||||
let outpoint = OutPoint {
|
||||
txid: init_tx.txid(),
|
||||
txid: init_tx.compute_txid(),
|
||||
vout: 0,
|
||||
};
|
||||
let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
|
||||
@ -2027,7 +2046,7 @@ fn test_bump_fee_remove_output_manually_selected_only() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let original_sent_received = wallet.sent_and_received(&tx);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -2074,7 +2093,7 @@ fn test_bump_fee_add_input() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let original_details = wallet.sent_and_received(&tx);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -2131,7 +2150,7 @@ fn test_bump_fee_absolute_add_input() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let original_sent_received = wallet.sent_and_received(&tx);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -2197,7 +2216,7 @@ fn test_bump_fee_no_change_add_input_and_change() {
|
||||
let original_fee = check_fee!(wallet, psbt);
|
||||
|
||||
let tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -2267,7 +2286,7 @@ fn test_bump_fee_add_input_change_dust() {
|
||||
let original_tx_weight = tx.weight();
|
||||
assert_eq!(tx.input.len(), 1);
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
wallet
|
||||
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
|
||||
.unwrap();
|
||||
@ -2335,7 +2354,7 @@ fn test_bump_fee_force_add_input() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
let mut tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let original_sent_received = wallet.sent_and_received(&tx);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
|
||||
}
|
||||
@ -2401,7 +2420,7 @@ fn test_bump_fee_absolute_force_add_input() {
|
||||
let psbt = builder.finish().unwrap();
|
||||
let mut tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let original_sent_received = wallet.sent_and_received(&tx);
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
|
||||
@ -2481,7 +2500,7 @@ fn test_bump_fee_unconfirmed_inputs_only() {
|
||||
ConfirmationTime::Unconfirmed { last_seen: 0 },
|
||||
);
|
||||
let mut tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
|
||||
}
|
||||
@ -2514,7 +2533,7 @@ fn test_bump_fee_unconfirmed_input() {
|
||||
.enable_rbf();
|
||||
let psbt = builder.finish().unwrap();
|
||||
let mut tx = psbt.extract_tx().expect("failed to extract tx");
|
||||
let txid = tx.txid();
|
||||
let txid = tx.compute_txid();
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
|
||||
}
|
||||
@ -3386,7 +3405,11 @@ fn test_taproot_foreign_utxo() {
|
||||
let mut builder = wallet1.build_tx();
|
||||
builder
|
||||
.add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
|
||||
.add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
|
||||
.add_foreign_utxo(
|
||||
utxo.outpoint,
|
||||
psbt_input,
|
||||
foreign_utxo_satisfaction.to_wu() as usize,
|
||||
)
|
||||
.unwrap();
|
||||
let psbt = builder.finish().unwrap();
|
||||
let sent_received =
|
||||
@ -3890,7 +3913,10 @@ fn test_fee_rate_sign_no_grinding_high_r() {
|
||||
.unwrap();
|
||||
// We only have one key in the partial_sigs map, this is a trick to retrieve it
|
||||
let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
|
||||
sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
|
||||
sig_len = psbt.inputs[0].partial_sigs[key]
|
||||
.signature
|
||||
.serialize_der()
|
||||
.len();
|
||||
}
|
||||
// Actually finalizing the transaction...
|
||||
wallet
|
||||
@ -3936,7 +3962,10 @@ fn test_fee_rate_sign_grinding_low_r() {
|
||||
.unwrap();
|
||||
|
||||
let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
|
||||
let sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
|
||||
let sig_len = psbt.inputs[0].partial_sigs[key]
|
||||
.signature
|
||||
.serialize_der()
|
||||
.len();
|
||||
assert_eq!(sig_len, 70);
|
||||
assert_fee_rate!(psbt, fee.unwrap_or(Amount::ZERO), fee_rate);
|
||||
}
|
||||
|
@ -643,7 +643,7 @@ where
|
||||
|
||||
match (broadcast)(chain_specific, &transaction) {
|
||||
Ok(_) => {
|
||||
println!("Broadcasted Tx : {}", transaction.txid());
|
||||
println!("Broadcasted Tx : {}", transaction.compute_txid());
|
||||
|
||||
let keychain_changeset = graph.lock().unwrap().insert_tx(transaction);
|
||||
|
||||
|
@ -94,7 +94,7 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
let tx = psbt.extract_tx()?;
|
||||
client.transaction_broadcast(&tx)?;
|
||||
println!("Tx broadcasted! Txid: {}", tx.txid());
|
||||
println!("Tx broadcasted! Txid: {}", tx.compute_txid());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
let tx = psbt.extract_tx()?;
|
||||
client.broadcast(&tx).await?;
|
||||
println!("Tx broadcasted! Txid: {}", tx.txid());
|
||||
println!("Tx broadcasted! Txid: {}", tx.compute_txid());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
let tx = psbt.extract_tx()?;
|
||||
client.broadcast(&tx)?;
|
||||
println!("Tx broadcasted! Txid: {}", tx.txid());
|
||||
println!("Tx broadcasted! Txid: {}", tx.compute_txid());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ fn plan_steps<Ak: Clone + CanDerive, Ctx: ScriptContext>(
|
||||
if max_sequence.is_height_locked() == older.is_height_locked() {
|
||||
if max_sequence.to_consensus_u32() >= older.to_consensus_u32() {
|
||||
Some(TermPlan {
|
||||
min_sequence: Some(*older),
|
||||
min_sequence: Some((*older).into()),
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
@ -318,8 +318,8 @@ fn plan_steps<Ak: Clone + CanDerive, Ctx: ScriptContext>(
|
||||
(lplan, rplan) => lplan.or(rplan),
|
||||
}
|
||||
}
|
||||
Terminal::Thresh(_, _) => todo!(),
|
||||
Terminal::Multi(_, _) => todo!(),
|
||||
Terminal::MultiA(_, _) => todo!(),
|
||||
Terminal::Thresh(_) => todo!(),
|
||||
Terminal::Multi(_) => todo!(),
|
||||
Terminal::MultiA(_) => todo!(),
|
||||
}
|
||||
}
|
||||
|
@ -87,20 +87,28 @@ pub enum RequiredSignatures<Ak> {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SigningError {
|
||||
SigHashError(sighash::Error),
|
||||
SigHashP2wpkh(sighash::P2wpkhError),
|
||||
SigHashTaproot(sighash::TaprootError),
|
||||
DerivationError(bip32::Error),
|
||||
}
|
||||
|
||||
impl From<sighash::Error> for SigningError {
|
||||
fn from(e: sighash::Error) -> Self {
|
||||
Self::SigHashError(e)
|
||||
impl From<sighash::TaprootError> for SigningError {
|
||||
fn from(v: sighash::TaprootError) -> Self {
|
||||
Self::SigHashTaproot(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<sighash::P2wpkhError> for SigningError {
|
||||
fn from(v: sighash::P2wpkhError) -> Self {
|
||||
Self::SigHashP2wpkh(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for SigningError {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
SigningError::SigHashError(e) => e.fmt(f),
|
||||
SigningError::SigHashP2wpkh(e) => e.fmt(f),
|
||||
SigningError::SigHashTaproot(e) => e.fmt(f),
|
||||
SigningError::DerivationError(e) => e.fmt(f),
|
||||
}
|
||||
}
|
||||
@ -170,8 +178,8 @@ impl RequiredSignatures<DescriptorPublicKey> {
|
||||
let sig = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
|
||||
|
||||
let bitcoin_sig = taproot::Signature {
|
||||
sig,
|
||||
hash_ty: schnorr_sighashty,
|
||||
signature: sig,
|
||||
sighash_type: schnorr_sighashty,
|
||||
};
|
||||
|
||||
auth_data
|
||||
@ -210,10 +218,10 @@ impl RequiredSignatures<DescriptorPublicKey> {
|
||||
};
|
||||
let keypair = Keypair::from_secret_key(&secp, &secret_key.clone());
|
||||
let msg = Message::from_digest(sighash.to_byte_array());
|
||||
let sig = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
|
||||
let signature = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
|
||||
let bitcoin_sig = taproot::Signature {
|
||||
sig,
|
||||
hash_ty: sighash_type,
|
||||
signature,
|
||||
sighash_type,
|
||||
};
|
||||
|
||||
auth_data
|
||||
|
Loading…
x
Reference in New Issue
Block a user