Skip to content

Commit 0e64ce7

Browse files
committed
Depend on the new bitcoind-json-rpc group of crates
There is an effort to improve the state of affairs in regards to integration testing extensively against multiple versions of Bitcoin Core. As part of this do: - Depend on the new `rust-bitcoind-json-rpc` crates - Run the integration tests against most versions of Core since 0.17.1 (Note the latest supported version is currently 26.0) This patch effects integration testing only and should hopefully help with our upgrade process because I will personally make sure the new crates are ready and tested during the rust-bitcoin RC cycle.
1 parent 9e1b3cd commit 0e64ce7

File tree

5 files changed

+101
-63
lines changed

5 files changed

+101
-63
lines changed

.github/workflows/rust.yml

+31-14
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,39 @@ jobs:
3434
DO_LINT: true
3535
run: ./contrib/test.sh
3636

37-
Int-tests:
38-
name: Integration tests
37+
Integration: # 1 job for each bitcoind version we support.
38+
name: Integration tests - stable toolchain
3939
runs-on: ubuntu-latest
40+
strategy:
41+
fail-fast: false
42+
matrix:
43+
feature:
44+
[
45+
"26_0",
46+
"25_2",
47+
"25_1",
48+
"25_0",
49+
"24_2",
50+
"24_1",
51+
"24_0_1",
52+
"23_2",
53+
"23_1",
54+
"23_0",
55+
"22_1",
56+
"22_0",
57+
"0_21_2",
58+
"0_20_2",
59+
"0_19_1",
60+
"0_18_1",
61+
"0_17_1",
62+
]
4063
steps:
41-
- name: Checkout Crate
42-
uses: actions/checkout@v2
43-
- name: Checkout Toolchain
44-
uses: actions-rs/toolchain@v1
45-
with:
46-
profile: minimal
47-
toolchain: stable
48-
override: true
49-
- name: Running integration tests
50-
env:
51-
DO_BITCOIND_TESTS: true
52-
run: ./contrib/test.sh
64+
- name: "Checkout repo"
65+
uses: actions/checkout@v4
66+
- name: "Select toolchain"
67+
uses: dtolnay/rust-toolchain@stable
68+
- name: "Run integration tests"
69+
run: cd bitcoind-tests && cargo test --features=${{ matrix.feature }}
5370

5471
Tests:
5572
name: Tests

bitcoind-tests/Cargo.toml

+21-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,26 @@ publish = false
99

1010
[dependencies]
1111
miniscript = {path = "../"}
12-
bitcoind = { version = "0.36.0" }
12+
bitcoind = { package = "bitcoind-json-rpc-regtest", version = "0.2.0" }
1313
actual-rand = { package = "rand", version = "0.8.4"}
1414
secp256k1 = {version = "0.29.0", features = ["rand-std"]}
15+
16+
[features]
17+
# Enable the same feature in `bitcoind`.
18+
"26_0" = ["bitcoind/26_0"]
19+
"25_2" = ["bitcoind/25_2"]
20+
"25_1" = ["bitcoind/25_1"]
21+
"25_0" = ["bitcoind/25_0"]
22+
"24_2" = ["bitcoind/24_2"]
23+
"24_1" = ["bitcoind/24_1"]
24+
"24_0_1" = ["bitcoind/24_0_1"]
25+
"23_2" = ["bitcoind/23_2"]
26+
"23_1" = ["bitcoind/23_1"]
27+
"23_0" = ["bitcoind/23_0"]
28+
"22_1" = ["bitcoind/22_1"]
29+
"22_0" = ["bitcoind/22_0"]
30+
"0_21_2" = ["bitcoind/0_21_2"]
31+
"0_20_2" = ["bitcoind/0_20_2"]
32+
"0_19_1" = ["bitcoind/0_19_1"]
33+
"0_18_1" = ["bitcoind/0_18_1"]
34+
"0_17_1" = ["bitcoind/0_17_1"]

bitcoind-tests/tests/setup/mod.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
extern crate miniscript;
22

3-
use bitcoind::bitcoincore_rpc::RpcApi;
4-
use bitcoind::BitcoinD;
5-
use miniscript::bitcoin;
3+
use core::convert::TryInto;
4+
5+
use bitcoind::client::json::model;
6+
use bitcoind::client::bitcoin;
67

78
pub mod test_util;
89

910
// Launch an instance of bitcoind with
10-
pub fn setup() -> BitcoinD {
11+
pub fn setup() -> bitcoind::BitcoinD {
1112
// Create env var BITCOIND_EXE_PATH to point to the ../bitcoind/bin/bitcoind binary
1213
let key = "BITCOIND_EXE";
1314
if std::env::var(key).is_err() {
@@ -29,13 +30,15 @@ pub fn setup() -> BitcoinD {
2930
let bitcoind = bitcoind::BitcoinD::new(exe_path).unwrap();
3031
let cl = &bitcoind.client;
3132
// generate to an address by the wallet. And wait for funds to mature
32-
let addr = cl.get_new_address(None, None).unwrap().assume_checked();
33+
let addr = cl.new_address().unwrap();
3334
let blks = cl.generate_to_address(101, &addr).unwrap();
34-
assert_eq!(blks.len(), 101);
35+
assert_eq!(blks.0.len(), 101);
3536

37+
let json = cl.get_balance().expect("failed to get balance");
38+
let concrete: model::GetBalance = json.try_into().unwrap();
3639
assert_eq!(
37-
cl.get_balance(Some(1) /*min conf*/, None).unwrap(),
38-
bitcoin::Amount::from_sat(100_000_000 * 50)
40+
concrete.0,
41+
bitcoin::Amount::from_sat(100_000_000 * 50),
3942
);
4043
bitcoind
4144
}

bitcoind-tests/tests/test_cpp.rs

+19-23
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ use std::collections::BTreeMap;
88
use std::fs::File;
99
use std::io::{self, BufRead};
1010
use std::path::Path;
11+
use std::convert::TryInto;
1112

1213
use bitcoin::hashes::{sha256d, Hash};
1314
use bitcoin::psbt::Psbt;
1415
use bitcoin::{
1516
psbt, secp256k1, transaction, Amount, OutPoint, Sequence, Transaction, TxIn, TxOut, Txid,
1617
};
17-
use bitcoind::bitcoincore_rpc::{json, Client, RpcApi};
18+
use bitcoind::{Client, AddressType};
19+
use bitcoind::client::json::model; // FIXME: Re-export this from someplace easier.
1820
use miniscript::bitcoin::absolute;
1921
use miniscript::psbt::PsbtExt;
2022
use miniscript::{bitcoin, DefiniteDescriptorKey, Descriptor};
@@ -52,11 +54,10 @@ fn btc<F: Into<f64>>(btc: F) -> Amount { Amount::from_btc(btc.into()).unwrap() }
5254
// Ideally, we should find by scriptPubkey, but this
5355
// works for temp test case
5456
fn get_vout(cl: &Client, txid: Txid, value: Amount) -> (OutPoint, TxOut) {
55-
let tx = cl
56-
.get_transaction(&txid, None)
57-
.unwrap()
58-
.transaction()
59-
.unwrap();
57+
let json = cl.get_transaction(txid).unwrap();
58+
let concrete: model::GetTransaction = json.try_into().unwrap();
59+
let tx = concrete.tx;
60+
6061
for (i, txout) in tx.output.into_iter().enumerate() {
6162
if txout.value == value {
6263
return (OutPoint::new(txid, i as u32), txout);
@@ -72,9 +73,9 @@ pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) {
7273
let pks = &testdata.pubdata.pks;
7374
// Generate some blocks
7475
let blocks = cl
75-
.generate_to_address(500, &cl.get_new_address(None, None).unwrap().assume_checked())
76+
.generate_to_address(500, &cl.new_address().unwrap())
7677
.unwrap();
77-
assert_eq!(blocks.len(), 500);
78+
assert_eq!(blocks.0.len(), 500);
7879

7980
// Next send some btc to each address corresponding to the miniscript
8081
let mut txids = vec![];
@@ -83,21 +84,15 @@ pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) {
8384
.send_to_address(
8485
&wsh.address(bitcoin::Network::Regtest).unwrap(),
8586
btc(1),
86-
None,
87-
None,
88-
None,
89-
None,
90-
None,
91-
None,
9287
)
9388
.unwrap();
9489
txids.push(txid);
9590
}
9691
// Wait for the funds to mature.
9792
let blocks = cl
98-
.generate_to_address(50, &cl.get_new_address(None, None).unwrap().assume_checked())
93+
.generate_to_address(50, &cl.new_address().unwrap())
9994
.unwrap();
100-
assert_eq!(blocks.len(), 50);
95+
assert_eq!(blocks.0.len(), 50);
10196
// Create a PSBT for each transaction.
10297
// Spend one input and spend one output for simplicity.
10398
let mut psbts = vec![];
@@ -131,9 +126,8 @@ pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) {
131126
// the node wallet tracks the receiving transaction
132127
// and we can check it by gettransaction RPC.
133128
let addr = cl
134-
.get_new_address(None, Some(json::AddressType::Bech32))
135-
.unwrap()
136-
.assume_checked();
129+
.new_address_with_type(AddressType::Bech32)
130+
.unwrap();
137131
psbt.unsigned_tx.output.push(TxOut {
138132
value: Amount::from_sat(99_999_000),
139133
script_pubkey: addr.script_pubkey(),
@@ -213,21 +207,23 @@ pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) {
213207
// Send the transactions to bitcoin node for mining.
214208
// Regtest mode has standardness checks
215209
// Check whether the node accepts the transactions
216-
let txid = cl
210+
let json = cl
217211
.send_raw_transaction(&tx)
218212
.unwrap_or_else(|_| panic!("{} send tx failed for ms {}", i, ms));
219-
spend_txids.push(txid);
213+
214+
let concrete: model::SendRawTransaction = json.try_into().unwrap();
215+
spend_txids.push(concrete.0);
220216
}
221217
}
222218
// Finally mine the blocks and await confirmations
223219
let _blocks = cl
224-
.generate_to_address(10, &cl.get_new_address(None, None).unwrap().assume_checked())
220+
.generate_to_address(10, &cl.new_address().unwrap())
225221
.unwrap();
226222
// Get the required transactions from the node mined in the blocks.
227223
for txid in spend_txids {
228224
// Check whether the transaction is mined in blocks
229225
// Assert that the confirmations are > 0.
230-
let num_conf = cl.get_transaction(&txid, None).unwrap().info.confirmations;
226+
let num_conf = cl.get_transaction(txid).unwrap().confirmations;
231227
assert!(num_conf > 0);
232228
}
233229
}

bitcoind-tests/tests/test_desc.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
use std::collections::BTreeMap;
88
use std::{error, fmt};
9+
use std::convert::TryInto;
910

1011
use actual_rand as rand;
1112
use bitcoin::blockdata::witness::Witness;
@@ -17,7 +18,8 @@ use bitcoin::{
1718
absolute, psbt, secp256k1, sighash, transaction, Amount, OutPoint, Sequence, Transaction, TxIn,
1819
TxOut, Txid,
1920
};
20-
use bitcoind::bitcoincore_rpc::{json, Client, RpcApi};
21+
use bitcoind::client::json::model; // FIXME: Re-export this from someplace easier.
22+
use bitcoind::{Client, AddressType};
2123
use miniscript::bitcoin::{self, ecdsa, taproot, ScriptBuf};
2224
use miniscript::psbt::{PsbtExt, PsbtInputExt};
2325
use miniscript::{Descriptor, Miniscript, ScriptContext, ToPublicKey};
@@ -30,11 +32,10 @@ fn btc<F: Into<f64>>(btc: F) -> Amount { Amount::from_btc(btc.into()).unwrap() }
3032

3133
// Find the Outpoint by spk
3234
fn get_vout(cl: &Client, txid: Txid, value: Amount, spk: ScriptBuf) -> (OutPoint, TxOut) {
33-
let tx = cl
34-
.get_transaction(&txid, None)
35-
.unwrap()
36-
.transaction()
37-
.unwrap();
35+
let json = cl.get_transaction(txid).unwrap();
36+
let concrete: model::GetTransaction = json.try_into().unwrap();
37+
let tx = concrete.tx;
38+
3839
for (i, txout) in tx.output.into_iter().enumerate() {
3940
if txout.value == value && spk == txout.script_pubkey {
4041
return (OutPoint::new(txid, i as u32), txout);
@@ -77,9 +78,9 @@ pub fn test_desc_satisfy(
7778
let x_only_pks = &testdata.pubdata.x_only_pks;
7879
// Generate some blocks
7980
let blocks = cl
80-
.generate_to_address(1, &cl.get_new_address(None, None).unwrap().assume_checked())
81+
.generate_to_address(1, &cl.new_address().unwrap())
8182
.unwrap();
82-
assert_eq!(blocks.len(), 1);
83+
assert_eq!(blocks.0.len(), 1);
8384

8485
let definite_desc = test_util::parse_test_desc(descriptor, &testdata.pubdata)
8586
.map_err(|_| DescError::DescParseError)?
@@ -92,13 +93,13 @@ pub fn test_desc_satisfy(
9293

9394
// Next send some btc to each address corresponding to the miniscript
9495
let txid = cl
95-
.send_to_address(&desc_address, btc(1), None, None, None, None, None, None)
96+
.send_to_address(&desc_address, btc(1))
9697
.unwrap();
9798
// Wait for the funds to mature.
9899
let blocks = cl
99-
.generate_to_address(2, &cl.get_new_address(None, None).unwrap().assume_checked())
100+
.generate_to_address(2, &cl.new_address().unwrap())
100101
.unwrap();
101-
assert_eq!(blocks.len(), 2);
102+
assert_eq!(blocks.0.len(), 2);
102103
// Create a PSBT for each transaction.
103104
// Spend one input and spend one output for simplicity.
104105
let mut psbt = Psbt {
@@ -130,9 +131,8 @@ pub fn test_desc_satisfy(
130131
// the node wallet tracks the receiving transaction
131132
// and we can check it by gettransaction RPC.
132133
let addr = cl
133-
.get_new_address(None, Some(json::AddressType::Bech32))
134-
.unwrap()
135-
.assume_checked();
134+
.new_address_with_type(AddressType::Bech32)
135+
.unwrap();
136136
// Had to decrease 'value', so that fees can be increased
137137
// (Was getting insufficient fees error, for deep script trees)
138138
psbt.unsigned_tx
@@ -285,18 +285,20 @@ pub fn test_desc_satisfy(
285285
// Send the transactions to bitcoin node for mining.
286286
// Regtest mode has standardness checks
287287
// Check whether the node accepts the transactions
288-
let txid = cl
288+
let json = cl
289289
.send_raw_transaction(&tx)
290290
.unwrap_or_else(|_| panic!("send tx failed for desc {}", definite_desc));
291+
let concrete: model::SendRawTransaction = json.try_into().unwrap();
292+
let txid = concrete.0;
291293

292294
// Finally mine the blocks and await confirmations
293295
let _blocks = cl
294-
.generate_to_address(1, &cl.get_new_address(None, None).unwrap().assume_checked())
296+
.generate_to_address(1, &cl.new_address().unwrap())
295297
.unwrap();
296298
// Get the required transactions from the node mined in the blocks.
297299
// Check whether the transaction is mined in blocks
298300
// Assert that the confirmations are > 0.
299-
let num_conf = cl.get_transaction(&txid, None).unwrap().info.confirmations;
301+
let num_conf = cl.get_transaction(txid).unwrap().confirmations;
300302
assert!(num_conf > 0);
301303
Ok(tx.input[0].witness.clone())
302304
}

0 commit comments

Comments
 (0)