Skip to content

Commit 6f46f58

Browse files
laanwjknst
authored andcommitted
Merge bitcoin#22918: rpc: Add level 3 verbosity to getblock RPC call (bitcoin#21245 modified)
5c34507 core_write: Rename calculate_fee to have_undo for clarity (fyquah) 8edf620 release-notes: Add release note about getblock verbosity level 3. (fyquah) 459104b rest: Add test for prevout fields in getblock (fyquah) 4330af6 rpc: Add test for level 3 verbosity getblock rpc call. (fyquah) 51dbc16 rpc: Add level 3 verbosity to getblock RPC call. (fyquah) 3cc9534 rpc: Replace boolean argument for tx details with enum class. (fyquah) Pull request description: Author of bitcoin#21245 expressed [time issues](bitcoin#21245 (comment)) in the original PR. Given that bitcoin#21245 has received a lot of review*, I have decided to open this new pull request with [modifications required to get ACK from luke-jr ](bitcoin#21245 (comment)) and a few nits of mine. ### Original PR description > Display the prevout in transaction inputs when calling getblock level 3 verbosity. This PR affects the existing `/rest/block` API by adding a `prevout` fields to tx inputs. This is mentioned in the change to the release notes. > > I added some functional tests that > > * checks that the RPC call still works when TxUndo can't be found > > * Doesn't display the "value" or "scriptPubKey" of the previous output when at a lower verbosity level > > > This "completes" the issue bitcoin#18771 ### Possible improvements * kiminuo@b0bf4f2 - I can include even this commit to this PR if deemed useful or I can leave it for a follow-up PR. See bitcoin#21245 (comment) for more context. ### Examples Examples of the `getblock` output with various verbose levels. Note that `000000000000001f682b188971cc1a121546be4e9d5baf22934fdc7f538288d5` contains only 2 transactions. #### Verbose level 0 ```bash ./bitcoin-cli -testnet getblock 000000000000001f682b188971cc1a121546be4e9d5baf22934fdc7f538288d5 0 ``` ##### Verbose level 1 ```bash ./bitcoin-cli -testnet getblock 000000000000001f682b188971cc1a121546be4e9d5baf22934fdc7f538288d5 1 ``` ##### Verbose level 2 ```bash ./bitcoin-cli -testnet getblock 000000000000001f682b188971cc1a121546be4e9d5baf22934fdc7f538288d5 2 ``` ##### Verbose level 3 ```bash ./bitcoin-cli -testnet getblock 000000000000001f682b188971cc1a121546be4e9d5baf22934fdc7f538288d5 3 ``` #### REST ```bash curl -H "content-type:text/plain;" http://127.0.0.1:18332/rest/block/000000000000001f682b188971cc1a121546be4e9d5baf22934fdc7f538288d5.json ``` <sub>* ... and my everyday obsessive checking of my email inbox whether the PR moves forward.</sub> Edit laanwj: Removed at symbol from message, and large example output to prevent it from all ending up in the commit message. ACKs for top commit: 0xB10C: ACK 5c34507 meshcollider: utACK 5c34507 theStack: ACK 5c34507 👘 promag: Concept ACK 5c34507 Tree-SHA512: bbff120d8fd76e617b723b102b0c606e0d8eb27f21c631d5f4cdab0892137c4bc7c65b1df144993405f942c91be47a26e80480102af55bff22621c19f518aea3
1 parent 4e8f6af commit 6f46f58

File tree

10 files changed

+153
-49
lines changed

10 files changed

+153
-49
lines changed

doc/release-notes-22918.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Updated RPCs
2+
3+
- The `getblock` RPC command now supports verbose level 3 containing transaction inputs
4+
`prevout` information. The existing `/rest/block/` REST endpoint is modified to contain
5+
this information too. Every `vin` field will contain an additional `prevout` subfield
6+
describing the spent output. `prevout` contains the following keys:
7+
- `generated` - true if the spent coins was a coinbase.
8+
- `height`
9+
- `value`
10+
- `scriptPubKey`
11+

src/bench/rpc_blockchain.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static void BlockToJsonVerbose(benchmark::Bench& bench)
4545
TestBlockAndIndex data;
4646
const LLMQContext& llmq_ctx = *data.testing_setup->m_node.llmq_ctx;
4747
bench.run([&] {
48-
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, &data.blockindex, &data.blockindex, *llmq_ctx.clhandler, *llmq_ctx.isman, /*verbose*/ true);
48+
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, &data.blockindex, &data.blockindex, *llmq_ctx.clhandler, *llmq_ctx.isman, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
4949
ankerl::nanobench::doNotOptimizeAway(univalue);
5050
});
5151
}
@@ -56,7 +56,7 @@ static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
5656
{
5757
TestBlockAndIndex data;
5858
const LLMQContext& llmq_ctx = *data.testing_setup->m_node.llmq_ctx;
59-
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, &data.blockindex, &data.blockindex, *llmq_ctx.clhandler, *llmq_ctx.isman, /*verbose*/ true);
59+
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, &data.blockindex, &data.blockindex, *llmq_ctx.clhandler, *llmq_ctx.isman, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
6060
bench.run([&] {
6161
auto str = univalue.write();
6262
ankerl::nanobench::doNotOptimizeAway(str);

src/core_io.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ class CTxUndo;
2222

2323
struct CSpentIndexTxInfo;
2424

25+
/**
26+
* Verbose level for block's transaction
27+
*/
28+
enum class TxVerbosity {
29+
SHOW_TXID, //!< Only TXID for each block's transaction
30+
SHOW_DETAILS, //!< Include TXID, inputs, outputs, and other common block's transaction information
31+
SHOW_DETAILS_AND_PREVOUT //!< The same as previous option with information about prevouts if available
32+
};
33+
2534
// core_read.cpp
2635
CScript ParseScript(const std::string& s);
2736
std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false);
@@ -47,6 +56,6 @@ std::string EncodeHexTx(const CTransaction& tx);
4756
std::string SighashToStr(unsigned char sighash_type);
4857
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool include_hex, bool include_address = true);
4958
void ScriptToUniv(const CScript& script, UniValue& out);
50-
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr, const CSpentIndexTxInfo* ptxSpentInfo = nullptr);
59+
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, const CSpentIndexTxInfo* ptxSpentInfo = nullptr);
5160

5261
#endif // BITCOIN_CORE_IO_H

src/core_write.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool include
173173
out.pushKV("type", GetTxnOutputType(type));
174174
}
175175

176-
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo, const CSpentIndexTxInfo* ptxSpentInfo)
176+
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo, TxVerbosity verbosity, const CSpentIndexTxInfo* ptxSpentInfo)
177177
{
178178
uint256 txid = tx.GetHash();
179179
entry.pushKV("txid", txid.GetHex());
@@ -188,7 +188,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
188188

189189
// If available, use Undo data to calculate the fee. Note that txundo == nullptr
190190
// for coinbase transactions and for transactions where undo data is unavailable.
191-
const bool calculate_fee = txundo != nullptr;
191+
const bool have_undo = txundo != nullptr;
192192
CAmount amt_total_in = 0;
193193
CAmount amt_total_out = 0;
194194

@@ -221,9 +221,28 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
221221
}
222222
}
223223
}
224-
if (calculate_fee) {
225-
const CTxOut& prev_txout = txundo->vprevout[i].out;
224+
if (have_undo) {
225+
const Coin& prev_coin = txundo->vprevout[i];
226+
const CTxOut& prev_txout = prev_coin.out;
227+
226228
amt_total_in += prev_txout.nValue;
229+
switch (verbosity) {
230+
case TxVerbosity::SHOW_TXID:
231+
case TxVerbosity::SHOW_DETAILS:
232+
break;
233+
234+
case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
235+
UniValue o_script_pub_key(UniValue::VOBJ);
236+
ScriptPubKeyToUniv(prev_txout.scriptPubKey, o_script_pub_key, /* includeHex */ true, /*include_address=*/true);
237+
238+
UniValue p(UniValue::VOBJ);
239+
p.pushKV("generated", bool(prev_coin.fCoinBase));
240+
p.pushKV("height", uint64_t(prev_coin.nHeight));
241+
p.pushKV("value", ValueFromAmount(prev_txout.nValue));
242+
p.pushKV("scriptPubKey", o_script_pub_key);
243+
in.pushKV("prevout", p);
244+
break;
245+
}
227246
}
228247
in.pushKV("sequence", (int64_t)txin.nSequence);
229248
vin.push_back(in);
@@ -257,7 +276,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
257276
}
258277
vout.push_back(out);
259278

260-
if (calculate_fee) {
279+
if (have_undo) {
261280
amt_total_out += txout.nValue;
262281
}
263282
}
@@ -306,7 +325,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
306325
}
307326
}
308327

309-
if (calculate_fee) {
328+
if (have_undo) {
310329
CAmount fee = amt_total_in - amt_total_out;
311330
if (tx.IsPlatformTransfer()) {
312331
auto payload = GetTxPayload<CAssetUnlockPayload>(tx);

src/rest.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ static bool rest_headers(const CoreContext& context,
289289
static bool rest_block(const CoreContext& context,
290290
HTTPRequest* req,
291291
const std::string& strURIPart,
292-
bool showTxDetails)
292+
TxVerbosity tx_verbosity)
293293
{
294294
if (!CheckWarmup(req))
295295
return false;
@@ -344,7 +344,7 @@ static bool rest_block(const CoreContext& context,
344344
const LLMQContext* llmq_ctx = GetLLMQContext(context, req);
345345
if (!llmq_ctx) return false;
346346

347-
UniValue objBlock = blockToJSON(chainman.m_blockman, block, tip, pblockindex, *llmq_ctx->clhandler, *llmq_ctx->isman, showTxDetails);
347+
UniValue objBlock = blockToJSON(chainman.m_blockman, block, tip, pblockindex, *llmq_ctx->clhandler, *llmq_ctx->isman, tx_verbosity);
348348
std::string strJSON = objBlock.write() + "\n";
349349
req->WriteHeader("Content-Type", "application/json");
350350
req->WriteReply(HTTP_OK, strJSON);
@@ -359,12 +359,12 @@ static bool rest_block(const CoreContext& context,
359359

360360
static bool rest_block_extended(const CoreContext& context, HTTPRequest* req, const std::string& strURIPart)
361361
{
362-
return rest_block(context, req, strURIPart, true);
362+
return rest_block(context, req, strURIPart, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
363363
}
364364

365365
static bool rest_block_notxdetails(const CoreContext& context, HTTPRequest* req, const std::string& strURIPart)
366366
{
367-
return rest_block(context, req, strURIPart, false);
367+
return rest_block(context, req, strURIPart, TxVerbosity::SHOW_TXID);
368368
}
369369

370370
static bool rest_filter_header(const CoreContext& context, HTTPRequest* req, const std::string& strURIPart)

src/rpc/blockchain.cpp

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -155,31 +155,36 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
155155
return result;
156156
}
157157

158-
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, const llmq::CChainLocksHandler& clhandler, const llmq::CInstantSendManager& isman, bool txDetails)
158+
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, const llmq::CChainLocksHandler& clhandler, const llmq::CInstantSendManager& isman, TxVerbosity verbosity)
159159
{
160160
UniValue result = blockheaderToJSON(tip, blockindex, clhandler);
161161

162162
result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION));
163163
UniValue txs(UniValue::VARR);
164-
if (txDetails) {
165-
CBlockUndo blockUndo;
166-
const bool have_undo{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex) && UndoReadFromDisk(blockUndo, blockindex))};
167-
for (size_t i = 0; i < block.vtx.size(); ++i) {
168-
const CTransactionRef& tx = block.vtx.at(i);
169-
// coinbase transaction (i == 0) doesn't have undo data
170-
const CTxUndo* txundo = (have_undo && i) ? &blockUndo.vtxundo.at(i - 1) : nullptr;
171-
UniValue objTx(UniValue::VOBJ);
172-
TxToUniv(*tx, uint256(), objTx, true, 0, txundo);
173-
bool fLocked = isman.IsLocked(tx->GetHash());
174-
objTx.pushKV("instantlock", fLocked || result["chainlock"].get_bool());
175-
objTx.pushKV("instantlock_internal", fLocked);
176-
txs.push_back(objTx);
177-
}
178-
} else {
179-
for (const CTransactionRef& tx : block.vtx) {
180-
txs.push_back(tx->GetHash().GetHex());
181-
}
164+
switch (verbosity) {
165+
case TxVerbosity::SHOW_TXID:
166+
for (const CTransactionRef& tx : block.vtx) {
167+
txs.push_back(tx->GetHash().GetHex());
168+
}
169+
break;
170+
case TxVerbosity::SHOW_DETAILS:
171+
case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
172+
CBlockUndo blockUndo;
173+
const bool have_undo{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex) && UndoReadFromDisk(blockUndo, blockindex))};
174+
175+
for (size_t i = 0; i < block.vtx.size(); ++i) {
176+
const CTransactionRef& tx = block.vtx.at(i);
177+
// coinbase transaction (i.e. i == 0) doesn't have undo data
178+
const CTxUndo* txundo = (have_undo && i > 0) ? &blockUndo.vtxundo.at(i - 1) : nullptr;
179+
UniValue objTx(UniValue::VOBJ);
180+
TxToUniv(*tx, uint256(), objTx, true, 0, txundo, verbosity);
181+
bool fLocked = isman.IsLocked(tx->GetHash());
182+
objTx.pushKV("instantlock", fLocked || result["chainlock"].get_bool());
183+
objTx.pushKV("instantlock_internal", fLocked);
184+
txs.push_back(objTx);
185+
}
182186
}
187+
183188
result.pushKV("tx", txs);
184189
if (!block.vtx[0]->vExtraPayload.empty()) {
185190
if (const auto opt_cbTx = GetTxPayload<CCbTx>(block.vtx[0]->vExtraPayload)) {
@@ -872,7 +877,8 @@ static RPCHelpMan getblock()
872877
return RPCHelpMan{"getblock",
873878
"\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
874879
"If verbosity is 1, returns an Object with information about block <hash>.\n"
875-
"If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n",
880+
"If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.\n"
881+
"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",
876882
{
877883
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
878884
{"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"},
@@ -968,7 +974,16 @@ static RPCHelpMan getblock()
968974
}
969975

970976
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
971-
return blockToJSON(chainman.m_blockman, block, tip, pblockindex, *llmq_ctx.clhandler, *llmq_ctx.isman, verbosity >= 2);
977+
TxVerbosity tx_verbosity;
978+
if (verbosity == 1) {
979+
tx_verbosity = TxVerbosity::SHOW_TXID;
980+
} else if (verbosity == 2) {
981+
tx_verbosity = TxVerbosity::SHOW_DETAILS;
982+
} else {
983+
tx_verbosity = TxVerbosity::SHOW_DETAILS_AND_PREVOUT;
984+
}
985+
986+
return blockToJSON(chainman.m_blockman, block, tip, pblockindex, *llmq_ctx.clhandler, *llmq_ctx.isman, tx_verbosity);
972987
},
973988
};
974989
}

src/rpc/blockchain.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_RPC_BLOCKCHAIN_H
77

88
#include <consensus/amount.h>
9+
#include <core_io.h>
910
#include <fs.h>
1011
#include <streams.h>
1112
#include <sync.h>
@@ -40,7 +41,7 @@ double GetDifficulty(const CBlockIndex* blockindex);
4041
void RPCNotifyBlockChange(const CBlockIndex*);
4142

4243
/** Block description to JSON */
43-
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, const llmq::CChainLocksHandler& clhandler, const llmq::CInstantSendManager& isman, bool txDetails = false) LOCKS_EXCLUDED(cs_main);
44+
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, const llmq::CChainLocksHandler& clhandler, const llmq::CInstantSendManager& isman, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
4445

4546
/** Block header to JSON */
4647
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex, const llmq::CChainLocksHandler& clhandler) LOCKS_EXCLUDED(cs_main);

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, const CTxMemPool
9696
txSpentInfoPtr = &txSpentInfo;
9797
}
9898

99-
TxToUniv(tx, uint256(), entry, true, 0, /* txundo = */ nullptr, txSpentInfoPtr);
99+
TxToUniv(tx, uint256(), entry, true, 0, /* txundo = */ nullptr, TxVerbosity::SHOW_DETAILS, txSpentInfoPtr);
100100

101101
bool chainLock = false;
102102
if (!hashBlock.IsNull()) {

test/functional/interface_rest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,15 @@ def run_test(self):
337337
if 'coinbase' not in tx['vin'][0]}
338338
assert_equal(non_coinbase_txs, set(txs))
339339

340+
# Verify that the non-coinbase tx has "prevout" key set
341+
for tx_obj in json_obj["tx"]:
342+
for vin in tx_obj["vin"]:
343+
if "coinbase" not in vin:
344+
assert "prevout" in vin
345+
assert_equal(vin["prevout"]["generated"], False)
346+
else:
347+
assert "prevout" not in vin
348+
340349
# Check the same but without tx details
341350
json_obj = self.test_rest_request(f"/block/notxdetails/{newblockhash[0]}")
342351
for tx in txs:

test/functional/rpc_blockchain.py

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -485,17 +485,55 @@ def _test_getblock(self):
485485
miniwallet.send_self_transfer(fee_rate=fee_per_kb, from_node=node)
486486
blockhash = self.generate(node, 1)[0]
487487

488-
self.log.info("Test getblock with verbosity 1 doesn't include fee")
489-
block = node.getblock(blockhash, 1)
490-
assert 'fee' not in block['tx'][1]
491-
492-
self.log.info('Test getblock with verbosity 2 includes expected fee')
493-
block = node.getblock(blockhash, 2)
494-
tx = block['tx'][1]
495-
assert 'fee' in tx
496-
assert_equal(tx['fee'], tx['size'] * fee_per_byte)
497-
498-
self.log.info("Test getblock with verbosity 2 still works with pruned Undo data")
488+
def assert_fee_not_in_block(verbosity):
489+
block = node.getblock(blockhash, verbosity)
490+
assert 'fee' not in block['tx'][1]
491+
492+
def assert_fee_in_block(verbosity):
493+
block = node.getblock(blockhash, verbosity)
494+
tx = block['tx'][1]
495+
assert 'fee' in tx
496+
assert_equal(tx['fee'], tx['size'] * fee_per_byte)
497+
498+
def assert_vin_contains_prevout(verbosity):
499+
block = node.getblock(blockhash, verbosity)
500+
tx = block["tx"][1]
501+
total_vin = Decimal("0.00000000")
502+
total_vout = Decimal("0.00000000")
503+
for vin in tx["vin"]:
504+
assert "prevout" in vin
505+
assert_equal(set(vin["prevout"].keys()), set(("value", "height", "generated", "scriptPubKey")))
506+
assert_equal(vin["prevout"]["generated"], True)
507+
total_vin += vin["prevout"]["value"]
508+
for vout in tx["vout"]:
509+
total_vout += vout["value"]
510+
assert_equal(total_vin, total_vout + tx["fee"])
511+
512+
def assert_vin_does_not_contain_prevout(verbosity):
513+
block = node.getblock(blockhash, verbosity)
514+
tx = block["tx"][1]
515+
if isinstance(tx, str):
516+
# In verbosity level 1, only the transaction hashes are written
517+
pass
518+
else:
519+
for vin in tx["vin"]:
520+
assert "prevout" not in vin
521+
522+
self.log.info("Test that getblock with verbosity 1 doesn't include fee")
523+
assert_fee_not_in_block(1)
524+
525+
self.log.info('Test that getblock with verbosity 2 and 3 includes expected fee')
526+
assert_fee_in_block(2)
527+
assert_fee_in_block(3)
528+
529+
self.log.info("Test that getblock with verbosity 1 and 2 does not include prevout")
530+
assert_vin_does_not_contain_prevout(1)
531+
assert_vin_does_not_contain_prevout(2)
532+
533+
self.log.info("Test that getblock with verbosity 3 includes prevout")
534+
assert_vin_contains_prevout(3)
535+
536+
self.log.info("Test that getblock with verbosity 2 and 3 still works with pruned Undo data")
499537
datadir = get_datadir_path(self.options.tmpdir, 0)
500538

501539
self.log.info("Test that getblock with invalid verbosity type returns proper error message")
@@ -509,8 +547,10 @@ def move_block_file(old, new):
509547
# Move instead of deleting so we can restore chain state afterwards
510548
move_block_file('rev00000.dat', 'rev_wrong')
511549

512-
block = node.getblock(blockhash, 2)
513-
assert 'fee' not in block['tx'][1]
550+
assert_fee_not_in_block(2)
551+
assert_fee_not_in_block(3)
552+
assert_vin_does_not_contain_prevout(2)
553+
assert_vin_does_not_contain_prevout(3)
514554

515555
# Restore chain state
516556
move_block_file('rev_wrong', 'rev00000.dat')

0 commit comments

Comments
 (0)