From 3e4421070af01374cd3daf77b28a2abc223c6f83 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 30 Apr 2020 18:55:57 +1000 Subject: [PATCH 1/2] Expose txinwitness for coinbase in JSON form txinwitness is used as the witness commitment nonce so is necessary if reconstructing block data from RPC data. --- src/core_write.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core_write.cpp b/src/core_write.cpp index cb1fc214eb..eb0cc35f06 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -198,13 +198,13 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); in.pushKV("scriptSig", o); - if (!tx.vin[i].scriptWitness.IsNull()) { - UniValue txinwitness(UniValue::VARR); - for (const auto& item : tx.vin[i].scriptWitness.stack) { - txinwitness.push_back(HexStr(item.begin(), item.end())); - } - in.pushKV("txinwitness", txinwitness); + } + if (!tx.vin[i].scriptWitness.IsNull()) { + UniValue txinwitness(UniValue::VARR); + for (const auto& item : tx.vin[i].scriptWitness.stack) { + txinwitness.push_back(HexStr(item.begin(), item.end())); } + in.pushKV("txinwitness", txinwitness); } in.pushKV("sequence", (int64_t)txin.nSequence); vin.push_back(in); From 34645c4dd04f1e9bc199fb722de0bb397ec0e131 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Sat, 2 May 2020 21:13:58 +1000 Subject: [PATCH 2/2] Test txinwitness is accessible on coinbase vin --- test/functional/feature_segwit.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py index fdd86310c0..94eb844dfb 100755 --- a/test/functional/feature_segwit.py +++ b/test/functional/feature_segwit.py @@ -20,6 +20,7 @@ from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash16 from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_is_hex_string, assert_raises_rpc_error, connect_nodes, hex_str_to_bytes, @@ -193,6 +194,14 @@ class SegWitTest(BitcoinTestFramework): assert self.nodes[1].getrawtransaction(tx_id, False, blockhash) == self.nodes[2].gettransaction(tx_id)["hex"] assert self.nodes[0].getrawtransaction(tx_id, False, blockhash) == tx.serialize_without_witness().hex() + # Coinbase contains the witness commitment nonce, check that RPC shows us + coinbase_txid = self.nodes[2].getblock(blockhash)['tx'][0] + coinbase_tx = self.nodes[2].gettransaction(txid=coinbase_txid, verbose=True) + witnesses = coinbase_tx["decoded"]["vin"][0]["txinwitness"] + assert_equal(len(witnesses), 1) + assert_is_hex_string(witnesses[0]) + assert_equal(witnesses[0], '00'*32) + self.log.info("Verify witness txs without witness data are invalid after the fork") self.fail_accept(self.nodes[2], 'non-mandatory-script-verify-flag (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False) 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)