From 4fa6ae33f564210307bac5334ca65f99a4309b70 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 21 May 2026 09:15:09 +1000 Subject: [PATCH 1/7] bitcoind: Simplify no-default-features feature gate The version features are weird in this crate, later Core versions enable earlier ones. So we can simplify the 'all-features' feature gating to just check for the earlies `0_17_2` with no change of functionality. --- bitcoind/src/client_versions.rs | 21 +--------------- bitcoind/src/versions.rs | 43 ++------------------------------- 2 files changed, 3 insertions(+), 61 deletions(-) diff --git a/bitcoind/src/client_versions.rs b/bitcoind/src/client_versions.rs index 93194eb3..31bc3720 100644 --- a/bitcoind/src/client_versions.rs +++ b/bitcoind/src/client_versions.rs @@ -62,24 +62,5 @@ pub use corepc_client::{client_sync::v17::*, types::v17 as vtype}; /// This is meaningless but we need it otherwise we can't get far enough into /// the build process to trigger the `compile_error!` in `./versions.rs`. -#[cfg(all( - not(feature = "30_0"), - not(feature = "29_0"), - not(feature = "28_2"), - not(feature = "28_1"), - not(feature = "28_0"), - not(feature = "27_2"), - not(feature = "27_1"), - not(feature = "27_0"), - not(feature = "26_2"), - not(feature = "25_2"), - not(feature = "24_2"), - not(feature = "23_2"), - not(feature = "22_1"), - not(feature = "0_21_2"), - not(feature = "0_20_2"), - not(feature = "0_19_1"), - not(feature = "0_18_1"), - not(feature = "0_17_2"), -))] +#[cfg(not(feature = "0_17_2"))] // Remember: later version features enable earlier ones. pub use corepc_client::{client_sync::v28::*, types::v28 as vtype}; diff --git a/bitcoind/src/versions.rs b/bitcoind/src/versions.rs index bebac683..212b1830 100644 --- a/bitcoind/src/versions.rs +++ b/bitcoind/src/versions.rs @@ -1,26 +1,6 @@ // An explicit version of Bitcoin Core must be selected by enabling some feature. // We check this here instead of in `lib.rs` because this file is included in `build.rs`. -#[cfg(all( - not(feature = "30_2"), - not(feature = "30_0"), - not(feature = "29_0"), - not(feature = "28_2"), - not(feature = "28_1"), - not(feature = "28_0"), - not(feature = "27_2"), - not(feature = "27_1"), - not(feature = "27_0"), - not(feature = "26_2"), - not(feature = "25_2"), - not(feature = "24_2"), - not(feature = "23_2"), - not(feature = "22_1"), - not(feature = "0_21_2"), - not(feature = "0_20_2"), - not(feature = "0_19_1"), - not(feature = "0_18_1"), - not(feature = "0_17_2") -))] +#[cfg(not(feature = "0_17_2"))] // Remember: later version features enable earlier ones. compile_error!("enable a feature in order to select the version of Bitcoin Core to use"); #[cfg(feature = "30_2")] @@ -83,24 +63,5 @@ pub const VERSION: &str = "0.17.2"; /// This is meaningless but we need it otherwise we can't get far enough into /// the build process to trigger the `compile_error!` in `./versions.rs`. -#[cfg(all( - not(feature = "30_0"), - not(feature = "29_0"), - not(feature = "28_2"), - not(feature = "28_1"), - not(feature = "28_0"), - not(feature = "27_2"), - not(feature = "27_1"), - not(feature = "27_0"), - not(feature = "26_2"), - not(feature = "25_2"), - not(feature = "24_2"), - not(feature = "23_2"), - not(feature = "22_1"), - not(feature = "0_21_2"), - not(feature = "0_20_2"), - not(feature = "0_19_1"), - not(feature = "0_18_1"), - not(feature = "0_17_2") -))] +#[cfg(not(feature = "0_17_2"))] // Remember: later version features enable earlier ones. pub const VERSION: &str = "never-used"; From 3b377c5b042da9ed0c1dadee8eaa08658591e4fb Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 21 May 2026 09:19:59 +1000 Subject: [PATCH 2/7] bitcoind: Move and document features The features on this crate are non-typical. Improve the docs and put the `latest` feature right below `default`. --- bitcoind/Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bitcoind/Cargo.toml b/bitcoind/Cargo.toml index 85b61410..b75603af 100644 --- a/bitcoind/Cargo.toml +++ b/bitcoind/Cargo.toml @@ -34,18 +34,18 @@ zip = { version = "0.6.6", default-features = false, features = ["bzip2", "defla # Please note, it is expected that a single version feature will be enabled however if you enable # multiple the highest version number will take precedence. # +# - `cargo test --features=latest,download` to download the latest version of Core that we support. # - `cargo test --features=27_2,download` to download Bitcoin Core binary `v27.2`. # - `cargo test --features=28_0` to use `bitcoind` from the host environment. # - `cargo test` is equivalent to `cargo test --features=0_17_2`. -# - `cargo test --all-features`: Same as using latest version. -# - `cargo test --no-default-features` does not work, you MUST enable a version feature. +# - `cargo test --all-features`: Will download latest version of Core we support. +# - `cargo test --no-default-features` does not build, you MUST enable a version feature. [features] default = ["0_17_2"] +latest = ["30_2"] download = ["anyhow", "bitcoin_hashes", "flate2", "tar", "bitreq", "zip"] -latest = ["30_2"] - # We support all minor releases of the latest four versions. 30_2 = ["30_0"] # Skip v30.1 due to wallet migration bug. From 474a858f7e44e7bfad7da8e2c8eebbdc13a65cd8 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 21 May 2026 09:31:12 +1000 Subject: [PATCH 3/7] bitcoind: Fix client versions re-exports This is buggy, I couldn't come up with a way to catch this in case we do it again another time when we add a later Core version. --- bitcoind/src/client_versions.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bitcoind/src/client_versions.rs b/bitcoind/src/client_versions.rs index 31bc3720..39b980a2 100644 --- a/bitcoind/src/client_versions.rs +++ b/bitcoind/src/client_versions.rs @@ -6,7 +6,10 @@ #![allow(unused_imports)] // Not all users need the json types. -#[cfg(feature = "30_0")] +#[cfg(feature = "30_2")] +pub use corepc_client::{client_sync::v30::*, types::v30 as vtype}; + +#[cfg(all(feature = "30_0", not(feature = "30_2")))] pub use corepc_client::{client_sync::v30::*, types::v30 as vtype}; #[cfg(all(feature = "29_0", not(feature = "30_0")))] From db07fdd7fc0ece5a191ef44245721de677c3d8e9 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 21 May 2026 09:23:11 +1000 Subject: [PATCH 4/7] bitcoind: Remove support for old point releases A few problems being fixed here: - We once committed to supporting all point releases for the latest 3 versions of Core. During 88ddaf161 it looks like this was changed to 4 and I missed this in review (or I don't remember it). - We want to add support for the latest version of Core (v31) Cut back early point releases to only be for the latest 2 versions, then when we add support for v31 it will be back to 3. Leave docs/comments saying 'three'. --- .github/workflows/rust.yaml | 4 ---- bitcoind/Cargo.toml | 10 +++------- bitcoind/src/client_versions.rs | 16 ++-------------- bitcoind/src/versions.rs | 16 ++-------------- integration_test/Cargo.toml | 8 ++------ 5 files changed, 9 insertions(+), 45 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 77f86d93..b20c5c0c 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -132,11 +132,7 @@ jobs: # removed due to a wallet migration bug. "29_0", "28_2", - "28_1", - "28_0", "27_2", - "27_1", - "27_0", "26_2", "25_2", "24_2", diff --git a/bitcoind/Cargo.toml b/bitcoind/Cargo.toml index b75603af..88742915 100644 --- a/bitcoind/Cargo.toml +++ b/bitcoind/Cargo.toml @@ -46,19 +46,15 @@ latest = ["30_2"] download = ["anyhow", "bitcoin_hashes", "flate2", "tar", "bitreq", "zip"] -# We support all minor releases of the latest four versions. +# We support all minor releases of the latest three versions. 30_2 = ["30_0"] # Skip v30.1 due to wallet migration bug. 30_0 = ["29_0"] 29_0 = ["28_2"] -28_2 = ["28_1"] -28_1 = ["28_0"] -28_0 = ["27_2"] -27_2 = ["27_1"] -27_1 = ["27_0"] -27_0 = ["26_2"] # We only support the latest minor version for older versions. +28_2 = ["27_2"] +27_2 = ["26_2"] 26_2 = ["25_2"] 25_2 = ["24_2"] 24_2 = ["23_2"] diff --git a/bitcoind/src/client_versions.rs b/bitcoind/src/client_versions.rs index 39b980a2..908583b6 100644 --- a/bitcoind/src/client_versions.rs +++ b/bitcoind/src/client_versions.rs @@ -18,22 +18,10 @@ pub use corepc_client::{client_sync::v29::*, types::v29 as vtype}; #[cfg(all(feature = "28_2", not(feature = "29_0")))] pub use corepc_client::{client_sync::v28::*, types::v28 as vtype}; -#[cfg(all(feature = "28_1", not(feature = "28_2")))] -pub use corepc_client::{client_sync::v28::*, types::v28 as vtype}; - -#[cfg(all(feature = "28_0", not(feature = "28_1")))] -pub use corepc_client::{client_sync::v28::*, types::v28 as vtype}; - -#[cfg(all(feature = "27_2", not(feature = "28_0")))] -pub use corepc_client::{client_sync::v27::*, types::v27 as vtype}; - -#[cfg(all(feature = "27_1", not(feature = "27_2")))] -pub use corepc_client::{client_sync::v27::*, types::v27 as vtype}; - -#[cfg(all(feature = "27_0", not(feature = "27_1")))] +#[cfg(all(feature = "27_2", not(feature = "28_2")))] pub use corepc_client::{client_sync::v27::*, types::v27 as vtype}; -#[cfg(all(feature = "26_2", not(feature = "27_0")))] +#[cfg(all(feature = "26_2", not(feature = "27_2")))] pub use corepc_client::{client_sync::v26::*, types::v26 as vtype}; #[cfg(all(feature = "25_2", not(feature = "26_2")))] diff --git a/bitcoind/src/versions.rs b/bitcoind/src/versions.rs index 212b1830..2a408b10 100644 --- a/bitcoind/src/versions.rs +++ b/bitcoind/src/versions.rs @@ -16,22 +16,10 @@ pub const VERSION: &str = "29.0"; #[cfg(all(feature = "28_2", not(feature = "29_0")))] pub const VERSION: &str = "28.2"; -#[cfg(all(feature = "28_1", not(feature = "28_2")))] -pub const VERSION: &str = "28.1"; - -#[cfg(all(feature = "28_0", not(feature = "28_1")))] -pub const VERSION: &str = "28.0"; - -#[cfg(all(feature = "27_2", not(feature = "28_0")))] +#[cfg(all(feature = "27_2", not(feature = "28_2")))] pub const VERSION: &str = "27.2"; -#[cfg(all(feature = "27_1", not(feature = "27_2")))] -pub const VERSION: &str = "27.1"; - -#[cfg(all(feature = "27_0", not(feature = "27_1")))] -pub const VERSION: &str = "27.0"; - -#[cfg(all(feature = "26_2", not(feature = "27_0")))] +#[cfg(all(feature = "26_2", not(feature = "27_2")))] pub const VERSION: &str = "26.2"; #[cfg(all(feature = "25_2", not(feature = "26_2")))] diff --git a/integration_test/Cargo.toml b/integration_test/Cargo.toml index 48532305..5ff9aaa3 100644 --- a/integration_test/Cargo.toml +++ b/integration_test/Cargo.toml @@ -16,18 +16,14 @@ download = ["bitcoind/download"] latest = ["30_2"] # Enable the same feature in `bitcoind` and the version feature here. -# All minor releases of the latest four versions. +# All minor releases of the latest three versions. 30_2 = ["v30_and_below", "bitcoind/30_2"] # Skip v30.1 due to wallet migration bug. 30_0 = ["v30_and_below", "bitcoind/30_0"] 29_0 = ["v29_and_below", "bitcoind/29_0"] +# Only the latest minor version for older versions. 28_2 = ["v28_and_below", "bitcoind/28_2"] -28_1 = ["v28_and_below", "bitcoind/28_1"] -28_0 = ["v28_and_below", "bitcoind/28_0"] 27_2 = ["v27_and_below", "bitcoind/27_2"] -27_1 = ["v27_and_below", "bitcoind/27_1"] -27_0 = ["v27_and_below", "bitcoind/27_0"] -# Only the latest minor version for older versions. 26_2 = ["v26_and_below", "bitcoind/26_2"] 25_2 = ["v25_and_below", "bitcoind/25_2"] 24_2 = ["v24_and_below", "bitcoind/24_2"] From 26f35d2d5b39ac12f1ad715c6f7d4920fc5a1921 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 21 May 2026 09:47:49 +1000 Subject: [PATCH 5/7] bitcoind: Remove support for v30.0 The wallet migration bug was present in both v30.0 and v30.1 but we continue to have a `30_0` feature - this is wrong, remove it. --- .github/workflows/rust.yaml | 3 +-- bitcoind/Cargo.toml | 5 ++--- bitcoind/build.rs | 2 +- bitcoind/src/client_versions.rs | 5 +---- bitcoind/src/versions.rs | 5 +---- integration_test/Cargo.toml | 3 +-- 6 files changed, 7 insertions(+), 16 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index b20c5c0c..b6410aa4 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -128,8 +128,7 @@ jobs: version: [ "30_2", - # Don't integration test v30.0 and v30.1 as the binaries have been - # removed due to a wallet migration bug. + # No `30_0` or `30_1` because of wallet migration bug. "29_0", "28_2", "27_2", diff --git a/bitcoind/Cargo.toml b/bitcoind/Cargo.toml index 88742915..e611175b 100644 --- a/bitcoind/Cargo.toml +++ b/bitcoind/Cargo.toml @@ -47,9 +47,8 @@ latest = ["30_2"] download = ["anyhow", "bitcoin_hashes", "flate2", "tar", "bitreq", "zip"] # We support all minor releases of the latest three versions. -30_2 = ["30_0"] -# Skip v30.1 due to wallet migration bug. -30_0 = ["29_0"] +30_2 = ["29_0"] +# No `30_0` or `30_1` because of wallet migration bug. 29_0 = ["28_2"] # We only support the latest minor version for older versions. diff --git a/bitcoind/build.rs b/bitcoind/build.rs index dc65b55b..6ec90208 100644 --- a/bitcoind/build.rs +++ b/bitcoind/build.rs @@ -95,7 +95,7 @@ mod download { #[cfg(not(target_os = "windows"))] let cache_complete = existing_filename.exists() && version_dir.join("bin").join("bitcoin-cli").exists() - && (!cfg!(feature = "30_0") + && (!cfg!(feature = "30_2") || version_dir.join("libexec").join("bitcoin-node").exists()); #[cfg(target_os = "windows")] let cache_complete = existing_filename.exists(); diff --git a/bitcoind/src/client_versions.rs b/bitcoind/src/client_versions.rs index 908583b6..b5409369 100644 --- a/bitcoind/src/client_versions.rs +++ b/bitcoind/src/client_versions.rs @@ -9,10 +9,7 @@ #[cfg(feature = "30_2")] pub use corepc_client::{client_sync::v30::*, types::v30 as vtype}; -#[cfg(all(feature = "30_0", not(feature = "30_2")))] -pub use corepc_client::{client_sync::v30::*, types::v30 as vtype}; - -#[cfg(all(feature = "29_0", not(feature = "30_0")))] +#[cfg(all(feature = "29_0", not(feature = "30_2")))] pub use corepc_client::{client_sync::v29::*, types::v29 as vtype}; #[cfg(all(feature = "28_2", not(feature = "29_0")))] diff --git a/bitcoind/src/versions.rs b/bitcoind/src/versions.rs index 2a408b10..6fb4ce48 100644 --- a/bitcoind/src/versions.rs +++ b/bitcoind/src/versions.rs @@ -7,10 +7,7 @@ compile_error!("enable a feature in order to select the version of Bitcoin Core #[allow(dead_code)] // Triggers in --all-features builds. pub const VERSION: &str = "30.2"; -#[cfg(all(feature = "30_0", not(feature = "30_2")))] -pub const VERSION: &str = "30.0"; - -#[cfg(all(feature = "29_0", not(feature = "30_0")))] +#[cfg(all(feature = "29_0", not(feature = "30_2")))] pub const VERSION: &str = "29.0"; #[cfg(all(feature = "28_2", not(feature = "29_0")))] diff --git a/integration_test/Cargo.toml b/integration_test/Cargo.toml index 5ff9aaa3..9b9d0728 100644 --- a/integration_test/Cargo.toml +++ b/integration_test/Cargo.toml @@ -18,8 +18,7 @@ latest = ["30_2"] # Enable the same feature in `bitcoind` and the version feature here. # All minor releases of the latest three versions. 30_2 = ["v30_and_below", "bitcoind/30_2"] -# Skip v30.1 due to wallet migration bug. -30_0 = ["v30_and_below", "bitcoind/30_0"] +# No `30_0` or `30_1` because of wallet migration bug. 29_0 = ["v29_and_below", "bitcoind/29_0"] # Only the latest minor version for older versions. 28_2 = ["v28_and_below", "bitcoind/28_2"] From cfd7b7f9b070a4d4fd3fefb09242738818aabd65 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 21 May 2026 09:55:08 +1000 Subject: [PATCH 6/7] integration_test: Remove incorrect feature gate `v30_and_below` is currently all versions, this feature gate is incorrect - remove it. --- integration_test/tests/wallet.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/integration_test/tests/wallet.rs b/integration_test/tests/wallet.rs index 5b88a0a6..3b99b357 100644 --- a/integration_test/tests/wallet.rs +++ b/integration_test/tests/wallet.rs @@ -1013,7 +1013,6 @@ fn wallet__send_to_address__modelled() { } #[test] -#[cfg(feature = "v30_and_below")] fn wallet__set_tx_fee() { #[cfg(feature = "v29_and_below")] let node = BitcoinD::with_wallet(Wallet::Default, &[]); From da3e0f33699cad70243c6a4cdc8edcb4a81dc890 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 21 May 2026 12:38:41 +1000 Subject: [PATCH 7/7] Add support for Bitcoin Core 31.0 Props to xyzconstant and 0xB10C for pushing me to do this. Add initial support for Bitcoin Core v31 We include types for the three new methods but they are untested. All failing tests, typically caused by changed fields, are feature gated out and marked as `TODO`. These can be tackled at a later date because downstream is waiting for this and don't need full support immediately. --- bitcoind/Cargo.toml | 2 + bitcoind/sha256/bitcoin-core-31.0-SHA256SUMS | 28 ++ bitcoind/src/versions.rs | 5 +- client/src/client_sync/mod.rs | 1 + client/src/client_sync/v31/blockchain.rs | 22 ++ client/src/client_sync/v31/mod.rs | 220 +++++++++++ .../src/client_sync/v31/raw_transactions.rs | 34 ++ integration_test/Cargo.toml | 4 +- integration_test/README.md | 1 + integration_test/tests/blockchain.rs | 10 + integration_test/tests/control.rs | 1 + integration_test/tests/hidden.rs | 7 + integration_test/tests/mining.rs | 5 +- integration_test/tests/network.rs | 9 +- integration_test/tests/wallet.rs | 1 + types/src/lib.rs | 1 + types/src/model/blockchain.rs | 22 ++ types/src/model/mod.rs | 31 +- types/src/model/raw_transactions.rs | 15 + types/src/v31/blockchain/into.rs | 29 ++ types/src/v31/blockchain/mod.rs | 40 ++ types/src/v31/mod.rs | 370 ++++++++++++++++++ types/src/v31/raw_transactions/into.rs | 33 ++ types/src/v31/raw_transactions/mod.rs | 69 ++++ verify/rpc-api-v31.txt | 168 ++++++++ verify/src/lib.rs | 4 + verify/src/main.rs | 3 +- verify/src/method/mod.rs | 3 + verify/src/method/v31.rs | 224 +++++++++++ 29 files changed, 1342 insertions(+), 20 deletions(-) create mode 100644 bitcoind/sha256/bitcoin-core-31.0-SHA256SUMS create mode 100644 client/src/client_sync/v31/blockchain.rs create mode 100644 client/src/client_sync/v31/mod.rs create mode 100644 client/src/client_sync/v31/raw_transactions.rs create mode 100644 types/src/v31/blockchain/into.rs create mode 100644 types/src/v31/blockchain/mod.rs create mode 100644 types/src/v31/mod.rs create mode 100644 types/src/v31/raw_transactions/into.rs create mode 100644 types/src/v31/raw_transactions/mod.rs create mode 100644 verify/rpc-api-v31.txt create mode 100644 verify/src/method/v31.rs diff --git a/bitcoind/Cargo.toml b/bitcoind/Cargo.toml index e611175b..685c58b2 100644 --- a/bitcoind/Cargo.toml +++ b/bitcoind/Cargo.toml @@ -42,11 +42,13 @@ zip = { version = "0.6.6", default-features = false, features = ["bzip2", "defla # - `cargo test --no-default-features` does not build, you MUST enable a version feature. [features] default = ["0_17_2"] +# TODO: Set this to 31_0 after all the TODOs are cleared from `types/src/v31/mod.rs`. latest = ["30_2"] download = ["anyhow", "bitcoin_hashes", "flate2", "tar", "bitreq", "zip"] # We support all minor releases of the latest three versions. +31_0 = ["30_2"] 30_2 = ["29_0"] # No `30_0` or `30_1` because of wallet migration bug. 29_0 = ["28_2"] diff --git a/bitcoind/sha256/bitcoin-core-31.0-SHA256SUMS b/bitcoind/sha256/bitcoin-core-31.0-SHA256SUMS new file mode 100644 index 00000000..ee4cc99f --- /dev/null +++ b/bitcoind/sha256/bitcoin-core-31.0-SHA256SUMS @@ -0,0 +1,28 @@ +91917647aaf50965fc834e048256fce17e8f5590658c7e8de2879fb66cdc9a73 bitcoin-31.0-aarch64-linux-gnu-debug.tar.gz +4de1d568dedd48604f75132421bc0abeca432639589b49a3909c81db3a813112 bitcoin-31.0-aarch64-linux-gnu.tar.gz +fc17562b66707d0c8d1863af0cd40d7c6818a8d7d7b360b8d43276b1593924d9 bitcoin-31.0-arm-linux-gnueabihf-debug.tar.gz +8c19d007bfc73502625095ea4073af3a98ceb722d500556ab173bac5bcadd0d6 bitcoin-31.0-arm-linux-gnueabihf.tar.gz +a2d7a13b4da53d4a3e4c517f3a0269e2429813417bb320d3b268993cfdc545d0 bitcoin-31.0-arm64-apple-darwin.tar.gz +fc119a34915daac57e5fbdf181c9295d862d6843d52a9380e39dc0d0ac69cf20 bitcoin-31.0-arm64-apple-darwin.zip +955563c720b4d5fc22a11d4b102940d605f1cb9eb0b564f50deb606412c631e5 bitcoin-31.0-arm64-apple-darwin-codesigning.tar.gz +48d34a140aeaacd63a4bd37c24ed1876df4b077c98a7e0dd9a4483d1032839f4 bitcoin-31.0-arm64-apple-darwin-unsigned.tar.gz +b639946d343114cca5d87b218aaece04d0d111374b725d90dffc7e2d1d3b99f5 bitcoin-31.0-arm64-apple-darwin-unsigned.zip +7e45bab1787af974307fc077e6688d3eaab6788f3ad0e3a65d8cc9e428c41219 bitcoin-31.0-codesignatures-31.0.tar.gz +0ba0ef5eea3aefd96cc1774be274c3d594812cfac0988809d706738bb067b3e3 bitcoin-31.0.tar.gz +efe3e7d0383d54e5d79ac47911be0100b99872fa5205510a2a22d1194a0212d8 bitcoin-31.0-powerpc64-linux-gnu-debug.tar.gz +1d9c865aa0ccf675fc068e79d9fa57a5a70b59132fca38bb322a7d44ce2f0ff2 bitcoin-31.0-powerpc64-linux-gnu.tar.gz +acd0e38f4bb99c7c3024e494ca218d3ae67ec4a8b3b7ae556a8292353fe308b5 bitcoin-31.0-riscv64-linux-gnu-debug.tar.gz +7ece4ea365bba9b2008b27f0717ef6a518598a572edaa2815e775faadc53c136 bitcoin-31.0-riscv64-linux-gnu.tar.gz +56824dd705bc2a3b22d42e8aa02ed53498d491ff7c2c8aa96831333871887ead bitcoin-31.0-x86_64-apple-darwin.tar.gz +8e230f36a2020072763adf742b20d95348cb20aaa0b0a918ca44ecdc83ac4efd bitcoin-31.0-x86_64-apple-darwin.zip +fccf54f31bd58a3f834add05fa5df36520313d936445c556be8f71ccf314b658 bitcoin-31.0-x86_64-apple-darwin-codesigning.tar.gz +d1d0174f07cf87d9af4318f7072350510fa0f1bf8d3d3b1ee7143ad5967b6bdf bitcoin-31.0-x86_64-apple-darwin-unsigned.tar.gz +b8d9b9915a1871ee12a3a9883fd47860028454fcd192864735f2e0d3a88b4735 bitcoin-31.0-x86_64-apple-darwin-unsigned.zip +96e3506195c5cc2ea9ca72fb2ddcbcf5246dd0db0d21d726f3c98eaf0c6b9078 bitcoin-31.0-x86_64-linux-gnu-debug.tar.gz +d3e4c58a35b1d0a97a457462c94f55501ad167c660c245cb1ffa565641c65074 bitcoin-31.0-x86_64-linux-gnu.tar.gz +1893e819d7554ca43e6e812dc642bd1fb4570a4077b07a03180ad1041e74e223 bitcoin-31.0-win64-setup.exe +82fd2c504a0f20a31d4d13bd407783d6fc7bf17622d0ce85228a9b92694e03f0 bitcoin-31.0-win64.zip +62baf547357029ac557d6fbbe91742c4ba6c1461c19ed4fab5131d4300b74d93 bitcoin-31.0-win64-codesigning.tar.gz +df3f8c2f6ce8fde8d2661d3c01f5265f90f938019d52e2f94acf2a9001af70ae bitcoin-31.0-win64-debug.zip +ad31d4d82a0ddcf1340a447575ca958ee664656ca2e77282737898e1b8209ec8 bitcoin-31.0-win64-setup-unsigned.exe +5ecd365b53a2896850178f90302375480933e6c85ef81bb8abe8675fd44e1d9c bitcoin-31.0-win64-unsigned.zip diff --git a/bitcoind/src/versions.rs b/bitcoind/src/versions.rs index 6fb4ce48..4a08d91a 100644 --- a/bitcoind/src/versions.rs +++ b/bitcoind/src/versions.rs @@ -3,8 +3,11 @@ #[cfg(not(feature = "0_17_2"))] // Remember: later version features enable earlier ones. compile_error!("enable a feature in order to select the version of Bitcoin Core to use"); -#[cfg(feature = "30_2")] +#[cfg(feature = "31_0")] #[allow(dead_code)] // Triggers in --all-features builds. +pub const VERSION: &str = "31.0"; + +#[cfg(all(feature = "30_2", not(feature = "31_0")))] pub const VERSION: &str = "30.2"; #[cfg(all(feature = "29_0", not(feature = "30_2")))] diff --git a/client/src/client_sync/mod.rs b/client/src/client_sync/mod.rs index baaf3f8b..38dd1170 100644 --- a/client/src/client_sync/mod.rs +++ b/client/src/client_sync/mod.rs @@ -17,6 +17,7 @@ pub mod v27; pub mod v28; pub mod v29; pub mod v30; +pub mod v31; use std::fs::File; use std::io::{BufRead, BufReader}; diff --git a/client/src/client_sync/v31/blockchain.rs b/client/src/client_sync/v31/blockchain.rs new file mode 100644 index 00000000..b8ebf41e --- /dev/null +++ b/client/src/client_sync/v31/blockchain.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! Macros for implementing JSON-RPC methods on a client. +//! +//! Specifically this is methods found under the `== Blockchain ==` section of the +//! API docs of Bitcoin Core `v31`. +//! +//! All macros require `Client` to be in scope. +//! +//! See or use the `define_jsonrpc_bitreq_client!` macro to define a `Client`. + +/// Implements Bitcoin Core JSON-RPC API method `getmempoolcluster`. +#[macro_export] +macro_rules! impl_client_v31__get_mempool_cluster { + () => { + impl Client { + pub fn get_mempool_cluster(&self, txid: Txid) -> Result { + self.call("getmempoolcluster", &[into_json(txid)?]) + } + } + }; +} diff --git a/client/src/client_sync/v31/mod.rs b/client/src/client_sync/v31/mod.rs new file mode 100644 index 00000000..41b21ddc --- /dev/null +++ b/client/src/client_sync/v31/mod.rs @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! A JSON-RPC client for testing against Bitcoin Core `v31`. +//! +//! We ignore option arguments unless they effect the shape of the returned JSON data. + +pub mod blockchain; +pub mod raw_transactions; + +use std::collections::BTreeMap; +use std::path::Path; + +use bitcoin::address::{Address, NetworkChecked}; +use bitcoin::{sign_message, Amount, Block, BlockHash, PublicKey, Txid}; +use serde_json::json; + +use crate::client_sync::into_json; +use crate::types::v31::*; + +#[rustfmt::skip] // Keep public re-exports separate. +pub use crate::client_sync::{ + v17::{ + AddNodeCommand, ImportMultiRequest, ImportMultiScriptPubKey, ImportMultiTimestamp, Input, Output, SetBanCommand, WalletCreateFundedPsbtInput, + FeeEstimateMode, + }, + v21::ImportDescriptorsRequest, + v23::AddressType, + v29::{TemplateRequest, TemplateRules} +}; + +crate::define_jsonrpc_bitreq_client!("v31"); +crate::impl_client_check_expected_server_version!({ [310000] }); + +// == Blockchain == +crate::impl_client_v29__dump_tx_out_set!(); +crate::impl_client_v17__get_best_block_hash!(); +crate::impl_client_v29__get_block!(); +crate::impl_client_v17__get_blockchain_info!(); +crate::impl_client_v17__get_block_count!(); +crate::impl_client_v19__get_block_filter!(); +crate::impl_client_v23__get_block_from_peer!(); +crate::impl_client_v17__get_block_hash!(); +crate::impl_client_v17__get_block_header!(); +crate::impl_client_v17__get_block_stats!(); +crate::impl_client_v26__get_chain_states!(); +crate::impl_client_v17__get_chain_tips!(); +crate::impl_client_v17__get_chain_tx_stats!(); +crate::impl_client_v23__get_deployment_info!(); +crate::impl_client_v30__get_descriptor_activity!(); +crate::impl_client_v17__get_difficulty!(); +crate::impl_client_v17__get_mempool_ancestors!(); +crate::impl_client_v31__get_mempool_cluster!(); +crate::impl_client_v17__get_mempool_descendants!(); +crate::impl_client_v17__get_mempool_entry!(); +crate::impl_client_v17__get_mempool_info!(); +crate::impl_client_v21__get_raw_mempool!(); +crate::impl_client_v17__get_tx_out!(); +crate::impl_client_v17__get_tx_out_proof!(); +crate::impl_client_v26__get_tx_out_set_info!(); +crate::impl_client_v24__get_tx_spending_prevout!(); +crate::impl_client_v26__import_mempool!(); +crate::impl_client_v26__load_tx_out_set!(); +crate::impl_client_v17__precious_block!(); +crate::impl_client_v17__prune_blockchain!(); +crate::impl_client_v23__save_mempool!(); +crate::impl_client_v25__scan_blocks!(); +crate::impl_client_v17__scan_tx_out_set!(); +crate::impl_client_v17__verify_chain!(); +crate::impl_client_v17__verify_tx_out_proof!(); +crate::impl_client_v17__estimate_raw_fee!(); +crate::impl_client_v17__wait_for_block!(); +crate::impl_client_v17__wait_for_block_height!(); +crate::impl_client_v17__wait_for_new_block!(); + +// == Control == +crate::impl_client_v17__get_memory_info!(); +crate::impl_client_v18__get_rpc_info!(); +crate::impl_client_v17__help!(); +crate::impl_client_v17__logging!(); +crate::impl_client_v17__stop!(); +crate::impl_client_v17__uptime!(); + +// == Generating == +crate::impl_client_v25__generate_block!(); +crate::impl_client_v17__generate_to_address!(); +crate::impl_client_v20__generate_to_descriptor!(); +crate::impl_client_v17__invalidate_block!(); + +// == Hidden == +crate::impl_client_v27__add_connection!(); +crate::impl_client_v21__add_peer_address!(); +crate::impl_client_v29__get_orphan_txs!(); +crate::impl_client_v29__get_orphan_txs_verbosity_1!(); +crate::impl_client_v29__get_orphan_txs_verbosity_2!(); +crate::impl_client_v26__get_raw_addrman!(); +crate::impl_client_v20__mock_scheduler!(); +crate::impl_client_v17__reconsider_block!(); +crate::impl_client_v17__sync_with_validation_interface_queue!(); + +// == Mining == +crate::impl_client_v17__get_block_template!(); +crate::impl_client_v17__get_mining_info!(); +crate::impl_client_v17__get_network_hashes_per_second!(); +crate::impl_client_v26__get_prioritised_transactions!(); +crate::impl_client_v17__prioritise_transaction!(); +crate::impl_client_v17__submit_block!(); +crate::impl_client_v18__submit_header!(); + +// == Network == +crate::impl_client_v17__add_node!(); +crate::impl_client_v17__clear_banned!(); +crate::impl_client_v17__disconnect_node!(); +crate::impl_client_v17__get_added_node_info!(); +crate::impl_client_v26__get_addr_man_info!(); +crate::impl_client_v17__get_connection_count!(); +crate::impl_client_v17__get_net_totals!(); +crate::impl_client_v17__get_network_info!(); +crate::impl_client_v18__get_node_addresses!(); +crate::impl_client_v17__get_peer_info!(); +crate::impl_client_v17__list_banned!(); +crate::impl_client_v17__ping!(); +crate::impl_client_v17__set_ban!(); +crate::impl_client_v17__set_network_active!(); + +// == Rawtransactions == +crate::impl_client_v31__abort_private_broadcast!(); +crate::impl_client_v18__analyze_psbt!(); +crate::impl_client_v17__combine_psbt!(); +crate::impl_client_v17__combine_raw_transaction!(); +crate::impl_client_v17__convert_to_psbt!(); +crate::impl_client_v17__create_psbt!(); +crate::impl_client_v17__create_raw_transaction!(); +crate::impl_client_v17__decode_psbt!(); +crate::impl_client_v17__decode_raw_transaction!(); +crate::impl_client_v17__decode_script!(); +crate::impl_client_v17__finalize_psbt!(); +crate::impl_client_v17__fund_raw_transaction!(); +crate::impl_client_v31__get_private_broadcast_info!(); +crate::impl_client_v17__get_raw_transaction!(); +crate::impl_client_v18__join_psbts!(); +crate::impl_client_v17__send_raw_transaction!(); +crate::impl_client_v17__sign_raw_transaction!(); +crate::impl_client_v17__sign_raw_transaction_with_key!(); +crate::impl_client_v28__submit_package!(); +crate::impl_client_v17__test_mempool_accept!(); +crate::impl_client_v18__utxo_update_psbt!(); + +// == Signer == +crate::impl_client_v22__enumerate_signers!(); + +// == Util == +crate::impl_client_v17__create_multisig!(); +crate::impl_client_v29__derive_addresses!(); +crate::impl_client_v17__estimate_smart_fee!(); +crate::impl_client_v18__get_descriptor_info!(); +crate::impl_client_v21__get_index_info!(); +crate::impl_client_v17__sign_message_with_priv_key!(); +crate::impl_client_v17__validate_address!(); +crate::impl_client_v17__verify_message!(); + +// == Wallet == +crate::impl_client_v17__abandon_transaction!(); +crate::impl_client_v17__abort_rescan!(); +crate::impl_client_v17__backup_wallet!(); +crate::impl_client_v17__bump_fee!(); +crate::impl_client_v22__create_wallet!(); +crate::impl_client_v23__create_wallet!(); +crate::impl_client_v28__create_wallet_descriptor!(); +crate::impl_client_v17__encrypt_wallet!(); +crate::impl_client_v17__get_addresses_by_label!(); +crate::impl_client_v17__get_address_info!(); +crate::impl_client_v17__get_balance!(); +crate::impl_client_v19__get_balances!(); +crate::impl_client_v28__get_hd_keys!(); +crate::impl_client_v18__get_received_by_label!(); +crate::impl_client_v17__get_new_address!(); +crate::impl_client_v17__get_raw_change_address!(); +crate::impl_client_v17__get_received_by_address!(); +crate::impl_client_v17__get_transaction!(); +crate::impl_client_v17__get_wallet_info!(); +crate::impl_client_v21__import_descriptors!(); +crate::impl_client_v17__import_pruned_funds!(); +crate::impl_client_v17__key_pool_refill!(); +crate::impl_client_v17__list_address_groupings!(); +crate::impl_client_v22__list_descriptors!(); +crate::impl_client_v18__list_received_by_label!(); +crate::impl_client_v17__list_labels!(); +crate::impl_client_v17__list_lock_unspent!(); +crate::impl_client_v17__list_received_by_address!(); +crate::impl_client_v17__list_since_block!(); +crate::impl_client_v17__list_transactions!(); +crate::impl_client_v17__list_unspent!(); +crate::impl_client_v18__list_wallet_dir!(); +crate::impl_client_v17__list_wallets!(); +crate::impl_client_v22__load_wallet!(); +crate::impl_client_v17__lock_unspent!(); +crate::impl_client_v24__migrate_wallet!(); +crate::impl_client_v21__psbt_bump_fee!(); +crate::impl_client_v17__remove_pruned_funds!(); +crate::impl_client_v17__rescan_blockchain!(); +crate::impl_client_v23__restore_wallet!(); +crate::impl_client_v21__send!(); +crate::impl_client_v24__send_all!(); +crate::impl_client_v17__send_many!(); +crate::impl_client_v21__send_many_verbose!(); +crate::impl_client_v17__send_to_address!(); +crate::impl_client_v19__set_wallet_flag!(); +crate::impl_client_v17__sign_message!(); +crate::impl_client_v17__sign_raw_transaction_with_wallet!(); +crate::impl_client_v24__simulate_raw_transaction!(); +crate::impl_client_v21__unload_wallet!(); +crate::impl_client_v17__wallet_create_funded_psbt!(); +crate::impl_client_v22__wallet_display_address!(); +crate::impl_client_v17__wallet_lock!(); +crate::impl_client_v17__wallet_passphrase!(); +crate::impl_client_v17__wallet_passphrase_change!(); +crate::impl_client_v17__wallet_process_psbt!(); + +// == Zmq == +crate::impl_client_v17__get_zmq_notifications!(); diff --git a/client/src/client_sync/v31/raw_transactions.rs b/client/src/client_sync/v31/raw_transactions.rs new file mode 100644 index 00000000..ca53487e --- /dev/null +++ b/client/src/client_sync/v31/raw_transactions.rs @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! Macros for implementing JSON-RPC methods on a client. +//! +//! Specifically this is methods found under the `== Rawtransactions ==` section of the +//! API docs of Bitcoin Core `v31`. +//! +//! All macros require `Client` to be in scope. +//! +//! See or use the `define_jsonrpc_bitreq_client!` macro to define a `Client`. + +/// Implements Bitcoin Core JSON-RPC API method `abortprivatebroadcast`. +#[macro_export] +macro_rules! impl_client_v31__abort_private_broadcast { + () => { + impl Client { + pub fn abort_private_broadcast(&self, id: &str) -> Result { + self.call("abortprivatebroadcast", &[id.into()]) + } + } + }; +} + +/// Implements Bitcoin Core JSON-RPC API method `getprivatebroadcastinfo`. +#[macro_export] +macro_rules! impl_client_v31__get_private_broadcast_info { + () => { + impl Client { + pub fn get_private_broadcast_info(&self) -> Result { + self.call("getprivatebroadcastinfo", &[]) + } + } + }; +} diff --git a/integration_test/Cargo.toml b/integration_test/Cargo.toml index 9b9d0728..d2e0ee3a 100644 --- a/integration_test/Cargo.toml +++ b/integration_test/Cargo.toml @@ -17,6 +17,7 @@ latest = ["30_2"] # Enable the same feature in `bitcoind` and the version feature here. # All minor releases of the latest three versions. +31_0 = ["v31_and_below", "bitcoind/31_0"] 30_2 = ["v30_and_below", "bitcoind/30_2"] # No `30_0` or `30_1` because of wallet migration bug. 29_0 = ["v29_and_below", "bitcoind/29_0"] @@ -38,7 +39,8 @@ latest = ["30_2"] # Each major version is tested with the same client. # A specific range of versions can be specified e.g. for 24-26: # #[cfg(all(feature = "v26_and_below", not(feature = "v23_and_below")))] -v30_and_below = [] +v31_and_below = [] +v30_and_below = ["v31_and_below"] v29_and_below = ["v30_and_below"] v28_and_below = ["v29_and_below"] v27_and_below = ["v28_and_below"] diff --git a/integration_test/README.md b/integration_test/README.md index 70497baa..3c66072b 100644 --- a/integration_test/README.md +++ b/integration_test/README.md @@ -32,4 +32,5 @@ alias test27='BITCOIND_EXE=/opt/bitcoin-27.2/bin/bitcoind cargo test --features= alias test28='BITCOIND_EXE=/opt/bitcoin-28.2/bin/bitcoind cargo test --features=28_2' alias test29='BITCOIND_EXE=/opt/bitcoin-29.0/bin/bitcoind cargo test --features=29_0' alias test30='BITCOIND_EXE=/opt/bitcoin-30.2/bin/bitcoind cargo test --features=30_2' +alias test31='BITCOIND_EXE=/opt/bitcoin-31.0/bin/bitcoind cargo test --features=31_0' ``` diff --git a/integration_test/tests/blockchain.rs b/integration_test/tests/blockchain.rs index 1eb4e474..a88e3bb1 100644 --- a/integration_test/tests/blockchain.rs +++ b/integration_test/tests/blockchain.rs @@ -4,6 +4,7 @@ #![allow(non_snake_case)] // Test names intentionally use double underscore. +#[cfg(feature = "v30_and_below")] use bitcoin::consensus::encode; use bitcoin::hex; use bitcoind::vtype::*; // All the version specific types. @@ -140,6 +141,7 @@ fn blockchain__get_best_block_hash__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn blockchain__get_block__modelled() { let node = BitcoinD::with_wallet(Wallet::None, &[]); let block_hash = node.client.best_block_hash().expect("best_block_hash failed"); @@ -234,6 +236,7 @@ fn blockchain__get_block_filter__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v22_and_below"))] fn blockchain__get_block_from_peer() { use bitcoin::hashes::Hash; @@ -379,6 +382,7 @@ fn blockchain__get_chain_tx_stats__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v22_and_below"))] fn blockchain__get_deployment_info__modelled() { let node = BitcoinD::with_wallet(Wallet::Default, &[]); @@ -460,6 +464,7 @@ fn blockchain__get_mempool_ancestors__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn blockchain__get_mempool_ancestors_verbose__modelled() { let node = BitcoinD::with_wallet(Wallet::Default, &[]); node.fund_wallet(); @@ -490,6 +495,7 @@ fn blockchain__get_mempool_descendants__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn blockchain__get_mempool_descendants_verbose__modelled() { let node = BitcoinD::with_wallet(Wallet::Default, &[]); node.fund_wallet(); @@ -508,6 +514,7 @@ fn blockchain__get_mempool_descendants_verbose__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn blockchain__get_mempool_entry__modelled() { let node = BitcoinD::with_wallet(Wallet::Default, &[]); node.fund_wallet(); @@ -519,6 +526,7 @@ fn blockchain__get_mempool_entry__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn blockchain__get_mempool_info__modelled() { let node = BitcoinD::with_wallet(Wallet::Default, &[]); node.fund_wallet(); @@ -533,6 +541,7 @@ fn blockchain__get_mempool_info__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn blockchain__get_raw_mempool__modelled() { let node = BitcoinD::with_wallet(Wallet::Default, &[]); node.fund_wallet(); @@ -788,6 +797,7 @@ fn blockchain__wait_for_block_height__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn blockchain__wait_for_new_block__modelled() { let (node1, node2, _node3) = integration_test::three_node_network(); node1.fund_wallet(); diff --git a/integration_test/tests/control.rs b/integration_test/tests/control.rs index d4f10445..537110e9 100644 --- a/integration_test/tests/control.rs +++ b/integration_test/tests/control.rs @@ -27,6 +27,7 @@ fn control__help() { } #[test] +#[cfg(feature = "v30_and_below")] fn control__logging() { let node = BitcoinD::with_wallet(Wallet::None, &[]); let _: Logging = node.client.logging().unwrap(); diff --git a/integration_test/tests/hidden.rs b/integration_test/tests/hidden.rs index 4fe66a8a..3a6b9578 100644 --- a/integration_test/tests/hidden.rs +++ b/integration_test/tests/hidden.rs @@ -4,13 +4,17 @@ #![allow(non_snake_case)] // Test names intentionally use double underscore. +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v28_and_below"))] use std::collections::HashMap; +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v28_and_below"))] use bitcoin::hashes::Hash; +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v28_and_below"))] use bitcoin::hex::DisplayHex; +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v28_and_below"))] use bitcoin::{ absolute, consensus, transaction, Amount, OutPoint, ScriptBuf, Sequence, Transaction, TxIn, @@ -18,11 +22,13 @@ use bitcoin::{ }; use bitcoind::mtype; use bitcoind::vtype::*; // All the version specific types. +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v21_and_below"))] use bitcoind::P2P; use integration_test::{BitcoinD, BitcoinDExt as _, Wallet}; #[test] +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v21_and_below"))] fn hidden__add_connection() { let (listener, dialer, _node3) = integration_test::three_node_network(); @@ -98,6 +104,7 @@ fn hidden__estimate_raw_fee__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] #[cfg(not(feature = "v28_and_below"))] fn hidden__get_orphan_txs__modelled() { // We use node1 to send node2 orphan transactions via a P2P `tx` message. diff --git a/integration_test/tests/mining.rs b/integration_test/tests/mining.rs index 7764345c..18d465a2 100644 --- a/integration_test/tests/mining.rs +++ b/integration_test/tests/mining.rs @@ -5,11 +5,14 @@ #![allow(non_snake_case)] // Test names intentionally use double underscore. use bitcoin::SignedAmount; +use bitcoind::mtype; use bitcoind::vtype::*; -use bitcoind::{mtype, TemplateRequest, TemplateRules}; +#[cfg(feature = "v30_and_below")] +use bitcoind::{TemplateRequest, TemplateRules}; use integration_test::{BitcoinD, BitcoinDExt as _, Wallet}; // All the version specific types. #[test] +#[cfg(feature = "v30_and_below")] fn mining__get_block_template__modelled() { // Requires connected nodes otherwise the RPC call errors. let (node1, node2, node3) = integration_test::three_node_network(); diff --git a/integration_test/tests/network.rs b/integration_test/tests/network.rs index 345a7ec5..f96e8483 100644 --- a/integration_test/tests/network.rs +++ b/integration_test/tests/network.rs @@ -4,8 +4,10 @@ #![allow(non_snake_case)] // Test names intentionally use double underscore. +#[cfg(feature = "v30_and_below")] +use bitcoind::mtype; use bitcoind::vtype::*; // All the version specific types. -use bitcoind::{mtype, AddNodeCommand, SetBanCommand}; +use bitcoind::{AddNodeCommand, SetBanCommand}; use integration_test::{BitcoinD, BitcoinDExt as _, Wallet}; #[test] @@ -34,6 +36,7 @@ fn network__clear_banned() { } #[test] +#[cfg(feature = "v30_and_below")] fn network__disconnect_node() { let (_node1, node2, _node3) = integration_test::three_node_network(); @@ -75,6 +78,7 @@ fn network__get_net_totals() { } #[test] +#[cfg(feature = "v30_and_below")] fn network__get_network_info__modelled() { let node = BitcoinD::with_wallet(Wallet::None, &[]); let json: GetNetworkInfo = node.client.get_network_info().expect("getnetworkinfo"); @@ -108,17 +112,20 @@ fn network__get_node_addresses() { } #[test] +#[cfg(feature = "v30_and_below")] fn network__get_peer_info() { get_peer_info_one_node_network(); get_peer_info_three_node_network(); } +#[cfg(feature = "v30_and_below")] fn get_peer_info_one_node_network() { let node = BitcoinD::with_wallet(Wallet::None, &[]); let json: GetPeerInfo = node.client.get_peer_info().expect("getpeerinfo"); assert_eq!(json.0.len(), 0); } +#[cfg(feature = "v30_and_below")] fn get_peer_info_three_node_network() { let (node1, node2, node3) = integration_test::three_node_network(); diff --git a/integration_test/tests/wallet.rs b/integration_test/tests/wallet.rs index 3b99b357..5b88a0a6 100644 --- a/integration_test/tests/wallet.rs +++ b/integration_test/tests/wallet.rs @@ -1013,6 +1013,7 @@ fn wallet__send_to_address__modelled() { } #[test] +#[cfg(feature = "v30_and_below")] fn wallet__set_tx_fee() { #[cfg(feature = "v29_and_below")] let node = BitcoinD::with_wallet(Wallet::Default, &[]); diff --git a/types/src/lib.rs b/types/src/lib.rs index dc5b96ec..bcaff395 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -31,6 +31,7 @@ pub mod v27; pub mod v28; pub mod v29; pub mod v30; +pub mod v31; // JSON types that model _all_ `bitcoind` versions. pub mod model; diff --git a/types/src/model/blockchain.rs b/types/src/model/blockchain.rs index ef78a689..e5d7369d 100644 --- a/types/src/model/blockchain.rs +++ b/types/src/model/blockchain.rs @@ -666,6 +666,28 @@ pub struct GetDifficulty(pub f64); #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct GetMempoolAncestors(pub Vec); +/// Models the result of JSON-RPC method `getmempoolcluster`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetMempoolCluster { + /// Total sigops-adjusted weight (as defined in BIP 141 and modified by `-bytespersigop`). + /// + pub cluster_weight: u64, + /// Number of transactions. + pub tx_count: u64, + /// Chunks in this cluster (in mining order). + pub chunks: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct Chunk { + /// Fees of the transactions in this chunk. + pub chunk_fee: Amount, + /// Sigops-adjusted weight of all transactions in this chunk. + pub chunk_weight: u64, + /// Transactions in this chunk in mining order (txids). + pub txs: Vec, +} + /// Models the result of JSON-RPC method `getmempoolancestors` with verbose set to true. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct GetMempoolAncestorsVerbose(pub BTreeMap); diff --git a/types/src/model/mod.rs b/types/src/model/mod.rs index d078e64b..09c4661b 100644 --- a/types/src/model/mod.rs +++ b/types/src/model/mod.rs @@ -27,15 +27,15 @@ use serde::{Deserialize, Serialize}; pub use self::{ blockchain::{ ActivityEntry, Bip9Info, Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, - Bip9Statistics, ChainState, ChainTips, ChainTipsStatus, DeploymentInfo, DumpTxOutSet, - GetBestBlockHash, GetBlockCount, GetBlockFilter, GetBlockHash, GetBlockHeader, - GetBlockHeaderVerbose, GetBlockStats, GetBlockVerboseOne, GetBlockVerboseThree, - GetBlockVerboseThreePrevout, GetBlockVerboseThreeTransaction, GetBlockVerboseTwo, - GetBlockVerboseTwoTransaction, GetBlockVerboseZero, GetBlockchainInfo, GetChainStates, - GetChainTips, GetChainTxStats, GetDeploymentInfo, GetDescriptorActivity, GetDifficulty, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetRawMempool, - GetRawMempoolSequence, GetRawMempoolVerbose, GetTxOut, GetTxOutSetInfo, + Bip9Statistics, ChainState, ChainTips, ChainTipsStatus, Chunk, DeploymentInfo, + DumpTxOutSet, GetBestBlockHash, GetBlockCount, GetBlockFilter, GetBlockHash, + GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerboseOne, + GetBlockVerboseThree, GetBlockVerboseThreePrevout, GetBlockVerboseThreeTransaction, + GetBlockVerboseTwo, GetBlockVerboseTwoTransaction, GetBlockVerboseZero, GetBlockchainInfo, + GetChainStates, GetChainTips, GetChainTxStats, GetDeploymentInfo, GetDescriptorActivity, + GetDifficulty, GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolCluster, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, + GetRawMempool, GetRawMempoolSequence, GetRawMempoolVerbose, GetTxOut, GetTxOutSetInfo, GetTxOutSetInfoBlockInfo, GetTxOutSetInfoUnspendables, GetTxSpendingPrevout, GetTxSpendingPrevoutItem, LoadTxOutSet, MempoolEntry, MempoolEntryFees, ReceiveActivity, ScanBlocksStart, ScanTxOutSetStart, ScanTxOutSetUnspent, Softfork, SoftforkType, @@ -52,12 +52,13 @@ pub use self::{ }, network::{GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoNetwork}, raw_transactions::{ - AnalyzePsbt, AnalyzePsbtInput, AnalyzePsbtInputMissing, CombinePsbt, CombineRawTransaction, - ConvertToPsbt, CreatePsbt, CreateRawTransaction, DecodePsbt, DecodeRawTransaction, - DecodeScript, DescriptorProcessPsbt, FinalizePsbt, FundRawTransaction, GetRawTransaction, - GetRawTransactionVerbose, JoinPsbts, MempoolAcceptance, MempoolAcceptanceFees, - SendRawTransaction, SignFail, SignRawTransaction, SignRawTransactionWithKey, SubmitPackage, - SubmitPackageTxResult, SubmitPackageTxResultFees, TestMempoolAccept, UtxoUpdatePsbt, + AbortPrivateBroadcast, AnalyzePsbt, AnalyzePsbtInput, AnalyzePsbtInputMissing, CombinePsbt, + CombineRawTransaction, ConvertToPsbt, CreatePsbt, CreateRawTransaction, DecodePsbt, + DecodeRawTransaction, DecodeScript, DescriptorProcessPsbt, FinalizePsbt, + FundRawTransaction, GetPrivateBroadcastInfo, GetRawTransaction, GetRawTransactionVerbose, + JoinPsbts, MempoolAcceptance, MempoolAcceptanceFees, SendRawTransaction, SignFail, + SignRawTransaction, SignRawTransactionWithKey, SubmitPackage, SubmitPackageTxResult, + SubmitPackageTxResultFees, TestMempoolAccept, UtxoUpdatePsbt, }, util::{ CreateMultisig, DeriveAddresses, DeriveAddressesMultipath, EstimateSmartFee, diff --git a/types/src/model/raw_transactions.rs b/types/src/model/raw_transactions.rs index f5583a73..d1022493 100644 --- a/types/src/model/raw_transactions.rs +++ b/types/src/model/raw_transactions.rs @@ -12,6 +12,13 @@ use bitcoin::hashes::{hash160, sha256}; use bitcoin::{Amount, BlockHash, FeeRate, Psbt, ScriptBuf, Sequence, Transaction, Txid, Wtxid}; use serde::{Deserialize, Serialize}; +/// Models the result of JSON-RPC method `abortprivatebroadcast`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct AbortPrivateBroadcast { + /// The removed transactions. + pub removed_transactions: Vec, +} + /// Models the result of JSON-RPC method `analyzepsbt`. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct AnalyzePsbt { @@ -142,6 +149,14 @@ pub struct FundRawTransaction { pub change_position: i64, } +/// Models the result of JSON-RPC method `getprivatebroadcastinfo`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetPrivateBroadcastInfo { + /// The transactions currently being broadcast. + pub transactions: Vec, + // Don't bother modelling the per-peer info. +} + /// Models the result of JSON-RPC method `getrawtransaction` with verbose set to `false`. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct GetRawTransaction(pub Transaction); diff --git a/types/src/v31/blockchain/into.rs b/types/src/v31/blockchain/into.rs new file mode 100644 index 00000000..b2d9352f --- /dev/null +++ b/types/src/v31/blockchain/into.rs @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::{hex, Amount, Txid}; + +use super::GetMempoolCluster; +use crate::model; + +impl GetMempoolCluster { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + // TODO: Use combinators. + let mut chunks = vec![]; + for chunk in self.chunks { + let txs = + chunk.txs.iter().map(|txid| txid.parse::()).collect::, _>>()?; + chunks.push(model::Chunk { + chunk_fee: Amount::from_sat(chunk.chunk_fee), + chunk_weight: chunk.chunk_weight, + txs, + }) + } + + Ok(model::GetMempoolCluster { + cluster_weight: self.cluster_weight, + tx_count: self.tx_count, + chunks, + }) + } +} diff --git a/types/src/v31/blockchain/mod.rs b/types/src/v31/blockchain/mod.rs new file mode 100644 index 00000000..e258585c --- /dev/null +++ b/types/src/v31/blockchain/mod.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v31` - blockchain. +//! +//! Types for methods found under the `== Blockchain ==` section of the API docs. + +mod into; + +use serde::{Deserialize, Serialize}; + +/// Result of JSON-RPC method `getmempoolcluster`. +/// +/// > getmempoolcluster "txid" +/// > +/// > Returns mempool data for given cluster +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[cfg_attr(feature = "serde-deny-unknown-fields", serde(deny_unknown_fields))] +pub struct GetMempoolCluster { + /// Total sigops-adjusted weight (as defined in BIP 141 and modified by `-bytespersigop`). + #[serde(rename = "clusterweight")] + pub cluster_weight: u64, + /// Number of transactions. + #[serde(rename = "txcount")] + pub tx_count: u64, + /// Chunks in this cluster (in mining order). + pub chunks: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct Chunk { + /// Fees of the transactions in this chunk. + #[serde(rename = "chunkfee")] + // FIXME: This is probably a float. https://github.com/rust-bitcoin/corepc/pull/598#discussion_r3283795812 + pub chunk_fee: u64, + /// Sigops-adjusted weight of all transactions in this chunk. + #[serde(rename = "chunkweight")] + pub chunk_weight: u64, + /// Transactions in this chunk in mining order (txids). + pub txs: Vec, +} diff --git a/types/src/v31/mod.rs b/types/src/v31/mod.rs new file mode 100644 index 00000000..ab70b620 --- /dev/null +++ b/types/src/v31/mod.rs @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! # JSON-RPC types for Bitcoin Core `v31` +//! +//! These structs are shaped for the JSON data returned by the JSON-RPC API. They use stdlib types +//! (or custom types) and where necessary implement an `into_model` function to convert the type to +//! a [`crate::model`] type of the same name. The types in this module are version specific. The +//! types in the `model` module are version nonspecific and are strongly typed using `rust-bitcoin`. +//! +//! ### Method name and implementation status +//! +//! Every JSON-RPC method supported by this version of Bitcoin Core is listed below along with the +//! type it returns and any implementation notes. +//! +//! Key to 'Returns' column: +//! +//! * version: method returns a version specific type but has no model type. +//! * version + model: method returns a version specific type and can be converted to a model type. +//! * returns foo: method returns a foo (e.g. string, boolean, or nothing). +//! * omitted: method intentionally unsupported with no plans of adding support. +//! +//! If a method has UNTESTED then there is no integration test yet for it. +//! +//!
+//! Methods from the == Blockchain == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | dumptxoutset | version + model | | +//! | getbestblockhash | version + model | | +//! | getblock | version + model | TODO: Fields have changed since v30 | +//! | getblockchaininfo | version + model | | +//! | getblockcount | version + model | | +//! | getblockfilter | version + model | | +//! | getblockfrompeer | returns nothing | TODO: Fields have changed since v30 | +//! | getblockhash | version + model | | +//! | getblockheader | version + model | Includes additional 'verbose' type | +//! | getblockstats | version + model | | +//! | getchainstates | version + model | | +//! | getchaintips | version + model | | +//! | getchaintxstats | version + model | | +//! | getdeploymentinfo | version + model | TODO: Fields have changed since v30 | | +//! | getdescriptoractivity | version + model | | +//! | getdifficulty | version + model | | +//! | getmempoolancestors | version + model | TODO: Fields have changed since v30 | +//! | getmempoolcluster | version + model | TODO: New in v31 | +//! | getmempooldescendants | version + model | TODO: Fields have changed since v30 | +//! | getmempoolentry | version + model | TODO: Fields have changed since v30 | +//! | getmempoolinfo | version + model | TODO: Fields have changed since v30 | +//! | getrawmempool | version + model | TODO: Fields have changed since v30 | +//! | gettxout | version + model | | +//! | gettxoutproof | returns string | | +//! | gettxoutsetinfo | version + model | | +//! | gettxspendingprevout | version + model | | +//! | importmempool | returns nothing | | +//! | loadtxoutset | version + model | UNTESTED | +//! | preciousblock | returns nothing | | +//! | pruneblockchain | version | | +//! | savemempool | version | | +//! | scanblocks | version + model | | +//! | scantxoutset | version + model | API marked as experimental | +//! | verifychain | version | | +//! | verifytxoutproof | version + model | | +//! | waitforblock | version + model | | +//! | waitforblockheight | version + model | | +//! | waitfornewblock | version + model | TODO: Fields have changed since v30 | +//! +//!
+//! +//!
+//! Methods from the == Control == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | getmemoryinfo | version | | +//! | getrpcinfo | version | | +//! | help | returns string | | +//! | logging | version | TODO: Fields have changed since v30 | +//! | stop | returns string | | +//! | uptime | returns numeric | | +//! +//!
+//! +//!
+//! Methods from the == Mining == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | getblocktemplate | version + model | TODO: Fields have changed since v30 | +//! | getmininginfo | version + model | | +//! | getnetworkhashps | returns numeric | | +//! | getprioritisedtransactions | version + model | | +//! | prioritisetransaction | returns boolean | | +//! | submitblock | returns nothing | | +//! | submitheader | returns nothing | | +//! +//!
+//! +//!
+//! Methods from the == Network == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | addnode | returns nothing | | +//! | clearbanned | returns nothing | | +//! | disconnectnode | returns nothing | TODO: Fields have changed since v30 | +//! | getaddednodeinfo | version | | +//! | getaddrmaninfo | version | | +//! | getconnectioncount | version | | +//! | getnettotals | version | | +//! | getnetworkinfo | version + model | TODO: Fields have changed since v30 | +//! | getnodeaddresses | version | | +//! | getpeerinfo | version | TODO: Fields have changed since v30 | +//! | listbanned | version | | +//! | ping | returns nothing | | +//! | setban | returns nothing | | +//! | setnetworkactive | version | | +//! +//!
+//! +//!
+//! Methods from the == Rawtransactions == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | abortprivatebroadcast | version + model | TODO: New in v31 | +//! | analyzepsbt | version + model | | +//! | combinepsbt | version + model | | +//! | combinerawtransaction | version + model | | +//! | converttopsbt | version + model | | +//! | createpsbt | version + model | | +//! | createrawtransaction | version + model | | +//! | decodepsbt | version + model | Musig not modelled: not in rust-bitcoin| +//! | descriptorprocesspsbt | returns boolean | | +//! | decoderawtransaction | version + model | | +//! | decodescript | version + model | | +//! | finalizepsbt | version + model | | +//! | fundrawtransaction | version + model | | +//! | getprivatebroadcastinfo | version + model | TODO: New in v31 | +//! | getrawtransaction | version + model | Includes additional 'verbose' type | +//! | joinpsbts | version + model | | +//! | sendrawtransaction | version + model | | +//! | signrawtransactionwithkey | version + model | | +//! | submitpackage | version + model | | +//! | testmempoolaccept | version + model | | +//! | utxoupdatepsbt | version + model | | +//! +//!
+//! +//!
+//! Methods from the == Signer == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | enumeratesigners | version | | +//! +//!
+//! +//!
+//! Methods from the == Util == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | createmultisig | version + model | | +//! | deriveaddresses | version + model | | +//! | estimatesmartfee | version + model | | +//! | getdescriptorinfo | version | | +//! | getindexinfo | version | | +//! | signmessagewithprivkey | version + model | | +//! | validateaddress | version + model | | +//! | verifymessage | version | | +//! +//!
+//! +//!
+//! Methods from the == Wallet == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | abandontransaction | returns nothing | | +//! | abortrescan | version | | +//! | backupwallet | returns nothing | | +//! | bumpfee | version + model | | +//! | createwallet | version + model | | +//! | createwalletdescriptor | version | | +//! | encryptwallet | version | | +//! | getaddressesbylabel | version + model | | +//! | getaddressinfo | version + model | | +//! | getbalance | version + model | | +//! | getbalances | version + model | | +//! | gethdkeys | version + model | | +//! | getnewaddress | version + model | | +//! | getrawchangeaddress | version + model | | +//! | getreceivedbyaddress | version + model | | +//! | getreceivedbylabel | version + model | | +//! | gettransaction | version + model | | +//! | getwalletinfo | version + model | | +//! | importdescriptors | version | | +//! | importprunedfunds | returns nothing | | +//! | keypoolrefill | returns nothing | | +//! | listaddressgroupings | version + model | | +//! | listdescriptors | version | | +//! | listlabels | version | | +//! | listlockunspent | version + model | | +//! | migratewallet | version | Untested in v30, unchanged from v29 | +//! | psbtbumpfee | version + model | | +//! | listreceivedbyaddress | version + model | | +//! | listreceivedbylabel | version + model | | +//! | listsinceblock | version + model | | +//! | listtransactions | version + model | | +//! | listunspent | version + model | | +//! | listwalletdir | version | | +//! | listwallets | version + model | | +//! | loadwallet | version + model | | +//! | lockunspent | version | | +//! | removeprunedfunds | returns nothing | | +//! | rescanblockchain | version + model | | +//! | restorewallet | version | | +//! | send | version + model | | +//! | sendall | version + model | | +//! | sendmany | version + model | | +//! | sendtoaddress | version + model | | +//! | setlabel | returns nothing | | +//! | setwalletflag | version | | +//! | signmessage | version + model | | +//! | signrawtransactionwithwallet | version + model | | +//! | simulaterawtransaction | version + model | | +//! | unloadwallet | returns nothing | | +//! | walletcreatefundedpsbt | version + model | | +//! | walletdisplayaddress | version + model | | +//! | walletlock | returns nothing | | +//! | walletpassphrase | returns nothing | | +//! | walletpassphrasechange | returns nothing | | +//! | walletprocesspsbt | version + model | | +//! +//!
+//! +//!
+//! Methods from the == Zmq == section +//! +//! | JSON-RPC Method Name | Returns | Notes | +//! |:-----------------------------------|:---------------:|:--------------------------------------:| +//! | getzmqnotifications | version | | +//! +//!
+ +mod blockchain; +mod raw_transactions; + +#[doc(inline)] +pub use self::{ + blockchain::{Chunk, GetMempoolCluster}, + raw_transactions::{ + AbortPrivateBroadcast, GetPrivateBroadcastInfo, PrivateBroadcastPeer, + PrivateBroadcastTransaction, RemovedTransaction, + }, +}; +#[doc(inline)] +pub use crate::{ + v17::{ + AbortRescan, AddedNode, AddedNodeAddress, AddressInformation, AddressPurpose, + Bip125Replaceable, Bip32DerivError, BlockTemplateTransaction, + BlockTemplateTransactionError, BumpFee, BumpFeeError, ChainTips, ChainTipsError, + ChainTipsStatus, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreateMultisigError, + CreatePsbt, CreateRawTransaction, DecodeRawTransaction, EncryptWallet, EstimateRawFee, + EstimateRawFeeError, EstimateSmartFee, FinalizePsbt, FinalizePsbtError, FundRawTransaction, + FundRawTransactionError, Generate, GenerateToAddress, GetAddedNodeInfo, + GetAddressInfoEmbeddedError, GetAddressesByLabel, GetBalance, GetBestBlockHash, + GetBlockCount, GetBlockHash, GetBlockStatsError, GetBlockTemplate, GetBlockTemplateError, + GetBlockVerboseZero, GetChainTips, GetChainTxStatsError, GetConnectionCount, GetDifficulty, + GetMemoryInfoStats, GetMempoolInfoError, GetNetTotals, GetNetworkInfoAddress, + GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetRawChangeAddress, + GetRawMempool, GetRawTransaction, GetRawTransactionVerbose, GetRawTransactionVerboseError, + GetReceivedByAddress, GetTransactionDetailError, GetTxOut, GetTxOutError, + ListAddressGroupings, ListAddressGroupingsError, ListAddressGroupingsItem, ListLabels, + ListLockUnspent, ListLockUnspentItem, ListLockUnspentItemError, ListReceivedByAddressError, + ListUnspentItemError, ListWallets, LockUnspent, Locked, NumericError, + PartialSignatureError, PruneBlockchain, RawFeeDetail, RawFeeRange, RawTransactionError, + RawTransactionInput, RawTransactionOutput, RescanBlockchain, ScanTxOutSetAbort, + ScanTxOutSetError, ScanTxOutSetStatus, ScriptType, SendRawTransaction, SendToAddress, + SetNetworkActive, SetTxFee, SignFail, SignFailError, SignMessage, SignMessageWithPrivKey, + SignRawTransaction, SignRawTransactionError, SignRawTransactionWithKey, + SignRawTransactionWithWallet, TransactionCategory, UploadTarget, ValidateAddress, + ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WaitForBlock, + WaitForBlockError, WaitForBlockHeight, WaitForBlockHeightError, WaitForNewBlock, + WaitForNewBlockError, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WitnessUtxo, + WitnessUtxoError, + }, + v18::{ + ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, + AnalyzePsbtInputMissingError, DeriveAddresses, GetAddressInfoError, GetReceivedByLabel, + GetZmqNotifications, JoinPsbts, JsonRpcError, ListReceivedByAddress, + ListReceivedByAddressItem, ListReceivedByLabel, ListReceivedByLabelError, + ListReceivedByLabelItem, UtxoUpdatePsbt, + }, + v19::{ + Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalancesMine, + GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetChainTxStats, GetRpcInfo, + MapMempoolEntryError, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, + SetWalletFlag, Softfork, SoftforkType, + }, + v20::GenerateToDescriptor, + v21::{ + AddPeerAddress, GetIndexInfo, GetIndexInfoName, GetRawMempoolSequence, ImportDescriptors, + ImportDescriptorsResult, PsbtBumpFee, PsbtBumpFeeError, Send, SendError, SendMany, + SendManyVerbose, + }, + v22::{ + AddConnection, Banned, EnumerateSigners, GetNodeAddresses, ListBanned, NodeAddress, + ScriptPubKey, Signers, WalletDisplayAddress, + }, + v23::{ + Bip9Info, Bip9Statistics, CreateMultisig, DecodeScript, DecodeScriptError, + DecodeScriptSegwit, DeploymentInfo, GetDeploymentInfo, GetDeploymentInfoError, + RestoreWallet, SaveMempool, + }, + v24::{ + GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, + GetMempoolDescendantsVerbose, GetMempoolEntry, GetRawMempoolVerbose, GetTransactionDetail, + GetTxSpendingPrevout, GetTxSpendingPrevoutError, GetTxSpendingPrevoutItem, ListUnspent, + ListUnspentItem, MempoolEntry, MigrateWallet, SendAll, SendAllError, + SimulateRawTransaction, + }, + v25::{ + DescriptorInfo, GenerateBlock, GenerateBlockError, GetBlockStats, ListDescriptors, + MempoolAcceptanceError, ScanBlocksAbort, ScanBlocksStartError, ScanBlocksStatus, + TestMempoolAcceptError, + }, + v26::{ + AddrManInfoNetwork, CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError, + DumpTxOutSet, DumpTxOutSetError, GetAddrManInfo, GetBalances, GetBalancesError, + GetPeerInfo, GetTransactionError, GetTxOutSetInfo, GetTxOutSetInfoBlockInfo, + GetTxOutSetInfoError, GetTxOutSetInfoUnspendables, LoadTxOutSet, LoadTxOutSetError, + LoadWallet, PeerInfo, ScanBlocksStart, UnloadWallet, WalletProcessPsbt, + WalletProcessPsbtError, + }, + v27::{GetPrioritisedTransactions, PrioritisedTransaction}, + v28::{ + CreateWalletDescriptor, GetAddressInfo, GetAddressInfoEmbedded, GetHdKeys, GetHdKeysError, + GetNetworkInfo, GetRawAddrMan, GetTransaction, HdKey, HdKeyDescriptor, ListSinceBlock, + ListSinceBlockError, ListTransactions, Logging, RawAddrManEntry, ScanTxOutSetStart, + ScanTxOutSetUnspent, SubmitPackage, SubmitPackageError, SubmitPackageTxResult, + SubmitPackageTxResultError, SubmitPackageTxResultFees, SubmitPackageTxResultFeesError, + TransactionItem, TransactionItemError, + }, + v29::{ + ActivityEntry, ChainState, DeriveAddressesMultipath, GetBlockHeader, GetBlockHeaderError, + GetBlockHeaderVerbose, GetBlockHeaderVerboseError, GetBlockVerboseOne, + GetBlockVerboseOneError, GetBlockVerboseThree, GetBlockVerboseThreeError, + GetBlockVerboseThreePrevout, GetBlockVerboseThreeTransaction, GetBlockVerboseTwo, + GetBlockVerboseTwoError, GetBlockVerboseTwoTransaction, GetBlockchainInfo, + GetBlockchainInfoError, GetChainStates, GetChainStatesError, GetDescriptorActivity, + GetDescriptorActivityError, GetDescriptorInfo, GetOrphanTxsError, + GetOrphanTxsVerboseOneEntryError, GetOrphanTxsVerboseTwoEntryError, + GetRawTransactionVerboseWithPrevout, MempoolAcceptance, MempoolAcceptanceFees, + NextBlockInfo, NextBlockInfoError, RawTransactionInputWithPrevout, ReceiveActivity, + SpendActivity, TestMempoolAccept, + }, + v30::{ + ControlBlocksError, DecodePsbt, DecodePsbtError, GetMempoolInfo, GetMiningInfo, + GetMiningInfoError, GetOrphanTxs, GetOrphanTxsVerboseOne, GetOrphanTxsVerboseOneEntry, + GetOrphanTxsVerboseTwo, GetOrphanTxsVerboseTwoEntry, GetWalletInfo, GetWalletInfoError, + GetWalletInfoScanning, GlobalXpub, GlobalXpubError, LastProcessedBlock, + LastProcessedBlockError, ListWalletDir, ListWalletDirWallet, Musig2PartialSig, + Musig2ParticipantPubKeys, Musig2Pubnonce, Proprietary, PsbtInput, PsbtInputError, + PsbtOutput, PsbtOutputError, TaprootBip32Deriv, TaprootBip32DerivsError, TaprootLeaf, + TaprootLeafError, TaprootScript, TaprootScriptError, TaprootScriptPathSig, + TaprootScriptPathSigError, + }, +}; diff --git a/types/src/v31/raw_transactions/into.rs b/types/src/v31/raw_transactions/into.rs new file mode 100644 index 00000000..5e66d576 --- /dev/null +++ b/types/src/v31/raw_transactions/into.rs @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: CC0-1.0 + +use bitcoin::consensus::encode; +use bitcoin::Transaction; + +use super::{AbortPrivateBroadcast, GetPrivateBroadcastInfo}; +use crate::model; + +impl AbortPrivateBroadcast { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let txs = self + .removed_transactions + .iter() + .map(|removed| encode::deserialize_hex::(&removed.hex)) + .collect::, _>>()?; + + Ok(model::AbortPrivateBroadcast { removed_transactions: txs }) + } +} + +impl GetPrivateBroadcastInfo { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let txs = self + .transactions + .iter() + .map(|tx| encode::deserialize_hex::(&tx.hex)) + .collect::, _>>()?; + + Ok(model::GetPrivateBroadcastInfo { transactions: txs }) + } +} diff --git a/types/src/v31/raw_transactions/mod.rs b/types/src/v31/raw_transactions/mod.rs new file mode 100644 index 00000000..da237e65 --- /dev/null +++ b/types/src/v31/raw_transactions/mod.rs @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v31` - raw transactions. +//! +//! Types for methods found under the `== Rawtransactions ==` section of the API docs. + +mod into; + +use serde::{Deserialize, Serialize}; + +/// Result of JSON-RPC method `abortprivatebroadcast`. +/// +/// > abortprivatebroadcast "id" +/// > +/// > Abort private broadcast attempts for a transaction currently being privately broadcast. +/// > The transaction will be removed from the private broadcast queue. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[cfg_attr(feature = "serde-deny-unknown-fields", serde(deny_unknown_fields))] +pub struct AbortPrivateBroadcast { + /// The removed transactions. + pub removed_transactions: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct RemovedTransaction { + /// The transaction hash in hex. + pub txid: String, + /// The transaction witness hash in hex. + pub wtxid: String, + /// The serialized, hex-encoded transaction data. + pub hex: String, +} + +/// Result of JSON-RPC method `getprivatebroadcastinfo`. +/// +/// > getprivatebroadcastinfo +/// > +/// > Returns information about transactions that are currently being privately broadcast. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[cfg_attr(feature = "serde-deny-unknown-fields", serde(deny_unknown_fields))] +pub struct GetPrivateBroadcastInfo { + /// The transactions currently being broadcast. + pub transactions: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct PrivateBroadcastTransaction { + /// The transaction hash in hex. + pub txid: String, + /// The transaction witness hash in hex. + pub wtxid: String, + /// The serialized, hex-encoded transaction data. + pub hex: String, + /// Per-peer send and acknowledgment information for this transaction. + pub peers: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct PrivateBroadcastPeer { + /// The address of the peer to which the transaction was sent. + pub address: String, + /// The time this transaction was picked for sending to this peer via private + /// broadcast (seconds since epoch). + pub sent: u64, + /// The time this peer acknowledged reception of the transaction (seconds since + /// epoch). + #[serde(skip_serializing_if = "Option::is_none")] + pub received: Option, +} diff --git a/verify/rpc-api-v31.txt b/verify/rpc-api-v31.txt new file mode 100644 index 00000000..98d74f6a --- /dev/null +++ b/verify/rpc-api-v31.txt @@ -0,0 +1,168 @@ +== Blockchain == +dumptxoutset "path" ( "type" {"rollback":n,...} ) +getbestblockhash +getblock "blockhash" ( verbosity ) +getblockchaininfo +getblockcount +getblockfilter "blockhash" ( "filtertype" ) +getblockfrompeer "blockhash" peer_id +getblockhash height +getblockheader "blockhash" ( verbose ) +getblockstats hash_or_height ( stats ) +getchainstates +getchaintips +getchaintxstats ( nblocks "blockhash" ) +getdeploymentinfo ( "blockhash" ) +getdescriptoractivity ["blockhash",...] [scanobjects,...] ( include_mempool ) +getdifficulty +getmempoolancestors "txid" ( verbose ) +getmempoolcluster "txid" +getmempooldescendants "txid" ( verbose ) +getmempoolentry "txid" +getmempoolinfo +getrawmempool ( verbose mempool_sequence ) +gettxout "txid" n ( include_mempool ) +gettxoutproof ["txid",...] ( "blockhash" ) +gettxoutsetinfo ( "hash_type" hash_or_height use_index ) +gettxspendingprevout [{"txid":"hex","vout":n},...] ( {"mempool_only":bool,"return_spending_tx":bool,...} ) +importmempool "filepath" ( options ) +loadtxoutset "path" +preciousblock "blockhash" +pruneblockchain height +savemempool +scanblocks "action" ( [scanobjects,...] start_height stop_height "filtertype" options ) +scantxoutset "action" ( [scanobjects,...] ) +verifychain ( checklevel nblocks ) +verifytxoutproof "proof" +waitforblock "blockhash" ( timeout ) +waitforblockheight height ( timeout ) +waitfornewblock ( timeout "current_tip" ) + +== Control == +getmemoryinfo ( "mode" ) +getrpcinfo +help ( "command" ) +logging ( ["include_category",...] ["exclude_category",...] ) +stop +uptime + +== Mining == +getblocktemplate {"mode":"str","capabilities":["str",...],"rules":["segwit","str",...],"longpollid":"str","data":"hex"} +getmininginfo +getnetworkhashps ( nblocks height ) +getprioritisedtransactions +prioritisetransaction "txid" ( dummy ) fee_delta +submitblock "hexdata" ( "dummy" ) +submitheader "hexdata" + +== Network == +addnode "node" "command" ( v2transport ) +clearbanned +disconnectnode ( "address" nodeid ) +getaddednodeinfo ( "node" ) +getaddrmaninfo +getconnectioncount +getnettotals +getnetworkinfo +getnodeaddresses ( count "network" ) +getpeerinfo +listbanned +ping +setban "subnet" "command" ( bantime absolute ) +setnetworkactive state + +== Rawtransactions == +abortprivatebroadcast "id" +analyzepsbt "psbt" +combinepsbt ["psbt",...] +combinerawtransaction ["hexstring",...] +converttopsbt "hexstring" ( permitsigdata iswitness ) +createpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount,...},{"data":"hex"},...] ( locktime replaceable version ) +createrawtransaction [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount,...},{"data":"hex"},...] ( locktime replaceable version ) +decodepsbt "psbt" +decoderawtransaction "hexstring" ( iswitness ) +decodescript "hexstring" +descriptorprocesspsbt "psbt" ["",{"desc":"str","range":n or [n,n]},...] ( "sighashtype" bip32derivs finalize ) +finalizepsbt "psbt" ( extract ) +fundrawtransaction "hexstring" ( options iswitness ) +getprivatebroadcastinfo +getrawtransaction "txid" ( verbosity "blockhash" ) +joinpsbts ["psbt",...] +sendrawtransaction "hexstring" ( maxfeerate maxburnamount ) +signrawtransactionwithkey "hexstring" ["privatekey",...] ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +submitpackage ["rawtx",...] ( maxfeerate maxburnamount ) +testmempoolaccept ["rawtx",...] ( maxfeerate ) +utxoupdatepsbt "psbt" ( ["",{"desc":"str","range":n or [n,n]},...] ) + +== Signer == +enumeratesigners + +== Util == +createmultisig nrequired ["key",...] ( "address_type" ) +deriveaddresses "descriptor" ( range ) +estimatesmartfee conf_target ( "estimate_mode" ) +getdescriptorinfo "descriptor" +getindexinfo ( "index_name" ) +signmessagewithprivkey "privkey" "message" +validateaddress "address" +verifymessage "address" "signature" "message" + +== Wallet == +abandontransaction "txid" +abortrescan +backupwallet "destination" +bumpfee "txid" ( options ) +createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse descriptors load_on_startup external_signer ) +createwalletdescriptor "type" ( {"internal":bool,"hdkey":"str",...} ) +encryptwallet "passphrase" +getaddressesbylabel "label" +getaddressinfo "address" +getbalance ( "dummy" minconf include_watchonly avoid_reuse ) +getbalances +gethdkeys ( {"active_only":bool,"private":bool,...} ) +getnewaddress ( "label" "address_type" ) +getrawchangeaddress ( "address_type" ) +getreceivedbyaddress "address" ( minconf include_immature_coinbase ) +getreceivedbylabel "label" ( minconf include_immature_coinbase ) +gettransaction "txid" ( include_watchonly verbose ) +getwalletinfo +importdescriptors requests +importprunedfunds "rawtransaction" "txoutproof" +keypoolrefill ( newsize ) +listaddressgroupings +listdescriptors ( private ) +listlabels ( "purpose" ) +listlockunspent +listreceivedbyaddress ( minconf include_empty include_watchonly "address_filter" include_immature_coinbase ) +listreceivedbylabel ( minconf include_empty include_watchonly include_immature_coinbase ) +listsinceblock ( "blockhash" target_confirmations include_watchonly include_removed include_change "label" ) +listtransactions ( "label" count skip include_watchonly ) +listunspent ( minconf maxconf ["address",...] include_unsafe query_options ) +listwalletdir +listwallets +loadwallet "filename" ( load_on_startup ) +lockunspent unlock ( [{"txid":"hex","vout":n},...] persistent ) +migratewallet ( "wallet_name" "passphrase" ) +psbtbumpfee "txid" ( options ) +removeprunedfunds "txid" +rescanblockchain ( start_height stop_height ) +restorewallet "wallet_name" "backup_file" ( load_on_startup ) +send [{"address":amount,...},{"data":"hex"},...] ( conf_target "estimate_mode" fee_rate options version ) +sendall ["address",{"address":amount,...},...] ( conf_target "estimate_mode" fee_rate options ) +sendmany ( "" ) {"address":amount,...} ( minconf "comment" ["address",...] replaceable conf_target "estimate_mode" fee_rate verbose ) +sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount replaceable conf_target "estimate_mode" avoid_reuse fee_rate verbose ) +setlabel "address" "label" +setwalletflag "flag" ( value ) +signmessage "address" "message" +signrawtransactionwithwallet "hexstring" ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +simulaterawtransaction ( ["rawtx",...] {"include_watchonly":bool,...} ) +unloadwallet ( "wallet_name" load_on_startup ) +walletcreatefundedpsbt ( [{"txid":"hex","vout":n,"sequence":n,"weight":n},...] ) [{"address":amount,...},{"data":"hex"},...] ( locktime options bip32derivs version ) +walletdisplayaddress "address" +walletlock +walletpassphrase "passphrase" timeout +walletpassphrasechange "oldpassphrase" "newpassphrase" +walletprocesspsbt "psbt" ( sign "sighashtype" bip32derivs finalize ) + +== Zmq == +getzmqnotifications diff --git a/verify/src/lib.rs b/verify/src/lib.rs index 03c3d23f..ab921522 100644 --- a/verify/src/lib.rs +++ b/verify/src/lib.rs @@ -48,6 +48,8 @@ pub enum Version { V29, /// Bitcoin Core v30. V30, + /// Bitcoin Core v31. + V31, } impl Version { @@ -68,6 +70,7 @@ impl Version { "v28" | "28" => Ok(Version::V28), "v29" | "29" => Ok(Version::V29), "v30" | "30" => Ok(Version::V30), + "v31" | "31" => Ok(Version::V31), other => Err(anyhow::Error::msg(format!("unknown version: '{}'", other))), } } @@ -91,6 +94,7 @@ impl fmt::Display for Version { V28 => "v28", V29 => "v29", V30 => "v30", + V31 => "v31", }; fmt::Display::fmt(&s, f) } diff --git a/verify/src/main.rs b/verify/src/main.rs index fc5aa7b3..f04a1642 100644 --- a/verify/src/main.rs +++ b/verify/src/main.rs @@ -21,7 +21,7 @@ use verify::{method, model, reexports, ssot, Version}; // TODO: Enable running from any directory, currently errors if run from `src/`. // TODO: Add a --quiet option. -const VERSIONS: [Version; 14] = [ +const VERSIONS: [Version; 15] = [ Version::V17, Version::V18, Version::V19, @@ -36,6 +36,7 @@ const VERSIONS: [Version; 14] = [ Version::V28, Version::V29, Version::V30, + Version::V31, ]; fn main() -> Result<()> { diff --git a/verify/src/method/mod.rs b/verify/src/method/mod.rs index b4527afe..77ccf025 100644 --- a/verify/src/method/mod.rs +++ b/verify/src/method/mod.rs @@ -16,6 +16,7 @@ pub mod v27; pub mod v28; pub mod v29; pub mod v30; +pub mod v31; use crate::Version; @@ -38,6 +39,7 @@ pub fn all_methods(version: Version) -> Vec { V28 => v28::METHODS, V29 => v29::METHODS, V30 => v30::METHODS, + V31 => v31::METHODS, }; list.iter().map(|m| m.name.to_string()).collect() @@ -81,6 +83,7 @@ impl Method { V28 => v28::METHODS, V29 => v29::METHODS, V30 => v30::METHODS, + V31 => v31::METHODS, }; list.iter().find(|&method| method.name == name) diff --git a/verify/src/method/v31.rs b/verify/src/method/v31.rs new file mode 100644 index 00000000..6730e56f --- /dev/null +++ b/verify/src/method/v31.rs @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! JSON RPC methods provided by Bitcoin Core v31. + +use super::Method; + +/// Data for the JSON RPC methods provided by Bitcoin Core v31. +pub const METHODS: &[Method] = &[ + // blockchain + Method::new_modelled("dumptxoutset", "DumpTxOutSet", "dump_tx_out_set"), + Method::new_modelled("getbestblockhash", "GetBestBlockHash", "get_best_block_hash"), + Method::new_modelled("getblock", "GetBlockVerboseZero", "get_block"), // We only check one of the types. + Method::new_modelled("getblockchaininfo", "GetBlockchainInfo", "get_blockchain_info"), + Method::new_modelled("getblockcount", "GetBlockCount", "get_block_count"), + Method::new_modelled("getblockfilter", "GetBlockFilter", "get_block_filter"), + Method::new_nothing("getblockfrompeer", "get_block_from_peer"), + Method::new_modelled("getblockhash", "GetBlockHash", "get_block_hash"), + Method::new_modelled("getblockheader", "GetBlockHeader", "get_block_header"), + Method::new_modelled("getblockstats", "GetBlockStats", "get_block_stats"), + Method::new_modelled("getchainstates", "GetChainStates", "get_chain_states"), + Method::new_modelled("getchaintips", "GetChainTips", "get_chain_tips"), + Method::new_modelled("getchaintxstats", "GetChainTxStats", "get_chain_tx_stats"), + Method::new_modelled("getdeploymentinfo", "GetDeploymentInfo", "get_deployment_info"), + Method::new_modelled( + "getdescriptoractivity", + "GetDescriptorActivity", + "get_descriptor_activity", + ), + Method::new_modelled("getdifficulty", "GetDifficulty", "get_difficulty"), + Method::new_modelled("getmempoolancestors", "GetMempoolAncestors", "get_mempool_ancestors"), + Method::new_modelled("getmempoolcluster", "GetMempoolCluster", "get_mempool_cluster"), + Method::new_modelled( + "getmempooldescendants", + "GetMempoolDescendants", + "get_mempool_descendants", + ), + Method::new_modelled("getmempoolentry", "GetMempoolEntry", "get_mempool_entry"), + Method::new_modelled("getmempoolinfo", "GetMempoolInfo", "get_mempool_info"), + Method::new_modelled("getrawmempool", "GetRawMempool", "get_raw_mempool"), + Method::new_modelled("gettxout", "GetTxOut", "get_tx_out"), + Method::new_string("gettxoutproof", "get_tx_out_proof"), + Method::new_modelled("gettxoutsetinfo", "GetTxOutSetInfo", "get_tx_out_set_info"), + Method::new_modelled("gettxspendingprevout", "GetTxSpendingPrevout", "get_tx_spending_prevout"), + Method::new_nothing("importmempool", "import_mempool"), + Method::new_modelled("loadtxoutset", "LoadTxOutSet", "load_tx_out_set"), + Method::new_nothing("preciousblock", "precious_block"), + Method::new_no_model("pruneblockchain", "PruneBlockchain", "prune_blockchain"), + Method::new_no_model("savemempool", "SaveMempool", "save_mempool"), + Method::new_modelled("scanblocks", "ScanBlocksStart", "scan_blocks"), + Method::new_modelled("scantxoutset", "ScanTxOutSetStart", "scan_tx_out_set"), + Method::new_no_model("verifychain", "VerifyChain", "verify_chain"), + Method::new_modelled("verifytxoutproof", "VerifyTxOutProof", "verify_tx_out_proof"), + Method::new_modelled("waitforblock", "WaitForBlock", "wait_for_block"), + Method::new_modelled("waitforblockheight", "WaitForBlockHeight", "wait_for_block_height"), + Method::new_modelled("waitfornewblock", "WaitForNewBlock", "wait_for_new_block"), + // control + Method::new_no_model("getrpcinfo", "GetRpcInfo", "get_rpc_info"), + Method::new_no_model("getmemoryinfo", "GetMemoryInfoStats", "get_memory_info"), + Method::new_string("help", "help"), + Method::new_no_model("logging", "Logging", "logging"), + Method::new_nothing("stop", "stop"), + Method::new_numeric("uptime", "uptime"), + // mining + Method::new_modelled("getblocktemplate", "GetBlockTemplate", "get_block_template"), + Method::new_modelled("getmininginfo", "GetMiningInfo", "get_mining_info"), + Method::new_numeric("getnetworkhashps", "get_network_hashes_per_second"), + Method::new_modelled( + "getprioritisedtransactions", + "GetPrioritisedTransactionsREMOVEME", + "get_prioritised_transactions", + ), + Method::new_bool("prioritisetransaction", "prioritise_transaction"), + Method::new_nothing("submitblock", "submit_block"), + Method::new_nothing("submitheader", "submit_header"), + // network + Method::new_nothing("addnode", "add_node"), + Method::new_nothing("clearbanned", "clear_banned"), + Method::new_nothing("disconnectnode", "disconnect_node"), + Method::new_no_model("getaddednodeinfo", "GetAddedNodeInfo", "get_added_node_info"), + Method::new_no_model("getaddrmaninfo", "GetAddrManInfo", "get_addr_man_info"), + Method::new_no_model("getconnectioncount", "GetConnectionCount", "get_connection_count"), + Method::new_no_model("getnettotals", "GetNetTotals", "get_net_totals"), + Method::new_modelled("getnetworkinfo", "GetNetworkInfo", "get_network_info"), + Method::new_no_model("getnodeaddresses", "GetNodeAddresses", "get_node_addresses"), + Method::new_no_model("getpeerinfo", "GetPeerInfo", "get_peer_info"), + Method::new_no_model("listbanned", "ListBanned", "list_banned"), + Method::new_nothing("ping", "ping"), + Method::new_nothing("setban", "set_ban"), + Method::new_no_model("setnetworkactive", "SetNetworkActive", "set_network_active"), + // raw transactions + Method::new_modelled( + "abortprivatebroadcast", + "AbortPrivateBroadcast", + "abort_private_broadcast", + ), + Method::new_modelled("analyzepsbt", "AnalyzePsbt", "analyze_psbt"), + Method::new_modelled("combinepsbt", "CombinePsbt", "combine_psbt"), + Method::new_modelled( + "combinerawtransaction", + "CombineRawTransaction", + "combine_raw_transaction", + ), + Method::new_modelled("converttopsbt", "ConvertToPsbt", "convert_to_psbt"), + Method::new_modelled("createpsbt", "CreatePsbt", "create_psbt"), + Method::new_modelled("createrawtransaction", "CreateRawTransaction", "create_raw_transaction"), + Method::new_modelled("decodepsbt", "DecodePsbt", "decode_psbt"), + Method::new_modelled("decoderawtransaction", "DecodeRawTransaction", "decode_raw_transaction"), + Method::new_modelled("decodescript", "DecodeScript", "decode_script"), + Method::new_modelled( + "descriptorprocesspsbt", + "DescriptorProcessPsbt", + "descriptor_process_psbt", + ), + Method::new_modelled("finalizepsbt", "FinalizePsbt", "finalize_psbt"), + Method::new_modelled("fundrawtransaction", "FundRawTransaction", "fund_raw_transaction"), + Method::new_modelled( + "getprivatebroadcastinfo", + "GetPrivateBroadcastInfo", + "get_private_broadcast_info", + ), + Method::new_modelled("getrawtransaction", "GetRawTransaction", "get_raw_transaction"), + Method::new_modelled("joinpsbts", "JoinPsbts", "join_psbts"), + Method::new_modelled("sendrawtransaction", "SendRawTransaction", "send_raw_transaction"), + Method::new_modelled( + "signrawtransactionwithkey", + "SignRawTransaction", + "sign_raw_transaction_with_key", + ), + Method::new_modelled("submitpackage", "SubmitPackage", "submit_package"), + Method::new_modelled("testmempoolaccept", "TestMempoolAccept", "test_mempool_accept"), + Method::new_modelled("utxoupdatepsbt", "UtxoUpdatePsbt", "utxo_update_psbt"), + Method::new_modelled("createmultisig", "CreateMultisig", "create_multisig"), + Method::new_modelled("deriveaddresses", "DeriveAddresses", "derive_addresses"), + Method::new_modelled("estimatesmartfee", "EstimateSmartFee", "estimate_smart_fee"), + Method::new_no_model("getdescriptorinfo", "GetDescriptorInfo", "get_descriptor_info"), + Method::new_no_model("getindexinfo", "GetIndexInfo", "get_index_info"), + Method::new_modelled( + "signmessagewithprivkey", + "SignMessageWithPrivKey", + "sign_message_with_priv_key", + ), + Method::new_modelled("validateaddress", "ValidateAddress", "validate_address"), + Method::new_bool("verifymessage", "verify_message"), + // signer + Method::new_no_model("enumeratesigners", "EnumerateSigners", "enumerate_signers"), + // wallet + Method::new_nothing("abandontransaction", "abandon_transaction"), + Method::new_no_model("abortrescan", "AbortRescan", "abort_rescan"), + Method::new_nothing("backupwallet", "backup_wallet"), + Method::new_modelled("bumpfee", "BumpFee", "bump_fee"), + Method::new_modelled("createwallet", "CreateWallet", "create_wallet"), + Method::new_no_model( + "createwalletdescriptor", + "CreateWalletDescriptor", + "create_wallet_descriptor", + ), + Method::new_no_model("encryptwallet", "EncryptWallet", "encrypt_wallet"), + Method::new_modelled("getaddressesbylabel", "GetAddressesByLabel", "get_addresses_by_label"), + Method::new_modelled("getaddressinfo", "GetAddressInfo", "get_address_info"), + Method::new_modelled("getbalance", "GetBalance", "get_balance"), + Method::new_modelled("getbalances", "GetBalances", "get_balances"), + Method::new_modelled("gethdkeys", "GetHdKeys", "get_hd_keys"), + Method::new_modelled("getnewaddress", "GetNewAddress", "get_new_address"), + Method::new_modelled("getrawchangeaddress", "GetRawChangeAddress", "get_raw_change_address"), + Method::new_modelled("getreceivedbyaddress", "GetReceivedByAddress", "get_received_by_address"), + Method::new_modelled("getreceivedbylabel", "GetReceivedByLabel", "get_received_by_label"), + Method::new_modelled("gettransaction", "GetTransaction", "get_transaction"), + Method::new_modelled("getwalletinfo", "GetWalletInfo", "get_wallet_info"), + Method::new_no_model("importdescriptors", "ImportDescriptors", "import_descriptors"), + Method::new_nothing("importprunedfunds", "import_pruned_funds"), + Method::new_nothing("keypoolrefill", "keypool_refill"), + Method::new_modelled("listaddressgroupings", "ListAddressGroupings", "list_address_groupings"), + Method::new_no_model("listdescriptors", "ListDescriptors", "list_descriptors"), + Method::new_no_model("listlabels", "ListLabels", "list_labels"), + Method::new_modelled("listlockunspent", "ListLockUnspent", "list_lock_unspent"), + Method::new_no_model("migratewallet", "MigrateWallet", "migrate_wallet"), + Method::new_modelled("psbtbumpfee", "PsbtBumpFee", "psbt_bump_fee"), + Method::new_modelled( + "listreceivedbyaddress", + "ListReceivedByAddress", + "list_received_by_address", + ), + Method::new_modelled("listreceivedbylabel", "ListReceivedByLabel", "list_received_by_label"), + Method::new_modelled("listsinceblock", "ListSinceBlock", "list_since_block"), + Method::new_modelled("listtransactions", "ListTransactions", "list_transactions"), + Method::new_modelled("listunspent", "ListUnspent", "list_unspent"), + Method::new_no_model("listwalletdir", "ListWalletDir", "list_wallet_dir"), + Method::new_modelled("listwallets", "ListWallets", "list_wallets"), + Method::new_modelled("loadwallet", "LoadWallet", "load_wallet"), + Method::new_no_model("lockunspent", "LockUnspent", "lock_unspent"), + Method::new_nothing("removeprunedfunds", "remove_pruned_funds"), + Method::new_modelled("rescanblockchain", "RescanBlockchain", "rescan_blockchain"), + Method::new_no_model("restorewallet", "RestoreWallet", "restore_wallet"), + Method::new_modelled("send", "Send", "send"), + Method::new_modelled("sendall", "SendAll", "send_all"), + Method::new_modelled("sendmany", "SendMany", "send_many"), + Method::new_modelled("sendtoaddress", "SendToAddress", "send_to_address"), + Method::new_nothing("setlabel", "set_label"), + Method::new_no_model("setwalletflag", "SetWalletFlag", "set_wallet_flag"), + Method::new_modelled("signmessage", "SignMessage", "sign_message"), + Method::new_modelled( + "signrawtransactionwithwallet", + "SignRawTransaction", + "sign_raw_transaction_with_wallet", + ), + Method::new_modelled( + "simulaterawtransaction", + "SimulateRawTransaction", + "simulate_raw_transaction", + ), + Method::new_nothing("unloadwallet", "unload_wallet"), + Method::new_modelled( + "walletcreatefundedpsbt", + "WalletCreateFundedPsbt", + "wallet_create_funded_psbt", + ), + Method::new_modelled("walletdisplayaddress", "WalletDisplayAddress", "wallet_display_address"), + Method::new_nothing("walletlock", "wallet_lock"), + Method::new_nothing("walletpassphrase", "wallet_passphrase"), + Method::new_nothing("walletpassphrasechange", "wallet_passphrase_change"), + Method::new_modelled("walletprocesspsbt", "WalletProcessPsbt", "wallet_process_psbt"), + // zmq + Method::new_no_model("getzmqnotifications", "GetZmqNotifications", "get_zmq_notifications"), +];