Skip to content

Commit dcccb50

Browse files
Add support for Bitcoin Core v29.0
Add support for the latest version of Core. Along the way fix various bugs, typos, and mistakes repo wide. Co-authored-by: Tobin C. Harding <[email protected]>
1 parent 845a41c commit dcccb50

Some content is hidden

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

61 files changed

+2600
-91
lines changed

.github/workflows/rust.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,13 @@ jobs:
210210
matrix:
211211
feature:
212212
[
213+
"29_0,download",
213214
"28_1,download",
214215
"28_0,download",
215216
"27_2,download",
216217
"27_1,download",
217218
"27_0,download",
218219
"26_2,download",
219-
"26_1,download",
220-
"26_0,download",
221220
"25_2,download",
222221
"24_2,download",
223222
"23_2,download",

client/src/client_sync/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub mod v25;
1515
pub mod v26;
1616
pub mod v27;
1717
pub mod v28;
18+
pub mod v29;
1819

1920
use std::fs::File;
2021
use std::io::{BufRead, BufReader};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 `== Blockchain ==` section of the
6+
//! API docs of Bitcoin Core `v29`.
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 `getdescriptoractivity`
13+
#[macro_export]
14+
macro_rules! impl_client_v29__getdescriptoractivity {
15+
() => {
16+
impl Client {
17+
pub fn get_descriptor_activity(&self) -> Result<GetDescriptorActivity> {
18+
let block_hashes: &[BlockHash] = &[];
19+
let scan_objects: &[&str] = &[];
20+
// FIXME: Core errors if we don't pass empty arrays?
21+
let params = vec![json!(block_hashes), json!(scan_objects)];
22+
self.call("getdescriptoractivity", &params)
23+
}
24+
}
25+
};
26+
}

client/src/client_sync/v29/mod.rs

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
//! A JSON-RPC client for testing against Bitcoin Core `v29`.
4+
//!
5+
//! We ignore option arguments unless they effect the shape of the returned JSON data.
6+
7+
pub mod blockchain;
8+
9+
use std::collections::BTreeMap;
10+
use std::path::Path;
11+
12+
use bitcoin::address::{Address, NetworkChecked};
13+
use bitcoin::{sign_message, Amount, Block, BlockHash, PublicKey, Txid};
14+
use serde::{Deserialize, Serialize};
15+
use serde_json::json;
16+
17+
use crate::client_sync::into_json;
18+
use crate::types::v29::*;
19+
20+
#[rustfmt::skip] // Keep public re-exports separate.
21+
pub use crate::client_sync::{
22+
v17::{Input, Output, WalletCreateFundedPsbtInput},
23+
v23::AddressType,
24+
};
25+
26+
crate::define_jsonrpc_minreq_client!("v29");
27+
crate::impl_client_check_expected_server_version!({ [290000] });
28+
29+
// == Blockchain ==
30+
crate::impl_client_v17__getbestblockhash!();
31+
crate::impl_client_v17__getblock!();
32+
crate::impl_client_v17__getblockchaininfo!();
33+
crate::impl_client_v17__getblockcount!();
34+
crate::impl_client_v19__getblockfilter!();
35+
crate::impl_client_v17__getblockhash!();
36+
crate::impl_client_v17__getblockheader!();
37+
crate::impl_client_v17__getblockstats!();
38+
crate::impl_client_v17__getchaintips!();
39+
crate::impl_client_v17__getchaintxstats!();
40+
crate::impl_client_v29__getdescriptoractivity!();
41+
crate::impl_client_v17__getdifficulty!();
42+
crate::impl_client_v17__getmempoolancestors!();
43+
crate::impl_client_v17__getmempooldescendants!();
44+
crate::impl_client_v17__getmempoolentry!();
45+
crate::impl_client_v17__getmempoolinfo!();
46+
crate::impl_client_v17__getrawmempool!();
47+
crate::impl_client_v17__gettxout!();
48+
crate::impl_client_v17__gettxoutproof!();
49+
crate::impl_client_v26__gettxoutsetinfo!();
50+
crate::impl_client_v17__preciousblock!();
51+
crate::impl_client_v17__pruneblockchain!();
52+
crate::impl_client_v23__savemempool!();
53+
crate::impl_client_v17__verifychain!();
54+
crate::impl_client_v17__verifytxoutproof!();
55+
56+
// == Control ==
57+
crate::impl_client_v17__getmemoryinfo!();
58+
crate::impl_client_v18__getrpcinfo!();
59+
crate::impl_client_v17__help!();
60+
crate::impl_client_v17__logging!();
61+
crate::impl_client_v17__stop!();
62+
crate::impl_client_v17__uptime!();
63+
64+
// == Generating ==
65+
crate::impl_client_v17__generatetoaddress!();
66+
crate::impl_client_v17__invalidateblock!();
67+
68+
// == Mining ==
69+
crate::impl_client_v17__getblocktemplate!();
70+
crate::impl_client_v17__getmininginfo!();
71+
crate::impl_client_v17__getnetworkhashps!();
72+
crate::impl_client_v26__get_prioritised_transactions!();
73+
crate::impl_client_v17__prioritisetransaction!();
74+
crate::impl_client_v17__submitblock!();
75+
76+
// == Network ==
77+
crate::impl_client_v17__getaddednodeinfo!();
78+
crate::impl_client_v17__getnettotals!();
79+
crate::impl_client_v17__getnetworkinfo!();
80+
crate::impl_client_v18__getnodeaddresses!();
81+
crate::impl_client_v17__getpeerinfo!();
82+
83+
// == Rawtransactions ==
84+
crate::impl_client_v18__analyzepsbt!();
85+
crate::impl_client_v17__combinepsbt!();
86+
crate::impl_client_v17__combinerawtransaction!();
87+
crate::impl_client_v17__converttopsbt!();
88+
crate::impl_client_v17__createpsbt!();
89+
crate::impl_client_v17__createrawtransaction!();
90+
crate::impl_client_v17__decodepsbt!();
91+
crate::impl_client_v17__decoderawtransaction!();
92+
crate::impl_client_v17__decodescript!();
93+
crate::impl_client_v17__finalizepsbt!();
94+
crate::impl_client_v17__fundrawtransaction!();
95+
crate::impl_client_v17__getrawtransaction!();
96+
crate::impl_client_v18__joinpsbts!();
97+
crate::impl_client_v17__sendrawtransaction!();
98+
crate::impl_client_v17__signrawtransaction!();
99+
crate::impl_client_v17__signrawtransactionwithkey!();
100+
crate::impl_client_v28__submitpackage!();
101+
crate::impl_client_v17__testmempoolaccept!();
102+
crate::impl_client_v18__utxoupdatepsbt!();
103+
104+
// == Util ==
105+
crate::impl_client_v17__createmultisig!();
106+
crate::impl_client_v17__estimatesmartfee!();
107+
crate::impl_client_v17__signmessagewithprivkey!();
108+
crate::impl_client_v17__validateaddress!();
109+
crate::impl_client_v17__verifymessage!();
110+
111+
// == Wallet ==
112+
crate::impl_client_v17__addmultisigaddress!();
113+
crate::impl_client_v17__bumpfee!();
114+
crate::impl_client_v23__createwallet!();
115+
crate::impl_client_v17__dumpprivkey!();
116+
crate::impl_client_v17__dumpwallet!();
117+
crate::impl_client_v17__getaddressesbylabel!();
118+
crate::impl_client_v17__getaddressinfo!();
119+
crate::impl_client_v17__getbalance!();
120+
crate::impl_client_v19__getbalances!();
121+
crate::impl_client_v17__getnewaddress!();
122+
crate::impl_client_v17__getrawchangeaddress!();
123+
crate::impl_client_v17__getreceivedbyaddress!();
124+
crate::impl_client_v17__gettransaction!();
125+
crate::impl_client_v17__getunconfirmedbalance!();
126+
crate::impl_client_v17__getwalletinfo!();
127+
crate::impl_client_v17__listaddressgroupings!();
128+
crate::impl_client_v17__listlabels!();
129+
crate::impl_client_v17__listlockunspent!();
130+
crate::impl_client_v17__listreceivedbyaddress!();
131+
crate::impl_client_v17__listsinceblock!();
132+
crate::impl_client_v17__listtransactions!();
133+
crate::impl_client_v17__listunspent!();
134+
crate::impl_client_v17__listwallets!();
135+
crate::impl_client_v22__loadwallet!();
136+
crate::impl_client_v17__rescanblockchain!();
137+
crate::impl_client_v17__sendmany!();
138+
crate::impl_client_v17__sendtoaddress!();
139+
crate::impl_client_v17__signmessage!();
140+
crate::impl_client_v17__signrawtransactionwithwallet!();
141+
crate::impl_client_v21__unloadwallet!();
142+
crate::impl_client_v17__walletcreatefundedpsbt!();
143+
crate::impl_client_v17__walletprocesspsbt!();
144+
145+
/// Arg for the `getblocktemplate` method. (v29+).
146+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
147+
pub struct TemplateRequest {
148+
#[serde(skip_serializing_if = "Option::is_none")]
149+
pub mode: Option<String>,
150+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
151+
pub capabilities: Vec<String>,
152+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
153+
pub rules: Vec<TemplateRules>,
154+
#[serde(skip_serializing_if = "Option::is_none")]
155+
pub longpollid: Option<String>,
156+
#[serde(skip_serializing_if = "Option::is_none")]
157+
pub data: Option<String>,
158+
}
159+
160+
/// Client side supported softfork deployment.
161+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
162+
#[serde(rename_all = "lowercase")]
163+
pub enum TemplateRules {
164+
/// SegWit v0 supported.
165+
Segwit,
166+
/// Signet supported.
167+
Signet,
168+
/// CSV supported.
169+
Csv,
170+
/// Taproot supported.
171+
Taproot,
172+
}

contrib/run-bitcoind.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ CONFIGURATION
4242
4343
- Examples
4444
45+
v29 29.0 290 /opt/bitcoin-29.0/bin/bitcoind
4546
v28 28.1 281 /opt/bitcoin-28.1/bin/bitcoind
4647
v24 24.2 242 /opt/bitcoin-24.2/bin/bitcoind
4748
v21 0.21.2 212 /opt/bitcoin-0.21.2/bin/bitcoind

integration_test/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ download = ["node/download"]
1515

1616
# Enable the same feature in `node` and the version feature here.
1717
# All minor releases of the latest three versions.
18+
29_0 = ["v29", "node/29_0"]
1819
28_1 = ["v28", "node/28_1"]
1920
28_0 = ["v28", "node/28_0"]
2021
27_2 = ["v27", "node/27_2"]
2122
27_1 = ["v27", "node/27_1"]
2223
27_0 = ["v27", "node/27_0"]
23-
26_2 = ["v26", "node/26_2"]
24-
26_1 = ["v26", "node/26_1"]
25-
26_0 = ["v26", "node/26_0"]
2624
# Only the latest minor version for older versions.
25+
26_2 = ["v26", "node/26_2"]
2726
25_2 = ["v25", "node/25_2"]
2827
24_2 = ["v24", "node/24_2"]
2928
23_2 = ["v23", "node/23_2"]
@@ -36,6 +35,7 @@ download = ["node/download"]
3635

3736
# These features are just for internal use (feature gating).
3837
# Each major version is tested with the same client.
38+
v29 = []
3939
v28 = []
4040
v27 = []
4141
v26 = []

integration_test/tests/blockchain.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,16 @@ fn blockchain__get_chain_tx_stats__modelled() {
148148
model.unwrap();
149149
}
150150

151+
#[test]
152+
#[cfg(feature = "v29")]
153+
fn blockchain__get_descriptor_activity__modelled() {
154+
let node = Node::with_wallet(Wallet::None, &["-coinstatsindex=1", "-txindex=1"]);
155+
156+
let json: GetDescriptorActivity = node.client.get_descriptor_activity().expect("getdescriptoractivity");
157+
let model: Result<mtype::GetDescriptorActivity, GetDescriptorActivityError> = json.into_model();
158+
model.unwrap();
159+
}
160+
151161
#[test]
152162
fn blockchain__get_difficulty__modelled() {
153163
let node = Node::with_wallet(Wallet::None, &[]);

integration_test/tests/mining.rs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,64 @@ fn mining__get_block_template__modelled() {
1919
node2.mine_a_block();
2020
node3.mine_a_block();
2121

22-
let options = TemplateRequest { rules: vec![TemplateRules::Segwit] };
22+
let options = match () {
23+
#[cfg(not(feature = "v29"))]
24+
() => TemplateRequest { rules: vec![TemplateRules::Segwit] },
25+
#[cfg(feature = "v29")]
26+
() => TemplateRequest {
27+
rules: vec![TemplateRules::Segwit],
28+
mode: Some("template".to_string()),
29+
..Default::default()
30+
}
31+
};
2332

24-
let json: GetBlockTemplate = node1.client.get_block_template(&options).expect("rpc");
25-
let model: Result<mtype::GetBlockTemplate, GetBlockTemplateError> = json.into_model();
26-
model.unwrap();
33+
let json: GetBlockTemplate = node1.client.get_block_template(&options)
34+
.expect("get_block_template RPC failed");
35+
let _: Result<mtype::GetBlockTemplate, GetBlockTemplateError> = json.into_model();
2736
}
2837

2938
#[test]
3039
fn mining__get_mining_info() {
3140
let node = Node::with_wallet(Wallet::Default, &[]);
32-
let _: GetMiningInfo = node.client.get_mining_info().expect("rpc");
41+
42+
let json: GetMiningInfo = node.client.get_mining_info().expect("rpc");
43+
44+
// Upto v9 there is no error converting into model.
45+
#[cfg(any(
46+
feature = "v17",
47+
feature = "v18",
48+
feature = "v19",
49+
feature = "v20",
50+
feature = "v21",
51+
feature = "v22",
52+
feature = "v23",
53+
feature = "v24",
54+
feature = "v25",
55+
feature = "v26",
56+
feature = "v27",
57+
feature = "v28",
58+
))]
59+
let _: mtype::GetMiningInfo = json.into_model();
60+
61+
// v29 onwards - these feature gates are shit, we need a better way to do this.
62+
#[cfg(not(any(
63+
feature = "v17",
64+
feature = "v18",
65+
feature = "v19",
66+
feature = "v20",
67+
feature = "v21",
68+
feature = "v22",
69+
feature = "v23",
70+
feature = "v24",
71+
feature = "v25",
72+
feature = "v26",
73+
feature = "v27",
74+
feature = "v28",
75+
)))]
76+
{
77+
let model: Result<mtype::GetMiningInfo, GetMiningInfoError> = json.into_model();
78+
model.unwrap();
79+
}
3380
}
3481

3582
#[test]

node/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,15 @@ default = ["0_17_2"]
4545
download = ["anyhow", "bitcoin_hashes", "flate2", "tar", "minreq", "zip"]
4646

4747
# We support all minor releases of the latest three versions.
48+
29_0 = ["28_1"]
4849
28_1 = ["28_0"]
4950
28_0 = ["27_2"]
5051
27_2 = ["27_1"]
5152
27_1 = ["27_0"]
5253
27_0 = ["26_2"]
53-
26_2 = ["26_1"]
54-
26_1 = ["26_0"]
55-
26_0 = ["25_2"]
5654

5755
# We only support the latest minor version for older versions.
56+
26_2 = ["25_2"]
5857
25_2 = ["24_2"]
5958
24_2 = ["23_2"]
6059
23_2 = ["22_1"]

node/contrib/extra_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
set -euox pipefail
1616

17-
FEATURES=("28_1" "28_0" "27_1" "27_0" "26_2" "26_1" "26_0" "25_2" "24_2" \
17+
FEATURES=("29_0" "28_1" "28_0" "27_1" "27_0" "26_2" "25_2" "24_2" \
1818
"23_2" "22_1" "0_21_2" "0_20_2" "0_19_1" "0_18_1" "0_17_2")
1919

2020
# Use the current `Cargo.lock` file without updating it.

0 commit comments

Comments
 (0)