diff --git a/client/src/client_sync/mod.rs b/client/src/client_sync/mod.rs
index 90987da3..fc32d66b 100644
--- a/client/src/client_sync/mod.rs
+++ b/client/src/client_sync/mod.rs
@@ -16,6 +16,7 @@ pub mod v26;
pub mod v27;
pub mod v28;
pub mod v29;
+pub mod v30;
use std::fs::File;
use std::io::{BufRead, BufReader};
diff --git a/client/src/client_sync/v30/mod.rs b/client/src/client_sync/v30/mod.rs
new file mode 100644
index 00000000..e62fa86c
--- /dev/null
+++ b/client/src/client_sync/v30/mod.rs
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: CC0-1.0
+
+//! A JSON-RPC client for testing against Bitcoin Core `v30`.
+//!
+//! We ignore option arguments unless they effect the shape of the returned JSON data.
+
+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::v30::*;
+
+#[rustfmt::skip] // Keep public re-exports separate.
+pub use crate::client_sync::{
+ v17::{AddNodeCommand, ImportMultiRequest, ImportMultiScriptPubKey, ImportMultiTimestamp, Input, Output, SetBanCommand, WalletCreateFundedPsbtInput,},
+ v21::ImportDescriptorsRequest,
+ v23::AddressType,
+ v29::{TemplateRequest, TemplateRules}
+};
+
+crate::define_jsonrpc_minreq_client!("v30");
+crate::impl_client_check_expected_server_version!({ [300000] });
+
+// == Blockchain ==
+crate::impl_client_v29__dump_tx_out_set!();
+crate::impl_client_v17__get_best_block_hash!();
+crate::impl_client_v17__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_v29__get_descriptor_activity!();
+crate::impl_client_v17__get_difficulty!();
+crate::impl_client_v17__get_mempool_ancestors!();
+crate::impl_client_v17__get_mempool_descendants!();
+crate::impl_client_v17__get_mempool_entry!();
+crate::impl_client_v17__get_mempool_info!();
+crate::impl_client_v17__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_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__verify_chain!();
+crate::impl_client_v17__verify_tx_out_proof!();
+
+// == 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_v21__add_peer_address!();
+
+// == 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_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_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_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_v17__set_tx_fee!();
+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/contrib/templates/bitcoind_aliases b/contrib/templates/bitcoind_aliases
index 5f635883..9d61f433 100644
--- a/contrib/templates/bitcoind_aliases
+++ b/contrib/templates/bitcoind_aliases
@@ -14,6 +14,7 @@ alias bt26='/opt/bitcoin-26.2/bin/bitcoin-cli -regtest -rpcuser=user -rpcpasswor
alias bt27='/opt/bitcoin-27.2/bin/bitcoin-cli -regtest -rpcuser=user -rpcpassword=password -rpcport=27249'
alias bt28='/opt/bitcoin-28.1/bin/bitcoin-cli -regtest -rpcuser=user -rpcpassword=password -rpcport=28149'
alias bt29='/opt/bitcoin-29.0/bin/bitcoin-cli -regtest -rpcuser=user -rpcpassword=password -rpcport=29049'
+alias bt30='/opt/bitcoin-30.0/bin/bitcoin-cli -regtest -rpcuser=user -rpcpassword=password -rpcport=30049'
# Test aliases for different Bitcoin Core versions
@@ -30,3 +31,4 @@ alias test26='BITCOIND_EXE=/opt/bitcoin-26.2/bin/bitcoind cargo test --features=
alias test27='BITCOIND_EXE=/opt/bitcoin-27.2/bin/bitcoind cargo test --features="27_2"'
alias test28='BITCOIND_EXE=/opt/bitcoin-28.1/bin/bitcoind cargo test --features="28_1"'
alias test29='BITCOIND_EXE=/opt/bitcoin-29.0/bin/bitcoind cargo test --features="29_0"'
+alias test30='BITCOIND_EXE=/opt/bitcoin-30.0/bin/bitcoind cargo test --features="30_0"'
diff --git a/contrib/templates/run-bitcoind.conf b/contrib/templates/run-bitcoind.conf
index 6e2d4e4f..9642cc33 100644
--- a/contrib/templates/run-bitcoind.conf
+++ b/contrib/templates/run-bitcoind.conf
@@ -11,3 +11,4 @@ v26 26.2 262 /opt/bitcoin-26.2/bin/bitcoind
v27 27.2 272 /opt/bitcoin-27.2/bin/bitcoind
v28 28.1 281 /opt/bitcoin-28.1/bin/bitcoind
v29 29.0 290 /opt/bitcoin-29.0/bin/bitcoind
+v30 30.0 300 /opt/bitcoin-30.0/bin/bitcoind
diff --git a/integration_test/Cargo.toml b/integration_test/Cargo.toml
index d4228aad..6a5df369 100644
--- a/integration_test/Cargo.toml
+++ b/integration_test/Cargo.toml
@@ -14,7 +14,8 @@ edition = "2021"
download = ["node/download"]
# Enable the same feature in `node` and the version feature here.
-# All minor releases of the latest three versions.
+# All minor releases of the latest four versions.
+30_0 = ["v30_and_below", "node/30_0"]
29_0 = ["v29_and_below", "node/29_0"]
28_2 = ["v28_and_below", "node/28_2"]
28_1 = ["v28_and_below", "node/28_1"]
@@ -38,7 +39,8 @@ download = ["node/download"]
# 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")))]
-v29_and_below = []
+v30_and_below = []
+v29_and_below = ["v30_and_below"]
v28_and_below = ["v29_and_below"]
v27_and_below = ["v28_and_below"]
v26_and_below = ["v27_and_below"]
diff --git a/integration_test/tests/blockchain.rs b/integration_test/tests/blockchain.rs
index a14f39e2..3a820e86 100644
--- a/integration_test/tests/blockchain.rs
+++ b/integration_test/tests/blockchain.rs
@@ -332,6 +332,7 @@ fn blockchain__get_mempool_entry__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn blockchain__get_mempool_info__modelled() {
let node = Node::with_wallet(Wallet::Default, &[]);
node.fund_wallet();
diff --git a/integration_test/tests/mining.rs b/integration_test/tests/mining.rs
index 897018ab..dd7e9e48 100644
--- a/integration_test/tests/mining.rs
+++ b/integration_test/tests/mining.rs
@@ -37,6 +37,7 @@ fn mining__get_block_template__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn mining__get_mining_info() {
let node = Node::with_wallet(Wallet::Default, &[]);
diff --git a/integration_test/tests/wallet.rs b/integration_test/tests/wallet.rs
index c3bb822f..99ba7396 100644
--- a/integration_test/tests/wallet.rs
+++ b/integration_test/tests/wallet.rs
@@ -59,6 +59,7 @@ fn wallet__abort_rescan() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__add_multisig_address__modelled() {
let nrequired = 2;
@@ -168,6 +169,7 @@ fn wallet__create_wallet_descriptor() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__dump_priv_key__modelled() {
// As of Core v23 the default wallet is an native descriptor wallet which does not
// support dumping private keys. Legacy wallets are supported upto v25 it seems.
@@ -200,6 +202,7 @@ fn wallet__dump_priv_key__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__dump_wallet() {
// As of Core v23 the default wallet is an native descriptor wallet which does not
// support dumping private keys. Legacy wallets are supported upto v25 it seems.
@@ -398,6 +401,7 @@ fn wallet__get_transaction__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__get_unconfirmed_balance__modelled() {
let node = Node::with_wallet(Wallet::Default, &[]);
let json: GetUnconfirmedBalance =
@@ -407,6 +411,7 @@ fn wallet__get_unconfirmed_balance__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__get_wallet_info__modelled() {
let node = Node::with_wallet(Wallet::Default, &[]);
node.mine_a_block();
@@ -433,6 +438,7 @@ fn wallet__get_wallet_info__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__import_address() {
let node = match () {
#[cfg(feature = "v22_and_below")]
@@ -517,6 +523,7 @@ fn wallet__import_pruned_funds() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__import_wallet() {
let node = match () {
#[cfg(feature = "v22_and_below")]
@@ -648,6 +655,7 @@ fn wallet__list_transactions__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__import_multi() {
let node = match () {
#[cfg(feature = "v22_and_below")]
@@ -711,6 +719,7 @@ fn wallet__import_multi() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__import_privkey() {
let node = match () {
#[cfg(feature = "v22_and_below")]
@@ -730,6 +739,7 @@ fn wallet__import_privkey() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__import_pubkey() {
let node = match () {
#[cfg(feature = "v22_and_below")]
@@ -805,7 +815,7 @@ fn wallet__list_unspent__modelled() {
}
#[test]
-#[cfg(not(feature = "v17"))]
+#[cfg(all(feature = "v29_and_below", not(feature = "v17")))]
fn wallet__list_wallet_dir() {
let wallet_name = "test-wallet";
let node = Node::with_wallet(Wallet::None, &[]);
@@ -853,7 +863,7 @@ fn wallet__lock_unspent() {
}
#[test]
-#[cfg(not(feature = "v23_and_below"))]
+#[cfg(all(feature = "v29_and_below", not(feature = "v23_and_below")))]
fn wallet__migrate_wallet() {
let node = Node::with_wallet(Wallet::None, &["-deprecatedrpc=create_bdb"]);
let wallet_name = "legacy_wallet";
@@ -865,7 +875,7 @@ fn wallet__migrate_wallet() {
}
#[test]
-#[cfg(not(feature = "v22_and_below"))]
+#[cfg(all(feature = "v29_and_below", not(feature = "v22_and_below")))]
fn wallet__new_keypool() {
let node = Node::with_wallet(Wallet::None, &["-deprecatedrpc=create_bdb"]);
node.client.create_legacy_wallet("legacy_wallet").expect("createlegacywallet");
@@ -1002,6 +1012,7 @@ fn wallet__send_to_address__modelled() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__set_tx_fee() {
let node = Node::with_wallet(Wallet::Default, &[]);
let fee_rate = FeeRate::from_sat_per_vb(2).expect("2 sat/vb is valid");
@@ -1021,6 +1032,7 @@ fn wallet__set_wallet_flag() {
}
#[test]
+#[cfg(feature = "v29_and_below")]
fn wallet__set_hd_seed() {
let node = match () {
#[cfg(feature = "v22_and_below")]
@@ -1181,7 +1193,7 @@ fn create_load_unload_wallet() {
}
#[test]
-#[cfg(not(feature = "v20_and_below"))]
+#[cfg(all(feature = "v29_and_below", not(feature = "v20_and_below")))]
fn wallet__upgrade_wallet() {
let node = Node::with_wallet(Wallet::Default, &[]);
diff --git a/node/Cargo.toml b/node/Cargo.toml
index 9ce61f30..f98149a8 100644
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -44,7 +44,8 @@ default = ["0_17_2"]
download = ["anyhow", "bitcoin_hashes", "flate2", "tar", "minreq", "zip"]
-# We support all minor releases of the latest three versions.
+# We support all minor releases of the latest four versions.
+30_0 = ["29_0"]
29_0 = ["28_2"]
28_2 = ["28_1"]
28_1 = ["28_0"]
diff --git a/node/contrib/extra_tests.sh b/node/contrib/extra_tests.sh
index 37a0ebe8..29052451 100755
--- a/node/contrib/extra_tests.sh
+++ b/node/contrib/extra_tests.sh
@@ -14,7 +14,7 @@
set -euox pipefail
-FEATURES=("29_0" "28_2" "28_1" "28_0" "27_1" "27_0" "26_2" "25_2" "24_2" \
+FEATURES=("30_0 "29_0" "28_2" "28_1" "28_0" "27_1" "27_0" "26_2" "25_2" "24_2" \
"23_2" "22_1" "0_21_2" "0_20_2" "0_19_1" "0_18_1" "0_17_2")
# Use the current `Cargo.lock` file without updating it.
diff --git a/node/sha256/bitcoin-core-30.0-SHA256SUMS b/node/sha256/bitcoin-core-30.0-SHA256SUMS
new file mode 100644
index 00000000..b4276f9e
--- /dev/null
+++ b/node/sha256/bitcoin-core-30.0-SHA256SUMS
@@ -0,0 +1,28 @@
+d4c91b1fb02708397317a79efa4fc5e1ad5f3b85fab894316e104cc8ebeb17b8 bitcoin-30.0-aarch64-linux-gnu-debug.tar.gz
+785f49061ae65fcf31b8323803bbaa284569dc65e7aba68229e2da222a449635 bitcoin-30.0-aarch64-linux-gnu.tar.gz
+fe60e9535c13cb58b39e1c82c446ca9afc96970ec309474b9e708e103d9e9e94 bitcoin-30.0-arm-linux-gnueabihf-debug.tar.gz
+68eef66e4c18396449450f45626e023dc96023742bb760aafcf4625a59c01c56 bitcoin-30.0-arm-linux-gnueabihf.tar.gz
+31c6eef5158c9416b8923adc090b88394421dbee7de0e676a39e43de12051580 bitcoin-30.0-arm64-apple-darwin.tar.gz
+f6e2d885027e25500c8b16406c95b0fb7e536a4e2bbaae2cf8b48a476a60abe1 bitcoin-30.0-arm64-apple-darwin.zip
+60fcd271f902c1dab821148b46342695cc1ee10366211ccd3ffb844256e4cd2f bitcoin-30.0-arm64-apple-darwin-codesigning.tar.gz
+11b8e7acc678eb372bf5f8a8a6ff4705cb3572e573218a1e6833c3abfa2268db bitcoin-30.0-arm64-apple-darwin-unsigned.tar.gz
+01c612aee1faa59bf6234aca112097d5799220ba05a020cf997d9993e85aa8ee bitcoin-30.0-arm64-apple-darwin-unsigned.zip
+38da8058a2d674f3ed402721178d6e52b1adb9f0a7a9686aaad0c99157ab0512 bitcoin-30.0-codesignatures-30.0.tar.gz
+9b472a4d51dfed9aa9d0ded2cb8c7bcb9267f8439a23a98f36eb509c1a5e6974 bitcoin-30.0.tar.gz
+d5ea7f1a20da39cec29bc9d8242b835bf0e0bcece2240b986507a9b61ba23501 bitcoin-30.0-powerpc64-linux-gnu-debug.tar.gz
+1402808855de1349a4abfdcd4295dd3e793359ceb10b39673542730e353fce63 bitcoin-30.0-powerpc64-linux-gnu.tar.gz
+10371a60e8b324f7dbca63381ba317b67ec3c7897c099a1a450232e70632e57c bitcoin-30.0-riscv64-linux-gnu-debug.tar.gz
+f720a3a97e69ce08ee6effe7f0830ffbee56833df5aa3acbf8fa159250947513 bitcoin-30.0-riscv64-linux-gnu.tar.gz
+4eadf7b06dca695b940ad30f46247aacbd439544a1be25b0ef3baab73777b3d2 bitcoin-30.0-x86_64-apple-darwin.tar.gz
+0eb10b714a4f5a0f7c40a9533d0bda141c739e7930c814e392baa99b3bf24790 bitcoin-30.0-x86_64-apple-darwin.zip
+84b7de64c8e25bcdfb5ba24f2b4c2d5205b19bf01b406d2e368944e2ebd191df bitcoin-30.0-x86_64-apple-darwin-codesigning.tar.gz
+f1dc0fea030dd392ea199c0f3caee13ca2b65a9a992eaf97bf3071ff997d32a1 bitcoin-30.0-x86_64-apple-darwin-unsigned.tar.gz
+f2f1362be35c8afcf3250f7badbd0c8060e82ced11ef7d0ebea4c83dca4001d5 bitcoin-30.0-x86_64-apple-darwin-unsigned.zip
+bde1cd4652971613fe1766357550e61d7dbe28b1b24c88efa456bc8849ad1221 bitcoin-30.0-x86_64-linux-gnu-debug.tar.gz
+00964ae375084113b1162f2f493b9372421608af23539766e315a3cb0ee54248 bitcoin-30.0-x86_64-linux-gnu.tar.gz
+3065d43b57f967687399f9c00d424556d16d33997e1653fdb5bf1934b95168e6 bitcoin-30.0-win64-setup.exe
+3d6f3af2cbfbeaf1958d0ffd77e04da6b8b82f26bb67aaa9111247620d5c95db bitcoin-30.0-win64.zip
+70e7b116cfb171af07b6f1605a6624a8a30c2b4edeba7dbf27766286cebe2a92 bitcoin-30.0-win64-codesigning.tar.gz
+8a16d8a1ef2d2c850d2d2d8461a220ba6e30011b689ac2e2ea6158650a676bbd bitcoin-30.0-win64-debug.zip
+190a9a979cb161913c1cc2501937a5fe16a8f5d08de034cc00fe9ea769088665 bitcoin-30.0-win64-setup-unsigned.exe
+bed46b79d0a5ee0db5ef8d19ce0077b0b6fe642367336447ca7acdc869f2823a bitcoin-30.0-win64-unsigned.zip
diff --git a/node/src/client_versions.rs b/node/src/client_versions.rs
index 601f91c3..93194eb3 100644
--- a/node/src/client_versions.rs
+++ b/node/src/client_versions.rs
@@ -6,7 +6,10 @@
#![allow(unused_imports)] // Not all users need the json types.
-#[cfg(feature = "29_0")]
+#[cfg(feature = "30_0")]
+pub use corepc_client::{client_sync::v30::*, types::v30 as vtype};
+
+#[cfg(all(feature = "29_0", not(feature = "30_0")))]
pub use corepc_client::{client_sync::v29::*, types::v29 as vtype};
#[cfg(all(feature = "28_2", not(feature = "29_0")))]
@@ -60,6 +63,7 @@ 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"),
diff --git a/node/src/versions.rs b/node/src/versions.rs
index 4b9ca4d2..1bc0e453 100644
--- a/node/src/versions.rs
+++ b/node/src/versions.rs
@@ -1,6 +1,7 @@
// 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_0"),
not(feature = "29_0"),
not(feature = "28_2"),
not(feature = "28_1"),
@@ -21,8 +22,11 @@
))]
compile_error!("enable a feature in order to select the version of Bitcoin Core to use");
-#[cfg(feature = "29_0")]
+#[cfg(feature = "30_0")]
#[allow(dead_code)] // Triggers in --all-features builds.
+pub const VERSION: &str = "30.0";
+
+#[cfg(all(feature = "29_0", not(feature = "30_0")))]
pub const VERSION: &str = "29.0";
#[cfg(all(feature = "28_2", not(feature = "29_0")))]
@@ -76,6 +80,7 @@ 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"),
diff --git a/types/src/lib.rs b/types/src/lib.rs
index fe1134ea..ba977cc5 100644
--- a/types/src/lib.rs
+++ b/types/src/lib.rs
@@ -30,6 +30,7 @@ pub mod v26;
pub mod v27;
pub mod v28;
pub mod v29;
+pub mod v30;
// JSON types that model _all_ `bitcoind` versions.
pub mod model;
diff --git a/types/src/v30/mod.rs b/types/src/v30/mod.rs
new file mode 100644
index 00000000..1442de44
--- /dev/null
+++ b/types/src/v30/mod.rs
@@ -0,0 +1,334 @@
+// SPDX-License-Identifier: CC0-1.0
+
+//! # JSON-RPC types for Bitcoin Core `v30`
+//!
+//! 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 | Includes additional 'verbose' type |
+//! | getblockchaininfo | version + model | |
+//! | getblockcount | version + model | |
+//! | getblockfilter | version + model | |
+//! | getblockfrompeer | returns nothing | |
+//! | 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 | |
+//! | getdescriptoractivity | version + model | |
+//! | getdifficulty | version + model | |
+//! | getmempoolancestors | version + model | |
+//! | getmempooldescendants | version + model | |
+//! | getmempoolentry | version + model | |
+//! | getmempoolinfo | version + model | TODO |
+//! | getrawmempool | version + model | Includes additional 'verbose' type |
+//! | 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 | omitted | API marked as experimental |
+//! | verifychain | version | |
+//! | verifytxoutproof | version + model | |
+//! | waitforblock | version + model | TODO |
+//! | waitforblockheight | version + model | TODO |
+//! | waitfornewblock | version + model | TODO |
+//!
+//!
+//!
+//!
+//! Methods from the == Control == section
+//!
+//! | JSON-RPC Method Name | Returns | Notes |
+//! |:-----------------------------------|:---------------:|:--------------------------------------:|
+//! | getmemoryinfo | version | |
+//! | getrpcinfo | version | |
+//! | help | returns string | |
+//! | logging | version | |
+//! | stop | returns string | |
+//! | uptime | returns numeric | |
+//!
+//!
+//!
+//!
+//! Methods from the == Mining == section
+//!
+//! | JSON-RPC Method Name | Returns | Notes |
+//! |:-----------------------------------|:---------------:|:--------------------------------------:|
+//! | getblocktemplate | version + model | |
+//! | getmininginfo | version + model | TODO |
+//! | getnetworkhashps | returns boolean | |
+//! | 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 | |
+//! | getaddednodeinfo | version | |
+//! | getaddrmaninfo | version | |
+//! | getconnectioncount | version | |
+//! | getnettotals | version | |
+//! | getnetworkinfo | version + model | |
+//! | getnodeaddresses | version | |
+//! | getpeerinfo | version | |
+//! | listbanned | version | |
+//! | ping | returns nothing | |
+//! | setban | returns nothing | |
+//! | setnetworkactive | version | |
+//!
+//!
+//!
+//!
+//! Methods from the == Rawtransactions == section
+//!
+//! | JSON-RPC Method Name | Returns | Notes |
+//! |:-----------------------------------|:---------------:|:--------------------------------------:|
+//! | analyzepsbt | version + model | |
+//! | combinepsbt | version + model | |
+//! | combinerawtransaction | version + model | |
+//! | converttopsbt | version + model | |
+//! | createpsbt | version + model | |
+//! | createrawtransaction | version + model | |
+//! | decodepsbt | version + model | TODO |
+//! | descriptorprocesspsbt | returns boolean | |
+//! | decoderawtransaction | version + model | |
+//! | decodescript | version + model | |
+//! | finalizepsbt | version + model | |
+//! | fundrawtransaction | version + model | |
+//! | 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 | TODO |
+//! | importdescriptors | version | |
+//! | importprunedfunds | returns nothing | |
+//! | keypoolrefill | returns nothing | |
+//! | listaddressgroupings | version + model | |
+//! | listdescriptors | version | |
+//! | listlabels | version | |
+//! | listlockunspent | version + model | |
+//! | migratewallet | version | TODO |
+//! | psbtbumpfee | version + model | |
+//! | listreceivedbyaddress | version + model | |
+//! | listreceivedbylabel | version + model | |
+//! | listsinceblock | version + model | |
+//! | listtransactions | version + model | |
+//! | listunspent | version + model | |
+//! | listwalletdir | version | TODO |
+//! | 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 | |
+//! | settxfee | version | TODO |
+//! | setwalletflag | version | |
+//! | signmessage | version + model | |
+//! | signrawtransactionwithwallet | version + model | |
+//! | simulaterawtransaction | version + model | |
+//! | unloadwallet | returns nothing | |
+//! | walletcreatefundedpsbt | version + model | |
+//! | walletdisplayaddress | version + model | UNTESTED |
+//! | 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 | |
+//!
+//!
+
+#[doc(inline)]
+pub use crate::{
+ v17::{
+ AbortRescan, AddedNode, AddedNodeAddress, AddressInformation, BumpFee, BumpFeeError,
+ ChainTips, ChainTipsError, ChainTipsStatus, CombinePsbt, CombineRawTransaction,
+ ConvertToPsbt, CreateMultisigError, CreatePsbt, CreateRawTransaction, DecodeRawTransaction,
+ EncryptWallet, 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, PruneBlockchain,
+ RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain,
+ ScriptType, SendRawTransaction, SendToAddress, SetNetworkActive, SetTxFee, SignMessage,
+ SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError,
+ SignRawTransactionWithKey, SignRawTransactionWithWallet, TransactionCategory, UploadTarget,
+ ValidateAddress, ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof,
+ WalletCreateFundedPsbt, WalletCreateFundedPsbtError, WitnessUtxo,
+ },
+ v18::{
+ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing,
+ AnalyzePsbtInputMissingError, DeriveAddresses, GetAddressInfoError, GetReceivedByLabel,
+ GetZmqNotifications, JoinPsbts, JsonRpcError, ListReceivedByAddress,
+ ListReceivedByAddressItem, ListReceivedByLabel, ListReceivedByLabelError, ListWalletDir,
+ ListWalletDirWallet, UtxoUpdatePsbt,
+ },
+ v19::{
+ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalancesMine,
+ GetBalancesWatchOnly, GetBlockFilter, GetBlockFilterError, GetChainTxStats, GetRpcInfo,
+ MapMempoolEntryError, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError,
+ SetWalletFlag, Softfork, SoftforkType,
+ },
+ v20::GenerateToDescriptor,
+ v21::{
+ AddPeerAddress, GetIndexInfo, GetIndexInfoName, ImportDescriptors, ImportDescriptorsResult,
+ PsbtBumpFee, PsbtBumpFeeError, Send, SendError, SendMany, SendManyVerbose,
+ },
+ v22::{
+ Banned, EnumerateSigners, GetNodeAddresses, ListBanned, NodeAddress, ScriptPubkey,
+ WalletDisplayAddress,
+ },
+ v23::{
+ Bip9Info, Bip9Statistics, CreateMultisig, DecodeScript, DecodeScriptError, DeploymentInfo,
+ GetDeploymentInfo, GetDeploymentInfoError, RestoreWallet, SaveMempool,
+ },
+ v24::{
+ DecodePsbt, DecodePsbtError, GetMempoolAncestors, GetMempoolAncestorsVerbose,
+ GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo,
+ GetRawMempoolVerbose, GetTransactionDetail, GetTxSpendingPrevout,
+ GetTxSpendingPrevoutError, GlobalXpub, ListUnspent, ListUnspentItem, MempoolEntry,
+ MigrateWallet, Proprietary, PsbtInput, PsbtOutput, SendAll, SendAllError,
+ SimulateRawTransaction, TaprootBip32Deriv, TaprootLeaf, TaprootScript,
+ TaprootScriptPathSig,
+ },
+ v25::{
+ GenerateBlock, GenerateBlockError, GetBlockStats, ListDescriptors, MempoolAcceptanceError,
+ ScanBlocksAbort, ScanBlocksStart, ScanBlocksStartError, ScanBlocksStatus,
+ TestMempoolAcceptError,
+ },
+ v26::{
+ AddrManInfoNetwork, CreateWallet, DescriptorProcessPsbt, DescriptorProcessPsbtError,
+ DumpTxOutSet, DumpTxOutSetError, GetAddrManInfo, GetBalances, GetBalancesError,
+ GetPeerInfo, GetTransactionError, GetTxOutSetInfo, GetTxOutSetInfoError, GetWalletInfo,
+ GetWalletInfoError, GetWalletInfoScanning, LastProcessedBlock, LastProcessedBlockError,
+ LoadTxOutSet, LoadTxOutSetError, LoadWallet, PeerInfo, UnloadWallet, WalletProcessPsbt,
+ WalletProcessPsbtError,
+ },
+ v27::{GetPrioritisedTransactions, PrioritisedTransaction},
+ v28::{
+ CreateWalletDescriptor, GetAddressInfo, GetAddressInfoEmbedded, GetHdKeys, GetHdKeysError,
+ GetNetworkInfo, GetTransaction, HdKey, HdKeyDescriptor, ListSinceBlock,
+ ListSinceBlockError, ListTransactions, Logging, SubmitPackage, SubmitPackageError,
+ SubmitPackageTxResult, SubmitPackageTxResultError, SubmitPackageTxResultFees,
+ SubmitPackageTxResultFeesError, TransactionItem, TransactionItemError,
+ },
+ v29::{
+ ActivityEntry, ChainState, DeriveAddressesMultipath, GetBlockHeader, GetBlockHeaderError,
+ GetBlockHeaderVerbose, GetBlockHeaderVerboseError, GetBlockVerboseOne,
+ GetBlockVerboseOneError, GetBlockchainInfo, GetBlockchainInfoError, GetChainStates,
+ GetChainStatesError, GetDescriptorActivity, GetDescriptorActivityError, GetDescriptorInfo,
+ GetMiningInfo, GetMiningInfoError, MempoolAcceptance, NextBlockInfo, NextBlockInfoError,
+ ReceiveActivity, SpendActivity, TestMempoolAccept,
+ },
+};
diff --git a/verify/rpc-api-v30.txt b/verify/rpc-api-v30.txt
new file mode 100644
index 00000000..bbe87963
--- /dev/null
+++ b/verify/rpc-api-v30.txt
@@ -0,0 +1,166 @@
+== 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 )
+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},...]
+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 ==
+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 )
+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"
+settxfee amount
+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 63e20f45..c7683acf 100644
--- a/verify/src/lib.rs
+++ b/verify/src/lib.rs
@@ -45,6 +45,8 @@ pub enum Version {
V28,
/// Bitcoin Core v29.
V29,
+ /// Bitcoin Core v30.
+ V30,
}
impl Version {
@@ -64,6 +66,7 @@ impl Version {
"v27" | "27" => Ok(Version::V27),
"v28" | "28" => Ok(Version::V28),
"v29" | "29" => Ok(Version::V29),
+ "v30" | "30" => Ok(Version::V30),
other => Err(anyhow::Error::msg(format!("unknown version: '{}'", other))),
}
}
@@ -86,6 +89,7 @@ impl fmt::Display for Version {
V27 => "v27",
V28 => "v28",
V29 => "v29",
+ V30 => "v30",
};
fmt::Display::fmt(&s, f)
}
diff --git a/verify/src/main.rs b/verify/src/main.rs
index e387a277..ebd553c0 100644
--- a/verify/src/main.rs
+++ b/verify/src/main.rs
@@ -20,7 +20,7 @@ use verify::{method, model, ssot, Version};
// TODO: Enable running from any directory, currently errors if run from `src/`.
// TODO: Add a --quiet option.
-const VERSIONS: [Version; 13] = [
+const VERSIONS: [Version; 14] = [
Version::V17,
Version::V18,
Version::V19,
@@ -34,6 +34,7 @@ const VERSIONS: [Version; 13] = [
Version::V27,
Version::V28,
Version::V29,
+ Version::V30,
];
fn main() -> Result<()> {
diff --git a/verify/src/method/mod.rs b/verify/src/method/mod.rs
index 51c02d75..b4527afe 100644
--- a/verify/src/method/mod.rs
+++ b/verify/src/method/mod.rs
@@ -15,6 +15,7 @@ pub mod v26;
pub mod v27;
pub mod v28;
pub mod v29;
+pub mod v30;
use crate::Version;
@@ -36,6 +37,7 @@ pub fn all_methods(version: Version) -> Vec {
V27 => v27::METHODS,
V28 => v28::METHODS,
V29 => v29::METHODS,
+ V30 => v30::METHODS,
};
list.iter().map(|m| m.name.to_string()).collect()
@@ -78,6 +80,7 @@ impl Method {
V27 => v27::METHODS,
V28 => v28::METHODS,
V29 => v29::METHODS,
+ V30 => v30::METHODS,
};
list.iter().find(|&method| method.name == name)
diff --git a/verify/src/method/v27.rs b/verify/src/method/v27.rs
index 4f41ad13..6a05663c 100644
--- a/verify/src/method/v27.rs
+++ b/verify/src/method/v27.rs
@@ -62,8 +62,6 @@ pub const METHODS: &[Method] = &[
),
Method::new_bool("prioritisetransaction", "prioritise_transaction"),
Method::new_nothing("submitblock", "submit_block"),
- 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"),
diff --git a/verify/src/method/v28.rs b/verify/src/method/v28.rs
index 380aeee8..eebcb626 100644
--- a/verify/src/method/v28.rs
+++ b/verify/src/method/v28.rs
@@ -62,8 +62,6 @@ pub const METHODS: &[Method] = &[
),
Method::new_bool("prioritisetransaction", "prioritise_transaction"),
Method::new_nothing("submitblock", "submit_block"),
- 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"),
diff --git a/verify/src/method/v29.rs b/verify/src/method/v29.rs
index bf6bb684..926f641e 100644
--- a/verify/src/method/v29.rs
+++ b/verify/src/method/v29.rs
@@ -67,8 +67,6 @@ pub const METHODS: &[Method] = &[
),
Method::new_bool("prioritisetransaction", "prioritise_transaction"),
Method::new_nothing("submitblock", "submit_block"),
- 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"),
diff --git a/verify/src/method/v30.rs b/verify/src/method/v30.rs
new file mode 100644
index 00000000..74b9a0e1
--- /dev/null
+++ b/verify/src/method/v30.rs
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: CC0-1.0
+
+//! JSON RPC methods provided by Bitcoin Core v30.
+
+use super::Method;
+
+/// Data for the JSON RPC methods provided by Bitcoin Core v30.
+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(
+ "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", "ScanTxOutSet", "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_nothing("getnetworkhashps", "get_network_hashes_per_second"),
+ Method::new_modelled(
+ "getprioritisedtransactions",
+ "GetPrioritisedTransactions",
+ "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("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("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("settxfee", "SetTxFee", "set_tx_fee"),
+ 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"),
+];