diff --git a/src/testutils/blockchain_tests.rs b/src/testutils/blockchain_tests.rs index 4229f5df..c7bcfb01 100644 --- a/src/testutils/blockchain_tests.rs +++ b/src/testutils/blockchain_tests.rs @@ -90,13 +90,19 @@ impl TestClient { map.insert(out.to_address.clone(), Amount::from_sat(out.value)); } + let input: Vec<_> = meta_tx + .input + .into_iter() + .map(|x| x.into_raw_tx_input()) + .collect(); + if self.get_balance(None, None).unwrap() < Amount::from_sat(required_balance) { panic!("Insufficient funds in bitcoind. Please generate a few blocks with: `bitcoin-cli generatetoaddress 10 {}`", self.get_new_address(None, None).unwrap()); } // FIXME: core can't create a tx with two outputs to the same address let tx = self - .create_raw_transaction_hex(&[], &map, meta_tx.locktime, meta_tx.replaceable) + .create_raw_transaction_hex(&input, &map, meta_tx.locktime, meta_tx.replaceable) .unwrap(); let tx = self.fund_raw_transaction(tx, None, None).unwrap(); let mut tx: Transaction = deserialize(&tx.hex).unwrap(); diff --git a/src/testutils/mod.rs b/src/testutils/mod.rs index 80f0d253..f05c9df4 100644 --- a/src/testutils/mod.rs +++ b/src/testutils/mod.rs @@ -15,11 +15,37 @@ pub mod blockchain_tests; use bitcoin::secp256k1::{Secp256k1, Verification}; -use bitcoin::{Address, PublicKey}; +use bitcoin::{Address, PublicKey, Txid}; use miniscript::descriptor::DescriptorPublicKey; use miniscript::{Descriptor, MiniscriptKey, TranslatePk}; +#[derive(Clone, Debug)] +pub struct TestIncomingInput { + pub txid: Txid, + pub vout: u32, + pub sequence: Option, +} + +impl TestIncomingInput { + pub fn new(txid: Txid, vout: u32, sequence: Option) -> Self { + Self { + txid, + vout, + sequence, + } + } + + #[cfg(feature = "test-blockchains")] + pub fn into_raw_tx_input(self) -> bitcoincore_rpc::json::CreateRawTransactionInput { + bitcoincore_rpc::json::CreateRawTransactionInput { + txid: self.txid, + vout: self.vout, + sequence: self.sequence, + } + } +} + #[derive(Clone, Debug)] pub struct TestIncomingOutput { pub value: u64, @@ -37,6 +63,7 @@ impl TestIncomingOutput { #[derive(Clone, Debug)] pub struct TestIncomingTx { + pub input: Vec, pub output: Vec, pub min_confirmations: Option, pub locktime: Option, @@ -45,12 +72,14 @@ pub struct TestIncomingTx { impl TestIncomingTx { pub fn new( + input: Vec, output: Vec, min_confirmations: Option, locktime: Option, replaceable: Option, ) -> Self { Self { + input, output, min_confirmations, locktime, @@ -58,6 +87,10 @@ impl TestIncomingTx { } } + pub fn add_input(&mut self, input: TestIncomingInput) { + self.input.push(input); + } + pub fn add_output(&mut self, output: TestIncomingOutput) { self.output.push(output); } @@ -123,16 +156,21 @@ macro_rules! testutils { }); ( @e $descriptors:expr, $child:expr ) => ({ testutils!(@external $descriptors, $child) }); ( @i $descriptors:expr, $child:expr ) => ({ testutils!(@internal $descriptors, $child) }); + ( @addr $addr:expr ) => ({ $addr }); - ( @tx ( $( ( $( $addr:tt )* ) => $amount:expr ),+ ) $( ( @locktime $locktime:expr ) )? $( ( @confirmations $confirmations:expr ) )? $( ( @replaceable $replaceable:expr ) )? ) => ({ + ( @tx ( $( ( $( $addr:tt )* ) => $amount:expr ),+ ) $( ( @inputs $( ($txid:expr, $vout:expr) ),+ ) )? $( ( @locktime $locktime:expr ) )? $( ( @confirmations $confirmations:expr ) )? $( ( @replaceable $replaceable:expr ) )? ) => ({ let outs = vec![$( $crate::testutils::TestIncomingOutput::new($amount, testutils!( $($addr)* ))),+]; + let _ins: Vec<$crate::testutils::TestIncomingInput> = vec![]; + $( + let _ins = vec![$( $crate::testutils::TestIncomingInput { txid: $txid, vout: $vout, sequence: None }),+]; + )? let locktime = None::$(.or(Some($locktime)))?; let min_confirmations = None::$(.or(Some($confirmations)))?; let replaceable = None::$(.or(Some($replaceable)))?; - $crate::testutils::TestIncomingTx::new(outs, min_confirmations, locktime, replaceable) + $crate::testutils::TestIncomingTx::new(_ins, outs, min_confirmations, locktime, replaceable) }); ( @literal $key:expr ) => ({