mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-07-05 05:02:06 +02:00
Merge bitcoin/bitcoin#23319: rpc: Return fee and prevout (utxos) to getrawtransaction
f86697163e
rpc: Return fee and prevout(s) to getrawtransaction (Douglas Chimento) Pull request description: Add fee response in BTC to getrawtransaction #23264 ### For Reviewers * Verbose arg is now an int * Verbose = 2 includes a `fee` field and `prevout` * [./test/functional/rpc_rawtransaction.py](./test/functional/rpc_rawtransaction.py) contains a new test to validate fields of new verbosity 2 (not the values) ``` bitcoin-cli -chain=test getrawtransaction 9ae533f7da9be4a34997db78343a8d8d6d6186b6bba3959e56f416a5c70e7de4 2 000000000000001d442e556146d5f2841d85150c200e8d8b8a4b5005b13878f6 ``` ``` "in_active_chain": true, "txid": "9ae533f7da9be4a34997db78343a8d8d6d6186b6bba3959e56f416a5c70e7de4", "hash": "7f23e3f3a0a256ddea1d35ffd43e9afdd67cc68389ef1a804bb20c76abd6863e", .... "vin": [ { "txid": "23fc75d6d74f6f97e225839af69ff36a612fe04db58a4414ec4828d1749a05a0", "vout": 0, "scriptSig": { "asm": "", "hex": "" }, "prevout": { "generated": false, "height": 2099486, "value": 0.00017764, "scriptPubKey": { "asm": "0 7846ce1ced3253d8bd43008db2ca364cc722f5a2", "hex": "00147846ce1ced3253d8bd43008db2ca364cc722f5a2", "address": "tb1q0prvu88dxffa302rqzxm9j3kfnrj9adzk49mlp", "type": "witness_v0_keyhash" } }, "sequence": 4294967295 }, ... "fee": 0.00000762 } ``` ACKs for top commit: achow101: ACKf86697163e
aureleoules: ACKf86697163e
hernanmarino: re ACKf86697163e
pablomartin4btc: re-tACKf86697163e
Tree-SHA512: 591fdc285d74fa7803e04ad01c7b70bc20fac6b1369e7bd5b8e2cde9b750ea52d6c70d79225b74bef4f4bbc0fb960877778017184e146119da4a55f9593d1224
This commit is contained in:
@ -14,6 +14,7 @@ Test the following RPCs:
|
||||
|
||||
from collections import OrderedDict
|
||||
from decimal import Decimal
|
||||
from itertools import product
|
||||
|
||||
from test_framework.blocktools import COINBASE_MATURITY
|
||||
from test_framework.messages import (
|
||||
@ -81,6 +82,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
self.generate(self.nodes[0], COINBASE_MATURITY + 1)
|
||||
|
||||
self.getrawtransaction_tests()
|
||||
self.getrawtransaction_verbosity_tests()
|
||||
self.createrawtransaction_tests()
|
||||
self.sendrawtransaction_tests()
|
||||
self.sendrawtransaction_testmempoolaccept_tests()
|
||||
@ -116,6 +118,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# 4. valid parameters - supply txid and 1 for verbose.
|
||||
# We only check the "hex" field of the output so we don't need to update this test every time the output format changes.
|
||||
assert_equal(self.nodes[n].getrawtransaction(txId, 1)["hex"], tx['hex'])
|
||||
assert_equal(self.nodes[n].getrawtransaction(txId, 2)["hex"], tx['hex'])
|
||||
|
||||
# 5. valid parameters - supply txid and True for non-verbose
|
||||
assert_equal(self.nodes[n].getrawtransaction(txId, True)["hex"], tx['hex'])
|
||||
@ -126,13 +129,14 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
# 6. invalid parameters - supply txid and invalid boolean values (strings) for verbose
|
||||
for value in ["True", "False"]:
|
||||
assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txid=txId, verbose=value)
|
||||
assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txid=txId, verbose=value)
|
||||
assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txid=txId, verbosity=value)
|
||||
|
||||
# 7. invalid parameters - supply txid and empty array
|
||||
assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txId, [])
|
||||
assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txId, [])
|
||||
|
||||
# 8. invalid parameters - supply txid and empty dict
|
||||
assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txId, {})
|
||||
assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txId, {})
|
||||
|
||||
# Make a tx by sending, then generate 2 blocks; block1 has the tx in it
|
||||
tx = self.wallet.send_self_transfer(from_node=self.nodes[2])['txid']
|
||||
@ -145,9 +149,10 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(gottx['in_active_chain'], True)
|
||||
if n == 0:
|
||||
self.log.info("Test getrawtransaction with -txindex, without blockhash: 'in_active_chain' should be absent")
|
||||
gottx = self.nodes[n].getrawtransaction(txid=tx, verbose=True)
|
||||
assert_equal(gottx['txid'], tx)
|
||||
assert 'in_active_chain' not in gottx
|
||||
for v in [1,2]:
|
||||
gottx = self.nodes[n].getrawtransaction(txid=tx, verbosity=v)
|
||||
assert_equal(gottx['txid'], tx)
|
||||
assert 'in_active_chain' not in gottx
|
||||
else:
|
||||
self.log.info("Test getrawtransaction without -txindex, without blockhash: expect the call to raise")
|
||||
assert_raises_rpc_error(-5, err_msg, self.nodes[n].getrawtransaction, txid=tx, verbose=True)
|
||||
@ -172,6 +177,70 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
block = self.nodes[0].getblock(self.nodes[0].getblockhash(0))
|
||||
assert_raises_rpc_error(-5, "The genesis block coinbase is not considered an ordinary transaction", self.nodes[0].getrawtransaction, block['merkleroot'])
|
||||
|
||||
def getrawtransaction_verbosity_tests(self):
|
||||
tx = self.wallet.send_self_transfer(from_node=self.nodes[1])['txid']
|
||||
[block1] = self.generate(self.nodes[1], 1)
|
||||
fields = [
|
||||
'blockhash',
|
||||
'blocktime',
|
||||
'confirmations',
|
||||
'hash',
|
||||
'hex',
|
||||
'in_active_chain',
|
||||
'locktime',
|
||||
'size',
|
||||
'time',
|
||||
'txid',
|
||||
'vin',
|
||||
'vout',
|
||||
'vsize',
|
||||
'weight',
|
||||
]
|
||||
prevout_fields = [
|
||||
'generated',
|
||||
'height',
|
||||
'value',
|
||||
'scriptPubKey',
|
||||
]
|
||||
script_pub_key_fields = [
|
||||
'address',
|
||||
'asm',
|
||||
'hex',
|
||||
'type',
|
||||
]
|
||||
# node 0 & 2 with verbosity 1 & 2
|
||||
for n, v in product([0, 2], [1, 2]):
|
||||
self.log.info(f"Test getrawtransaction_verbosity {v} {'with' if n == 0 else 'without'} -txindex, with blockhash")
|
||||
gottx = self.nodes[n].getrawtransaction(txid=tx, verbosity=v, blockhash=block1)
|
||||
missing_fields = set(fields).difference(gottx.keys())
|
||||
if missing_fields:
|
||||
raise AssertionError(f"fields {', '.join(missing_fields)} are not in transaction")
|
||||
|
||||
assert(len(gottx['vin']) > 0)
|
||||
if v == 1:
|
||||
assert('fee' not in gottx)
|
||||
assert('prevout' not in gottx['vin'][0])
|
||||
if v == 2:
|
||||
assert(isinstance(gottx['fee'], Decimal))
|
||||
assert('prevout' in gottx['vin'][0])
|
||||
prevout = gottx['vin'][0]['prevout']
|
||||
script_pub_key = prevout['scriptPubKey']
|
||||
|
||||
missing_fields = set(prevout_fields).difference(prevout.keys())
|
||||
if missing_fields:
|
||||
raise AssertionError(f"fields {', '.join(missing_fields)} are not in transaction")
|
||||
|
||||
missing_fields = set(script_pub_key_fields).difference(script_pub_key.keys())
|
||||
if missing_fields:
|
||||
raise AssertionError(f"fields {', '.join(missing_fields)} are not in transaction")
|
||||
|
||||
# check verbosity 2 without blockhash but with txindex
|
||||
assert('fee' in self.nodes[0].getrawtransaction(txid=tx, verbosity=2))
|
||||
# check that coinbase has no fee or does not throw any errors for verbosity 2
|
||||
coin_base = self.nodes[1].getblock(block1)['tx'][0]
|
||||
gottx = self.nodes[1].getrawtransaction(txid=coin_base, verbosity=2, blockhash=block1)
|
||||
assert('fee' not in gottx)
|
||||
|
||||
def createrawtransaction_tests(self):
|
||||
self.log.info("Test createrawtransaction")
|
||||
# Test `createrawtransaction` required parameters
|
||||
|
Reference in New Issue
Block a user