@@ -1711,15 +1711,15 @@ impl Wallet {
17111711 &mut self,
17121712 txid: Txid,
17131713 ) -> Result<TxBuilder<'_, DefaultCoinSelectionAlgorithm>, BuildFeeBumpError> {
1714- let graph = self.indexed_graph.graph();
1714+ let tx_graph = self.indexed_graph.graph();
17151715 let txout_index = &self.indexed_graph.index;
17161716 let chain_tip = self.chain.tip().block_id();
1717- let chain_positions = graph
1717+ let chain_positions: HashMap<Txid, ChainPosition<_>> = tx_graph
17181718 .list_canonical_txs(&self.chain, chain_tip, CanonicalizationParams::default())
17191719 .map(|canon_tx| (canon_tx.tx_node.txid, canon_tx.chain_position))
1720- .collect::<HashMap<Txid, _>> ();
1720+ .collect();
17211721
1722- let mut tx = graph
1722+ let mut tx = tx_graph
17231723 .get_tx(txid)
17241724 .ok_or(BuildFeeBumpError::TransactionNotFound(txid))?
17251725 .as_ref()
@@ -1746,73 +1746,62 @@ impl Wallet {
17461746 let fee = self
17471747 .calculate_fee(&tx)
17481748 .map_err(|_| BuildFeeBumpError::FeeRateUnavailable)?;
1749- let fee_rate = self
1750- .calculate_fee_rate(&tx)
1751- .map_err(|_| BuildFeeBumpError::FeeRateUnavailable)?;
1749+ let fee_rate = fee / tx.weight();
17521750
17531751 // Remove the inputs from the tx and process them.
1754- let utxos = tx
1752+ let utxos: Vec<WeightedUtxo> = tx
17551753 .input
17561754 .drain(..)
17571755 .map(|txin| -> Result<_, BuildFeeBumpError> {
1758- graph
1759- // Get previous transaction.
1760- .get_tx(txin.previous_output.txid)
1761- .ok_or(BuildFeeBumpError::UnknownUtxo(txin.previous_output))
1762- // Get chain position.
1763- .and_then(|prev_tx| {
1756+ let outpoint = txin.previous_output;
1757+ let prev_txout = tx_graph
1758+ .get_txout(outpoint)
1759+ .cloned()
1760+ .ok_or(BuildFeeBumpError::UnknownUtxo(outpoint))?;
1761+ match txout_index.index_of_spk(prev_txout.script_pubkey.clone()) {
1762+ Some(&(keychain, derivation_index)) => {
1763+ let txout = prev_txout;
17641764 let chain_position = chain_positions
1765- .get(&txin.previous_output .txid)
1765+ .get(&outpoint .txid)
17661766 .cloned()
1767- .ok_or(BuildFeeBumpError::UnknownUtxo(txin.previous_output))?;
1768- let prev_txout = prev_tx
1769- .output
1770- .get(txin.previous_output.vout as usize)
1771- .ok_or(BuildFeeBumpError::InvalidOutputIndex(txin.previous_output))
1772- .cloned()?;
1773- Ok((prev_tx, prev_txout, chain_position))
1774- })
1775- .map(|(prev_tx, prev_txout, chain_position)| {
1776- match txout_index.index_of_spk(prev_txout.script_pubkey.clone()) {
1777- Some(&(keychain, derivation_index)) => WeightedUtxo {
1778- satisfaction_weight: self
1779- .public_descriptor(keychain)
1780- .max_weight_to_satisfy()
1781- .unwrap(),
1782- utxo: Utxo::Local(LocalOutput {
1783- outpoint: txin.previous_output,
1784- txout: prev_txout.clone(),
1785- keychain,
1786- is_spent: true,
1787- derivation_index,
1788- chain_position,
1789- }),
1790- },
1791- None => {
1792- let satisfaction_weight = Weight::from_wu_usize(
1793- serialize(&txin.script_sig).len() * 4
1794- + serialize(&txin.witness).len(),
1795- );
1796- WeightedUtxo {
1797- utxo: Utxo::Foreign {
1798- outpoint: txin.previous_output,
1799- sequence: txin.sequence,
1800- psbt_input: Box::new(psbt::Input {
1801- witness_utxo: prev_txout
1802- .script_pubkey
1803- .witness_version()
1804- .map(|_| prev_txout.clone()),
1805- non_witness_utxo: Some(prev_tx.as_ref().clone()),
1806- ..Default::default()
1807- }),
1808- },
1809- satisfaction_weight,
1810- }
1811- }
1812- }
1813- })
1767+ .ok_or(BuildFeeBumpError::TransactionNotFound(outpoint.txid))?;
1768+ Ok(WeightedUtxo {
1769+ satisfaction_weight: self
1770+ .public_descriptor(keychain)
1771+ .max_weight_to_satisfy()
1772+ .expect("descriptor should be satisfiable"),
1773+ utxo: Utxo::Local(LocalOutput {
1774+ outpoint,
1775+ txout,
1776+ keychain,
1777+ is_spent: true,
1778+ derivation_index,
1779+ chain_position,
1780+ }),
1781+ })
1782+ }
1783+ None => Ok(WeightedUtxo {
1784+ satisfaction_weight: Weight::from_wu_usize(
1785+ serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len(),
1786+ ),
1787+ utxo: Utxo::Foreign {
1788+ outpoint,
1789+ sequence: txin.sequence,
1790+ psbt_input: Box::new(psbt::Input {
1791+ witness_utxo: prev_txout
1792+ .script_pubkey
1793+ .witness_version()
1794+ .map(|_| prev_txout),
1795+ non_witness_utxo: tx_graph
1796+ .get_tx(outpoint.txid)
1797+ .map(|tx| tx.as_ref().clone()),
1798+ ..Default::default()
1799+ }),
1800+ },
1801+ }),
1802+ }
18141803 })
1815- .collect::<Result<Vec<WeightedUtxo>, BuildFeeBumpError >>()?;
1804+ .collect::<Result<_, _ >>()?;
18161805
18171806 if tx.output.len() > 1 {
18181807 let mut change_index = None;
@@ -1832,7 +1821,6 @@ impl Wallet {
18321821 }
18331822
18341823 let params = TxParams {
1835- // TODO: figure out what rbf option should be?
18361824 version: Some(tx.version),
18371825 recipients: tx
18381826 .output
0 commit comments