Skip to content
This repository was archived by the owner on Nov 26, 2024. It is now read-only.

Commit fcd9696

Browse files
committed
Add support for Bitcoin Core v28
Add support and testing for Bitcoin Core versions `28.0`
1 parent 32a0c84 commit fcd9696

File tree

22 files changed

+718
-18
lines changed

22 files changed

+718
-18
lines changed

.github/workflows/rust.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ jobs:
178178
matrix:
179179
feature:
180180
[
181+
"28_0",
181182
"27_1",
182183
"27_0",
183184
"26_2",

client/src/client_sync/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod v24;
1414
pub mod v25;
1515
pub mod v26;
1616
pub mod v27;
17+
pub mod v28;
1718

1819
use std::fs::File;
1920
use std::io::{BufRead, BufReader};

client/src/client_sync/v28.rs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
//! A JSON-RPC client for testing against Bitcoin Core `v28`.
4+
//!
5+
//! We ignore option arguments unless they effect the shape of the returned JSON data.
6+
7+
use bitcoin::address::{Address, NetworkChecked};
8+
use bitcoin::{Amount, Block, BlockHash, Txid};
9+
10+
use crate::client_sync::{handle_defaults, into_json};
11+
use crate::json::v28::*;
12+
13+
crate::define_jsonrpc_minreq_client!("v28");
14+
15+
// == Blockchain ==
16+
crate::impl_client_v17__getblockchaininfo!();
17+
crate::impl_client_v17__getbestblockhash!();
18+
crate::impl_client_v17__getblock!();
19+
crate::impl_client_v17__gettxout!();
20+
21+
// == Control ==
22+
crate::impl_client_v17__stop!();
23+
24+
// == Generating ==
25+
crate::impl_client_v17__generatetoaddress!();
26+
27+
// == Network ==
28+
crate::impl_client_v17__getnetworkinfo!();
29+
crate::impl_client_check_expected_server_version!({ [280000] });
30+
31+
// == Rawtransactions ==
32+
crate::impl_client_v17__sendrawtransaction!();
33+
34+
// == Wallet ==
35+
crate::impl_client_v17__createwallet!();
36+
crate::impl_client_v22__unloadwallet!();
37+
crate::impl_client_v22__loadwallet!();
38+
crate::impl_client_v17__getbalance!();
39+
crate::impl_client_v19__getbalances!();
40+
crate::impl_client_v17__getnewaddress!();
41+
crate::impl_client_v17__sendtoaddress!();
42+
crate::impl_client_v17__gettransaction!();
43+
44+
pub use crate::client_sync::v23::AddressType;

contrib/run_bitcoind.sh

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ COMMAND
2323
- stop Kill all bitcoind nodes using 'pkill bitcoind'.
2424
2525
KNOWN_VERSION
26+
- v28 Bitcoin Core v28.0
2627
- v27 Bitcoin Core v27.1
2728
- v26 Bitcoin Core v26.2
2829
- v25 Bitcoin Core v25.2
@@ -49,6 +50,7 @@ main() {
4950

5051
case $cmd in
5152
all)
53+
start "v28" # 28.0
5254
start "v27" # 27.1
5355
start "v26" # 26.2
5456
start "v25" # 25.2
@@ -84,6 +86,11 @@ start() {
8486
local version="$1"
8587

8688
case $version in
89+
v28)
90+
local version_number="28.0"
91+
local version_id="280"
92+
;;
93+
8794
v27)
8895
local version_number="27.1"
8996
local version_id="271"

integration_test/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ edition = "2021"
1313
[features]
1414
# Enable the same feature in `bitcoind` and the version feature here.
1515
# All minor releases (but only the latest patch release).
16+
"28_0" = ["v28", "bitcoind/28_0"]
1617
"27_1" = ["v27", "bitcoind/27_1"]
1718
"27_0" = ["v27", "bitcoind/27_0"]
1819
"26_2" = ["v26", "bitcoind/26_2"]
@@ -37,6 +38,7 @@ edition = "2021"
3738
"0_17_1" = ["v17", "bitcoind/0_17_1"]
3839

3940
# Each minor version is tested with the same client.
41+
"v28" = []
4042
"v27" = []
4143
"v26" = []
4244
"v25" = []

integration_test/tests/v28_api.rs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//! Test the JSON-RPC API against `bitcoind v28.0`.
2+
3+
#![cfg(feature = "v28")]
4+
5+
use integration_test::*;
6+
7+
// == Blockchain ==
8+
mod blockchain {
9+
use super::*;
10+
11+
impl_test_v17__getblockchaininfo!();
12+
impl_test_v17__getbestblockhash!();
13+
impl_test_v17__getblock_verbosity_0!();
14+
impl_test_v17__getblock_verbosity_1!();
15+
}
16+
17+
// == Control ==
18+
mod control {
19+
use super::*;
20+
21+
impl_test_v17__stop!();
22+
}
23+
24+
// == Generating ==
25+
mod generating {
26+
use super::*;
27+
28+
impl_test_v17__generatetoaddress!();
29+
}
30+
31+
// == Network ==
32+
mod network {
33+
use super::*;
34+
35+
impl_test_v17__getnetworkinfo!();
36+
}
37+
38+
// == Rawtransactions ==
39+
mod raw_transactions {
40+
use super::*;
41+
42+
impl_test_v17__sendrawtransaction!();
43+
}
44+
45+
// == Wallet ==
46+
mod wallet {
47+
use super::*;
48+
49+
impl_test_v17__createwallet!();
50+
impl_test_v17__loadwallet!();
51+
52+
impl_test_v17__getnewaddress!();
53+
impl_test_v17__getbalance!();
54+
impl_test_v19__getbalances!();
55+
impl_test_v17__sendtoaddress!();
56+
impl_test_v17__gettransaction!();
57+
}

json/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub mod v24;
1919
pub mod v25;
2020
pub mod v26;
2121
pub mod v27;
22+
pub mod v28;
2223

2324
// JSON types that model _all_ `bitcoind` versions.
2425
pub mod model;
@@ -82,4 +83,3 @@ fn btc_per_kb(btc_per_kb: f64) -> Result<Option<FeeRate>, ParseAmountError> {
8283

8384
Ok(rate)
8485
}
85-

json/src/model/blockchain.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub struct GetBlockchainInfo {
9797
/// Status of softforks in progress, maps softfork name -> [`Softfork`].
9898
pub softforks: BTreeMap<String, Softfork>,
9999
/// Any network and blockchain warnings.
100-
pub warnings: String,
100+
pub warnings: Vec<String>,
101101
}
102102

103103
/// Status of softfork.

json/src/model/network.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub struct GetNetworkInfo {
3636
/// List of local addresses.
3737
pub local_addresses: Vec<GetNetworkInfoAddress>,
3838
/// Any network and blockchain warnings.
39-
pub warnings: String,
39+
pub warnings: Vec<String>,
4040
}
4141

4242
/// Part of the result of the JSON-RPC method `getnetworkinfo` (information per network).

json/src/v17/blockchain.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl GetBlockchainInfo {
346346
automatic_pruning: self.automatic_pruning,
347347
prune_target_size,
348348
softforks,
349-
warnings: self.warnings,
349+
warnings: vec![self.warnings],
350350
})
351351
}
352352
}

json/src/v17/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ pub use self::{
182182
generating::{Generate, GenerateToAddress},
183183
network::{
184184
AddedNode, AddedNodeAddress, Banned, GetAddedNodeInfo, GetNetTotals, GetNetworkInfo,
185-
GetNetworkInfoAddress, GetNetworkInfoNetwork, GetPeerInfo, ListBanned, PeerInfo,
186-
UploadTarget,
185+
GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetPeerInfo, ListBanned,
186+
PeerInfo, UploadTarget,
187187
},
188188
raw_transactions::SendRawTransaction,
189189
wallet::{

json/src/v17/network.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl GetNetworkInfo {
177177
relay_fee,
178178
incremental_fee,
179179
local_addresses: self.local_addresses.into_iter().map(|a| a.into_model()).collect(),
180-
warnings: self.warnings,
180+
warnings: vec![self.warnings],
181181
})
182182
}
183183
}

json/src/v19/blockchain.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl GetBlockchainInfo {
171171
automatic_pruning: self.automatic_pruning,
172172
prune_target_size,
173173
softforks,
174-
warnings: self.warnings,
174+
warnings: vec![self.warnings],
175175
})
176176
}
177177
}

json/src/v19/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ mod wallet;
160160
#[doc(inline)]
161161
pub use self::{
162162
blockchain::{
163-
Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBlockchainInfo, Softfork,
164-
SoftforkType,
163+
Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBlockchainInfo,
164+
GetBlockchainInfoError, Softfork, SoftforkType,
165165
},
166166
wallet::{GetBalances, GetBalancesMine, GetBalancesWatchOnly},
167167
};

json/src/v28/blockchain.rs

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
//! The JSON-RPC API for Bitcoin Core v28.0 - blockchain.
4+
//!
5+
//! Types for methods found under the `== Blockchain ==` section of the API docs.
6+
7+
use std::collections::BTreeMap;
8+
9+
use bitcoin::{BlockHash, Network, Work};
10+
use serde::{Deserialize, Serialize};
11+
12+
use super::{GetBlockchainInfoError, Softfork};
13+
use crate::model;
14+
15+
#[rustfmt::skip] // Keep public re-exports separate.
16+
17+
/// Result of JSON-RPC method `getblockchaininfo`.
18+
///
19+
/// Method call: `getblockchaininfo`
20+
///
21+
/// > Returns an object containing various state info regarding blockchain processing.
22+
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
23+
pub struct GetBlockchainInfo {
24+
/// Current network name as defined in BIP70 (main, test, signet, regtest).
25+
pub chain: String,
26+
/// The current number of blocks processed in the server.
27+
pub blocks: i64,
28+
/// The current number of headers we have validated.
29+
pub headers: i64,
30+
/// The hash of the currently best block.
31+
#[serde(rename = "bestblockhash")]
32+
pub best_block_hash: String,
33+
/// The current difficulty.
34+
pub difficulty: f64,
35+
/// Median time for the current best block.
36+
#[serde(rename = "mediantime")]
37+
pub median_time: i64,
38+
/// Estimate of verification progress (between 0 and 1).
39+
#[serde(rename = "verificationprogress")]
40+
pub verification_progress: f64,
41+
/// Estimate of whether this node is in Initial Block Download (IBD) mode.
42+
#[serde(rename = "initialblockdownload")]
43+
pub initial_block_download: bool,
44+
/// Total amount of work in active chain, in hexadecimal.
45+
#[serde(rename = "chainwork")]
46+
pub chain_work: String,
47+
/// The estimated size of the block and undo files on disk.
48+
pub size_on_disk: u64,
49+
/// If the blocks are subject to pruning.
50+
pub pruned: bool,
51+
/// Lowest-height complete block stored (only present if pruning is enabled).
52+
#[serde(rename = "pruneheight")]
53+
pub prune_height: Option<i64>,
54+
/// Whether automatic pruning is enabled (only present if pruning is enabled).
55+
pub automatic_pruning: Option<bool>,
56+
/// The target size used by pruning (only present if automatic pruning is enabled).
57+
pub prune_target_size: Option<i64>,
58+
/// Status of softforks in progress, maps softfork name -> [`Softfork`].
59+
#[serde(default)]
60+
pub softforks: BTreeMap<String, Softfork>,
61+
/// Any network and blockchain warnings.
62+
pub warnings: Vec<String>,
63+
}
64+
65+
impl GetBlockchainInfo {
66+
/// Converts version specific type to a version in-specific, more strongly typed type.
67+
pub fn into_model(self) -> Result<model::GetBlockchainInfo, GetBlockchainInfoError> {
68+
use GetBlockchainInfoError as E;
69+
70+
let chain = Network::from_core_arg(&self.chain).map_err(E::Chain)?;
71+
let best_block_hash =
72+
self.best_block_hash.parse::<BlockHash>().map_err(E::BestBlockHash)?;
73+
let chain_work = Work::from_unprefixed_hex(&self.chain_work).map_err(E::ChainWork)?;
74+
let prune_height =
75+
self.prune_height.map(|h| crate::to_u32(h, "prune_height")).transpose()?;
76+
let prune_target_size =
77+
self.prune_target_size.map(|h| crate::to_u32(h, "prune_target_size")).transpose()?;
78+
let softforks = BTreeMap::new(); // TODO: Handle softforks stuff.
79+
80+
Ok(model::GetBlockchainInfo {
81+
chain,
82+
blocks: crate::to_u32(self.blocks, "blocks")?,
83+
headers: crate::to_u32(self.headers, "headers")?,
84+
best_block_hash,
85+
difficulty: self.difficulty,
86+
median_time: crate::to_u32(self.median_time, "median_time")?,
87+
verification_progress: self.verification_progress,
88+
initial_block_download: self.initial_block_download,
89+
chain_work,
90+
size_on_disk: self.size_on_disk,
91+
pruned: self.pruned,
92+
prune_height,
93+
automatic_pruning: self.automatic_pruning,
94+
prune_target_size,
95+
softforks,
96+
warnings: self.warnings,
97+
})
98+
}
99+
}

0 commit comments

Comments
 (0)