Skip to content

Commit

Permalink
tests(api): add coin selection to create_spend tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jp1ac4 committed Oct 18, 2023
1 parent c82ef5d commit 5c3d9f4
Showing 1 changed file with 77 additions and 0 deletions.
77 changes: 77 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,12 @@ mod tests {
spend_txid: None,
spend_block: None,
}]);
// If we try to use coin selection, the unconfirmed coin will not be used as a candidate
// and so we get a coin selection error due to insufficient funds.
assert!(matches!(
control.create_spend(&destinations, &[], 1),
Err(CommandError::CoinSelectionError(..))
));
let res = control.create_spend(&destinations, &[dummy_op], 1).unwrap();
assert!(res.psbt.inputs[0].non_witness_utxo.is_some());
let tx = res.psbt.unsigned_tx;
Expand Down Expand Up @@ -1173,6 +1179,12 @@ mod tests {
control.create_spend(&destinations, &[dummy_op], 1),
Err(CommandError::AlreadySpent(dummy_op))
);
// If we try to use coin selection, the spent coin will not be used as a candidate
// and so we get a coin selection error due to insufficient funds.
assert!(matches!(
control.create_spend(&destinations, &[], 1),
Err(CommandError::CoinSelectionError(..))
));

// We'd bail out if they tried to create a transaction with a too high feerate.
let dummy_op_dup = bitcoin::OutPoint {
Expand All @@ -1196,6 +1208,71 @@ mod tests {
)))
);

// Add a confirmed unspent coin to be used for coin selection.
let confirmed_op_1 = bitcoin::OutPoint {
txid: dummy_op.txid,
vout: dummy_op.vout + 100,
};
db_conn.new_unspent_coins(&[Coin {
outpoint: confirmed_op_1,
is_immature: false,
block_info: Some(BlockInfo {
height: 174500,
time: 174500,
}),
amount: bitcoin::Amount::from_sat(80_000),
derivation_index: bip32::ChildNumber::from(42),
is_change: false,
spend_txid: None,
spend_block: None,
}]);
// Coin selection error due to insufficient funds.
assert!(matches!(
control.create_spend(&destinations, &[], 1),
Err(CommandError::CoinSelectionError(..))
));
// Set destination amount equal to value of confirmed coins.
*destinations.get_mut(&dummy_addr).unwrap() = 80_000;
// Coin selection error occurs due to insufficient funds to pay fee.
assert!(matches!(
control.create_spend(&destinations, &[], 1),
Err(CommandError::CoinSelectionError(..))
));
let confirmed_op_2 = bitcoin::OutPoint {
txid: confirmed_op_1.txid,
vout: confirmed_op_1.vout + 10,
};
// Add new confirmed coin to cover the fee.
db_conn.new_unspent_coins(&[Coin {
outpoint: confirmed_op_2,
is_immature: false,
block_info: Some(BlockInfo {
height: 174500,
time: 174500,
}),
amount: bitcoin::Amount::from_sat(20_000),
derivation_index: bip32::ChildNumber::from(43),
is_change: false,
spend_txid: None,
spend_block: None,
}]);
let res = control.create_spend(&destinations, &[], 2).unwrap();
let tx = res.psbt.unsigned_tx;
let mut tx_prev_outpoints = tx
.input
.iter()
.map(|txin| txin.previous_output)
.collect::<Vec<OutPoint>>();
tx_prev_outpoints.sort();
assert_eq!(tx.input.len(), 2);
assert_eq!(tx_prev_outpoints, vec![confirmed_op_1, confirmed_op_2]);
assert_eq!(tx.output.len(), 2);
assert_eq!(
tx.output[0].script_pubkey,
dummy_addr.payload.script_pubkey()
);
assert_eq!(tx.output[0].value, 80_000);

// Can't create a transaction that spends an immature coinbase deposit.
let imma_op = bitcoin::OutPoint::from_str(
"4753a1d74c0af8dd0a0f3b763c14faf3bd9ed03cbdf33337a074fb0e9f6c7810:0",
Expand Down

0 comments on commit 5c3d9f4

Please sign in to comment.