|
4 | 4 |
|
5 | 5 | #include "coins.h"
|
6 | 6 | #include "random.h"
|
| 7 | +#include "script/standard.h" |
7 | 8 | #include "uint256.h"
|
| 9 | +#include "utilstrencodings.h" |
8 | 10 | #include "test/test_bitcoin.h"
|
9 | 11 | #include "main.h"
|
10 | 12 | #include "consensus/validation.h"
|
@@ -345,4 +347,73 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
|
345 | 347 | BOOST_CHECK(spent_a_duplicate_coinbase);
|
346 | 348 | }
|
347 | 349 |
|
| 350 | +BOOST_AUTO_TEST_CASE(ccoins_serialization) |
| 351 | +{ |
| 352 | + // Good example |
| 353 | + CDataStream ss1(ParseHex("0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e"), SER_DISK, CLIENT_VERSION); |
| 354 | + CCoins cc1; |
| 355 | + ss1 >> cc1; |
| 356 | + BOOST_CHECK_EQUAL(cc1.nVersion, 1); |
| 357 | + BOOST_CHECK_EQUAL(cc1.fCoinBase, false); |
| 358 | + BOOST_CHECK_EQUAL(cc1.nHeight, 203998); |
| 359 | + BOOST_CHECK_EQUAL(cc1.vout.size(), 2); |
| 360 | + BOOST_CHECK_EQUAL(cc1.IsAvailable(0), false); |
| 361 | + BOOST_CHECK_EQUAL(cc1.IsAvailable(1), true); |
| 362 | + BOOST_CHECK_EQUAL(cc1.vout[1].nValue, 60000000000ULL); |
| 363 | + BOOST_CHECK_EQUAL(HexStr(cc1.vout[1].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("816115944e077fe7c803cfa57f29b36bf87c1d35")))))); |
| 364 | + |
| 365 | + // Good example |
| 366 | + CDataStream ss2(ParseHex("0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b"), SER_DISK, CLIENT_VERSION); |
| 367 | + CCoins cc2; |
| 368 | + ss2 >> cc2; |
| 369 | + BOOST_CHECK_EQUAL(cc2.nVersion, 1); |
| 370 | + BOOST_CHECK_EQUAL(cc2.fCoinBase, true); |
| 371 | + BOOST_CHECK_EQUAL(cc2.nHeight, 120891); |
| 372 | + BOOST_CHECK_EQUAL(cc2.vout.size(), 17); |
| 373 | + for (int i = 0; i < 17; i++) { |
| 374 | + BOOST_CHECK_EQUAL(cc2.IsAvailable(i), i == 4 || i == 16); |
| 375 | + } |
| 376 | + BOOST_CHECK_EQUAL(cc2.vout[4].nValue, 234925952); |
| 377 | + BOOST_CHECK_EQUAL(HexStr(cc2.vout[4].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("61b01caab50f1b8e9c50a5057eb43c2d9563a4ee")))))); |
| 378 | + BOOST_CHECK_EQUAL(cc2.vout[16].nValue, 110397); |
| 379 | + BOOST_CHECK_EQUAL(HexStr(cc2.vout[16].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("8c988f1a4a4de2161e0f50aac7f17e7f9555caa4")))))); |
| 380 | + |
| 381 | + // Smallest possible example |
| 382 | + CDataStream ssx(SER_DISK, CLIENT_VERSION); |
| 383 | + BOOST_CHECK_EQUAL(HexStr(ssx.begin(), ssx.end()), ""); |
| 384 | + |
| 385 | + CDataStream ss3(ParseHex("0002000600"), SER_DISK, CLIENT_VERSION); |
| 386 | + CCoins cc3; |
| 387 | + ss3 >> cc3; |
| 388 | + BOOST_CHECK_EQUAL(cc3.nVersion, 0); |
| 389 | + BOOST_CHECK_EQUAL(cc3.fCoinBase, false); |
| 390 | + BOOST_CHECK_EQUAL(cc3.nHeight, 0); |
| 391 | + BOOST_CHECK_EQUAL(cc3.vout.size(), 1); |
| 392 | + BOOST_CHECK_EQUAL(cc3.IsAvailable(0), true); |
| 393 | + BOOST_CHECK_EQUAL(cc3.vout[0].nValue, 0); |
| 394 | + BOOST_CHECK_EQUAL(cc3.vout[0].scriptPubKey.size(), 0); |
| 395 | + |
| 396 | + // scriptPubKey that ends beyond the end of the stream |
| 397 | + CDataStream ss4(ParseHex("0002000800"), SER_DISK, CLIENT_VERSION); |
| 398 | + try { |
| 399 | + CCoins cc4; |
| 400 | + ss4 >> cc4; |
| 401 | + BOOST_CHECK_MESSAGE(false, "We should have thrown"); |
| 402 | + } catch (const std::ios_base::failure& e) { |
| 403 | + } |
| 404 | + |
| 405 | + // Very large scriptPubKey (3*10^9 bytes) past the end of the stream |
| 406 | + CDataStream tmp(SER_DISK, CLIENT_VERSION); |
| 407 | + uint64_t x = 3000000000ULL; |
| 408 | + tmp << VARINT(x); |
| 409 | + BOOST_CHECK_EQUAL(HexStr(tmp.begin(), tmp.end()), "8a95c0bb00"); |
| 410 | + CDataStream ss5(ParseHex("0002008a95c0bb0000"), SER_DISK, CLIENT_VERSION); |
| 411 | + try { |
| 412 | + CCoins cc5; |
| 413 | + ss5 >> cc5; |
| 414 | + BOOST_CHECK_MESSAGE(false, "We should have thrown"); |
| 415 | + } catch (const std::ios_base::failure& e) { |
| 416 | + } |
| 417 | +} |
| 418 | + |
348 | 419 | BOOST_AUTO_TEST_SUITE_END()
|
0 commit comments