feat(chain)!: wrap TxGraph txs with Arc
Wrapping transactions as `Arc<Transaction>` allows us to share transactions cheaply between the chain-source and receiving structures. Therefore the chain-source can keep already-fetched transactions (save bandwidth) and have a shared pointer to the transactions (save memory). This is better than the current way we do things, which is to refer back to the receiving structures mid-sync. Documentation for `TxGraph` is also updated.
This commit is contained in:
@@ -942,7 +942,7 @@ impl<D> Wallet<D> {
|
||||
/// # let mut wallet: Wallet<()> = todo!();
|
||||
/// # let txid:Txid = todo!();
|
||||
/// let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
|
||||
/// let fee = wallet.calculate_fee(tx).expect("fee");
|
||||
/// let fee = wallet.calculate_fee(&tx).expect("fee");
|
||||
/// ```
|
||||
///
|
||||
/// ```rust, no_run
|
||||
@@ -973,7 +973,7 @@ impl<D> Wallet<D> {
|
||||
/// # let mut wallet: Wallet<()> = todo!();
|
||||
/// # let txid:Txid = todo!();
|
||||
/// let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
|
||||
/// let fee_rate = wallet.calculate_fee_rate(tx).expect("fee rate");
|
||||
/// let fee_rate = wallet.calculate_fee_rate(&tx).expect("fee rate");
|
||||
/// ```
|
||||
///
|
||||
/// ```rust, no_run
|
||||
@@ -981,8 +981,8 @@ impl<D> Wallet<D> {
|
||||
/// # use bdk::Wallet;
|
||||
/// # let mut wallet: Wallet<()> = todo!();
|
||||
/// # let mut psbt: PartiallySignedTransaction = todo!();
|
||||
/// let tx = &psbt.clone().extract_tx();
|
||||
/// let fee_rate = wallet.calculate_fee_rate(tx).expect("fee rate");
|
||||
/// let tx = psbt.clone().extract_tx();
|
||||
/// let fee_rate = wallet.calculate_fee_rate(&tx).expect("fee rate");
|
||||
/// ```
|
||||
/// [`insert_txout`]: Self::insert_txout
|
||||
pub fn calculate_fee_rate(&self, tx: &Transaction) -> Result<FeeRate, CalculateFeeError> {
|
||||
@@ -1003,8 +1003,8 @@ impl<D> Wallet<D> {
|
||||
/// # use bdk::Wallet;
|
||||
/// # let mut wallet: Wallet<()> = todo!();
|
||||
/// # let txid:Txid = todo!();
|
||||
/// let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
|
||||
/// let (sent, received) = wallet.sent_and_received(tx);
|
||||
/// let tx = wallet.get_tx(txid).expect("tx exists").tx_node.tx;
|
||||
/// let (sent, received) = wallet.sent_and_received(&tx);
|
||||
/// ```
|
||||
///
|
||||
/// ```rust, no_run
|
||||
@@ -1065,7 +1065,7 @@ impl<D> Wallet<D> {
|
||||
pub fn get_tx(
|
||||
&self,
|
||||
txid: Txid,
|
||||
) -> Option<CanonicalTx<'_, Transaction, ConfirmationTimeHeightAnchor>> {
|
||||
) -> Option<CanonicalTx<'_, Arc<Transaction>, ConfirmationTimeHeightAnchor>> {
|
||||
let graph = self.indexed_graph.graph();
|
||||
|
||||
Some(CanonicalTx {
|
||||
@@ -1167,7 +1167,8 @@ impl<D> Wallet<D> {
|
||||
/// Iterate over the transactions in the wallet.
|
||||
pub fn transactions(
|
||||
&self,
|
||||
) -> impl Iterator<Item = CanonicalTx<'_, Transaction, ConfirmationTimeHeightAnchor>> + '_ {
|
||||
) -> impl Iterator<Item = CanonicalTx<'_, Arc<Transaction>, ConfirmationTimeHeightAnchor>> + '_
|
||||
{
|
||||
self.indexed_graph
|
||||
.graph()
|
||||
.list_chain_txs(&self.chain, self.chain.tip().block_id())
|
||||
@@ -1670,6 +1671,7 @@ impl<D> Wallet<D> {
|
||||
let mut tx = graph
|
||||
.get_tx(txid)
|
||||
.ok_or(BuildFeeBumpError::TransactionNotFound(txid))?
|
||||
.as_ref()
|
||||
.clone();
|
||||
|
||||
let pos = graph
|
||||
@@ -1739,7 +1741,7 @@ impl<D> Wallet<D> {
|
||||
sequence: Some(txin.sequence),
|
||||
psbt_input: Box::new(psbt::Input {
|
||||
witness_utxo: Some(txout.clone()),
|
||||
non_witness_utxo: Some(prev_tx.clone()),
|
||||
non_witness_utxo: Some(prev_tx.as_ref().clone()),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
@@ -2295,7 +2297,7 @@ impl<D> Wallet<D> {
|
||||
psbt_input.witness_utxo = Some(prev_tx.output[prev_output.vout as usize].clone());
|
||||
}
|
||||
if !desc.is_taproot() && (!desc.is_witness() || !only_witness_utxo) {
|
||||
psbt_input.non_witness_utxo = Some(prev_tx.clone());
|
||||
psbt_input.non_witness_utxo = Some(prev_tx.as_ref().clone());
|
||||
}
|
||||
}
|
||||
Ok(psbt_input)
|
||||
|
||||
@@ -208,12 +208,12 @@ fn test_get_funded_wallet_sent_and_received() {
|
||||
|
||||
let mut tx_amounts: Vec<(Txid, (u64, u64))> = wallet
|
||||
.transactions()
|
||||
.map(|ct| (ct.tx_node.txid, wallet.sent_and_received(ct.tx_node.tx)))
|
||||
.map(|ct| (ct.tx_node.txid, wallet.sent_and_received(&ct.tx_node)))
|
||||
.collect();
|
||||
tx_amounts.sort_by(|a1, a2| a1.0.cmp(&a2.0));
|
||||
|
||||
let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
|
||||
let (sent, received) = wallet.sent_and_received(tx);
|
||||
let (sent, received) = wallet.sent_and_received(&tx);
|
||||
|
||||
// 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 as change. The remaining 1000
|
||||
@@ -227,7 +227,7 @@ fn test_get_funded_wallet_tx_fees() {
|
||||
let (wallet, txid) = get_funded_wallet(get_test_wpkh());
|
||||
|
||||
let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
|
||||
let tx_fee = wallet.calculate_fee(tx).expect("transaction fee");
|
||||
let tx_fee = wallet.calculate_fee(&tx).expect("transaction fee");
|
||||
|
||||
// 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 as change. The remaining 1000
|
||||
@@ -240,7 +240,9 @@ fn test_get_funded_wallet_tx_fee_rate() {
|
||||
let (wallet, txid) = get_funded_wallet(get_test_wpkh());
|
||||
|
||||
let tx = wallet.get_tx(txid).expect("transaction").tx_node.tx;
|
||||
let tx_fee_rate = wallet.calculate_fee_rate(tx).expect("transaction fee rate");
|
||||
let tx_fee_rate = wallet
|
||||
.calculate_fee_rate(&tx)
|
||||
.expect("transaction fee rate");
|
||||
|
||||
// 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 as change. The remaining 1000
|
||||
@@ -1307,7 +1309,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
|
||||
.add_foreign_utxo(
|
||||
utxo2.outpoint,
|
||||
psbt::Input {
|
||||
non_witness_utxo: Some(tx1),
|
||||
non_witness_utxo: Some(tx1.as_ref().clone()),
|
||||
..Default::default()
|
||||
},
|
||||
satisfaction_weight
|
||||
@@ -1320,7 +1322,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
|
||||
.add_foreign_utxo(
|
||||
utxo2.outpoint,
|
||||
psbt::Input {
|
||||
non_witness_utxo: Some(tx2),
|
||||
non_witness_utxo: Some(tx2.as_ref().clone()),
|
||||
..Default::default()
|
||||
},
|
||||
satisfaction_weight
|
||||
@@ -1384,7 +1386,7 @@ fn test_add_foreign_utxo_only_witness_utxo() {
|
||||
let mut builder = builder.clone();
|
||||
let tx2 = wallet2.get_tx(txid2).unwrap().tx_node.tx;
|
||||
let psbt_input = psbt::Input {
|
||||
non_witness_utxo: Some(tx2.clone()),
|
||||
non_witness_utxo: Some(tx2.as_ref().clone()),
|
||||
..Default::default()
|
||||
};
|
||||
builder
|
||||
@@ -3050,7 +3052,8 @@ fn test_taproot_sign_using_non_witness_utxo() {
|
||||
let mut psbt = builder.finish().unwrap();
|
||||
|
||||
psbt.inputs[0].witness_utxo = None;
|
||||
psbt.inputs[0].non_witness_utxo = Some(wallet.get_tx(prev_txid).unwrap().tx_node.tx.clone());
|
||||
psbt.inputs[0].non_witness_utxo =
|
||||
Some(wallet.get_tx(prev_txid).unwrap().tx_node.as_ref().clone());
|
||||
assert!(
|
||||
psbt.inputs[0].non_witness_utxo.is_some(),
|
||||
"Previous tx should be present in the database"
|
||||
|
||||
Reference in New Issue
Block a user