diff --git a/src/sv2/messages.cpp b/src/sv2/messages.cpp index 0bdb0037..403c7709 100644 --- a/src/sv2/messages.cpp +++ b/src/sv2/messages.cpp @@ -13,6 +13,13 @@ node::Sv2NewTemplateMsg::Sv2NewTemplateMsg(const CBlockHeader& header, const CTr m_coinbase_tx_version = coinbase_tx->CURRENT_VERSION; m_coinbase_prefix = coinbase_tx->vin[0].scriptSig; + if (coinbase_tx->HasWitness()) { + const auto& witness_stack{coinbase_tx->vin[0].scriptWitness.stack}; + Assert(witness_stack.size() == 1 || witness_stack[0].size() == 32); + m_coinbase_witness = uint256(witness_stack[0]); + } else { + m_coinbase_witness = uint256(0); + } m_coinbase_tx_input_sequence = coinbase_tx->vin[0].nSequence; // The coinbase nValue already contains the nFee + the Block Subsidy when built using CreateBlock(). diff --git a/src/sv2/messages.h b/src/sv2/messages.h index 31b38ef4..59e3a9e7 100644 --- a/src/sv2/messages.h +++ b/src/sv2/messages.h @@ -282,6 +282,18 @@ struct Sv2NewTemplateMsg */ CScript m_coinbase_prefix; + /** + * 32 byte array of the first (and only) witness stack element of the coinbase. + * + * If there is no segwit commitment in m_coinbase_tx_outputs this value + * must be ignored. + * + * This is the BIP 141 witness reserved value. A future soft fork may move + * the witness reserved value elsewhere. In that case this field still + * represents the coinbase witness, for backward compatibility. + */ + uint256 m_coinbase_witness; + /** * The coinbase transaction input’s nSequence field. */ @@ -324,6 +336,7 @@ struct Sv2NewTemplateMsg << m_version << m_coinbase_tx_version << m_coinbase_prefix + << m_coinbase_witness << m_coinbase_tx_input_sequence << m_coinbase_tx_value_remaining << m_coinbase_tx_outputs_count; diff --git a/src/test/sv2_messages_tests.cpp b/src/test/sv2_messages_tests.cpp index e4453f55..d3cd54e9 100644 --- a/src/test/sv2_messages_tests.cpp +++ b/src/test/sv2_messages_tests.cpp @@ -113,6 +113,7 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_test) // U32 02000000 coinbase tx version // B0_255 04 coinbase_prefix len // 03012100 coinbase prefix + // U256 0000000000000000000000000000000000000000000000000000000000000000 - witness // U32 ffffffff coinbase tx input sequence // U64 0040075af0750700 coinbase tx value remaining // U32 01000000 coinbase tx outputs count @@ -122,7 +123,7 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_test) // U32 dbc80d00 coinbase lock time (height 903,387) // SEQ0_255[U256] 01 merkle path length // 1a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e - merkle path - std::string expected{"01000000000000000000000030020000000403012100ffffffff0040075af0750700010000000c000100000000000000036a012adbc80d00011a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e"}; + std::string expected{"010000000000000000000000300200000004030121000000000000000000000000000000000000000000000000000000000000000000ffffffff0040075af0750700010000000c000100000000000000036a012adbc80d00011a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e"}; node::Sv2NewTemplateMsg new_template; new_template.m_template_id = 1; @@ -134,6 +135,8 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_test) CScript prefix(coinbase_prefix.begin(), coinbase_prefix.end()); new_template.m_coinbase_prefix = prefix; + new_template.m_coinbase_witness = uint256(0); + new_template.m_coinbase_tx_input_sequence = 4294967295; new_template.m_coinbase_tx_value_remaining = MAX_MONEY; @@ -167,6 +170,7 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_MultipleOutputs_test) // U32 02000000 coinbase tx version // B0_255 04 coinbase_prefix len // 03012100 coinbase prefix + // U256 0000000000000000000000000000000000000000000000000000000000000000 - witness // U32 ffffffff coinbase tx input sequence // U64 0040075af0750700 coinbase tx value remaining // U32 03000000 coinbase tx outputs count (3 OP_RETURN outputs, dummy filtered) @@ -180,7 +184,7 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_MultipleOutputs_test) // U32 dbc80d00 coinbase lock time (height 903,387) // SEQ0_255[U256] 01 merkle path length // 1a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e - merkle path - std::string expected{"01000000000000000000000030020000000403012100ffffffff0040075af07507000300000021006400000000000000026a51c800000000000000026a522c01000000000000026a53dbc80d00011a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e"}; + std::string expected{"010000000000000000000000300200000004030121000000000000000000000000000000000000000000000000000000000000000000ffffffff0040075af07507000300000021006400000000000000026a51c800000000000000026a522c01000000000000026a53dbc80d00011a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e"}; // Create realistic coinbase transaction with dummy anyone-can-spend output CMutableTransaction coinbase_tx; diff --git a/src/test/sv2_template_provider_tests.cpp b/src/test/sv2_template_provider_tests.cpp index a7e3f9f2..222d87a8 100644 --- a/src/test/sv2_template_provider_tests.cpp +++ b/src/test/sv2_template_provider_tests.cpp @@ -63,6 +63,7 @@ BOOST_AUTO_TEST_CASE(client_tests) 4 + // version 4 + // coinbase_tx_version 2 + // coinbase_prefix (CompactSize(1) + 1-byte OP_0) + 32 + // coinbase_witness (fixed-size reserved value) 4 + // coinbase_tx_input_sequence 8 + // coinbase_tx_value_remaining 4 + // coinbase_tx_outputs_count (2 - mock creates 3, only 2 OP_RETURN outputs pass filter)