Merge bitcoin/bitcoin#36251: rest: add `generated` and `height` to spenttxouts JSON
What changed, and why it matters
This change adds two extra pieces of information—whether a spent output came from a coinbase transaction and the block height at which it was created—to a Bitcoin Core REST API endpoint. It is a feature/parity improvement to make the REST output match an existing RPC output. There is no indication it fixes a security bug or introduces a vulnerability.
No security action required. Treat as a normal feature/documentation update during review or deployment.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit extends the /rest/spenttxouts/BLOCKHASH.json endpoint to include generated (coinbase flag) and height fields for each previous output, aligning it with the prevout objects returned by getblock RPC verbosity 3. The data already existed internally in the Coin object and is now simply serialized into the JSON response. Binary and hex formats are intentionally left unchanged for backwards compatibility. Tests are updated to compare the REST JSON output directly against the RPC output.
Changed components
src/rest.cpp/rest/spenttxouts/BLOCKHASH.json REST endpointdoc/REST-interface.mddoc/release-notes-36251.mdtest/functional/interface_rest.pyInspect captured patch +13 / −5
### doc/REST-interface.md
@@ -97,6 +97,7 @@ Responds with 404 if block not found.
Given a block hash: returns a collection of spent transaction output lists,
one per transaction in the block.
Responds with 404 if the block doesn't exist or its undo data is not available.
+The JSON format matches the prevout objects of the `getblock` RPC with verbosity 3.
#### Chaininfos
`GET /rest/chaininfo.json`
### doc/release-notes-36251.md
@@ -0,0 +1,7 @@
+Updated REST APIs
+-----------------
+
+- The `/rest/spenttxouts/BLOCKHASH.json` endpoint now includes the `generated`
+ (whether the previous output is a coinbase output) and `height` fields for
+ each previous output, matching the `prevout` objects of the `getblock` RPC
+ with verbosity 3. The binary and hex formats are unchanged.
### src/rest.cpp
@@ -325,6 +325,8 @@ static void BlockUndoToJSON(const CBlockUndo& block_undo, UniValue& result)
UniValue tx_prevouts(UniValue::VARR);
for (const Coin& coin : tx_undo.vprevout) {
UniValue prevout(UniValue::VOBJ);
+ prevout.pushKV("generated", coin.IsCoinBase());
+ prevout.pushKV("height", coin.nHeight);
prevout.pushKV("value", ValueFromAmount(coin.out.nValue));
UniValue script_pub_key(UniValue::VOBJ);
### test/functional/interface_rest.py
@@ -451,14 +451,12 @@ def run_test(self):
for i, tx in enumerate(block["tx"]):
prevouts = [txin["prevout"] for txin in tx["vin"] if "coinbase" not in txin]
- # compare with `getblock` JSON output (coinbase tx has no prevouts)
+ # compare binary REST format with `getblock` JSON output (coinbase tx has no prevouts)
actual = [(txout.scriptPubKey.hex(), Decimal(txout.nValue) / COIN) for txout in spent[i]]
expected = [(p["scriptPubKey"]["hex"], p["value"]) for p in prevouts]
assert_equal(expected, actual)
- # also compare JSON format
- actual = [(prevout["scriptPubKey"], prevout["value"]) for prevout in spent_json[i]]
- expected = [(p["scriptPubKey"], p["value"]) for p in prevouts]
- assert_equal(expected, actual)
+ # also compare the JSON REST format to the getblock verbosity 3 RPC output
+ assert_equal(spent_json[i], prevouts)
self.log.info("Test the /blockpart URI")
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.