/// The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000
/// to a foreign address and one returning 50_000 back to the wallet. The remaining 1000
/// sats are the transaction fee.
-pub fn get_funded_wallet(descriptor: &str, change_descriptor: &str) -> (Wallet, bitcoin::Txid) {
+pub fn get_funded_wallet(descriptor: &str, change_descriptor: &str) -> (Wallet, Txid) {
new_funded_wallet(descriptor, Some(change_descriptor))
}
-fn new_funded_wallet(descriptor: &str, change_descriptor: Option<&str>) -> (Wallet, bitcoin::Txid) {
+fn new_funded_wallet(descriptor: &str, change_descriptor: Option<&str>) -> (Wallet, Txid) {
let params = if let Some(change_desc) = change_descriptor {
Wallet::create(descriptor.to_string(), change_desc.to_string())
} else {
.unwrap();
let tx0 = Transaction {
- version: transaction::Version::ONE,
- lock_time: bitcoin::absolute::LockTime::ZERO,
- input: vec![TxIn {
- previous_output: OutPoint {
- txid: Txid::all_zeros(),
- vout: 0,
- },
- script_sig: Default::default(),
- sequence: Default::default(),
- witness: Default::default(),
- }],
output: vec![TxOut {
value: Amount::from_sat(76_000),
script_pubkey: receive_address.script_pubkey(),
}],
+ ..new_tx(0)
};
let tx1 = Transaction {
- version: transaction::Version::ONE,
- lock_time: bitcoin::absolute::LockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint {
txid: tx0.compute_txid(),
vout: 0,
},
- script_sig: Default::default(),
- sequence: Default::default(),
- witness: Default::default(),
+ ..Default::default()
}],
output: vec![
TxOut {
script_pubkey: sendto_address.script_pubkey(),
},
],
+ ..new_tx(0)
};
- wallet
- .insert_checkpoint(BlockId {
+ insert_checkpoint(
+ &mut wallet,
+ BlockId {
height: 42,
hash: BlockHash::all_zeros(),
- })
- .unwrap();
- wallet
- .insert_checkpoint(BlockId {
+ },
+ );
+ insert_checkpoint(
+ &mut wallet,
+ BlockId {
height: 1_000,
hash: BlockHash::all_zeros(),
- })
- .unwrap();
- wallet
- .insert_checkpoint(BlockId {
+ },
+ );
+ insert_checkpoint(
+ &mut wallet,
+ BlockId {
height: 2_000,
hash: BlockHash::all_zeros(),
- })
- .unwrap();
+ },
+ );
- wallet.insert_tx(tx0.clone());
+ insert_tx(&mut wallet, tx0.clone());
insert_anchor(
&mut wallet,
tx0.compute_txid(),
},
);
- wallet.insert_tx(tx1.clone());
+ insert_tx(&mut wallet, tx1.clone());
insert_anchor(
&mut wallet,
tx1.compute_txid(),
/// The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000
/// to a foreign address and one returning 50_000 back to the wallet. The remaining 1000
/// sats are the transaction fee.
-pub fn get_funded_wallet_single(descriptor: &str) -> (Wallet, bitcoin::Txid) {
+pub fn get_funded_wallet_single(descriptor: &str) -> (Wallet, Txid) {
new_funded_wallet(descriptor, None)
}
/// Get funded segwit wallet
-pub fn get_funded_wallet_wpkh() -> (Wallet, bitcoin::Txid) {
+pub fn get_funded_wallet_wpkh() -> (Wallet, Txid) {
let (desc, change_desc) = get_test_wpkh_and_change_desc();
get_funded_wallet(desc, change_desc)
}
"tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG,{pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
}
+/// A new empty transaction with the given locktime
+pub fn new_tx(locktime: u32) -> Transaction {
+ Transaction {
+ version: transaction::Version::ONE,
+ lock_time: absolute::LockTime::from_consensus(locktime),
+ input: vec![],
+ output: vec![],
+ }
+}
+
/// Construct a new [`FeeRate`] from the given raw `sat_vb` feerate. This is
/// useful in cases where we want to create a feerate from a `f64`, as the
/// traditional [`FeeRate::from_sat_per_vb`] method will only accept an integer.
};
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
+ insert_tx(wallet, tx);
match pos {
ChainPosition::Confirmed(anchor) => {
lock_time: absolute::LockTime::ZERO,
};
let txid = small_output_tx.compute_txid();
- wallet.insert_tx(small_output_tx);
+ insert_tx(&mut wallet, small_output_tx);
let anchor = ConfirmationBlockTime {
block_id: wallet.latest_checkpoint().block_id(),
confirmation_time: 200,
lock_time: absolute::LockTime::ZERO,
};
let txid = small_output_tx.compute_txid();
- wallet.insert_tx(small_output_tx.clone());
+ insert_tx(&mut wallet, small_output_tx.clone());
let anchor = ConfirmationBlockTime {
block_id: wallet.latest_checkpoint().block_id(),
confirmation_time: 200,
value: Amount::from_sat(50_000),
}],
};
- let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
let root_id = external_policy.id;
}
#[test]
-#[should_panic(
- expected = "MissingTxOut([OutPoint { txid: 21d7fb1bceda00ab4069fc52d06baa13470803e9050edd16f5736e5d8c4925fd, vout: 0 }])"
-)]
fn test_calculate_fee_with_missing_foreign_utxo() {
+ use bdk_chain::tx_graph::CalculateFeeError;
let (mut wallet1, _) = get_funded_wallet_wpkh();
let (wallet2, _) =
get_funded_wallet_single("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
.unwrap();
let psbt = builder.finish().unwrap();
let tx = psbt.extract_tx().expect("failed to extract tx");
- wallet1.calculate_fee(&tx).unwrap();
+ let res = wallet1.calculate_fee(&tx);
+ assert!(
+ matches!(res, Err(CalculateFeeError::MissingTxOut(outpoints)) if outpoints[0] == utxo.outpoint)
+ );
}
#[test]
let tx = psbt.extract_tx().expect("failed to extract tx");
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
wallet.build_fee_bump(txid).unwrap().finish().unwrap();
}
let tx = psbt.extract_tx().expect("failed to extract tx");
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
+ insert_tx(&mut wallet, tx);
let anchor = ConfirmationBlockTime {
block_id: wallet.latest_checkpoint().get(42).unwrap().block_id(),
let tx = psbt.extract_tx().expect("failed to extract tx");
let txid = tx.compute_txid();
-
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_rate(FeeRate::BROADCAST_MIN);
let tx = psbt.extract_tx().expect("failed to extract tx");
let txid = tx.compute_txid();
-
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_absolute(Amount::from_sat(10));
let tx = psbt.extract_tx().expect("failed to extract tx");
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_absolute(Amount::ZERO);
let tx = psbt.extract_tx().expect("failed to extract tx");
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let feerate = FeeRate::from_sat_per_kwu(625); // 2.5 sat/vb
let mut builder = wallet.build_fee_bump(txid).unwrap();
let original_sent_received = wallet.sent_and_received(&tx);
let original_fee = check_fee!(wallet, psbt);
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let feerate = FeeRate::from_sat_per_kwu(625); // 2.5 sat/vb
let mut builder = wallet.build_fee_bump(txid).unwrap();
let tx = psbt.extract_tx().expect("failed to extract tx");
let original_sent_received = wallet.sent_and_received(&tx);
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder
}],
};
let txid = tx.compute_txid();
- wallet.insert_tx(tx.clone());
+ insert_tx(&mut wallet, tx.clone());
let anchor = ConfirmationBlockTime {
block_id: wallet.latest_checkpoint().block_id(),
confirmation_time: 42_000,
let original_sent_received = wallet.sent_and_received(&tx);
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
assert_eq!(original_sent_received.0, Amount::from_sat(25_000));
// for the new feerate, it should be enough to reduce the output, but since we specify
}],
};
- wallet.insert_tx(init_tx.clone());
+ insert_tx(&mut wallet, init_tx.clone());
let anchor = ConfirmationBlockTime {
block_id: wallet.latest_checkpoint().block_id(),
confirmation_time: 200,
let tx = psbt.extract_tx().expect("failed to extract tx");
let original_sent_received = wallet.sent_and_received(&tx);
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
assert_eq!(original_sent_received.0, Amount::from_sat(25_000));
let mut builder = wallet.build_fee_bump(txid).unwrap();
}],
};
let txid = init_tx.compute_txid();
- wallet.insert_tx(init_tx);
+ insert_tx(&mut wallet, init_tx);
let anchor = ConfirmationBlockTime {
block_id: wallet.latest_checkpoint().block_id(),
confirmation_time: 200,
let tx = psbt.extract_tx().expect("failed to extract tx");
let original_details = wallet.sent_and_received(&tx);
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_rate(FeeRate::from_sat_per_vb_unchecked(50));
let tx = psbt.extract_tx().expect("failed to extract tx");
let original_sent_received = wallet.sent_and_received(&tx);
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_absolute(Amount::from_sat(6_000));
let tx = psbt.extract_tx().expect("failed to extract tx");
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
// Now bump the fees, the wallet should add an extra input and a change output, and leave
// the original output untouched.
assert_eq!(tx.input.len(), 1);
assert_eq!(tx.output.len(), 2);
let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
// We set a fee high enough that during rbf we are forced to add
for txin in &mut tx.input {
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
}
- wallet.insert_tx(tx.clone());
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx.clone());
// the new fee_rate is low enough that just reducing the change would be fine, but we force
// the addition of an extra input with `add_utxo()`
let mut builder = wallet.build_fee_bump(txid).unwrap();
for txin in &mut tx.input {
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
}
- wallet.insert_tx(tx.clone());
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx.clone());
// the new fee_rate is low enough that just reducing the change would be fine, but we force
// the addition of an extra input with `add_utxo()`
for txin in &mut tx.input {
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
}
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_rate(FeeRate::from_sat_per_vb_unchecked(25));
builder.finish().unwrap();
for txin in &mut tx.input {
txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
}
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 0);
+ insert_tx(&mut wallet, tx);
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder
height: confirmation_height,
hash: BlockHash::all_zeros(),
};
- wallet.insert_checkpoint(confirmation_block_id).unwrap();
+ insert_checkpoint(&mut wallet, confirmation_block_id);
let coinbase_tx = Transaction {
version: transaction::Version::ONE,
lock_time: absolute::LockTime::ZERO,
}],
};
let txid = coinbase_tx.compute_txid();
- wallet.insert_tx(coinbase_tx);
+ insert_tx(&mut wallet, coinbase_tx);
let anchor = ConfirmationBlockTime {
block_id: confirmation_block_id,
confirmation_time: 30_000,
))
);
- wallet
- .insert_checkpoint(BlockId {
+ insert_checkpoint(
+ &mut wallet,
+ BlockId {
height: maturity_time,
hash: BlockHash::all_zeros(),
- })
- .unwrap();
+ },
+ );
let balance = wallet.balance();
assert_eq!(
balance,
let mut psbt = builder.finish().unwrap();
assert!(wallet.sign(&mut psbt, SignOptions::default()).unwrap());
let tx = psbt.extract_tx().unwrap();
- let txid = tx.compute_txid();
- wallet.insert_tx(tx);
- insert_seen_at(&mut wallet, txid, 4);
+ let _txid = tx.compute_txid();
+ insert_tx(&mut wallet, tx);
let unspent: Vec<_> = wallet.list_unspent().collect();
assert_eq!(unspent.len(), 1);
let utxo = unspent.first().unwrap();