Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions include/bitcoin/server/protocols/protocol_bitcoind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class BCS_API protocol_bitcoind
network::tracker<protocol_bitcoind>(session->log),
p2kh_(session->server_settings().wallet.p2kh_prefix),
p2sh_(session->server_settings().wallet.p2sh_prefix),
flags_(session->system_settings().flags()),
witness_(session->server_settings().wallet.witness_prefix)
{
}
Expand Down Expand Up @@ -94,6 +95,10 @@ class BCS_API protocol_bitcoind
code validate_tx(const system::chain::transaction& tx) const NOEXCEPT;
code broadcast_tx(const system::chain::transaction::cptr& tx) NOEXCEPT;

/// The bitcoind scriptPubKey object with network context.
boost::json::value script_public_key(
const system::chain::script& script) const NOEXCEPT;

private:
// Senders.
void send_rpc(network::rpc::response_t&& model,
Expand All @@ -112,6 +117,7 @@ class BCS_API protocol_bitcoind
// These are thread safe.
const uint8_t p2kh_;
const uint8_t p2sh_;
const uint32_t flags_;
const std::string witness_;
};

Expand Down
4 changes: 4 additions & 0 deletions include/bitcoin/server/protocols/protocol_electrum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class BCS_API protocol_electrum
turbo_(session->database_settings().turbo),
p2kh_(session->server_settings().wallet.p2kh_prefix),
p2sh_(session->server_settings().wallet.p2sh_prefix),
flags_(session->system_settings().flags()),
witness_(session->server_settings().wallet.witness_prefix),
channel_(std::dynamic_pointer_cast<channel_t>(channel)),
notification_strand_(channel_->service().get_executor()),
network::tracker<protocol_electrum>(session->log)
Expand Down Expand Up @@ -361,6 +363,8 @@ class BCS_API protocol_electrum
const bool turbo_;
const uint8_t p2kh_;
const uint8_t p2sh_;
const uint32_t flags_;
const std::string witness_;
std::atomic_bool stopping_{};
std::atomic_bool subscribed_height_{};
std::atomic_bool subscribed_header_{};
Expand Down
27 changes: 20 additions & 7 deletions include/bitcoin/server/serializers/bitcoind_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,36 @@ BCS_API void inject_tx_context(boost::json::object& out,

/// Per-input prevout context (requires populate_with_metadata).
BCS_API void inject_tx_prevouts(boost::json::object& out,
const node::query& query,
const system::chain::transaction& tx) NOEXCEPT;
const node::query& query, const system::chain::transaction& tx,
uint8_t p2kh, uint8_t p2sh, const std::string& witness,
uint32_t flags) NOEXCEPT;

/// The address of a singular output script (empty if unaddressable).
BCS_API std::string to_address(const system::chain::script& script,
uint8_t p2kh, uint8_t p2sh, const std::string& witness) NOEXCEPT;

/// The network context (desc, address) of a scriptPubKey object.
BCS_API void inject_script_context(boost::json::object& out,
const system::chain::script& script, uint8_t p2kh, uint8_t p2sh,
const std::string& witness) NOEXCEPT;

/// The network context of each vout scriptPubKey object.
BCS_API void inject_tx_scripts(boost::json::object& out,
const system::chain::transaction& tx, uint8_t p2kh, uint8_t p2sh,
const std::string& witness) NOEXCEPT;

/// The bitcoind scriptPubKey object (asm, hex, type, desc, address).
BCS_API boost::json::value to_script_public_key(
const system::chain::script& script, uint8_t p2kh, uint8_t p2sh,
const std::string& witness, uint32_t flags) NOEXCEPT;

/// Append the block's receive/spend activity on the watched scripts (hex
/// encoded), requires populate_without_metadata (getdescriptoractivity).
BCS_API void inject_activity(network::rpc::array_t& out,
const system::chain::block& block, size_t height,
const std::string& blockhash,
const std::unordered_set<std::string>& watch) NOEXCEPT;

/// The bitcoind block header object.
BCS_API boost::json::object header_to_bitcoind(
const system::chain::header& header) NOEXCEPT;
const std::unordered_set<std::string>& watch, uint8_t p2kh,
uint8_t p2sh, const std::string& witness, uint32_t flags) NOEXCEPT;

/// The bitcoind chain name, resolved from the genesis block.
BCS_API std::string chain_name(const node::query& query) NOEXCEPT;
Expand Down
6 changes: 4 additions & 2 deletions include/bitcoin/server/serializers/bitcoind_psbt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ BCS_API network::rpc::object_t to_unknown(

/// The bitcoind decodepsbt input object.
BCS_API network::rpc::object_t decode_psbt_input(
const system::wallet::psbt::input& in) NOEXCEPT;
const system::wallet::psbt::input& in, uint8_t p2kh, uint8_t p2sh,
const std::string& witness, uint32_t flags) NOEXCEPT;

/// The bitcoind decodepsbt output object.
BCS_API network::rpc::object_t decode_psbt_output(
const system::wallet::psbt::output& out) NOEXCEPT;
const system::wallet::psbt::output& out, uint8_t p2kh, uint8_t p2sh,
const std::string& witness, uint32_t flags) NOEXCEPT;

} // namespace server
} // namespace libbitcoin
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/server/serializers/btcd_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace btcd {
BCS_API boost::json::object search_transaction(const node::query& query,
const database::tx_link& link, const system::chain::transaction& tx,
const std::set<std::string>& filter, bool prevouts, uint8_t p2kh,
uint8_t p2sh, const std::string& witness) NOEXCEPT;
uint8_t p2sh, const std::string& witness, uint32_t flags) NOEXCEPT;

} // namespace btcd
} // namespace server
Expand Down
6 changes: 6 additions & 0 deletions src/protocols/bitcoind/protocol_bitcoind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,12 @@ code protocol_bitcoind::broadcast_tx(
return error::success;
}

boost::json::value protocol_bitcoind::script_public_key(
const chain::script& script) const NOEXCEPT
{
return to_script_public_key(script, p2kh_, p2sh_, witness_, flags_);
}

BC_POP_WARNING()
BC_POP_WARNING()
BC_POP_WARNING()
Expand Down
25 changes: 15 additions & 10 deletions src/protocols/bitcoind/protocol_bitcoind_blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,25 +184,28 @@ bool protocol_bitcoind_blockchain::handle_get_block(const code& ec,

auto model = level == block_verbosity::hashed ?
value_from(bitcoind_hashed(*block)) :
value_from(bitcoind_verbose(*block));
value_from(bitcoind_verbose(*block, flags_));

const auto& settings = system_settings();
const auto& header = block->header();
inject_block_context(model.as_object(), query, settings, link, header);

if (level >= block_verbosity::verbose &&
query.populate_with_metadata(*block))
if (level >= block_verbosity::verbose)
{
const auto populated = query.populate_with_metadata(*block);
auto entry = model.as_object().at("tx").as_array().begin();
std::ranges::for_each(*block->transactions_ptr(),
[&](const auto& tx) NOEXCEPT
{
if (!tx->is_coinbase())
auto& object = entry->as_object();
inject_tx_scripts(object, *tx, p2kh_, p2sh_, witness_);
if (populated && !tx->is_coinbase())
{
if (level == block_verbosity::prevouts)
inject_tx_prevouts(entry->as_object(), query, *tx);
inject_tx_prevouts(object, query, *tx, p2kh_, p2sh_,
witness_, flags_);

entry->as_object()["fee"] =
object["fee"] =
tx->fee() / to_floating(chain::satoshi_per_bitcoin);
}

Expand Down Expand Up @@ -344,10 +347,11 @@ bool protocol_bitcoind_blockchain::handle_get_block_header(const code& ec,
return true;
}

auto out = header_to_bitcoind(*header);
auto model = value_from(bitcoind(*header));
auto& out = model.as_object();
out["nTx"] = query.get_tx_count(link);
inject_block_context(out, query, system_settings(), link, *header);
send_result(value{ std::move(out) }, 512);
send_result(std::move(model), 512);
return true;
}

Expand Down Expand Up @@ -602,7 +606,7 @@ bool protocol_bitcoind_blockchain::handle_get_tx_out(const code& ec,
{ "bestblock", encode_hash(query.get_header_key(header_link)) },
{ "confirmations", depth },
{ "value", coins },
{ "scriptPubKey", value_from(bitcoind(output->script())) },
{ "scriptPubKey", script_public_key(output->script()) },
{ "coinbase", query.is_coinbase(tx_link) }
}, 256);
return true;
Expand Down Expand Up @@ -1321,7 +1325,8 @@ bool protocol_bitcoind_blockchain::handle_get_descriptor_activity(
return true;
}

inject_activity(activity, *block, height, encode_hash(hash), watch);
inject_activity(activity, *block, height, encode_hash(hash), watch,
p2kh_, p2sh_, witness_, flags_);
}

const auto size = 256 * activity.size();
Expand Down
11 changes: 5 additions & 6 deletions src/protocols/bitcoind/protocol_bitcoind_rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,9 @@ bool protocol_bitcoind_rest::handle_get_tx(const code& ec,
return true;
case json:
{
auto model = value_from(bitcoind(*tx));
auto model = value_from(bitcoind(*tx, flags_));
inject_tx_context(model.as_object(), query, link);
inject_tx_scripts(model.as_object(), *tx, p2kh_, p2sh_, witness_);
send_json(std::move(model), two * size);
return true;
}
Expand Down Expand Up @@ -395,7 +396,7 @@ bool protocol_bitcoind_rest::handle_get_block_headers(const code& ec,
return true;
}

out.push_back(header_to_bitcoind(*header));
out.push_back(value_from(bitcoind(*header)));
}

send_json(std::move(out), links.size() * two * header_size);
Expand Down Expand Up @@ -541,8 +542,7 @@ bool protocol_bitcoind_rest::handle_get_block_spent_tx_outputs(const code& ec,
{
{ "value", output->value() /
to_floating(chain::satoshi_per_bitcoin) },
{ "scriptPubKey", value_from(bitcoind(
output->script())) }
{ "scriptPubKey", script_public_key(output->script()) }
});

models.emplace_back(std::move(prevouts));
Expand Down Expand Up @@ -822,8 +822,7 @@ bool protocol_bitcoind_rest::handle_get_utxos(const code& ec,
{ "height", unspent.height },
{ "value", unspent.out->value() /
to_floating(chain::satoshi_per_bitcoin) },
{ "scriptPubKey", value_from(bitcoind(
unspent.out->script())) }
{ "scriptPubKey", script_public_key(unspent.out->script()) }
});

send_json(object
Expand Down
35 changes: 26 additions & 9 deletions src/protocols/bitcoind/protocol_bitcoind_transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ bool protocol_bitcoind_transaction::handle_decode_raw_transaction(const code& ec
return true;
}

send_result(value_from(bitcoind(tx)), two * tx.serialized_size(true));
auto model = value_from(bitcoind(tx, flags_));
inject_tx_scripts(model.as_object(), tx, p2kh_, p2sh_, witness_);
send_result(std::move(model), two * tx.serialized_size(true));
return true;
}

Expand Down Expand Up @@ -180,14 +182,15 @@ bool protocol_bitcoind_transaction::handle_get_raw_transaction(const code& ec,
return true;
}

auto model = value_from(bitcoind(*tx));
inject_tx_context(model.as_object(), query, link);
auto model = value_from(bitcoind(*tx, flags_));
auto& object = model.as_object();
inject_tx_context(object, query, link);
inject_tx_scripts(object, *tx, p2kh_, p2sh_, witness_);
if (level == verbosity::json_verbose && !tx->is_coinbase() &&
query.populate_with_metadata(*tx))
{
inject_tx_prevouts(model.as_object(), query, *tx);
model.as_object()["fee"] =
tx->fee() / to_floating(chain::satoshi_per_bitcoin);
inject_tx_prevouts(object, query, *tx, p2kh_, p2sh_, witness_, flags_);
object["fee"] = tx->fee() / to_floating(chain::satoshi_per_bitcoin);
}

send_result(std::move(model), two * tx->serialized_size(witness));
Expand Down Expand Up @@ -548,7 +551,15 @@ bool protocol_bitcoind_transaction::handle_decode_psbt(const code& ec,
object_t result{};
const auto version0 = (doc.version() == psbt_tx::version_0);
if (version0)
result.emplace("tx", value_from(bitcoind(doc.unsigned_tx())));
{
const auto& unsigned_tx = doc.unsigned_tx();
auto tx = value_from(bitcoind(unsigned_tx, flags_));
inject_tx_scripts(tx.as_object(), unsigned_tx, p2kh_, p2sh_, witness_);

// bitcoind omits the hex of the decoded psbt transaction.
tx.as_object().erase("hex");
result.emplace("tx", std::move(tx));
}

if (!doc.xpubs().empty())
{
Expand Down Expand Up @@ -587,11 +598,17 @@ bool protocol_bitcoind_transaction::handle_decode_psbt(const code& ec,

array_t ins{};
for (const auto& in: doc.inputs())
ins.emplace_back(decode_psbt_input(in));
{
auto entry = decode_psbt_input(in, p2kh_, p2sh_, witness_, flags_);
ins.emplace_back(std::move(entry));
}

array_t outs{};
for (const auto& out: doc.outputs())
outs.emplace_back(decode_psbt_output(out));
{
auto entry = decode_psbt_output(out, p2kh_, p2sh_, witness_, flags_);
outs.emplace_back(std::move(entry));
}

result.emplace("inputs", std::move(ins));
result.emplace("outputs", std::move(outs));
Expand Down
Loading
Loading