diff --git a/Makefile.am b/Makefile.am
index 656ab084..c9cc1efa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -56,6 +56,7 @@ src_libbitcoin_node_la_SOURCES = \
src/parse/query.cpp \
src/parse/target.cpp \
src/protocols/protocol.cpp \
+ src/protocols/protocol_bitcoind.cpp \
src/protocols/protocol_block_in_106.cpp \
src/protocols/protocol_block_in_31800.cpp \
src/protocols/protocol_block_out_106.cpp \
@@ -206,7 +207,8 @@ include_bitcoin_node_interfaces_HEADERS = \
include/bitcoin/node/interfaces/explore.hpp \
include/bitcoin/node/interfaces/interfaces.hpp \
include/bitcoin/node/interfaces/stratum_v1.hpp \
- include/bitcoin/node/interfaces/stratum_v2.hpp
+ include/bitcoin/node/interfaces/stratum_v2.hpp \
+ include/bitcoin/node/interfaces/types.hpp
include_bitcoin_node_parsedir = ${includedir}/bitcoin/node/parse
include_bitcoin_node_parse_HEADERS = \
diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt
index 56c2ea0d..d9b89989 100644
--- a/builds/cmake/CMakeLists.txt
+++ b/builds/cmake/CMakeLists.txt
@@ -268,6 +268,7 @@ add_library( ${CANONICAL_LIB_NAME}
"../../src/parse/query.cpp"
"../../src/parse/target.cpp"
"../../src/protocols/protocol.cpp"
+ "../../src/protocols/protocol_bitcoind.cpp"
"../../src/protocols/protocol_block_in_106.cpp"
"../../src/protocols/protocol_block_in_31800.cpp"
"../../src/protocols/protocol_block_out_106.cpp"
diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
index f6bcf24b..dc0fc4e5 100644
--- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj
@@ -141,6 +141,7 @@
+
@@ -197,6 +198,7 @@
+
diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
index 20807abe..aa009766 100644
--- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters
@@ -123,6 +123,9 @@
src\protocols
+
+ src\protocols
+
src\protocols
@@ -287,6 +290,9 @@
include\bitcoin\node\interfaces
+
+ include\bitcoin\node\interfaces
+
include\bitcoin\node\parse
diff --git a/include/bitcoin/node.hpp b/include/bitcoin/node.hpp
index 0ce94314..1d0ed22b 100644
--- a/include/bitcoin/node.hpp
+++ b/include/bitcoin/node.hpp
@@ -51,6 +51,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/include/bitcoin/node/error.hpp b/include/bitcoin/node/error.hpp
index 13d584b2..d85a6618 100644
--- a/include/bitcoin/node/error.hpp
+++ b/include/bitcoin/node/error.hpp
@@ -117,6 +117,8 @@ enum error_t : uint8_t
invalid_component,
invalid_subcomponent,
extra_segment,
+
+ /// server (json-rpc parse codes)
unexpected_parse
};
diff --git a/include/bitcoin/node/interfaces/bitcoind.hpp b/include/bitcoin/node/interfaces/bitcoind.hpp
index 91001136..17f70038 100644
--- a/include/bitcoin/node/interfaces/bitcoind.hpp
+++ b/include/bitcoin/node/interfaces/bitcoind.hpp
@@ -20,6 +20,7 @@
#define LIBBITCOIN_NODE_INTERFACES_BITCOIND_HPP
#include
+#include
namespace libbitcoin {
namespace node {
@@ -31,118 +32,118 @@ struct bitcoind_methods
{
/// Blockchain methods.
method<"getbestblockhash">{},
- method<"getblock", string_t, optional<0_u32>>{ "blockhash", "verbosity" },
+ method<"getblock", string_t, optional<0>>{ "blockhash", "verbosity" },
method<"getblockchaininfo">{},
method<"getblockcount">{},
method<"getblockfilter", string_t, optional<"basic"_t>>{ "blockhash", "filtertype" },
- method<"getblockhash", number_t>{ "height" },
+ ////method<"getblockhash", double>{ "height" },
method<"getblockheader", string_t, optional>{ "blockhash", "verbose" },
method<"getblockstats", string_t, optional>{ "hash_or_height", "stats" },
- method<"getchaintxstats", optional<-1_i32>, optional<""_t>>{ "nblocks", "blockhash" },
+ method<"getchaintxstats", optional<-1>, optional<""_t>>{ "nblocks", "blockhash" },
method<"getchainwork">{},
method<"gettxout", string_t, number_t, optional>{ "txid", "n", "include_mempool" },
method<"gettxoutsetinfo">{},
- method<"pruneblockchain", number_t>{ "height" },
+ ////method<"pruneblockchain", number_t>{ "height" },
method<"savemempool">{},
method<"scantxoutset", string_t, optional>{ "action", "scanobjects" },
- method<"verifychain", optional<4_u32>, optional<288_u32>>{ "checklevel", "nblocks" },
- method<"verifytxoutset", string_t>{ "input_verify_flag" },
+ method<"verifychain", optional<4>, optional<288>>{ "checklevel", "nblocks" },
+ ////method<"verifytxoutset", string_t>{ "input_verify_flag" },
- /// Control methods.
- method<"getmemoryinfo", optional<"stats"_t>>{ "mode" },
- method<"getrpcinfo">{},
- method<"help", optional<""_t>>{ "command" },
- method<"logging", optional<"*"_t>>{ "include" },
- method<"stop">{},
- method<"uptime">{},
+ /////// Control methods.
+ ////method<"getmemoryinfo", optional<"stats"_t>>{ "mode" },
+ ////method<"getrpcinfo">{},
+ ////method<"help", optional<""_t>>{ "command" },
+ ////method<"logging", optional<"*"_t>>{ "include" },
+ ////method<"stop">{},
+ ////method<"uptime">{},
- /// Mining methods.
- method<"getblocktemplate", optional>{ "template_request" },
- method<"getmininginfo">{},
- method<"getnetworkhashps", optional<120_u32>, optional<-1_i32>>{ "nblocks", "height" },
- method<"prioritisetransaction", string_t, number_t, number_t>{ "txid", "dummy", "priority_delta" },
- method<"submitblock", string_t, optional<""_t>>{ "block", "parameters" },
+ /////// Mining methods.
+ ////method<"getblocktemplate", optional>{ "template_request" },
+ ////method<"getmininginfo">{},
+ ////method<"getnetworkhashps", optional<120_u32>, optional<-1_i32>>{ "nblocks", "height" },
+ ////method<"prioritisetransaction", string_t, number_t, number_t>{ "txid", "dummy", "priority_delta" },
+ ////method<"submitblock", string_t, optional<""_t>>{ "block", "parameters" },
- /// Network methods.
- method<"addnode", string_t, string_t>{ "node", "command" },
- method<"clearbanned">{},
- method<"disconnectnode", string_t, optional<-1_i32>>{ "address", "nodeid" },
- method<"getaddednodeinfo", optional, optional, optional<""_t>>{ "include_chain_info", "dns", "addnode" },
- method<"getconnectioncount">{},
- method<"getnetworkinfo">{},
- method<"getpeerinfo">{},
- method<"listbanned">{},
- method<"ping">{},
- method<"setban", string_t, string_t, optional<86400_u32>, optional, optional<""_t>>{ "addr", "command", "bantime", "absolute", "reason" },
- method<"setnetworkactive", boolean_t>{ "state" },
+ /////// Network methods.
+ ////method<"addnode", string_t, string_t>{ "node", "command" },
+ ////method<"clearbanned">{},
+ ////method<"disconnectnode", string_t, optional<-1_i32>>{ "address", "nodeid" },
+ ////method<"getaddednodeinfo", optional, optional, optional<""_t>>{ "include_chain_info", "dns", "addnode" },
+ ////method<"getconnectioncount">{},
+ ////method<"getnetworkinfo">{},
+ ////method<"getpeerinfo">{},
+ ////method<"listbanned">{},
+ ////method<"ping">{},
+ ////method<"setban", string_t, string_t, optional<86400_u32>, optional, optional<""_t>>{ "addr", "command", "bantime", "absolute", "reason" },
+ ////method<"setnetworkactive", boolean_t>{ "state" },
- /// Rawtransactions methods.
- method<"combinerawtransaction", array_t>{ "txs" },
- method<"createrawtransaction", array_t, object_t, optional<0_u32>, optional>{ "inputs", "outputs", "locktime", "replaceable" },
- method<"decoderawtransaction", string_t>{ "hexstring" },
- method<"fundrawtransaction", string_t, optional>{ "rawtx", "options" },
- method<"getrawtransaction", string_t, optional<0_u32>, optional<""_t>>{ "txid", "verbose", "blockhash" },
- method<"sendrawtransaction", string_t, optional<0_u32>>{ "hexstring", "maxfeerate" },
- method<"signrawtransactionwithkey", string_t, optional, optional, optional<"ALL|FORKID"_t>>{ "hexstring", "privkeys", "prevtxs", "sighashtype" },
- method<"testmempoolaccept", array_t, optional<0_u32>>{ "rawtxs", "maxfeerate" },
- method<"testrawtransaction", string_t>{ "rawtx" },
+ /////// Rawtransactions methods.
+ ////method<"combinerawtransaction", array_t>{ "txs" },
+ ////method<"createrawtransaction", array_t, object_t, optional<0_u32>, optional>{ "inputs", "outputs", "locktime", "replaceable" },
+ ////method<"decoderawtransaction", string_t>{ "hexstring" },
+ ////method<"fundrawtransaction", string_t, optional>{ "rawtx", "options" },
+ ////method<"getrawtransaction", string_t, optional<0_u32>, optional<""_t>>{ "txid", "verbose", "blockhash" },
+ ////method<"sendrawtransaction", string_t, optional<0_u32>>{ "hexstring", "maxfeerate" },
+ ////method<"signrawtransactionwithkey", string_t, optional, optional, optional<"ALL|FORKID"_t>>{ "hexstring", "privkeys", "prevtxs", "sighashtype" },
+ ////method<"testmempoolaccept", array_t, optional<0_u32>>{ "rawtxs", "maxfeerate" },
+ ////method<"testrawtransaction", string_t>{ "rawtx" },
- /// Util methods (node-related).
- method<"createmultisig", number_t, array_t>{ "nrequired", "keys" },
- method<"decodepsbt", string_t>{ "psbt" },
- method<"decodescript", string_t>{ "hex" },
- method<"estimaterawfee", number_t, optional<"unset"_t>>{ "conf_target", "estimate_mode" },
- method<"getdescriptorinfo", string_t>{ "descriptor" },
- method<"validateaddress", string_t>{ "address" },
+ /////// Util methods (node-related).
+ ////method<"createmultisig", number_t, array_t>{ "nrequired", "keys" },
+ ////method<"decodepsbt", string_t>{ "psbt" },
+ ////method<"decodescript", string_t>{ "hex" },
+ ////method<"estimaterawfee", number_t, optional<"unset"_t>>{ "conf_target", "estimate_mode" },
+ ////method<"getdescriptorinfo", string_t>{ "descriptor" },
+ ////method<"validateaddress", string_t>{ "address" },
- /// Wallet methods (unsupported).
- method<"abandontransaction", string_t>{ "txid" },
- method<"addmultisigaddress", number_t, array_t, optional<""_t>, optional<"legacy"_t>>{ "nrequired", "keys", "label", "address_type" },
- method<"backupwallet", string_t>{ "destination" },
- method<"bumpfee", string_t, optional>{ "txid", "options" },
- method<"createwallet", string_t, optional, optional, optional, optional<""_t>, optional, optional, optional, optional<"set"_t>>{ "wallet_name", "disable_private_keys", "blank", "passphrase", "avoid_reuse", "descriptors", "load_on_startup", "external_signer", "change_type" },
- method<"dumpprivkey", string_t>{ "address" },
- method<"dumpwallet", string_t>{ "filename" },
- method<"encryptwallet", string_t>{ "passphrase" },
- method<"getaddressinfo", string_t>{ "address" },
- method<"getbalances">{},
- method<"getnewaddress", optional<""_t>, optional<"legacy"_t>>{ "label", "address_type" },
- method<"getreceivedbyaddress", string_t, optional<0>>{ "address", "minconf" },
- method<"getreceivedbylabel", string_t, optional<0>>{ "label", "minconf" },
- method<"gettransaction", string_t, optional, optional>{ "txid", "include_watchonly", "verbose" },
- method<"getunconfirmedbalance">{},
- method<"getwalletinfo">{},
- method<"importaddress", string_t, optional<""_t>, optional, optional>{ "address", "label", "rescan", "p2sh" },
- method<"importmulti", array_t, optional>{ "requests", "options" },
- method<"importprivkey", string_t, optional<""_t>, optional>{ "privkey", "label", "rescan" },
- method<"importprunedfunds", string_t, string_t>{ "rawtransaction", "txoutproof" },
- method<"importpubkey", string_t, optional<""_t>, optional>{ "pubkey", "label", "rescan" },
- method<"importwallet", string_t>{ "filename" },
- method<"keypoolrefill", optional<100>>{ "newsize" },
- method<"listaddressgroupings", optional<1>, optional>{ "minconf", "include_watchonly" },
- method<"listlabels", optional<"receive"_t>>{ "purpose" },
- method<"listlockunspent">{},
- method<"listreceivedbyaddress", optional<1>, optional, optional, optional<""_t>>{ "minconf", "include_empty", "include_watchonly", "address_filter" },
- method<"listreceivedbylabel", optional<1>, optional, optional>{ "minconf", "include_empty", "include_watchonly" },
- method<"listtransactions", optional<""_t>, optional<10>, optional<0>, optional>{ "label", "count", "skip", "include_watchonly" },
- method<"listunspent", optional<1>, optional, optional, optional>{ "minconf", "addresses", "include_unsafe", "query_options" },
- method<"loadwallet", string_t, optional>{ "filename", "load_on_startup" },
- method<"lockunspent", boolean_t, optional>{ "unlock", "transactions" },
- method<"removeprunedfunds", string_t>{ "txid" },
- method<"rescanblockchain", optional<0>>{ "start_height" },
- method<"send", object_t, optional>{ "outputs", "options" },
- method<"sendmany", string_t, object_t, optional<1>, optional<""_t>, optional<""_t>, optional, optional, optional<25>, optional<"unset"_t>, optional, optional<0>>{ "dummy", "outputs", "minconf", "comment", "comment_to", "subtractfeefrom", "replaceable", "conf_target", "estimate_mode", "avoid_reuse", "fee_rate" },
- method<"sendtoaddress", string_t, number_t, optional<""_t>, optional<""_t>, optional, optional<25>, optional<"unset"_t>, optional, optional<0>, optional>{ "address", "amount", "comment", "comment_to", "subtractfeefromamount", "conf_target", "estimate_mode", "avoid_reuse", "fee_rate", "verbose" },
- method<"setlabel", string_t, string_t>{ "address", "label" },
- method<"settxfee", number_t>{ "amount" },
- method<"signmessage", string_t, string_t>{ "address", "message" },
- method<"signmessagewithprivkey", string_t, string_t>{ "privkey", "message" },
- method<"syncwithvalidationinterfacequeue">{},
- method<"unloadwallet", optional<""_t>, optional>{ "wallet_name", "load_on_startup" },
- method<"walletcreatefundedpsbt", optional, optional, optional<0>, optional>{ "inputs", "outputs", "locktime", "options" },
- method<"walletlock">{},
- method<"walletpassphrase", string_t, number_t>{ "passphrase", "timeout" },
- method<"walletprocesspsbt", string_t, optional, optional, optional>{ "psbt", "sign", "bip32derivs", "complete" }
+ /////// Wallet methods (unsupported).
+ ////method<"abandontransaction", string_t>{ "txid" },
+ ////method<"addmultisigaddress", number_t, array_t, optional<""_t>, optional<"legacy"_t>>{ "nrequired", "keys", "label", "address_type" },
+ ////method<"backupwallet", string_t>{ "destination" },
+ ////method<"bumpfee", string_t, optional>{ "txid", "options" },
+ ////method<"createwallet", string_t, optional, optional, optional, optional<""_t>, optional, optional, optional, optional<"set"_t>>{ "wallet_name", "disable_private_keys", "blank", "passphrase", "avoid_reuse", "descriptors", "load_on_startup", "external_signer", "change_type" },
+ ////method<"dumpprivkey", string_t>{ "address" },
+ ////method<"dumpwallet", string_t>{ "filename" },
+ ////method<"encryptwallet", string_t>{ "passphrase" },
+ ////method<"getaddressinfo", string_t>{ "address" },
+ ////method<"getbalances">{},
+ ////method<"getnewaddress", optional<""_t>, optional<"legacy"_t>>{ "label", "address_type" },
+ ////method<"getreceivedbyaddress", string_t, optional<0>>{ "address", "minconf" },
+ ////method<"getreceivedbylabel", string_t, optional<0>>{ "label", "minconf" },
+ ////method<"gettransaction", string_t, optional, optional>{ "txid", "include_watchonly", "verbose" },
+ ////method<"getunconfirmedbalance">{},
+ ////method<"getwalletinfo">{},
+ ////method<"importaddress", string_t, optional<""_t>, optional, optional>{ "address", "label", "rescan", "p2sh" },
+ ////method<"importmulti", array_t, optional>{ "requests", "options" },
+ ////method<"importprivkey", string_t, optional<""_t>, optional>{ "privkey", "label", "rescan" },
+ ////method<"importprunedfunds", string_t, string_t>{ "rawtransaction", "txoutproof" },
+ ////method<"importpubkey", string_t, optional<""_t>, optional>{ "pubkey", "label", "rescan" },
+ ////method<"importwallet", string_t>{ "filename" },
+ ////method<"keypoolrefill", optional<100>>{ "newsize" },
+ ////method<"listaddressgroupings", optional<1>, optional>{ "minconf", "include_watchonly" },
+ ////method<"listlabels", optional<"receive"_t>>{ "purpose" },
+ ////method<"listlockunspent">{},
+ ////method<"listreceivedbyaddress", optional<1>, optional, optional, optional<""_t>>{ "minconf", "include_empty", "include_watchonly", "address_filter" },
+ ////method<"listreceivedbylabel", optional<1>, optional, optional>{ "minconf", "include_empty", "include_watchonly" },
+ ////method<"listtransactions", optional<""_t>, optional<10>, optional<0>, optional>{ "label", "count", "skip", "include_watchonly" },
+ ////method<"listunspent", optional<1>, optional, optional, optional>{ "minconf", "addresses", "include_unsafe", "query_options" },
+ ////method<"loadwallet", string_t, optional>{ "filename", "load_on_startup" },
+ ////method<"lockunspent", boolean_t, optional>{ "unlock", "transactions" },
+ ////method<"removeprunedfunds", string_t>{ "txid" },
+ ////method<"rescanblockchain", optional<0>>{ "start_height" },
+ ////method<"send", object_t, optional>{ "outputs", "options" },
+ ////method<"sendmany", string_t, object_t, optional<1>, optional<""_t>, optional<""_t>, optional, optional, optional<25>, optional<"unset"_t>, optional, optional<0>>{ "dummy", "outputs", "minconf", "comment", "comment_to", "subtractfeefrom", "replaceable", "conf_target", "estimate_mode", "avoid_reuse", "fee_rate" },
+ ////method<"sendtoaddress", string_t, number_t, optional<""_t>, optional<""_t>, optional, optional<25>, optional<"unset"_t>, optional, optional<0>, optional>{ "address", "amount", "comment", "comment_to", "subtractfeefromamount", "conf_target", "estimate_mode", "avoid_reuse", "fee_rate", "verbose" },
+ ////method<"setlabel", string_t, string_t>{ "address", "label" },
+ ////method<"settxfee", number_t>{ "amount" },
+ ////method<"signmessage", string_t, string_t>{ "address", "message" },
+ ////method<"signmessagewithprivkey", string_t, string_t>{ "privkey", "message" },
+ ////method<"syncwithvalidationinterfacequeue">{},
+ ////method<"unloadwallet", optional<""_t>, optional>{ "wallet_name", "load_on_startup" },
+ ////method<"walletcreatefundedpsbt", optional, optional, optional<0>, optional>{ "inputs", "outputs", "locktime", "options" },
+ ////method<"walletlock">{},
+ ////method<"walletpassphrase", string_t, number_t>{ "passphrase", "timeout" },
+ ////method<"walletprocesspsbt", string_t, optional, optional, optional>{ "psbt", "sign", "bip32derivs", "complete" }
};
template
@@ -152,107 +153,108 @@ struct bitcoind_methods
using at = method_at;
// Derive this from above in c++26 using reflection.
- using getbestblockhash = at<0>;
- using getblock = at<1>;
- using getblockchaininfo = at<2>;
- using getblockcount = at<3>;
- using getblockfilter = at<4>;
- using getblockhash = at<5>;
- using getblockheader = at<6>;
- using getblockstats = at<7>;
- using getchaintxstats = at<8>;
- using getchainwork = at<9>;
- using gettxout = at<10>;
- using gettxoutsetinfo = at<11>;
- using pruneblockchain = at<12>;
- using savemempool = at<13>;
- using scantxoutset = at<14>;
- using verifychain = at<15>;
- using verifytxoutset = at<16>;
- using getmemoryinfo = at<17>;
- using getrpcinfo = at<18>;
- using help = at<19>;
- using logging = at<20>;
- using stop = at<21>;
- using uptime = at<22>;
- using getblocktemplate = at<23>;
- using getmininginfo = at<24>;
- using getnetworkhashps = at<25>;
- using prioritisetransaction = at<26>;
- using submitblock = at<27>;
- using addnode = at<28>;
- using clearbanned = at<29>;
- using disconnectnode = at<30>;
- using getaddednodeinfo = at<31>;
- using getconnectioncount = at<32>;
- using getnetworkinfo = at<33>;
- using getpeerinfo = at<34>;
- using listbanned = at<35>;
- using ping = at<36>;
- using setban = at<37>;
- using setnetworkactive = at<38>;
- using combinerawtransaction = at<39>;
- using createrawtransaction = at<40>;
- using decoderawtransaction = at<41>;
- using fundrawtransaction = at<42>;
- using getrawtransaction = at<43>;
- using sendrawtransaction = at<44>;
- using signrawtransactionwithkey = at<45>;
- using testmempoolaccept = at<46>;
- using testrawtransaction = at<47>;
- using createmultisig = at<48>;
- using decodepsbt = at<49>;
- using decodescript = at<50>;
- using estimaterawfee = at<51>;
- using getdescriptorinfo = at<52>;
- using validateaddress = at<53>;
- using abandontransaction = at<54>;
- using addmultisigaddress = at<55>;
- using backupwallet = at<56>;
- using bumpfee = at<57>;
- using createwallet = at<58>;
- using dumpprivkey = at<59>;
- using dumpwallet = at<60>;
- using encryptwallet = at<61>;
- using getaddressinfo = at<62>;
- using getbalances = at<63>;
- using getnewaddress = at<64>;
- using getreceivedbyaddress = at<65>;
- using getreceivedbylabel = at<66>;
- using gettransaction = at<67>;
- using getunconfirmedbalance = at<68>;
- using getwalletinfo = at<69>;
- using importaddress = at<70>;
- using importmulti = at<71>;
- using importprivkey = at<72>;
- using importprunedfunds = at<73>;
- using importpubkey = at<74>;
- using importwallet = at<75>;
- using keypoolrefill = at<76>;
- using listaddressgroupings = at<77>;
- using listlabels = at<78>;
- using listlockunspent = at<79>;
- using listreceivedbyaddress = at<80>;
- using listreceivedbylabel = at<81>;
- using listtransactions = at<82>;
- using listunspent = at<83>;
- using loadwallet = at<84>;
- using lockunspent = at<85>;
- using removeprunedfunds = at<86>;
- using rescanblockchain = at<87>;
- using send = at<88>;
- using sendmany = at<89>;
- using sendtoaddress = at<90>;
- using setlabel = at<91>;
- using settxfee = at<92>;
- using signmessage = at<93>;
- using signmessagewithprivkey = at<94>;
- using syncwithvalidationinterfacequeue = at<95>;
- using unloadwallet = at<96>;
- using walletcreatefundedpsbt = at<97>;
- using walletlock = at<98>;
- using walletpassphrase = at<99>;
- using walletprocesspsbt = at<100>;
+ using get_best_block_hash = at<0>;
+ using get_block = at<1>;
+ using get_block_chain_info = at<2>;
+ using get_block_count = at<3>;
+ using get_block_filter = at<4>;
+ ////using get_block_hash = at<5>;
+ using get_block_header = at<5>;
+ using get_block_stats = at<6>;
+ using get_chain_tx_stats = at<7>;
+ using get_chain_work = at<8>;
+ using get_tx_out = at<9>;
+ using get_tx_out_set_info = at<10>;
+ ////using prune_block_chain = at<12>;
+ using save_mem_pool = at<11>;
+ using scan_tx_out_set = at<12>;
+ using verify_chain = at<13>;
+ ////using verify_tx_out_set = at<16>;
+
+ ////using get_memory_info = at<17>;
+ ////using get_rpc_info = at<18>;
+ ////using help = at<19>;
+ ////using logging = at<20>;
+ ////using stop = at<21>;
+ ////using uptime = at<22>;
+ ////using get_block_template = at<23>;
+ ////using get_mining_info = at<24>;
+ ////using get_network_hash_ps = at<25>;
+ ////using prioritise_transaction = at<26>;
+ ////using submit_block = at<27>;
+ ////using add_node = at<28>;
+ ////using clear_banned = at<29>;
+ ////using disconnect_node = at<30>;
+ ////using get_added_node_info = at<31>;
+ ////using get_connection_count = at<32>;
+ ////using get_network_info = at<33>;
+ ////using get_peer_info = at<34>;
+ ////using list_banned = at<35>;
+ ////using ping = at<36>;
+ ////using set_ban = at<37>;
+ ////using set_network_active = at<38>;
+ ////using combine_raw_transaction = at<39>;
+ ////using create_raw_transaction = at<40>;
+ ////using decode_raw_transaction = at<41>;
+ ////using fund_raw_transaction = at<42>;
+ ////using get_raw_transaction = at<43>;
+ ////using send_raw_transaction = at<44>;
+ ////using sign_raw_transaction_with_key = at<45>;
+ ////using test_mem_pool_accept = at<46>;
+ ////using test_raw_transaction = at<47>;
+ ////using create_multisig = at<48>;
+ ////using decode_psbt = at<49>;
+ ////using decode_script = at<50>;
+ ////using estimate_raw_fee = at<51>;
+ ////using get_descriptor_info = at<52>;
+ ////using validate_address = at<53>;
+ ////using abandon_transaction = at<54>;
+ ////using add_multisig_address = at<55>;
+ ////using backup_wallet = at<56>;
+ ////using bump_fee = at<57>;
+ ////using create_wallet = at<58>;
+ ////using dump_priv_key = at<59>;
+ ////using dump_wallet = at<60>;
+ ////using encrypt_wallet = at<61>;
+ ////using get_address_info = at<62>;
+ ////using get_balances = at<63>;
+ ////using get_new_address = at<64>;
+ ////using get_received_by_address = at<65>;
+ ////using get_received_by_label = at<66>;
+ ////using get_transaction = at<67>;
+ ////using get_unconfirmed_balance = at<68>;
+ ////using get_wallet_info = at<69>;
+ ////using import_address = at<70>;
+ ////using import_multi = at<71>;
+ ////using import_priv_key = at<72>;
+ ////using import_pruned_funds = at<73>;
+ ////using import_pub_key = at<74>;
+ ////using import_wallet = at<75>;
+ ////using key_pool_refill = at<76>;
+ ////using list_address_groupings = at<77>;
+ ////using list_labels = at<78>;
+ ////using list_lock_unspent = at<79>;
+ ////using list_received_by_address = at<80>;
+ ////using list_received_by_label = at<81>;
+ ////using list_transactions = at<82>;
+ ////using list_unspent = at<83>;
+ ////using load_wallet = at<84>;
+ ////using lock_unspent = at<85>;
+ ////using remove_pruned_funds = at<86>;
+ ////using rescan_block_chain = at<87>;
+ ////using send = at<88>;
+ ////using send_many = at<89>;
+ ////using send_to_address = at<90>;
+ ////using set_label = at<91>;
+ ////using set_tx_fee = at<92>;
+ ////using sign_message = at<93>;
+ ////using sign_message_with_priv_key = at<94>;
+ ////using sync_with_validation_interface_queue = at<95>;
+ ////using unload_wallet = at<96>;
+ ////using wallet_create_funded_psbt = at<97>;
+ ////using wallet_lock = at<98>;
+ ////using wallet_passphrase = at<99>;
+ ////using wallet_process_psbt = at<100>;
};
} // namespace interface
diff --git a/include/bitcoin/node/interfaces/electrum.hpp b/include/bitcoin/node/interfaces/electrum.hpp
index 1ea7159d..4b8b3254 100644
--- a/include/bitcoin/node/interfaces/electrum.hpp
+++ b/include/bitcoin/node/interfaces/electrum.hpp
@@ -20,6 +20,7 @@
#define LIBBITCOIN_NODE_INTERFACES_ELECTRUM_HPP
#include
+#include
namespace libbitcoin {
namespace node {
diff --git a/include/bitcoin/node/interfaces/explore.hpp b/include/bitcoin/node/interfaces/explore.hpp
index 93b95e91..4b7a8df2 100644
--- a/include/bitcoin/node/interfaces/explore.hpp
+++ b/include/bitcoin/node/interfaces/explore.hpp
@@ -20,6 +20,7 @@
#define LIBBITCOIN_NODE_INTERFACES_EXPLORE_HPP
#include
+#include
namespace libbitcoin {
namespace node {
diff --git a/include/bitcoin/node/interfaces/interfaces.hpp b/include/bitcoin/node/interfaces/interfaces.hpp
index 5ac6d2a1..95a376bf 100644
--- a/include/bitcoin/node/interfaces/interfaces.hpp
+++ b/include/bitcoin/node/interfaces/interfaces.hpp
@@ -19,42 +19,12 @@
#ifndef LIBBITCOIN_NODE_INTERFACES_HPP
#define LIBBITCOIN_NODE_INTERFACES_HPP
-namespace libbitcoin {
-namespace node {
-namespace interface {
-
-/// Alias network::rpc names within interface::.
-
-template
-using method = network::rpc::method;
-template
-using method_at = network::rpc::method_at;
-template
-using publish = network::rpc::publish;
-
-template
-using optional = network::rpc::optional;
-template
-using nullable = network::rpc::nullable;
-using boolean_t = network::rpc::boolean_t;
-using string_t = network::rpc::string_t;
-using number_t = network::rpc::number_t;
-using object_t = network::rpc::object_t;
-using array_t = network::rpc::array_t;
-
-namespace empty { constexpr auto array = network::rpc::empty::array; };
-namespace empty { constexpr auto object = network::rpc::empty::object; };
-
-} // namespace interface
-} // namespace node
-} // namespace libbitcoin
-
#include
#include
#include
#include
#include
+#include
namespace libbitcoin {
namespace node {
diff --git a/include/bitcoin/node/interfaces/stratum_v1.hpp b/include/bitcoin/node/interfaces/stratum_v1.hpp
index 89f0a5e7..0c052b35 100644
--- a/include/bitcoin/node/interfaces/stratum_v1.hpp
+++ b/include/bitcoin/node/interfaces/stratum_v1.hpp
@@ -20,6 +20,7 @@
#define LIBBITCOIN_NODE_INTERFACES_STRATUM_V1_HPP
#include
+#include
namespace libbitcoin {
namespace node {
diff --git a/include/bitcoin/node/interfaces/stratum_v2.hpp b/include/bitcoin/node/interfaces/stratum_v2.hpp
index 9b0e2498..a266d0e5 100644
--- a/include/bitcoin/node/interfaces/stratum_v2.hpp
+++ b/include/bitcoin/node/interfaces/stratum_v2.hpp
@@ -20,6 +20,7 @@
#define LIBBITCOIN_NODE_INTERFACES_STRATUM_V2_HPP
#include
+#include
namespace libbitcoin {
namespace node {
diff --git a/include/bitcoin/node/interfaces/types.hpp b/include/bitcoin/node/interfaces/types.hpp
new file mode 100644
index 00000000..855ba89b
--- /dev/null
+++ b/include/bitcoin/node/interfaces/types.hpp
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
+ *
+ * This file is part of libbitcoin.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+#ifndef LIBBITCOIN_NODE_INTERFACES_TYPES_HPP
+#define LIBBITCOIN_NODE_INTERFACES_TYPES_HPP
+
+#include
+
+namespace libbitcoin {
+namespace node {
+namespace interface {
+
+/// Alias network::rpc names within interface::.
+
+template
+using method = network::rpc::method;
+template
+using method_at = network::rpc::method_at;
+template
+using publish = network::rpc::publish;
+
+template
+using optional = network::rpc::optional;
+template
+using nullable = network::rpc::nullable;
+using boolean_t = network::rpc::boolean_t;
+using string_t = network::rpc::string_t;
+using number_t = network::rpc::number_t;
+using object_t = network::rpc::object_t;
+using array_t = network::rpc::array_t;
+
+namespace empty { constexpr auto array = network::rpc::empty::array; };
+namespace empty { constexpr auto object = network::rpc::empty::object; };
+
+} // namespace interface
+} // namespace node
+} // namespace libbitcoin
+
+#endif
diff --git a/include/bitcoin/node/protocols/protocol_bitcoind.hpp b/include/bitcoin/node/protocols/protocol_bitcoind.hpp
index 31d803b0..3f723c49 100644
--- a/include/bitcoin/node/protocols/protocol_bitcoind.hpp
+++ b/include/bitcoin/node/protocols/protocol_bitcoind.hpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
namespace libbitcoin {
@@ -33,6 +34,8 @@ class BCN_API protocol_bitcoind
{
public:
typedef std::shared_ptr ptr;
+ using interface = interface::bitcoind;
+ using dispatcher = network::rpc::dispatcher;
inline protocol_bitcoind(const auto& session,
const network::channel::ptr& channel,
@@ -43,18 +46,64 @@ class BCN_API protocol_bitcoind
}
/// Public start is required.
- inline void start() NOEXCEPT override
+ void start() NOEXCEPT override;
+
+protected:
+ template
+ inline void subscribe(Method&& method, Args&&... args) NOEXCEPT
{
- node::protocol_http::start();
+ dispatcher_.subscribe(BIND_SHARED(method, args));
}
-////protected:
-//// void handle_receive_get(const code& ec,
-//// const network::http::method::get& request) NOEXCEPT override;
+ /// Dispatch.
+ void handle_receive_post(const code& ec,
+ const network::http::method::post::cptr& post) NOEXCEPT override;
+
+ /// Handlers.
+ bool handle_get_best_block_hash(const code& ec,
+ interface::get_best_block_hash) NOEXCEPT;
+ bool handle_get_block(const code& ec,
+ interface::get_block, const std::string&, double) NOEXCEPT;
+ bool handle_get_block_chain_info(const code& ec,
+ interface::get_block_chain_info) NOEXCEPT;
+ bool handle_get_block_count(const code& ec,
+ interface::get_block_count) NOEXCEPT;
+ bool handle_get_block_filter(const code& ec,
+ interface::get_block_filter, const std::string&,
+ const std::string&) NOEXCEPT;
+ ////bool handle_get_block_hash(const code& ec,
+ //// interface::get_block_hash, double) NOEXCEPT;
+ bool handle_get_block_header(const code& ec,
+ interface::get_block_header, const std::string&, bool) NOEXCEPT;
+ bool handle_get_block_stats(const code& ec,
+ interface::get_block_stats, const std::string&,
+ const network::rpc::array_t&) NOEXCEPT;
+ bool handle_get_chain_tx_stats(const code& ec,
+ interface::get_chain_tx_stats, double, const std::string&) NOEXCEPT;
+ bool handle_get_chain_work(const code& ec,
+ interface::get_chain_work) NOEXCEPT;
+ bool handle_get_tx_out(const code& ec,
+ interface::get_tx_out, const std::string&, double, bool) NOEXCEPT;
+ bool handle_get_tx_out_set_info(const code& ec,
+ interface::get_tx_out_set_info) NOEXCEPT;
+ ////bool handle_prune_block_chain(const code& ec,
+ //// interface::prune_block_chain, double) NOEXCEPT;
+ bool handle_save_mem_pool(const code& ec,
+ interface::save_mem_pool) NOEXCEPT;
+ bool handle_scan_tx_out_set(const code& ec,
+ interface::scan_tx_out_set, const std::string&,
+ const network::rpc::array_t&) NOEXCEPT;
+ bool handle_verify_chain(const code& ec,
+ interface::verify_chain, double, double) NOEXCEPT;
+ //bool handle_verify_tx_out_set(const code& ec,
+ // interface::verify_tx_out_set, const std::string&) NOEXCEPT;
private:
// This is thread safe.
////const options_t& options_;
+
+ // This is protected by strand.
+ dispatcher dispatcher_{};
};
} // namespace node
diff --git a/include/bitcoin/node/protocols/protocol_explore.hpp b/include/bitcoin/node/protocols/protocol_explore.hpp
index 6b40bec7..8821b69e 100644
--- a/include/bitcoin/node/protocols/protocol_explore.hpp
+++ b/include/bitcoin/node/protocols/protocol_explore.hpp
@@ -172,8 +172,11 @@ class BCN_API protocol_explore
database::header_link to_header(const std::optional& height,
const std::optional& hash) NOEXCEPT;
- dispatcher dispatcher_{};
+ // This is thread safe.
std::atomic_bool stopping_{};
+
+ // This is protected by strand.
+ dispatcher dispatcher_{};
};
} // namespace node
diff --git a/src/protocols/protocol_bitcoind.cpp b/src/protocols/protocol_bitcoind.cpp
new file mode 100644
index 00000000..50d1f2f3
--- /dev/null
+++ b/src/protocols/protocol_bitcoind.cpp
@@ -0,0 +1,238 @@
+/**
+ * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
+ *
+ * This file is part of libbitcoin.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+#include
+
+#include
+#include
+
+namespace libbitcoin {
+namespace node {
+
+#define CLASS protocol_bitcoind
+#define SUBSCRIBE_BITCOIND(method, ...) \
+ subscribe(&CLASS::method, __VA_ARGS__)
+
+using namespace system;
+using namespace network::rpc;
+using namespace network::http;
+using namespace std::placeholders;
+using namespace boost::json;
+
+using json_t = json_body::value_type;
+
+BC_PUSH_WARNING(SMART_PTR_NOT_NEEDED)
+BC_PUSH_WARNING(NO_VALUE_OR_CONST_REF_SHARED_PTR)
+
+// Start.
+// ----------------------------------------------------------------------------
+
+void protocol_bitcoind::start() NOEXCEPT
+{
+ using namespace std::placeholders;
+
+ BC_ASSERT(stranded());
+
+ if (started())
+ return;
+
+ SUBSCRIBE_BITCOIND(handle_get_best_block_hash, _1, _2);
+ SUBSCRIBE_BITCOIND(handle_get_block, _1, _2, _3, _4);
+ SUBSCRIBE_BITCOIND(handle_get_block_chain_info, _1, _2);
+ SUBSCRIBE_BITCOIND(handle_get_block_count, _1, _2);
+ SUBSCRIBE_BITCOIND(handle_get_block_filter, _1, _2, _3, _4);
+ ////SUBSCRIBE_BITCOIND(handle_get_block_hash, _1, _2, _3);
+ SUBSCRIBE_BITCOIND(handle_get_block_header, _1, _2, _3, _4);
+ SUBSCRIBE_BITCOIND(handle_get_block_stats, _1, _2, _3, _4);
+ SUBSCRIBE_BITCOIND(handle_get_chain_tx_stats, _1, _2, _3, _4);
+ SUBSCRIBE_BITCOIND(handle_get_chain_work, _1, _2);
+ SUBSCRIBE_BITCOIND(handle_get_tx_out, _1, _2, _3, _4, _5);
+ SUBSCRIBE_BITCOIND(handle_get_tx_out_set_info, _1, _2);
+ ////SUBSCRIBE_BITCOIND(handle_prune_block_chain, _1, _2, _3);
+ SUBSCRIBE_BITCOIND(handle_save_mem_pool, _1, _2);
+ SUBSCRIBE_BITCOIND(handle_scan_tx_out_set, _1, _2, _3, _4);
+ SUBSCRIBE_BITCOIND(handle_verify_chain, _1, _2, _3, _4);
+ ////SUBSCRIBE_BITCOIND(handle_verify_tx_out_set, _1, _2, _3);
+ protocol_bitcoind::start();
+}
+
+// Dispatch.
+// ----------------------------------------------------------------------------
+
+void protocol_bitcoind::handle_receive_post(const code& ec,
+ const network::http::method::post::cptr& post) NOEXCEPT
+{
+ BC_ASSERT(stranded());
+
+ if (stopped(ec))
+ return;
+
+ const auto& body = post->body();
+ if (!body.contains())
+ {
+ send_not_acceptable(*post);
+ return;
+ }
+
+ request_t request{};
+ try
+ {
+ request = value_to(body.get().model);
+ }
+ catch (const boost::system::system_error& e)
+ {
+ send_bad_target(e.code(), *post);
+ return;
+ }
+ catch (...)
+ {
+ send_bad_target(error::unexpected_parse, *post);
+ return;
+ }
+
+ // TODO: post-process request.
+ if (const auto code = dispatcher_.notify(request))
+ stop(code);
+}
+
+// Handlers.
+// ----------------------------------------------------------------------------
+
+bool protocol_bitcoind::handle_get_best_block_hash(const code& ec,
+ interface::get_best_block_hash) NOEXCEPT
+{
+ return !ec;
+}
+
+// method<"getblock", string_t, optional<0_u32>>{ "blockhash", "verbosity" },
+bool protocol_bitcoind::handle_get_block(const code& ec,
+ interface::get_block, const std::string&, double) NOEXCEPT
+{
+ return !ec;
+}
+
+bool protocol_bitcoind::handle_get_block_chain_info(const code& ec,
+ interface::get_block_chain_info) NOEXCEPT
+{
+ return !ec;
+}
+
+bool protocol_bitcoind::handle_get_block_count(const code& ec,
+ interface::get_block_count) NOEXCEPT
+{
+ return !ec;
+}
+
+// method<"getblockfilter", string_t, optional<"basic"_t>>{ "blockhash", "filtertype" },
+bool protocol_bitcoind::handle_get_block_filter(const code& ec,
+ interface::get_block_filter, const std::string&, const std::string&) NOEXCEPT
+{
+ return !ec;
+}
+
+////// method<"getblockhash", number_t>{ "height" },
+////bool protocol_bitcoind::handle_get_block_hash(const code& ec,
+//// interface::get_block_hash, network::rpc::number_t) NOEXCEPT
+////{
+//// return !ec;
+////}
+
+// method<"getblockheader", string_t, optional>{ "blockhash", "verbose" },
+bool protocol_bitcoind::handle_get_block_header(const code& ec,
+ interface::get_block_header, const std::string&, bool) NOEXCEPT
+{
+ return !ec;
+}
+
+// method<"getblockstats", string_t, optional>{ "hash_or_height", "stats" },
+bool protocol_bitcoind::handle_get_block_stats(const code& ec,
+ interface::get_block_stats, const std::string&,
+ const network::rpc::array_t&) NOEXCEPT
+{
+ return !ec;
+}
+
+// method<"getchaintxstats", optional<-1_i32>, optional<""_t>>{ "nblocks", "blockhash" },
+bool protocol_bitcoind::handle_get_chain_tx_stats(const code& ec,
+ interface::get_chain_tx_stats, double, const std::string&) NOEXCEPT
+{
+ return !ec;
+}
+
+bool protocol_bitcoind::handle_get_chain_work(const code& ec,
+ interface::get_chain_work) NOEXCEPT
+{
+ return !ec;
+}
+
+// method<"gettxout", string_t, number_t, optional>{ "txid", "n", "include_mempool" },
+bool protocol_bitcoind::handle_get_tx_out(const code& ec,
+ interface::get_tx_out, const std::string&, double, bool) NOEXCEPT
+{
+ return !ec;
+}
+
+bool protocol_bitcoind::handle_get_tx_out_set_info(const code& ec,
+ interface::get_tx_out_set_info) NOEXCEPT
+{
+ return !ec;
+}
+
+////// method<"pruneblockchain", number_t>{ "height" },
+////bool protocol_bitcoind::handle_prune_block_chain(const code& ec,
+//// interface::prune_block_chain, double) NOEXCEPT
+////{
+//// return !ec;
+////}
+
+bool protocol_bitcoind::handle_save_mem_pool(const code& ec,
+ interface::save_mem_pool) NOEXCEPT
+{
+ return !ec;
+}
+
+// method<"scantxoutset", string_t, optional>{ "action", "scanobjects" },
+bool protocol_bitcoind::handle_scan_tx_out_set(const code& ec,
+ interface::scan_tx_out_set, const std::string&,
+ const network::rpc::array_t&) NOEXCEPT
+{
+ return !ec;
+}
+
+// method<"verifychain", optional<4_u32>, optional<288_u32>>{ "checklevel", "nblocks" },
+bool protocol_bitcoind::handle_verify_chain(const code& ec,
+ interface::verify_chain, double, double) NOEXCEPT
+{
+ return !ec;
+}
+
+////// method<"verifytxoutset", string_t>{ "input_verify_flag" },
+////bool protocol_bitcoind::handle_verify_tx_out_set(const code& ec,
+//// interface::verify_tx_out_set, const std::string&) NOEXCEPT
+////{
+//// return !ec;
+////}
+
+BC_POP_WARNING()
+BC_POP_WARNING()
+
+#undef SUBSCRIBE_BITCOIND
+#undef CLASS
+
+} // namespace node
+} // namespace libbitcoin
diff --git a/src/protocols/protocol_explore.cpp b/src/protocols/protocol_explore.cpp
index e1077e04..66cafbab 100644
--- a/src/protocols/protocol_explore.cpp
+++ b/src/protocols/protocol_explore.cpp
@@ -29,7 +29,6 @@ namespace libbitcoin {
namespace node {
#define CLASS protocol_explore
-
#define SUBSCRIBE_EXPLORE(method, ...) \
subscribe(&CLASS::method, __VA_ARGS__)
@@ -1161,6 +1160,7 @@ BC_POP_WARNING()
BC_POP_WARNING()
#undef SUBSCRIBE_EXPLORE
+#undef CLASS
} // namespace node
} // namespace libbitcoin
diff --git a/src/sessions/session.cpp b/src/sessions/session.cpp
index 9708658f..16687924 100644
--- a/src/sessions/session.cpp
+++ b/src/sessions/session.cpp
@@ -26,8 +26,6 @@
namespace libbitcoin {
namespace node {
-#define CLASS session
-
using namespace system::chain;
using namespace database;
using namespace network;