From b8fa99d00c7e229ac8e8bdf32cd71d6b2f6de10b Mon Sep 17 00:00:00 2001 From: Antoni Spaanderman <56turtle56@gmail.com> Date: Thu, 22 Jun 2023 23:07:40 +0200 Subject: [PATCH 1/2] add getzmqnotifications rpc --- client/src/client.rs | 5 +++++ json/src/lib.rs | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/client/src/client.rs b/client/src/client.rs index faea7490..e80215d8 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1261,6 +1261,11 @@ pub trait RpcApi: Sized { ) -> Result { self.call("scantxoutset", &["start".into(), into_json(descriptors)?]) } + + /// Returns information about the active ZeroMQ notifications + fn get_zmq_notifications(&self) -> Result> { + self.call("getzmqnotifications", &[]) + } } /// Client implements a JSON-RPC client for the Bitcoin Core daemon or compatible APIs. diff --git a/json/src/lib.rs b/json/src/lib.rs index 3574ef1b..bcabe43b 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -2140,6 +2140,14 @@ pub struct GetIndexInfoResult { pub basic_block_filter_index: Option, } +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] +pub struct GetZmqNotificationsResult { + #[serde(rename = "type")] + pub notification_type: String, + pub address: String, + pub hwm: u64, +} + impl<'a> serde::Serialize for PubKeyOrAddress<'a> { fn serialize(&self, serializer: S) -> Result where From a9be191a48c43d675e0a0cca9fbf734e66e0d28d Mon Sep 17 00:00:00 2001 From: Antoni Spaanderman <56turtle56@gmail.com> Date: Wed, 24 Apr 2024 11:23:27 +0200 Subject: [PATCH 2/2] add getzmqnotifications integration test --- integration_test/run.sh | 4 +++- integration_test/src/main.rs | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/integration_test/run.sh b/integration_test/run.sh index be15d005..5d75d1d7 100755 --- a/integration_test/run.sh +++ b/integration_test/run.sh @@ -34,7 +34,9 @@ bitcoind -regtest $BLOCKFILTERARG $FALLBACKFEEARG \ -rpcport=12349 \ -server=1 \ -txindex=1 \ - -printtoconsole=0 & + -printtoconsole=0 \ + -zmqpubrawblock=tcp://0.0.0.0:28332 \ + -zmqpubrawtx=tcp://0.0.0.0:28333 & PID2=$! # Let it connect to the other node. diff --git a/integration_test/src/main.rs b/integration_test/src/main.rs index 7c439619..c1d42cf1 100644 --- a/integration_test/src/main.rs +++ b/integration_test/src/main.rs @@ -32,7 +32,7 @@ use bitcoin::{ Transaction, TxIn, TxOut, Txid, Witness, }; use bitcoincore_rpc::bitcoincore_rpc_json::{ - GetBlockTemplateModes, GetBlockTemplateRules, ScanTxOutRequest, + GetBlockTemplateModes, GetBlockTemplateRules, GetZmqNotificationsResult, ScanTxOutRequest, }; lazy_static! { @@ -226,6 +226,7 @@ fn main() { test_add_ban(&cl); test_set_network_active(&cl); test_get_index_info(&cl); + test_get_zmq_notifications(&cl); test_stop(cl); } @@ -1426,6 +1427,36 @@ fn test_get_index_info(cl: &Client) { } } +fn test_get_zmq_notifications(cl: &Client) { + let mut zmq_info = cl.get_zmq_notifications().unwrap(); + + // it doesn't matter in which order Bitcoin Core returns the result, + // but checking it is easier if it has a known order + + // sort_by_key does not allow returning references to parameters of the compare function + // (removing the lifetime from the return type mimics this behavior, but we don't want it) + fn compare_fn(result: &GetZmqNotificationsResult) -> impl Ord + '_ { + (&result.address, &result.notification_type, result.hwm) + } + zmq_info.sort_by(|a, b| compare_fn(a).cmp(&compare_fn(b))); + + assert!( + zmq_info + == [ + GetZmqNotificationsResult { + notification_type: "pubrawblock".to_owned(), + address: "tcp://0.0.0.0:28332".to_owned(), + hwm: 1000 + }, + GetZmqNotificationsResult { + notification_type: "pubrawtx".to_owned(), + address: "tcp://0.0.0.0:28333".to_owned(), + hwm: 1000 + }, + ] + ); +} + fn test_stop(cl: Client) { println!("Stopping: '{}'", cl.stop().unwrap()); }