Skip to content

Commit 297466b

Browse files
author
MarcoFalke
committed
Merge #18826: Expose txinwitness for coinbase in JSON form from RPC
34645c4 Test txinwitness is accessible on coinbase vin (Rod Vagg) 3e44210 Expose txinwitness for coinbase in JSON form (Rod Vagg) Pull request description: ## Rationale The CLI can provide you with everything about transactions and blocks that you need to reconstruct the block structure and raw block itself **except** for the witness commitment nonce which is stored in the `scriptWitness` of the coinbase and is not printed. You could manually parse the raw `"hex"` fields for transactions if you really wanted to, but this seems to defeat the point of having a JSONification of the raw block/transaction data. Without the nonce you can't: 1. calculate and validate the witness commitment yourself, you can generate the witness tx merkle root but you don't have the nonce to combine it with 2. reconstruct the raw block form because you don't have `scriptWitness` stack associated with the coinbase (although you know how big it will be and can guess the common case of `[0x000...000]`) I'm building some archiving tooling for block data and being able to do a validated two-way conversion is very helpful. ## What This PR simply makes the `txinwitness` field not dependent on whether we are working with the coinbase or not. So you get it for the coinbase as well as the rest. ## Examples Common case of a `[0x000...000]` nonce: 00000000000000000000140a7289f3aada855dfd23b0bb13bb5502b0ca60cdd7 ```json "vin": [ { "coinbase": "0368890904c1fe8d5e2f706f6f6c696e2e636f6d2ffabe6d6d5565843a681160cf7b08b1b74ac90a719e6d6ab28c16d336b924f0dc2fcabdc6010000000000000051bf2ad74af345dbe642154b2658931612a70d195e007add0100ffffffff", "txinwitness": [ "0000000000000000000000000000000000000000000000000000000000000000" ], "sequence": 4294967295 } ], ... ``` Novel nonce value: 000000000000000000008c31945b2012258366cc600a3e9a3ee0598e8f797731 ```json "vin": [ { "coinbase": "031862082cfabe6d6d80c099b5e21f4c186d54eb292e17026932e52b1b807fa1380574c5adc1c843450200000000000000", "txinwitness": [ "5b5032506f6f6c5d5b5032506f6f6c5d5b5032506f6f6c5d5b5032506f6f6c5d" ], "sequence": 4294967295 } ], ... ``` ## Alternatives This field could be renamed for the coinbase, `"witnessnonce"` perhaps. It could also be omitted when null/zero (`0x000...000`). ## Tests This didn't break any tests and I couldn't find an obvious way to include a test for this. If this is desired I'd apreicate some pointers. ACKs for top commit: MarcoFalke: ACK 34645c4 Tree-SHA512: b192facc1dfd210a5ec3f0d5d1ac6d0cae81eb35be15eaa71f60009a538dd6a79ab396f218434e7e998563f7f0df2c396cc925cb91619f6841c5a67806148c85
2 parents 3e58734 + 34645c4 commit 297466b

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

src/core_write.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,13 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
198198
o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
199199
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
200200
in.pushKV("scriptSig", o);
201-
if (!tx.vin[i].scriptWitness.IsNull()) {
202-
UniValue txinwitness(UniValue::VARR);
203-
for (const auto& item : tx.vin[i].scriptWitness.stack) {
204-
txinwitness.push_back(HexStr(item.begin(), item.end()));
205-
}
206-
in.pushKV("txinwitness", txinwitness);
201+
}
202+
if (!tx.vin[i].scriptWitness.IsNull()) {
203+
UniValue txinwitness(UniValue::VARR);
204+
for (const auto& item : tx.vin[i].scriptWitness.stack) {
205+
txinwitness.push_back(HexStr(item.begin(), item.end()));
207206
}
207+
in.pushKV("txinwitness", txinwitness);
208208
}
209209
in.pushKV("sequence", (int64_t)txin.nSequence);
210210
vin.push_back(in);

test/functional/feature_segwit.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from test_framework.test_framework import BitcoinTestFramework
2121
from test_framework.util import (
2222
assert_equal,
23+
assert_is_hex_string,
2324
assert_raises_rpc_error,
2425
connect_nodes,
2526
hex_str_to_bytes,
@@ -188,6 +189,14 @@ def run_test(self):
188189
assert self.nodes[1].getrawtransaction(tx_id, False, blockhash) == self.nodes[2].gettransaction(tx_id)["hex"]
189190
assert self.nodes[0].getrawtransaction(tx_id, False, blockhash) == tx.serialize_without_witness().hex()
190191

192+
# Coinbase contains the witness commitment nonce, check that RPC shows us
193+
coinbase_txid = self.nodes[2].getblock(blockhash)['tx'][0]
194+
coinbase_tx = self.nodes[2].gettransaction(txid=coinbase_txid, verbose=True)
195+
witnesses = coinbase_tx["decoded"]["vin"][0]["txinwitness"]
196+
assert_equal(len(witnesses), 1)
197+
assert_is_hex_string(witnesses[0])
198+
assert_equal(witnesses[0], '00'*32)
199+
191200
self.log.info("Verify witness txs without witness data are invalid after the fork")
192201
self.fail_accept(self.nodes[2], 'non-mandatory-script-verify-flag (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False)
193202
self.fail_accept(self.nodes[2], 'non-mandatory-script-verify-flag (Witness program was passed an empty witness)', wit_ids[NODE_2][P2WSH][2], sign=False)

0 commit comments

Comments
 (0)