From 7f485de4046dbd15380a2cb1a14425ac4cf0acae Mon Sep 17 00:00:00 2001 From: ViniciusCestarii Date: Tue, 2 Jun 2026 09:02:34 -0300 Subject: [PATCH 01/10] ipc: add NodeRpc interface with getNetworkInfo and getDeploymentInfo --- src/init/bitcoin-node.cpp | 2 + src/interfaces/init.h | 2 + src/interfaces/noderpc.h | 105 +++++++++++++++++++++++ src/ipc/CMakeLists.txt | 1 + src/ipc/capnp/init-types.h | 1 + src/ipc/capnp/init.capnp | 3 + src/ipc/capnp/noderpc-types.h | 22 +++++ src/ipc/capnp/noderpc.capnp | 87 +++++++++++++++++++ src/node/interfaces.cpp | 157 ++++++++++++++++++++++++++++++++++ 9 files changed, 380 insertions(+) create mode 100644 src/interfaces/noderpc.h create mode 100644 src/ipc/capnp/noderpc-types.h create mode 100644 src/ipc/capnp/noderpc.capnp diff --git a/src/init/bitcoin-node.cpp b/src/init/bitcoin-node.cpp index 84fbb55ea822..0004367739e7 100644 --- a/src/init/bitcoin-node.cpp +++ b/src/init/bitcoin-node.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,7 @@ class BitcoinNodeInit : public interfaces::Init std::unique_ptr makeNode() override { return interfaces::MakeNode(m_node); } std::unique_ptr makeChain() override { return interfaces::MakeChain(m_node); } std::unique_ptr makeMining() override { return interfaces::MakeMining(m_node); } + std::unique_ptr makeNodeRpc() override { return interfaces::MakeNodeRpc(m_node); } std::unique_ptr makeEcho() override { return interfaces::MakeEcho(); } void stop() override { makeNode()->startShutdown(); } interfaces::Ipc* ipc() override { return m_ipc.get(); } diff --git a/src/interfaces/init.h b/src/interfaces/init.h index a0e534577189..1f43b2b6b253 100644 --- a/src/interfaces/init.h +++ b/src/interfaces/init.h @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -33,6 +34,7 @@ class Init virtual std::unique_ptr makeNode() { return nullptr; } virtual std::unique_ptr makeChain() { return nullptr; } virtual std::unique_ptr makeMining() { return nullptr; } + virtual std::unique_ptr makeNodeRpc() { return nullptr; } virtual std::unique_ptr makeEcho() { return nullptr; } virtual void stop() {} virtual Ipc* ipc() { return nullptr; } diff --git a/src/interfaces/noderpc.h b/src/interfaces/noderpc.h new file mode 100644 index 000000000000..0424b61e3a1a --- /dev/null +++ b/src/interfaces/noderpc.h @@ -0,0 +1,105 @@ +// Copyright (c) 2025-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_INTERFACES_NODERPC_H +#define BITCOIN_INTERFACES_NODERPC_H + +#include + +#include +#include +#include +#include +#include +#include + +namespace node { +struct NodeContext; +} // namespace node + +namespace interfaces { + +struct NetworkInfoNetwork { + std::string name; + bool limited{false}; + bool reachable{false}; + std::string proxy; + bool proxy_randomize_credentials{false}; +}; + +struct NetworkInfoLocalAddress { + std::string address; + uint16_t port{0}; + int score{0}; +}; + +struct NetworkInfo { + int version{0}; + std::string subversion; + int protocolversion{0}; + std::string localservices; + std::vector localservicesnames; + bool localrelay{false}; + int64_t timeoffset{0}; + size_t connections{0}; + size_t connections_in{0}; + size_t connections_out{0}; + bool networkactive{false}; + std::vector networks; + int64_t relayfee{0}; + int64_t incrementalfee{0}; + std::vector localaddresses; + std::vector warnings; +}; + +struct BIP9Statistics { + int period{0}; + int threshold{0}; + int elapsed{0}; + int count{0}; + bool possible{false}; +}; + +struct BIP9DeploymentInfo { + int bit{-1}; + int64_t start_time{0}; + int64_t timeout{0}; + int min_activation_height{0}; + std::string status; + int since{0}; + std::string status_next; + std::optional statistics; + std::string signalling; +}; + +struct DeploymentInfo { + std::string name; + std::string type; + bool active{false}; + int height{-1}; + std::optional bip9; +}; + +struct DeploymentsInfo { + std::string hash; + int height{-1}; + std::vector script_flags; + std::vector deployments; +}; + +class NodeRpc +{ +public: + virtual ~NodeRpc() = default; + + virtual NetworkInfo getNetworkInfo() = 0; + + virtual DeploymentsInfo getDeploymentInfo(const std::optional& block_hash) = 0; +}; + +std::unique_ptr MakeNodeRpc(node::NodeContext& context); + +} // namespace interfaces + +#endif // BITCOIN_INTERFACES_NODERPC_H diff --git a/src/ipc/CMakeLists.txt b/src/ipc/CMakeLists.txt index 5378ef1924bf..970d423ba95f 100644 --- a/src/ipc/CMakeLists.txt +++ b/src/ipc/CMakeLists.txt @@ -14,6 +14,7 @@ target_capnp_sources(bitcoin_ipc ${CMAKE_CURRENT_SOURCE_DIR} capnp/echo.capnp capnp/init.capnp capnp/mining.capnp + capnp/noderpc.capnp ) target_link_libraries(bitcoin_ipc diff --git a/src/ipc/capnp/init-types.h b/src/ipc/capnp/init-types.h index 2abd7b211e17..ab804c32d9aa 100644 --- a/src/ipc/capnp/init-types.h +++ b/src/ipc/capnp/init-types.h @@ -7,5 +7,6 @@ #include #include +#include #endif // BITCOIN_IPC_CAPNP_INIT_TYPES_H diff --git a/src/ipc/capnp/init.capnp b/src/ipc/capnp/init.capnp index 094305b44341..6e419b931e30 100644 --- a/src/ipc/capnp/init.capnp +++ b/src/ipc/capnp/init.capnp @@ -11,14 +11,17 @@ using Proxy = import "/mp/proxy.capnp"; $Proxy.include("interfaces/echo.h"); $Proxy.include("interfaces/init.h"); $Proxy.include("interfaces/mining.h"); +$Proxy.include("interfaces/noderpc.h"); $Proxy.includeTypes("ipc/capnp/init-types.h"); using Echo = import "echo.capnp"; using Mining = import "mining.capnp"; +using NodeRpc = import "noderpc.capnp"; interface Init $Proxy.wrap("interfaces::Init") { construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap); makeEcho @1 (context :Proxy.Context) -> (result :Echo.Echo); makeMining @2 (context :Proxy.Context) -> (result :Mining.Mining); stop @3 (context :Proxy.Context) -> (); + makeNodeRpc @4 (context :Proxy.Context) -> (result :NodeRpc.NodeRpc); } diff --git a/src/ipc/capnp/noderpc-types.h b/src/ipc/capnp/noderpc-types.h new file mode 100644 index 000000000000..650bb7d41eb2 --- /dev/null +++ b/src/ipc/capnp/noderpc-types.h @@ -0,0 +1,22 @@ +// Copyright (c) 2025-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_IPC_CAPNP_NODERPC_TYPES_H +#define BITCOIN_IPC_CAPNP_NODERPC_TYPES_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#endif // BITCOIN_IPC_CAPNP_NODERPC_TYPES_H diff --git a/src/ipc/capnp/noderpc.capnp b/src/ipc/capnp/noderpc.capnp new file mode 100644 index 000000000000..e81510aa73bf --- /dev/null +++ b/src/ipc/capnp/noderpc.capnp @@ -0,0 +1,87 @@ +# Copyright (c) 2025-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +@0xb1a2c3d4e5f60718; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("ipc::capnp::messages"); + +using Proxy = import "/mp/proxy.capnp"; +$Proxy.include("interfaces/noderpc.h"); +$Proxy.includeTypes("ipc/capnp/noderpc-types.h"); + +interface NodeRpc $Proxy.wrap("interfaces::NodeRpc") { + destroy @0 (context :Proxy.Context) -> (); + getNetworkInfo @1 (context :Proxy.Context) -> (result :NetworkInfo); + getDeploymentInfo @2 (context :Proxy.Context, blockHash :Data) -> (result :DeploymentsInfo); +} + +struct NetworkInfoNetwork $Proxy.wrap("interfaces::NetworkInfoNetwork") { + name @0 :Text; + limited @1 :Bool; + reachable @2 :Bool; + proxy @3 :Text; + proxyRandomizeCredentials @4 :Bool $Proxy.name("proxy_randomize_credentials"); +} + +struct NetworkInfoLocalAddress $Proxy.wrap("interfaces::NetworkInfoLocalAddress") { + address @0 :Text; + port @1 :UInt16; + score @2 :Int32; +} + +struct NetworkInfo $Proxy.wrap("interfaces::NetworkInfo") { + version @0 :Int32; + subversion @1 :Text; + protocolversion @2 :Int32; + localservices @3 :Text; + localservicesnames @4 :List(Text); + localrelay @5 :Bool; + timeoffset @6 :Int64; + connections @7 :UInt64; + connectionsIn @8 :UInt64 $Proxy.name("connections_in"); + connectionsOut @9 :UInt64 $Proxy.name("connections_out"); + networkactive @10 :Bool; + networks @11 :List(NetworkInfoNetwork); + relayfee @12 :Int64; + incrementalfee @13 :Int64; + localaddresses @14 :List(NetworkInfoLocalAddress); + warnings @15 :List(Text); +} + +struct BIP9Statistics $Proxy.wrap("interfaces::BIP9Statistics") { + period @0 :Int32; + threshold @1 :Int32; + elapsed @2 :Int32; + count @3 :Int32; + possible @4 :Bool; +} + +struct BIP9DeploymentInfo $Proxy.wrap("interfaces::BIP9DeploymentInfo") { + bit @0 :Int32; + startTime @1 :Int64 $Proxy.name("start_time"); + timeout @2 :Int64; + minActivationHeight @3 :Int32 $Proxy.name("min_activation_height"); + status @4 :Text; + since @5 :Int32; + statusNext @6 :Text $Proxy.name("status_next"); + statistics @7 :BIP9Statistics; + signalling @8 :Text; +} + +struct DeploymentInfo $Proxy.wrap("interfaces::DeploymentInfo") { + name @0 :Text; + type @1 :Text; + active @2 :Bool; + height @3 :Int32; + bip9 @4 :BIP9DeploymentInfo; +} + +struct DeploymentsInfo $Proxy.wrap("interfaces::DeploymentsInfo") { + hash @0 :Text; + height @1 :Int32; + scriptFlags @2 :List(Text) $Proxy.name("script_flags"); + deployments @3 :List(DeploymentInfo); +} + diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 50b70fafcb0f..ba81decb8f63 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -8,17 +8,22 @@ #include #include #include +#include #include #include #include #include #include +#include #include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -38,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -46,8 +52,11 @@ #include #include #include +#include +#include