diff --git a/src/sv2/messages.cpp b/src/sv2/messages.cpp index 91300074..742e84bd 100644 --- a/src/sv2/messages.cpp +++ b/src/sv2/messages.cpp @@ -13,6 +13,9 @@ node::Sv2NewTemplateMsg::Sv2NewTemplateMsg(const CBlockHeader& header, const nod m_coinbase_tx_version = coinbase.version; m_coinbase_prefix = coinbase.script_sig_prefix; + if (coinbase.witness.has_value()) { + m_coinbase_witness.assign(coinbase.witness->begin(), coinbase.witness->end()); + } m_coinbase_tx_input_sequence = coinbase.sequence; // 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 3e71359a..b1ce00d1 100644 --- a/src/sv2/messages.h +++ b/src/sv2/messages.h @@ -283,6 +283,14 @@ struct Sv2NewTemplateMsg */ CScript m_coinbase_prefix; + /** + * The first (and only) witness stack element of the coinbase. + * + * Empty when no witness commitment output is present in + * m_coinbase_tx_outputs. Otherwise, this must contain exactly 32 bytes. + */ + std::vector m_coinbase_witness; + /** * The coinbase transaction input’s nSequence field. */ @@ -321,11 +329,14 @@ struct Sv2NewTemplateMsg template void Serialize(Stream& s) const { + Assert(m_coinbase_witness.empty() || m_coinbase_witness.size() == 32); + s << m_template_id << m_future_template << 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..7f4a6cfa 100644 --- a/src/test/sv2_messages_tests.cpp +++ b/src/test/sv2_messages_tests.cpp @@ -113,6 +113,8 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_test) // U32 02000000 coinbase tx version // B0_255 04 coinbase_prefix len // 03012100 coinbase prefix + // B0_32 20 coinbase_witness len + // 0000000000000000000000000000000000000000000000000000000000000000 - witness // U32 ffffffff coinbase tx input sequence // U64 0040075af0750700 coinbase tx value remaining // U32 01000000 coinbase tx outputs count @@ -122,7 +124,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{"01000000000000000000000030020000000403012100200000000000000000000000000000000000000000000000000000000000000000ffffffff0040075af0750700010000000c000100000000000000036a012adbc80d00011a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e"}; node::Sv2NewTemplateMsg new_template; new_template.m_template_id = 1; @@ -134,6 +136,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 = std::vector(32, 0); + new_template.m_coinbase_tx_input_sequence = 4294967295; new_template.m_coinbase_tx_value_remaining = MAX_MONEY; @@ -167,6 +171,7 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_MultipleOutputs_test) // U32 02000000 coinbase tx version // B0_255 04 coinbase_prefix len // 03012100 coinbase prefix + // B0_32 00 coinbase_witness len // 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 +185,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{"0100000000000000000000003002000000040301210000ffffffff0040075af07507000300000021006400000000000000026a51c800000000000000026a522c01000000000000026a53dbc80d00011a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e"}; // Create realistic coinbase transaction with dummy anyone-can-spend output CMutableTransaction coinbase_tx; diff --git a/src/test/sv2_mock_mining.cpp b/src/test/sv2_mock_mining.cpp index 17a544e3..b0864857 100644 --- a/src/test/sv2_mock_mining.cpp +++ b/src/test/sv2_mock_mining.cpp @@ -28,6 +28,7 @@ MockBlockTemplate::MockBlockTemplate(std::shared_ptr st, uint256 prev cb.vin.resize(1); cb.vin[0].prevout.SetNull(); cb.vin[0].scriptSig = CScript() << OP_0; + cb.vin[0].scriptWitness.stack.emplace_back(32, 0); cb.vout.resize(3); // Output 0: Dummy anyone-can-spend output with full reward (will be filtered out by sv2-tp) diff --git a/src/test/sv2_template_provider_tests.cpp b/src/test/sv2_template_provider_tests.cpp index 29c039c3..6b605648 100644 --- a/src/test/sv2_template_provider_tests.cpp +++ b/src/test/sv2_template_provider_tests.cpp @@ -116,7 +116,7 @@ BOOST_AUTO_TEST_CASE(client_tests) tester.receiveMessage(request_transaction_data_msg); BOOST_TEST_MESSAGE("Receive RequestTransactionData.Success"); // RequestTransactionData.Success on-wire size derived from constants and actual tx size - constexpr size_t SV2_RTD_SUCCESS_PREFIX = 8 /*template_id*/ + 2 /*excess len*/ + 2 /*tx_count=1*/; + constexpr size_t SV2_RTD_SUCCESS_PREFIX = 8 /*template_id*/ + 2 + 32 /*excess data*/ + 2 /*tx_count=1*/; constexpr size_t SV2_U24_LEN = 3; // u24 length per tx { // Serialize the same deterministic dummy transaction to get exact size diff --git a/src/test/sv2_tp_tester.h b/src/test/sv2_tp_tester.h index 5082ff99..cc1992b7 100644 --- a/src/test/sv2_tp_tester.h +++ b/src/test/sv2_tp_tester.h @@ -72,6 +72,7 @@ class TPTester { 4 + // version 4 + // coinbase_tx_version 2 + // coinbase_prefix (CompactSize(1) + 1-byte OP_0) + 1 + 32 + // coinbase_witness (B0_32 length + 32-byte witness) 4 + // coinbase_tx_input_sequence 8 + // coinbase_tx_value_remaining 4 + // coinbase_tx_outputs_count