Skip to content

Commit 830a05a

Browse files
committed
Overhaul integration testing
It has been a while since I started this project and in that time the testing strategy has evolved. Overhaul the integration tests: - Use new strategy of using explicit types (vtype, mtype, and error type) so that the integration tests ensure we re-exported things correctly. - Remove a bunch of feature gating, thereby improving test coverage. - A few other little things along the way. This patch is neigh on impossible to review with any confidence - as is typical in this lib.
1 parent 27e4b38 commit 830a05a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+726
-491
lines changed

client/src/client_sync/v17/blockchain.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ macro_rules! impl_client_v17__getblock {
5151
}
5252

5353
/// Gets a block by blockhash with verbose set to 0.
54-
pub fn get_block_verbose_zero(&self, hash: BlockHash) -> Result<GetBlockVerbosityZero> {
54+
pub fn get_block_verbose_zero(&self, hash: BlockHash) -> Result<GetBlockVerboseZero> {
5555
self.call("getblock", &[into_json(hash)?, 0.into()])
5656
}
5757

5858
/// Gets a block by blockhash with verbose set to 1.
59-
pub fn get_block_verbose_one(&self, hash: BlockHash) -> Result<GetBlockVerbosityOne> {
59+
pub fn get_block_verbose_one(&self, hash: BlockHash) -> Result<GetBlockVerboseOne> {
6060
self.call("getblock", &[into_json(hash)?, 1.into()])
6161
}
6262
}
@@ -279,7 +279,11 @@ macro_rules! impl_client_v17__preciousblock {
279279
() => {
280280
impl Client {
281281
pub fn precious_block(&self, hash: BlockHash) -> Result<()> {
282-
self.call("preciousblock", &[into_json(hash)?])
282+
match self.call("preciousblock", &[into_json(hash)?]) {
283+
Ok(serde_json::Value::Null) => Ok(()),
284+
Ok(res) => Err(Error::Returned(res.to_string())),
285+
Err(err) => Err(err.into()),
286+
}
283287
}
284288
}
285289
};

client/src/client_sync/v17/generating.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,17 @@ macro_rules! impl_client_v17__generate {
3838
}
3939

4040
/// Implements Bitcoin Core JSON-RPC API method `invalidateblock`
41+
// This method does not appear in the output of `bitcoin-cli help`.
4142
#[macro_export]
4243
macro_rules! impl_client_v17__invalidateblock {
4344
() => {
4445
impl Client {
4546
pub fn invalidate_block(&self, hash: BlockHash) -> Result<()> {
46-
self.call("invalidateblock", &[into_json(hash)?])
47+
match self.call("invalidateblock", &[into_json(hash)?]) {
48+
Ok(serde_json::Value::Null) => Ok(()),
49+
Ok(res) => Err(Error::Returned(res.to_string())),
50+
Err(err) => Err(err.into()),
51+
}
4752
}
4853
}
4954
};

client/src/client_sync/v17/wallet.rs

+9-19
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//!
1010
//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`.
1111
12-
/// Implements Bitcoin Core JSON-RPC API method `createwallet`.
12+
/// Implements Bitcoin Core JSON-RPC API method `addmultisigaddress`.
1313
#[macro_export]
1414
macro_rules! impl_client_v17__addmultisigaddress {
1515
() => {
@@ -123,24 +123,16 @@ macro_rules! impl_client_v17__getnewaddress {
123123
impl Client {
124124
/// Gets a new address from `bitcoind` and parses it assuming its correct.
125125
pub fn new_address(&self) -> Result<bitcoin::Address> {
126-
use core::str::FromStr;
127-
128126
let json = self.get_new_address(None, None)?;
129-
let address = bitcoin::Address::from_str(&json.0)
130-
.expect("assume the address is valid")
131-
.assume_checked(); // Assume bitcoind will return an valid address for the network its on.
132-
Ok(address)
127+
let model = json.into_model().unwrap();
128+
Ok(model.0.assume_checked())
133129
}
134130

135131
/// Gets a new address from `bitcoind` and parses it assuming its correct.
136132
pub fn new_address_with_type(&self, ty: AddressType) -> Result<bitcoin::Address> {
137-
use core::str::FromStr;
138-
139133
let json = self.get_new_address(None, Some(ty))?;
140-
let address = bitcoin::Address::from_str(&json.0)
141-
.expect("assume the address is valid")
142-
.assume_checked(); // Assume bitcoind will return an valid address for the network its on.
143-
Ok(address)
134+
let model = json.into_model().unwrap();
135+
Ok(model.0.assume_checked())
144136
}
145137

146138
/// Gets a new address with label from `bitcoind` and parses it assuming its correct.
@@ -149,15 +141,13 @@ macro_rules! impl_client_v17__getnewaddress {
149141
&self,
150142
label: &str,
151143
) -> Result<bitcoin::Address<bitcoin::address::NetworkUnchecked>> {
152-
use core::str::FromStr;
153-
154144
let json = self.get_new_address(Some(label), None)?;
155-
let address =
156-
bitcoin::Address::from_str(&json.0).expect("assume the address is valid");
157-
Ok(address)
145+
let model = json.into_model().unwrap();
146+
Ok(model.0)
158147
}
159148

160-
fn get_new_address(
149+
/// Gets a new address - low level RPC call.
150+
pub fn get_new_address(
161151
&self,
162152
label: Option<&str>,
163153
ty: Option<AddressType>,

client/src/client_sync/v19/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::types::v19::*;
2020
pub use crate::client_sync::{v17::AddressType, WalletCreateFundedPsbtInput};
2121

2222
crate::define_jsonrpc_minreq_client!("v19");
23+
crate::impl_client_check_expected_server_version!({ [190100] });
2324

2425
// == Blockchain ==
2526
crate::impl_client_v17__getbestblockhash!();
@@ -64,8 +65,9 @@ crate::impl_client_v17__prioritisetransaction!();
6465
crate::impl_client_v17__submitblock!();
6566

6667
// == Network ==
68+
crate::impl_client_v17__getaddednodeinfo!();
69+
crate::impl_client_v17__getnettotals!();
6770
crate::impl_client_v17__getnetworkinfo!();
68-
crate::impl_client_check_expected_server_version!({ [190100] });
6971
crate::impl_client_v17__getpeerinfo!();
7072

7173
// == Rawtransactions ==
@@ -82,6 +84,7 @@ crate::impl_client_v17__dumpwallet!();
8284
crate::impl_client_v17__getaddressesbylabel!();
8385
crate::impl_client_v17__getaddressinfo!();
8486
crate::impl_client_v17__getbalance!();
87+
crate::impl_client_v19__getbalances!();
8588
crate::impl_client_v17__getnewaddress!();
8689
crate::impl_client_v17__getrawchangeaddress!();
8790
crate::impl_client_v17__getreceivedbyaddress!();

client/src/client_sync/v20.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::types::v20::*;
1717
pub use crate::client_sync::{v17::AddressType, WalletCreateFundedPsbtInput};
1818

1919
crate::define_jsonrpc_minreq_client!("v20");
20+
crate::impl_client_check_expected_server_version!({ [200200] });
2021

2122
// == Blockchain ==
2223
crate::impl_client_v17__getbestblockhash!();
@@ -61,8 +62,9 @@ crate::impl_client_v17__prioritisetransaction!();
6162
crate::impl_client_v17__submitblock!();
6263

6364
// == Network ==
65+
crate::impl_client_v17__getaddednodeinfo!();
66+
crate::impl_client_v17__getnettotals!();
6467
crate::impl_client_v17__getnetworkinfo!();
65-
crate::impl_client_check_expected_server_version!({ [200200] });
6668
crate::impl_client_v17__getpeerinfo!();
6769

6870
// == Rawtransactions ==

client/src/client_sync/v21/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::types::v21::*;
1919
pub use crate::client_sync::{v17::AddressType, WalletCreateFundedPsbtInput};
2020

2121
crate::define_jsonrpc_minreq_client!("v21");
22+
crate::impl_client_check_expected_server_version!({ [210200] });
2223

2324
// == Blockchain ==
2425
crate::impl_client_v17__getbestblockhash!();
@@ -63,8 +64,9 @@ crate::impl_client_v17__prioritisetransaction!();
6364
crate::impl_client_v17__submitblock!();
6465

6566
// == Network ==
67+
crate::impl_client_v17__getaddednodeinfo!();
68+
crate::impl_client_v17__getnettotals!();
6669
crate::impl_client_v17__getnetworkinfo!();
67-
crate::impl_client_check_expected_server_version!({ [210200] });
6870
crate::impl_client_v17__getpeerinfo!();
6971

7072
// == Rawtransactions ==

client/src/client_sync/v22/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::types::v22::*;
2020
pub use crate::client_sync::{v17::AddressType, WalletCreateFundedPsbtInput};
2121

2222
crate::define_jsonrpc_minreq_client!("v22");
23+
crate::impl_client_check_expected_server_version!({ [220100] });
2324

2425
// == Blockchain ==
2526
crate::impl_client_v17__getbestblockhash!();
@@ -64,8 +65,9 @@ crate::impl_client_v17__prioritisetransaction!();
6465
crate::impl_client_v17__submitblock!();
6566

6667
// == Network ==
68+
crate::impl_client_v17__getaddednodeinfo!();
69+
crate::impl_client_v17__getnettotals!();
6770
crate::impl_client_v17__getnetworkinfo!();
68-
crate::impl_client_check_expected_server_version!({ [220000, 220100] });
6971
crate::impl_client_v17__getpeerinfo!();
7072

7173
// == Rawtransactions ==

client/src/client_sync/v23.rs renamed to client/src/client_sync/v23/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
//!
55
//! We ignore option arguments unless they effect the shape of the returned JSON data.
66
7+
pub mod wallet;
8+
79
use std::collections::BTreeMap;
810
use std::path::Path;
911

@@ -18,6 +20,7 @@ use crate::types::v23::*;
1820
pub use crate::client_sync::WalletCreateFundedPsbtInput;
1921

2022
crate::define_jsonrpc_minreq_client!("v23");
23+
crate::impl_client_check_expected_server_version!({ [230200] });
2124

2225
// == Blockchain ==
2326
crate::impl_client_v17__getbestblockhash!();
@@ -62,8 +65,9 @@ crate::impl_client_v17__prioritisetransaction!();
6265
crate::impl_client_v17__submitblock!();
6366

6467
// == Network ==
68+
crate::impl_client_v17__getaddednodeinfo!();
69+
crate::impl_client_v17__getnettotals!();
6570
crate::impl_client_v17__getnetworkinfo!();
66-
crate::impl_client_check_expected_server_version!({ [230000, 230100, 230200] });
6771
crate::impl_client_v17__getpeerinfo!();
6872

6973
// == Rawtransactions ==
@@ -74,7 +78,7 @@ crate::impl_client_v17__sendrawtransaction!();
7478
// == Wallet ==
7579
crate::impl_client_v17__addmultisigaddress!();
7680
crate::impl_client_v17__bumpfee!();
77-
crate::impl_client_v17__createwallet!();
81+
crate::impl_client_v23__createwallet!();
7882
crate::impl_client_v17__dumpprivkey!();
7983
crate::impl_client_v17__dumpwallet!();
8084
crate::impl_client_v17__getaddressesbylabel!();

client/src/client_sync/v23/wallet.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
//! Macros for implementing JSON-RPC methods on a client.
4+
//!
5+
//! Specifically this is methods found under the `== Wallet ==` section of the
6+
//! API docs of Bitcoin Core `v23`.
7+
//!
8+
//! All macros require `Client` to be in scope.
9+
//!
10+
//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`.
11+
12+
/// Implements Bitcoin Core JSON-RPC API method `createwallet`.
13+
#[macro_export]
14+
macro_rules! impl_client_v23__createwallet {
15+
() => {
16+
impl Client {
17+
/// Calls `createwallet` with `wallet` as the only argument.
18+
pub fn create_wallet(&self, wallet: &str) -> Result<CreateWallet> {
19+
self.call("createwallet", &[wallet.into()])
20+
}
21+
22+
/// Creates a legacy wallet (i.e not a native descriptor wallet).
23+
///
24+
/// > createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse descriptors load_on_startup external_signer )
25+
/// >
26+
/// > Creates and loads a new wallet.
27+
/// >
28+
/// > Arguments:
29+
/// > 1. wallet_name (string, required) The name for the new wallet. If this is a path, the wallet will be created at the path location.
30+
/// > 2. disable_private_keys (boolean, optional, default=false) Disable the possibility of private keys (only watchonlys are possible in this mode).
31+
/// > 3. blank (boolean, optional, default=false) Create a blank wallet. A blank wallet has no keys or HD seed. One can be set using sethdseed.
32+
/// > 4. passphrase (string, optional) Encrypt the wallet with this passphrase.
33+
/// > 5. avoid_reuse (boolean, optional, default=false) Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind.
34+
/// > 6. descriptors (boolean, optional, default=true) Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation
35+
/// > 7. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged.
36+
/// > 8. external_signer (boolean, optional, default=false) Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true.
37+
pub fn create_legacy_wallet(&self, wallet: &str) -> Result<CreateWallet> {
38+
let disable_private_keys = false;
39+
let blank = false;
40+
let passphrase = String::new();
41+
let avoid_reuse = false;
42+
let descriptors = false;
43+
44+
self.call(
45+
"createwallet",
46+
&[
47+
wallet.into(),
48+
disable_private_keys.into(),
49+
blank.into(),
50+
passphrase.into(),
51+
avoid_reuse.into(),
52+
descriptors.into(),
53+
],
54+
)
55+
}
56+
}
57+
};
58+
}

client/src/client_sync/v24.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::types::v24::*;
1717
pub use crate::client_sync::{v23::AddressType, WalletCreateFundedPsbtInput};
1818

1919
crate::define_jsonrpc_minreq_client!("v24");
20+
crate::impl_client_check_expected_server_version!({ [240200] });
2021

2122
// == Blockchain ==
2223
crate::impl_client_v17__getbestblockhash!();
@@ -61,8 +62,9 @@ crate::impl_client_v17__prioritisetransaction!();
6162
crate::impl_client_v17__submitblock!();
6263

6364
// == Network ==
65+
crate::impl_client_v17__getaddednodeinfo!();
66+
crate::impl_client_v17__getnettotals!();
6467
crate::impl_client_v17__getnetworkinfo!();
65-
crate::impl_client_check_expected_server_version!({ [240001, 240100, 240200] });
6668
crate::impl_client_v17__getpeerinfo!();
6769

6870
// == Rawtransactions ==
@@ -73,7 +75,7 @@ crate::impl_client_v17__sendrawtransaction!();
7375
// == Wallet ==
7476
crate::impl_client_v17__addmultisigaddress!();
7577
crate::impl_client_v17__bumpfee!();
76-
crate::impl_client_v17__createwallet!();
78+
crate::impl_client_v23__createwallet!();
7779
crate::impl_client_v17__dumpprivkey!();
7880
crate::impl_client_v17__dumpwallet!();
7981
crate::impl_client_v17__getaddressesbylabel!();

client/src/client_sync/v25.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::types::v25::*;
1717
pub use crate::client_sync::{v23::AddressType, WalletCreateFundedPsbtInput};
1818

1919
crate::define_jsonrpc_minreq_client!("v25");
20+
crate::impl_client_check_expected_server_version!({ [250200] });
2021

2122
// == Blockchain ==
2223
crate::impl_client_v17__getbestblockhash!();
@@ -61,8 +62,9 @@ crate::impl_client_v17__prioritisetransaction!();
6162
crate::impl_client_v17__submitblock!();
6263

6364
// == Network ==
65+
crate::impl_client_v17__getaddednodeinfo!();
66+
crate::impl_client_v17__getnettotals!();
6467
crate::impl_client_v17__getnetworkinfo!();
65-
crate::impl_client_check_expected_server_version!({ [250000, 250100, 250200] });
6668
crate::impl_client_v17__getpeerinfo!();
6769

6870
// == Rawtransactions ==
@@ -73,7 +75,7 @@ crate::impl_client_v17__sendrawtransaction!();
7375
// == Wallet ==
7476
crate::impl_client_v17__addmultisigaddress!();
7577
crate::impl_client_v17__bumpfee!();
76-
crate::impl_client_v17__createwallet!();
78+
crate::impl_client_v23__createwallet!();
7779
crate::impl_client_v17__dumpprivkey!();
7880
crate::impl_client_v17__dumpwallet!();
7981
crate::impl_client_v17__getaddressesbylabel!();

client/src/client_sync/v26/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::types::v26::*;
2020
pub use crate::client_sync::{v23::AddressType, WalletCreateFundedPsbtInput};
2121

2222
crate::define_jsonrpc_minreq_client!("v26");
23+
crate::impl_client_check_expected_server_version!({ [260000, 260100, 260200] });
2324

2425
// == Blockchain ==
2526
crate::impl_client_v17__getbestblockhash!();
@@ -65,8 +66,9 @@ crate::impl_client_v17__prioritisetransaction!();
6566
crate::impl_client_v17__submitblock!();
6667

6768
// == Network ==
69+
crate::impl_client_v17__getaddednodeinfo!();
70+
crate::impl_client_v17__getnettotals!();
6871
crate::impl_client_v17__getnetworkinfo!();
69-
crate::impl_client_check_expected_server_version!({ [260000, 260100, 260200] });
7072
crate::impl_client_v17__getpeerinfo!();
7173

7274
// == Rawtransactions ==
@@ -77,7 +79,7 @@ crate::impl_client_v17__sendrawtransaction!();
7779
// == Wallet ==
7880
crate::impl_client_v17__addmultisigaddress!();
7981
crate::impl_client_v17__bumpfee!();
80-
crate::impl_client_v17__createwallet!();
82+
crate::impl_client_v23__createwallet!();
8183
crate::impl_client_v17__dumpprivkey!();
8284
crate::impl_client_v17__dumpwallet!();
8385
crate::impl_client_v17__getaddressesbylabel!();

client/src/client_sync/v27.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::types::v27::*;
1717
pub use crate::client_sync::{v23::AddressType, WalletCreateFundedPsbtInput};
1818

1919
crate::define_jsonrpc_minreq_client!("v27");
20+
crate::impl_client_check_expected_server_version!({ [270000, 270100] });
2021

2122
// == Blockchain ==
2223
crate::impl_client_v17__getbestblockhash!();
@@ -62,8 +63,9 @@ crate::impl_client_v17__prioritisetransaction!();
6263
crate::impl_client_v17__submitblock!();
6364

6465
// == Network ==
66+
crate::impl_client_v17__getaddednodeinfo!();
67+
crate::impl_client_v17__getnettotals!();
6568
crate::impl_client_v17__getnetworkinfo!();
66-
crate::impl_client_check_expected_server_version!({ [270000, 270100] });
6769
crate::impl_client_v17__getpeerinfo!();
6870

6971
// == Rawtransactions ==
@@ -74,7 +76,7 @@ crate::impl_client_v17__sendrawtransaction!();
7476
// == Wallet ==
7577
crate::impl_client_v17__addmultisigaddress!();
7678
crate::impl_client_v17__bumpfee!();
77-
crate::impl_client_v17__createwallet!();
79+
crate::impl_client_v23__createwallet!();
7880
crate::impl_client_v17__dumpprivkey!();
7981
crate::impl_client_v17__dumpwallet!();
8082
crate::impl_client_v17__getaddressesbylabel!();

0 commit comments

Comments
 (0)