Skip to content

Commit 1e44169

Browse files
committed
Add tests for CCoins deserialization
1 parent 5d0434d commit 1e44169

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

src/test/coins_tests.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
#include "coins.h"
66
#include "random.h"
7+
#include "script/standard.h"
78
#include "uint256.h"
9+
#include "utilstrencodings.h"
810
#include "test/test_bitcoin.h"
911
#include "main.h"
1012
#include "consensus/validation.h"
@@ -345,4 +347,73 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
345347
BOOST_CHECK(spent_a_duplicate_coinbase);
346348
}
347349

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+
348419
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)