mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-05 10:42:13 +02:00
Merge bitcoin/bitcoin#22918: rpc: Add level 3 verbosity to getblock RPC call (#21245 modified)
5c34507ecbcore_write: Rename calculate_fee to have_undo for clarity (fyquah)8edf6204a8release-notes: Add release note about getblock verbosity level 3. (fyquah)459104b2aarest: Add test for prevout fields in getblock (fyquah)4330af6f72rpc: Add test for level 3 verbosity getblock rpc call. (fyquah)51dbc167e9rpc: Add level 3 verbosity to getblock RPC call. (fyquah)3cc95345carpc: Replace boolean argument for tx details with enum class. (fyquah) Pull request description: Author of #21245 expressed [time issues](https://github.com/bitcoin/bitcoin/pull/21245#issuecomment-902332088) in the original PR. Given that #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 ](https://github.com/bitcoin/bitcoin/pull/21245#issuecomment-905150806) 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 #18771 ### Possible improvements *b0bf4f255f- I can include even this commit to this PR if deemed useful or I can leave it for a follow-up PR. See https://github.com/bitcoin/bitcoin/pull/21245#issuecomment-894853784 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: ACK5c34507ecbmeshcollider: utACK5c34507ecbtheStack: ACK5c34507ecb👘 promag: Concept ACK5c34507ecbTree-SHA512: bbff120d8fd76e617b723b102b0c606e0d8eb27f21c631d5f4cdab0892137c4bc7c65b1df144993405f942c91be47a26e80480102af55bff22621c19f518aea3
This commit is contained in:
@@ -318,6 +318,15 @@ class RESTTest (BitcoinTestFramework):
|
||||
if 'coinbase' not in tx['vin'][0]}
|
||||
assert_equal(non_coinbase_txs, set(txs))
|
||||
|
||||
# Verify that the non-coinbase tx has "prevout" key set
|
||||
for tx_obj in json_obj["tx"]:
|
||||
for vin in tx_obj["vin"]:
|
||||
if "coinbase" not in vin:
|
||||
assert "prevout" in vin
|
||||
assert_equal(vin["prevout"]["generated"], False)
|
||||
else:
|
||||
assert "prevout" not in vin
|
||||
|
||||
# Check the same but without tx details
|
||||
json_obj = self.test_rest_request(f"/block/notxdetails/{newblockhash[0]}")
|
||||
for tx in txs:
|
||||
|
||||
@@ -434,17 +434,55 @@ class BlockchainTest(BitcoinTestFramework):
|
||||
miniwallet.send_self_transfer(fee_rate=fee_per_kb, from_node=node)
|
||||
blockhash = self.generate(node, 1)[0]
|
||||
|
||||
self.log.info("Test getblock with verbosity 1 doesn't include fee")
|
||||
block = node.getblock(blockhash, 1)
|
||||
assert 'fee' not in block['tx'][1]
|
||||
def assert_fee_not_in_block(verbosity):
|
||||
block = node.getblock(blockhash, verbosity)
|
||||
assert 'fee' not in block['tx'][1]
|
||||
|
||||
self.log.info('Test getblock with verbosity 2 includes expected fee')
|
||||
block = node.getblock(blockhash, 2)
|
||||
tx = block['tx'][1]
|
||||
assert 'fee' in tx
|
||||
assert_equal(tx['fee'], tx['vsize'] * fee_per_byte)
|
||||
def assert_fee_in_block(verbosity):
|
||||
block = node.getblock(blockhash, verbosity)
|
||||
tx = block['tx'][1]
|
||||
assert 'fee' in tx
|
||||
assert_equal(tx['fee'], tx['vsize'] * fee_per_byte)
|
||||
|
||||
self.log.info("Test getblock with verbosity 2 still works with pruned Undo data")
|
||||
def assert_vin_contains_prevout(verbosity):
|
||||
block = node.getblock(blockhash, verbosity)
|
||||
tx = block["tx"][1]
|
||||
total_vin = Decimal("0.00000000")
|
||||
total_vout = Decimal("0.00000000")
|
||||
for vin in tx["vin"]:
|
||||
assert "prevout" in vin
|
||||
assert_equal(set(vin["prevout"].keys()), set(("value", "height", "generated", "scriptPubKey")))
|
||||
assert_equal(vin["prevout"]["generated"], True)
|
||||
total_vin += vin["prevout"]["value"]
|
||||
for vout in tx["vout"]:
|
||||
total_vout += vout["value"]
|
||||
assert_equal(total_vin, total_vout + tx["fee"])
|
||||
|
||||
def assert_vin_does_not_contain_prevout(verbosity):
|
||||
block = node.getblock(blockhash, verbosity)
|
||||
tx = block["tx"][1]
|
||||
if isinstance(tx, str):
|
||||
# In verbosity level 1, only the transaction hashes are written
|
||||
pass
|
||||
else:
|
||||
for vin in tx["vin"]:
|
||||
assert "prevout" not in vin
|
||||
|
||||
self.log.info("Test that getblock with verbosity 1 doesn't include fee")
|
||||
assert_fee_not_in_block(1)
|
||||
|
||||
self.log.info('Test that getblock with verbosity 2 and 3 includes expected fee')
|
||||
assert_fee_in_block(2)
|
||||
assert_fee_in_block(3)
|
||||
|
||||
self.log.info("Test that getblock with verbosity 1 and 2 does not include prevout")
|
||||
assert_vin_does_not_contain_prevout(1)
|
||||
assert_vin_does_not_contain_prevout(2)
|
||||
|
||||
self.log.info("Test that getblock with verbosity 3 includes prevout")
|
||||
assert_vin_contains_prevout(3)
|
||||
|
||||
self.log.info("Test that getblock with verbosity 2 and 3 still works with pruned Undo data")
|
||||
datadir = get_datadir_path(self.options.tmpdir, 0)
|
||||
|
||||
self.log.info("Test getblock with invalid verbosity type returns proper error message")
|
||||
@@ -458,8 +496,10 @@ class BlockchainTest(BitcoinTestFramework):
|
||||
# Move instead of deleting so we can restore chain state afterwards
|
||||
move_block_file('rev00000.dat', 'rev_wrong')
|
||||
|
||||
block = node.getblock(blockhash, 2)
|
||||
assert 'fee' not in block['tx'][1]
|
||||
assert_fee_not_in_block(2)
|
||||
assert_fee_not_in_block(3)
|
||||
assert_vin_does_not_contain_prevout(2)
|
||||
assert_vin_does_not_contain_prevout(3)
|
||||
|
||||
# Restore chain state
|
||||
move_block_file('rev_wrong', 'rev00000.dat')
|
||||
|
||||
Reference in New Issue
Block a user