Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
167aec4
Round amounts within tolerance and enforce max money.
evoskuil Aug 26, 2026
45a7a05
Validate base58 address network prefixes.
evoskuil Aug 26, 2026
605bd03
Answer rpc ping without pinging peers.
evoskuil Aug 26, 2026
0ff5639
Organize block submission carrying a known header.
evoskuil Aug 26, 2026
41a93a8
Exclude unconfirmed outputs from gettxout.
evoskuil Aug 26, 2026
4ce85ad
Report descriptor spends unconditionally as spend_vin.
evoskuil Aug 26, 2026
d7db845
Report live networkactive state.
evoskuil Aug 26, 2026
32b6209
Report warnings as arrays.
evoskuil Aug 26, 2026
9c9fbf3
Limit createmultisig to sixteen keys.
evoskuil Aug 26, 2026
9b4053b
Report self inclusive median time past as bitcoind.
evoskuil Aug 26, 2026
12dc670
Match bitcoind argument names and defaults.
evoskuil Aug 26, 2026
3bcc731
Match bitcoind transaction construction surface.
evoskuil Aug 26, 2026
e94c552
Serve rest headers from the active chain only.
evoskuil Aug 26, 2026
d1bf603
Add the rest tx endpoint.
evoskuil Aug 26, 2026
0a47f80
Distinguish rest bad request from not found.
evoskuil Aug 26, 2026
41eef6d
Declare missing bitcoind methods and serve rpc.discover.
evoskuil Aug 26, 2026
aeb3375
Style.
evoskuil Aug 26, 2026
6d6f7dc
Comment style.
evoskuil Aug 26, 2026
3070c06
Match definition order to declaration order.
evoskuil Aug 26, 2026
9f34ce8
Note bitcoind quoted-amount input deviation.
evoskuil Aug 26, 2026
e9cdb38
Reword quoted-amount comments.
evoskuil Aug 26, 2026
d3e8554
Report per-tx fee at getblock verbosity two.
evoskuil Aug 26, 2026
f2dc6fb
Suppress response objects for v2 notifications.
evoskuil Aug 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/bitcoin/server/interfaces/bitcoind_blockchain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct bitcoind_blockchain_methods
method<"pruneblockchain", number_t>{ unimplemented, "height" },
method<"savemempool">{ unimplemented },
method<"scantxoutset", string_t, optional<empty::array>>{ "action", "scanobjects" },
method<"verifychain", optional<4.0>, optional<288.0>>{ "checklevel", "nblocks" },
method<"verifychain", optional<3.0>, optional<6.0>>{ "checklevel", "nblocks" },
method<"dumptxoutset">{ unimplemented },
method<"loadtxoutset">{ unimplemented },
method<"gettxoutproof", array_t, optional<""_t>>{ "txids", "blockhash" },
Expand All @@ -53,13 +53,13 @@ struct bitcoind_blockchain_methods
method<"getchainstates">{},
method<"getchaintips">{},
method<"getdeploymentinfo", optional<""_t>>{ "blockhash" },
method<"getdescriptoractivity", optional<empty::array>, optional<empty::array>, optional<false>>{ "blockhashes", "scanobjects", "include_spent" },
method<"getdescriptoractivity", optional<empty::array>, optional<empty::array>, optional<true>>{ "blockhashes", "scanobjects", "include_mempool" },
method<"getdifficulty">{},
method<"preciousblock">{ unimplemented },
method<"scanblocks", string_t, optional<empty::array>, optional<0.0>, optional<-1.0>, optional<"basic"_t>>{ "action", "scanobjects", "start_height", "stop_height", "filtertype" },
method<"scanblocks", string_t, optional<empty::array>, optional<0.0>, optional<-1.0>, optional<"basic"_t>, optional<empty::object>>{ "action", "scanobjects", "start_height", "stop_height", "filtertype", "options" },
method<"waitforblock", string_t, optional<0.0>>{ "blockhash", "timeout" },
method<"waitforblockheight", number_t, optional<0.0>>{ "height", "timeout" },
method<"waitfornewblock", optional<0.0>>{ "timeout" },
method<"waitfornewblock", optional<0.0>, optional<""_t>>{ "timeout", "current_tip" },
method<"getmempoolancestors">{ unimplemented },
method<"getmempoolcluster">{ unimplemented },
method<"getmempooldescendants">{ unimplemented },
Expand Down
6 changes: 4 additions & 2 deletions include/bitcoin/server/interfaces/bitcoind_control.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ struct bitcoind_control_methods
method<"help", optional<""_t>>{ "command" },
method<"stop">{ unimplemented },
method<"getmemoryinfo", optional<"stats"_t>>{ "mode" },
method<"getopenrpcinfo">{},
method<"getopenrpcinfo", optional<false>>{ "show_hidden" },
method<"getrpcinfo">{},
method<"logging", optional<empty::array>, optional<empty::array>>{ "include", "exclude" },
method<"uptime">{}
method<"uptime">{},
method<"rpc.discover", optional<false>>{ "show_hidden" }
};

template <typename... Args>
Expand All @@ -58,6 +59,7 @@ struct bitcoind_control_methods
using get_rpc_info = at<4>;
using logging = at<5>;
using uptime = at<6>;
using rpc_discover = at<7>;
};

} // namespace interface
Expand Down
6 changes: 5 additions & 1 deletion include/bitcoin/server/interfaces/bitcoind_rest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ struct bitcoind_rest_methods
// info (json only)
method<"chain_information">{},
method<"mempool_information">{},
method<"fork_information", nullable<system::hash_cptr>>{ "hash" }
method<"fork_information", nullable<system::hash_cptr>>{ "hash" },

// transactions
method<"tx", uint8_t, system::hash_cptr>{ "media", "hash" }
};

template <typename... Args>
Expand All @@ -77,6 +80,7 @@ struct bitcoind_rest_methods
using chain_information = at<11>;
using mempool_information = at<12>;
using fork_information = at<13>;
using tx = at<14>;
};

} // namespace interface
Expand Down
17 changes: 11 additions & 6 deletions include/bitcoin/server/interfaces/bitcoind_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,26 @@ struct bitcoind_transaction_methods
{
static constexpr std::tuple methods
{
method<"createrawtransaction", array_t, object_t, optional<0.0>, optional<false>>{ "inputs", "outputs", "locktime", "replaceable" },
method<"createrawtransaction", array_t, value_t, optional<0.0>, optional<true>, optional<2.0>>{ "inputs", "outputs", "locktime", "replaceable", "version" },
method<"decoderawtransaction", string_t, nullable<boolean_t>>{ "hexstring", "iswitness" },
method<"getrawtransaction", string_t, optional<0.0>, optional<""_t>>{ "txid", "verbosity", "blockhash" },
method<"sendrawtransaction", string_t, optional<0.0>>{ "hexstring", "maxfeerate" },
method<"testmempoolaccept", array_t, optional<0.0>>{ "rawtxs", "maxfeerate" },
// bitcoind also accepts quoted amounts (slop; needs dispatch special case).
method<"sendrawtransaction", string_t, optional<0.1>, optional<0.0>>{ "hexstring", "maxfeerate", "maxburnamount" },
method<"testmempoolaccept", array_t, optional<0.1>>{ "rawtxs", "maxfeerate" },
method<"analyzepsbt", string_t>{ "psbt" },
method<"combinepsbt", array_t>{ "txs" },
method<"converttopsbt", string_t, optional<false>, nullable<boolean_t>>{ "hexstring", "permitsigdata", "iswitness" },
method<"createpsbt", array_t, object_t, optional<0.0>, optional<false>>{ "inputs", "outputs", "locktime", "replaceable" },
method<"converttopsbt", string_t, optional<false>, nullable<boolean_t>, optional<2.0>>{ "hexstring", "permitsigdata", "iswitness", "psbt_version" },
method<"createpsbt", array_t, value_t, optional<0.0>, optional<true>, optional<2.0>, optional<2.0>>{ "inputs", "outputs", "locktime", "replaceable", "version", "psbt_version" },
method<"decodepsbt", string_t>{ "psbt" },
method<"finalizepsbt", string_t, optional<true>>{ "psbt", "extract" },
method<"joinpsbts", array_t>{ "txs" },
method<"descriptorprocesspsbt">{ unimplemented },
method<"utxoupdatepsbt", string_t, optional<empty::array>>{ "psbt", "descriptors" },
method<"abortprivatebroadcast">{ unimplemented },
method<"getprivatebroadcastinfo">{ unimplemented },
method<"submitpackage">{ unimplemented }
method<"submitpackage">{ unimplemented },
method<"combinerawtransaction">{ unimplemented },
method<"signrawtransactionwithkey">{ unimplemented }
};

template <typename... Args>
Expand Down Expand Up @@ -78,6 +81,8 @@ struct bitcoind_transaction_methods
using abort_private_broadcast = at<14>;
using get_private_broadcast_info = at<15>;
using submit_package = at<16>;
using combine_raw_transaction = at<17>;
using sign_raw_transaction_with_key = at<18>;
};

} // namespace interface
Expand Down
6 changes: 4 additions & 2 deletions include/bitcoin/server/interfaces/bitcoind_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ struct bitcoind_utility_methods
{
static constexpr std::tuple methods
{
method<"decodescript", string_t>{ "hex" },
method<"decodescript", string_t>{ "hexstring" },
method<"validateaddress", string_t>{ "address" },
method<"createmultisig", number_t, array_t, optional<"legacy"_t>>{ "nrequired", "keys", "address_type" },
method<"deriveaddresses", string_t, nullable<value_t>>{ "descriptor", "range" },
method<"getdescriptorinfo", string_t>{ "descriptor" },
method<"verifymessage", string_t, string_t, string_t>{ "address", "signature", "message" },
method<"getindexinfo", optional<""_t>>{ "index_name" },
method<"estimatesmartfee">{ unimplemented }
method<"estimatesmartfee">{ unimplemented },
method<"signmessagewithprivkey">{ unimplemented }
};

template <typename... Args>
Expand All @@ -60,6 +61,7 @@ struct bitcoind_utility_methods
using verify_message = at<5>;
using get_index_info = at<6>;
using estimate_smart_fee = at<7>;
using sign_message_with_priv_key = at<8>;
};

} // namespace interface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,25 @@ class BCS_API protocol_bitcoind_blockchain
rpc_interface::get_descriptor_activity,
const network::rpc::array_t& blockhashes,
const network::rpc::array_t& scanobjects,
bool include_spent) NOEXCEPT;
bool include_mempool) NOEXCEPT;
bool handle_get_difficulty(const code& ec,
rpc_interface::get_difficulty) NOEXCEPT;
bool handle_precious_block(const code& ec,
rpc_interface::precious_block) NOEXCEPT;
bool handle_scan_blocks(const code& ec,
rpc_interface::scan_blocks, const std::string& action,
const network::rpc::array_t& scanobjects, double start_height,
double stop_height, const std::string& filtertype) NOEXCEPT;
double stop_height, const std::string& filtertype,
const network::rpc::object_t& options) NOEXCEPT;
bool handle_wait_for_block(const code& ec,
rpc_interface::wait_for_block, const std::string& blockhash,
double timeout) NOEXCEPT;
bool handle_wait_for_block_height(const code& ec,
rpc_interface::wait_for_block_height, double height,
double timeout) NOEXCEPT;
bool handle_wait_for_new_block(const code& ec,
rpc_interface::wait_for_new_block, double timeout) NOEXCEPT;
rpc_interface::wait_for_new_block, double timeout,
const std::string& current_tip) NOEXCEPT;
bool handle_get_mempool_ancestors(const code& ec,
rpc_interface::get_mempool_ancestors) NOEXCEPT;
bool handle_get_mempool_cluster(const code& ec,
Expand Down Expand Up @@ -161,7 +163,7 @@ class BCS_API protocol_bitcoind_blockchain
void do_wait_event() NOEXCEPT;
void handle_wait_timeout(const code& ec) NOEXCEPT;
bool wait_done() const NOEXCEPT;
void send_tip() NOEXCEPT;
void send_top() NOEXCEPT;

enum class set_hash : uint8_t { none, muhash, serialized };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,19 @@ class BCS_API protocol_bitcoind_control
bool handle_get_memory_info(const code& ec,
rpc_interface::get_memory_info, const std::string& mode) NOEXCEPT;
bool handle_get_openrpc_info(const code& ec,
rpc_interface::get_openrpc_info) NOEXCEPT;
rpc_interface::get_openrpc_info, bool show_hidden) NOEXCEPT;
bool handle_get_rpc_info(const code& ec,
rpc_interface::get_rpc_info) NOEXCEPT;
bool handle_logging(const code& ec, rpc_interface::logging,
const network::rpc::array_t& include,
const network::rpc::array_t& exclude) NOEXCEPT;
bool handle_uptime(const code& ec,
rpc_interface::uptime) NOEXCEPT;
bool handle_rpc_discover(const code& ec,
rpc_interface::rpc_discover, bool show_hidden) NOEXCEPT;

private:
void send_openrpc() NOEXCEPT;
};

} // namespace server
Expand Down
2 changes: 2 additions & 0 deletions include/bitcoin/server/protocols/protocol_bitcoind_rest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class BCS_API protocol_bitcoind_rest
/// REST interface handlers.
bool handle_get_block(const code& ec, rest_interface::block,
uint8_t media, const system::hash_cptr& hash) NOEXCEPT;
bool handle_get_tx(const code& ec, rest_interface::tx,
uint8_t media, const system::hash_cptr& hash) NOEXCEPT;
bool handle_get_block_hash(const code& ec, rest_interface::block_hash,
uint8_t media, uint32_t height) NOEXCEPT;
bool handle_get_block_txs(const code& ec, rest_interface::block_txs,
Expand Down
21 changes: 13 additions & 8 deletions include/bitcoin/server/protocols/protocol_bitcoind_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ class BCS_API protocol_bitcoind_transaction
bool handle_create_raw_transaction(const code& ec,
rpc_interface::create_raw_transaction,
const network::rpc::array_t& inputs,
const network::rpc::object_t& outputs, double locktime,
bool replaceable) NOEXCEPT;
const network::rpc::value_t& outputs, double locktime,
bool replaceable, double version) NOEXCEPT;
bool handle_decode_raw_transaction(const code& ec,
rpc_interface::decode_raw_transaction, const std::string& hexstring,
const std::optional<bool>& iswitness) NOEXCEPT;
Expand All @@ -68,7 +68,7 @@ class BCS_API protocol_bitcoind_transaction
double verbose, const std::string& blockhash) NOEXCEPT;
bool handle_send_raw_transaction(const code& ec,
rpc_interface::send_raw_transaction, const std::string& hexstring,
double maxfeerate) NOEXCEPT;
double maxfeerate, double maxburnamount) NOEXCEPT;
bool handle_test_mempool_accept(const code& ec,
rpc_interface::test_mempool_accept,
const network::rpc::array_t& rawtxs, double maxfeerate) NOEXCEPT;
Expand All @@ -79,11 +79,12 @@ class BCS_API protocol_bitcoind_transaction
const network::rpc::array_t& txs) NOEXCEPT;
bool handle_convert_to_psbt(const code& ec,
rpc_interface::convert_to_psbt, const std::string& hexstring,
bool permitsigdata, const std::optional<bool>& iswitness) NOEXCEPT;
bool permitsigdata, const std::optional<bool>& iswitness,
double psbt_version) NOEXCEPT;
bool handle_create_psbt(const code& ec,
rpc_interface::create_psbt, const network::rpc::array_t& inputs,
const network::rpc::object_t& outputs, double locktime,
bool replaceable) NOEXCEPT;
const network::rpc::value_t& outputs, double locktime,
bool replaceable, double version, double psbt_version) NOEXCEPT;
bool handle_decode_psbt(const code& ec,
rpc_interface::decode_psbt, const std::string& psbt) NOEXCEPT;
bool handle_finalize_psbt(const code& ec,
Expand All @@ -101,14 +102,18 @@ class BCS_API protocol_bitcoind_transaction
/// Shared transaction construction (createrawtransaction, createpsbt).
code build_transaction(system::chain::transaction& out,
const network::rpc::array_t& inputs,
const network::rpc::object_t& outputs, double locktime,
bool replaceable) const NOEXCEPT;
const network::rpc::value_t& outputs, double locktime,
bool replaceable, double version) const NOEXCEPT;
bool handle_abort_private_broadcast(const code& ec,
rpc_interface::abort_private_broadcast) NOEXCEPT;
bool handle_get_private_broadcast_info(const code& ec,
rpc_interface::get_private_broadcast_info) NOEXCEPT;
bool handle_submit_package(const code& ec,
rpc_interface::submit_package) NOEXCEPT;
bool handle_combine_raw_transaction(const code& ec,
rpc_interface::combine_raw_transaction) NOEXCEPT;
bool handle_sign_raw_transaction_with_key(const code& ec,
rpc_interface::sign_raw_transaction_with_key) NOEXCEPT;
};

} // namespace server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class BCS_API protocol_bitcoind_utility
protected:
/// Handlers.
bool handle_decode_script(const code& ec,
rpc_interface::decode_script, const std::string& hex) NOEXCEPT;
rpc_interface::decode_script, const std::string& hexstring) NOEXCEPT;
bool handle_validate_address(const code& ec,
rpc_interface::validate_address,
const std::string& address) NOEXCEPT;
Expand All @@ -77,6 +77,8 @@ class BCS_API protocol_bitcoind_utility
rpc_interface::get_index_info, const std::string& index_name) NOEXCEPT;
bool handle_estimate_smart_fee(const code& ec,
rpc_interface::estimate_smart_fee) NOEXCEPT;
bool handle_sign_message_with_priv_key(const code& ec,
rpc_interface::sign_message_with_priv_key) NOEXCEPT;
};

} // namespace server
Expand Down
5 changes: 3 additions & 2 deletions src/parsers/bitcoind_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ code output_script(script& out, const std::string& text, uint8_t p2kh,
{
using namespace wallet;

if (const payment_address payment{ text }; payment)
// The parsers accept any prefix, so the configured ones are checks.
if (const payment_address payment{ text }; payment &&
((payment.prefix() == p2kh) || (payment.prefix() == p2sh)))
{
out = payment.output_script(p2kh, p2sh);
return error::success;
}

// The parse accepts any prefix, so the configured one is a check.
if (const witness_address payment{ text };
payment && payment.prefix() == witness)
{
Expand Down
23 changes: 22 additions & 1 deletion src/parsers/bitcoind_target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ code bitcoind_target(request_t& out, const std::string_view& path) NOEXCEPT
++segment;

if (segment == segments.size())
return error::missing_target;
return error::invalid_target;

const auto target = segments[segment++];

Expand Down Expand Up @@ -161,6 +161,27 @@ code bitcoind_target(request_t& out, const std::string_view& path) NOEXCEPT
return error::success;
}

// /rest/tx/<txid>.<ext>
if (target == "tx")
{
if (segment == segments.size())
return error::missing_hash;

std::string name{};
uint8_t media{};
if (!split_leaf(name, media, segments[segment++]))
return error::invalid_target;

const auto hash = to_hash(name);
if (!hash)
return error::invalid_hash;

method = "tx";
params["media"] = media;
params["hash"] = hash;
return error::success;
}

// /rest/blockhashbyheight/<height>.<ext>
if (target == "blockhashbyheight")
{
Expand Down
Loading
Loading