|
2 | 2 | #include <boost/test/unit_test.hpp> |
3 | 3 | #include <sv2/messages.h> |
4 | 4 | #include <util/strencodings.h> |
| 5 | +#include <primitives/transaction.h> |
| 6 | +#include <primitives/block.h> |
| 7 | +#include <script/script.h> |
5 | 8 |
|
6 | 9 | BOOST_AUTO_TEST_SUITE(sv2_messages_tests) |
7 | 10 |
|
@@ -153,6 +156,74 @@ BOOST_AUTO_TEST_CASE(Sv2NewTemplate_test) |
153 | 156 | BOOST_CHECK_EQUAL(HexStr(ss), expected); |
154 | 157 | } |
155 | 158 |
|
| 159 | +BOOST_AUTO_TEST_CASE(Sv2NewTemplate_MultipleOutputs_test) |
| 160 | +{ |
| 161 | + // NewTemplate with realistic coinbase: 1 dummy anyone-can-spend output + 3 OP_RETURN outputs |
| 162 | + // Tests that only OP_RETURN outputs are serialized (dummy output filtered out) |
| 163 | + // |
| 164 | + // U64 0100000000000000 template_id |
| 165 | + // BOOL 00 future_template |
| 166 | + // U32 00000030 version |
| 167 | + // U32 02000000 coinbase tx version |
| 168 | + // B0_255 04 coinbase_prefix len |
| 169 | + // 03012100 coinbase prefix |
| 170 | + // U32 ffffffff coinbase tx input sequence |
| 171 | + // U64 0040075af0750700 coinbase tx value remaining |
| 172 | + // U32 03000000 coinbase tx outputs count (3 OP_RETURN outputs, dummy filtered) |
| 173 | + // B0_64K 2100 coinbase_tx_outputs (33 bytes total) |
| 174 | + // 6400000000000000 output 1: 100 sats |
| 175 | + // 026a51 output 1: script (OP_RETURN OP_1) |
| 176 | + // c800000000000000 output 2: 200 sats |
| 177 | + // 026a52 output 2: script (OP_RETURN OP_2) |
| 178 | + // 2c01000000000000 output 3: 300 sats |
| 179 | + // 026a53 output 3: script (OP_RETURN OP_3) |
| 180 | + // U32 dbc80d00 coinbase lock time (height 903,387) |
| 181 | + // SEQ0_255[U256] 01 merkle path length |
| 182 | + // 1a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e - merkle path |
| 183 | + std::string expected{"01000000000000000000000030020000000403012100ffffffff0040075af07507000300000021006400000000000000026a51c800000000000000026a522c01000000000000026a53dbc80d00011a6240823de4c8d6aaf826851bdf2b0e8d5acf7c31e8578cff4c394b5a32bd4e"}; |
| 184 | + |
| 185 | + // Create realistic coinbase transaction with dummy anyone-can-spend output |
| 186 | + CMutableTransaction coinbase_tx; |
| 187 | + coinbase_tx.version = 2; |
| 188 | + coinbase_tx.vin.resize(1); |
| 189 | + coinbase_tx.vin[0].prevout.SetNull(); |
| 190 | + std::vector<uint8_t> coinbase_prefix_bytes{0x03, 0x01, 0x21, 0x00}; |
| 191 | + coinbase_tx.vin[0].scriptSig = CScript(coinbase_prefix_bytes.begin(), coinbase_prefix_bytes.end()); |
| 192 | + coinbase_tx.vin[0].nSequence = 4294967295; |
| 193 | + |
| 194 | + coinbase_tx.vout.resize(4); |
| 195 | + // Output 0: Dummy anyone-can-spend output with full reward (will be filtered out by sv2-tp) |
| 196 | + coinbase_tx.vout[0].nValue = MAX_MONEY; |
| 197 | + coinbase_tx.vout[0].scriptPubKey = CScript() << OP_TRUE; |
| 198 | + |
| 199 | + // Outputs 1-3: OP_RETURN outputs (will be included in NewTemplate message) |
| 200 | + coinbase_tx.vout[1] = CTxOut(100, CScript() << OP_RETURN << 1); |
| 201 | + coinbase_tx.vout[2] = CTxOut(200, CScript() << OP_RETURN << 2); |
| 202 | + coinbase_tx.vout[3] = CTxOut(300, CScript() << OP_RETURN << 3); |
| 203 | + |
| 204 | + coinbase_tx.nLockTime = 903387; |
| 205 | + |
| 206 | + CBlockHeader header; |
| 207 | + header.nVersion = 805306368; |
| 208 | + header.hashPrevBlock.SetNull(); |
| 209 | + header.nTime = 0; |
| 210 | + header.nBits = 0; |
| 211 | + header.nNonce = 0; |
| 212 | + |
| 213 | + std::vector<uint256> merkle_path; |
| 214 | + CMutableTransaction mtx_tx; |
| 215 | + CTransaction tx{mtx_tx}; |
| 216 | + merkle_path.push_back(tx.GetHash().ToUint256()); |
| 217 | + |
| 218 | + // Use constructor which filters outputs to only OP_RETURN |
| 219 | + node::Sv2NewTemplateMsg new_template{header, MakeTransactionRef(coinbase_tx), merkle_path, 1, false}; |
| 220 | + |
| 221 | + DataStream ss{}; |
| 222 | + ss << new_template; |
| 223 | + |
| 224 | + BOOST_CHECK_EQUAL(HexStr(ss), expected); |
| 225 | +} |
| 226 | + |
156 | 227 | BOOST_AUTO_TEST_CASE(Sv2NetHeader_NewTemplate_test) |
157 | 228 | { |
158 | 229 | // 0000 - extension type |
|
0 commit comments