mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
rpc: Add level 3 verbosity to getblock RPC call.
Display the prevout in transaction inputs when calling getblock level 3 verbosity. Co-authored-by: Luke Dashjr <luke_github1@dashjr.org> Co-authored-by: 0xB10C <19157360+0xB10C@users.noreply.github.com>
This commit is contained in:
parent
3cc95345ca
commit
51dbc167e9
6 changed files with 37 additions and 12 deletions
|
@ -40,7 +40,7 @@ static void BlockToJsonVerbose(benchmark::Bench& bench)
|
||||||
{
|
{
|
||||||
TestBlockAndIndex data;
|
TestBlockAndIndex data;
|
||||||
bench.run([&] {
|
bench.run([&] {
|
||||||
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, TxVerbosity::SHOW_DETAILS);
|
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
|
||||||
ankerl::nanobench::doNotOptimizeAway(univalue);
|
ankerl::nanobench::doNotOptimizeAway(univalue);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ BENCHMARK(BlockToJsonVerbose);
|
||||||
static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
|
static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
|
||||||
{
|
{
|
||||||
TestBlockAndIndex data;
|
TestBlockAndIndex data;
|
||||||
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, TxVerbosity::SHOW_DETAILS);
|
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
|
||||||
bench.run([&] {
|
bench.run([&] {
|
||||||
auto str = univalue.write();
|
auto str = univalue.write();
|
||||||
ankerl::nanobench::doNotOptimizeAway(str);
|
ankerl::nanobench::doNotOptimizeAway(str);
|
||||||
|
|
|
@ -25,7 +25,8 @@ class CTxUndo;
|
||||||
*/
|
*/
|
||||||
enum class TxVerbosity {
|
enum class TxVerbosity {
|
||||||
SHOW_TXID, //!< Only TXID for each block's transaction
|
SHOW_TXID, //!< Only TXID for each block's transaction
|
||||||
SHOW_DETAILS //!< Include TXID, inputs, outputs, and other common block's transaction information
|
SHOW_DETAILS, //!< Include TXID, inputs, outputs, and other common block's transaction information
|
||||||
|
SHOW_DETAILS_AND_PREVOUT //!< The same as previous option with information about prevouts if available
|
||||||
};
|
};
|
||||||
|
|
||||||
// core_read.cpp
|
// core_read.cpp
|
||||||
|
@ -54,6 +55,6 @@ std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0);
|
||||||
std::string SighashToStr(unsigned char sighash_type);
|
std::string SighashToStr(unsigned char sighash_type);
|
||||||
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool include_hex, bool include_address = true);
|
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool include_hex, bool include_address = true);
|
||||||
void ScriptToUniv(const CScript& script, UniValue& out);
|
void ScriptToUniv(const CScript& script, UniValue& out);
|
||||||
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr);
|
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS);
|
||||||
|
|
||||||
#endif // BITCOIN_CORE_IO_H
|
#endif // BITCOIN_CORE_IO_H
|
||||||
|
|
|
@ -163,7 +163,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool include
|
||||||
out.pushKV("type", GetTxnOutputType(type));
|
out.pushKV("type", GetTxnOutputType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo)
|
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo, TxVerbosity verbosity)
|
||||||
{
|
{
|
||||||
entry.pushKV("txid", tx.GetHash().GetHex());
|
entry.pushKV("txid", tx.GetHash().GetHex());
|
||||||
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
|
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
|
||||||
|
@ -204,8 +204,27 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
|
||||||
in.pushKV("txinwitness", txinwitness);
|
in.pushKV("txinwitness", txinwitness);
|
||||||
}
|
}
|
||||||
if (calculate_fee) {
|
if (calculate_fee) {
|
||||||
const CTxOut& prev_txout = txundo->vprevout[i].out;
|
const Coin& prev_coin = txundo->vprevout[i];
|
||||||
|
const CTxOut& prev_txout = prev_coin.out;
|
||||||
|
|
||||||
amt_total_in += prev_txout.nValue;
|
amt_total_in += prev_txout.nValue;
|
||||||
|
switch (verbosity) {
|
||||||
|
case TxVerbosity::SHOW_TXID:
|
||||||
|
case TxVerbosity::SHOW_DETAILS:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
|
||||||
|
UniValue o_script_pub_key(UniValue::VOBJ);
|
||||||
|
ScriptPubKeyToUniv(prev_txout.scriptPubKey, o_script_pub_key, /* includeHex */ true);
|
||||||
|
|
||||||
|
UniValue p(UniValue::VOBJ);
|
||||||
|
p.pushKV("generated", bool(prev_coin.fCoinBase));
|
||||||
|
p.pushKV("height", uint64_t(prev_coin.nHeight));
|
||||||
|
p.pushKV("value", ValueFromAmount(prev_txout.nValue));
|
||||||
|
p.pushKV("scriptPubKey", o_script_pub_key);
|
||||||
|
in.pushKV("prevout", p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
in.pushKV("sequence", (int64_t)txin.nSequence);
|
in.pushKV("sequence", (int64_t)txin.nSequence);
|
||||||
vin.push_back(in);
|
vin.push_back(in);
|
||||||
|
|
|
@ -327,7 +327,7 @@ static bool rest_block(const std::any& context,
|
||||||
|
|
||||||
static bool rest_block_extended(const std::any& context, HTTPRequest* req, const std::string& strURIPart)
|
static bool rest_block_extended(const std::any& context, HTTPRequest* req, const std::string& strURIPart)
|
||||||
{
|
{
|
||||||
return rest_block(context, req, strURIPart, TxVerbosity::SHOW_DETAILS);
|
return rest_block(context, req, strURIPart, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rest_block_notxdetails(const std::any& context, HTTPRequest* req, const std::string& strURIPart)
|
static bool rest_block_notxdetails(const std::any& context, HTTPRequest* req, const std::string& strURIPart)
|
||||||
|
|
|
@ -217,15 +217,16 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TxVerbosity::SHOW_DETAILS:
|
case TxVerbosity::SHOW_DETAILS:
|
||||||
|
case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
|
||||||
CBlockUndo blockUndo;
|
CBlockUndo blockUndo;
|
||||||
const bool have_undo = !IsBlockPruned(blockindex) && UndoReadFromDisk(blockUndo, blockindex);
|
const bool have_undo = !IsBlockPruned(blockindex) && UndoReadFromDisk(blockUndo, blockindex);
|
||||||
|
|
||||||
for (size_t i = 0; i < block.vtx.size(); ++i) {
|
for (size_t i = 0; i < block.vtx.size(); ++i) {
|
||||||
const CTransactionRef& tx = block.vtx.at(i);
|
const CTransactionRef& tx = block.vtx.at(i);
|
||||||
// coinbase transaction (i.e. i == 0) doesn't have undo data
|
// coinbase transaction (i.e. i == 0) doesn't have undo data
|
||||||
const CTxUndo* txundo = (have_undo && i) ? &blockUndo.vtxundo.at(i - 1) : nullptr;
|
const CTxUndo* txundo = (have_undo && i > 0) ? &blockUndo.vtxundo.at(i - 1) : nullptr;
|
||||||
UniValue objTx(UniValue::VOBJ);
|
UniValue objTx(UniValue::VOBJ);
|
||||||
TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags(), txundo);
|
TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags(), txundo, verbosity);
|
||||||
txs.push_back(objTx);
|
txs.push_back(objTx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -937,7 +938,8 @@ static RPCHelpMan getblock()
|
||||||
return RPCHelpMan{"getblock",
|
return RPCHelpMan{"getblock",
|
||||||
"\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
|
"\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
|
||||||
"If verbosity is 1, returns an Object with information about block <hash>.\n"
|
"If verbosity is 1, returns an Object with information about block <hash>.\n"
|
||||||
"If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.\n",
|
"If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.\n"
|
||||||
|
"If verbosity is 3, returns an Object with information about block <hash> and information about each transaction, including prevout information for inputs (only for unpruned blocks in the current best chain).\n",
|
||||||
{
|
{
|
||||||
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
|
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
|
||||||
{"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{1}, "0 for hex-encoded data, 1 for a json object, and 2 for json object with transaction data"},
|
{"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{1}, "0 for hex-encoded data, 1 for a json object, and 2 for json object with transaction data"},
|
||||||
|
@ -1027,8 +1029,10 @@ static RPCHelpMan getblock()
|
||||||
TxVerbosity tx_verbosity;
|
TxVerbosity tx_verbosity;
|
||||||
if (verbosity == 1) {
|
if (verbosity == 1) {
|
||||||
tx_verbosity = TxVerbosity::SHOW_TXID;
|
tx_verbosity = TxVerbosity::SHOW_TXID;
|
||||||
} else {
|
} else if (verbosity == 2) {
|
||||||
tx_verbosity = TxVerbosity::SHOW_DETAILS;
|
tx_verbosity = TxVerbosity::SHOW_DETAILS;
|
||||||
|
} else {
|
||||||
|
tx_verbosity = TxVerbosity::SHOW_DETAILS_AND_PREVOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return blockToJSON(block, tip, pblockindex, tx_verbosity);
|
return blockToJSON(block, tip, pblockindex, tx_verbosity);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define BITCOIN_RPC_BLOCKCHAIN_H
|
#define BITCOIN_RPC_BLOCKCHAIN_H
|
||||||
|
|
||||||
#include <consensus/amount.h>
|
#include <consensus/amount.h>
|
||||||
|
#include <core_io.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ double GetDifficulty(const CBlockIndex* blockindex);
|
||||||
void RPCNotifyBlockChange(const CBlockIndex*);
|
void RPCNotifyBlockChange(const CBlockIndex*);
|
||||||
|
|
||||||
/** Block description to JSON */
|
/** Block description to JSON */
|
||||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, TxVerbosity verbosity = TxVerbosity::SHOW_TXID) LOCKS_EXCLUDED(cs_main);
|
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
|
||||||
|
|
||||||
/** Mempool information to JSON */
|
/** Mempool information to JSON */
|
||||||
UniValue MempoolInfoToJSON(const CTxMemPool& pool);
|
UniValue MempoolInfoToJSON(const CTxMemPool& pool);
|
||||||
|
|
Loading…
Add table
Reference in a new issue