Line data Source code
1 : // Copyright (c) 2012-2020 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include <compressor.h>
6 : #include <script/standard.h>
7 : #include <test/util/setup_common.h>
8 :
9 : #include <stdint.h>
10 :
11 : #include <boost/test/unit_test.hpp>
12 :
13 : // amounts 0.00000001 .. 0.00100000
14 : #define NUM_MULTIPLES_UNIT 100000
15 :
16 : // amounts 0.01 .. 100.00
17 : #define NUM_MULTIPLES_CENT 10000
18 :
19 : // amounts 1 .. 10000
20 : #define NUM_MULTIPLES_1BTC 10000
21 :
22 : // amounts 50 .. 21000000
23 : #define NUM_MULTIPLES_50BTC 420000
24 :
25 89 : BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)
26 :
27 540000 : bool static TestEncode(uint64_t in) {
28 540000 : return in == DecompressAmount(CompressAmount(in));
29 : }
30 :
31 100000 : bool static TestDecode(uint64_t in) {
32 100000 : return in == CompressAmount(DecompressAmount(in));
33 : }
34 :
35 6 : bool static TestPair(uint64_t dec, uint64_t enc) {
36 12 : return CompressAmount(dec) == enc &&
37 6 : DecompressAmount(enc) == dec;
38 : }
39 :
40 95 : BOOST_AUTO_TEST_CASE(compress_amounts)
41 : {
42 1 : BOOST_CHECK(TestPair( 0, 0x0));
43 1 : BOOST_CHECK(TestPair( 1, 0x1));
44 1 : BOOST_CHECK(TestPair( CENT, 0x7));
45 1 : BOOST_CHECK(TestPair( COIN, 0x9));
46 1 : BOOST_CHECK(TestPair( 50*COIN, 0x32));
47 1 : BOOST_CHECK(TestPair(21000000*COIN, 0x1406f40));
48 :
49 100001 : for (uint64_t i = 1; i <= NUM_MULTIPLES_UNIT; i++)
50 100000 : BOOST_CHECK(TestEncode(i));
51 :
52 10001 : for (uint64_t i = 1; i <= NUM_MULTIPLES_CENT; i++)
53 10000 : BOOST_CHECK(TestEncode(i * CENT));
54 :
55 10001 : for (uint64_t i = 1; i <= NUM_MULTIPLES_1BTC; i++)
56 10000 : BOOST_CHECK(TestEncode(i * COIN));
57 :
58 420001 : for (uint64_t i = 1; i <= NUM_MULTIPLES_50BTC; i++)
59 420000 : BOOST_CHECK(TestEncode(i * 50 * COIN));
60 :
61 100001 : for (uint64_t i = 0; i < 100000; i++)
62 100000 : BOOST_CHECK(TestDecode(i));
63 1 : }
64 :
65 95 : BOOST_AUTO_TEST_CASE(compress_script_to_ckey_id)
66 : {
67 : // case CKeyID
68 1 : CKey key;
69 1 : key.MakeNewKey(true);
70 1 : CPubKey pubkey = key.GetPubKey();
71 :
72 1 : CScript script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
73 1 : BOOST_CHECK_EQUAL(script.size(), 25U);
74 :
75 1 : std::vector<unsigned char> out;
76 1 : bool done = CompressScript(script, out);
77 1 : BOOST_CHECK_EQUAL(done, true);
78 :
79 : // Check compressed script
80 1 : BOOST_CHECK_EQUAL(out.size(), 21U);
81 1 : BOOST_CHECK_EQUAL(out[0], 0x00);
82 1 : BOOST_CHECK_EQUAL(memcmp(&out[1], &script[3], 20), 0); // compare the 20 relevant chars of the CKeyId in the script
83 1 : }
84 :
85 95 : BOOST_AUTO_TEST_CASE(compress_script_to_cscript_id)
86 : {
87 : // case CScriptID
88 1 : CScript script, redeemScript;
89 1 : script << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
90 1 : BOOST_CHECK_EQUAL(script.size(), 23U);
91 :
92 1 : std::vector<unsigned char> out;
93 1 : bool done = CompressScript(script, out);
94 1 : BOOST_CHECK_EQUAL(done, true);
95 :
96 : // Check compressed script
97 1 : BOOST_CHECK_EQUAL(out.size(), 21U);
98 1 : BOOST_CHECK_EQUAL(out[0], 0x01);
99 1 : BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 20), 0); // compare the 20 relevant chars of the CScriptId in the script
100 1 : }
101 :
102 95 : BOOST_AUTO_TEST_CASE(compress_script_to_compressed_pubkey_id)
103 : {
104 1 : CKey key;
105 1 : key.MakeNewKey(true); // case compressed PubKeyID
106 :
107 1 : CScript script = CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // COMPRESSED_PUBLIC_KEY_SIZE (33)
108 1 : BOOST_CHECK_EQUAL(script.size(), 35U);
109 :
110 1 : std::vector<unsigned char> out;
111 1 : bool done = CompressScript(script, out);
112 1 : BOOST_CHECK_EQUAL(done, true);
113 :
114 : // Check compressed script
115 1 : BOOST_CHECK_EQUAL(out.size(), 33U);
116 1 : BOOST_CHECK_EQUAL(memcmp(&out[0], &script[1], 1), 0);
117 1 : BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // compare the 32 chars of the compressed CPubKey
118 1 : }
119 :
120 95 : BOOST_AUTO_TEST_CASE(compress_script_to_uncompressed_pubkey_id)
121 : {
122 1 : CKey key;
123 1 : key.MakeNewKey(false); // case uncompressed PubKeyID
124 1 : CScript script = CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // PUBLIC_KEY_SIZE (65)
125 1 : BOOST_CHECK_EQUAL(script.size(), 67U); // 1 char code + 65 char pubkey + OP_CHECKSIG
126 :
127 1 : std::vector<unsigned char> out;
128 1 : bool done = CompressScript(script, out);
129 1 : BOOST_CHECK_EQUAL(done, true);
130 :
131 : // Check compressed script
132 1 : BOOST_CHECK_EQUAL(out.size(), 33U);
133 1 : BOOST_CHECK_EQUAL(memcmp(&out[1], &script[2], 32), 0); // first 32 chars of CPubKey are copied into out[1:]
134 1 : BOOST_CHECK_EQUAL(out[0], 0x04 | (script[65] & 0x01)); // least significant bit (lsb) of last char of pubkey is mapped into out[0]
135 1 : }
136 :
137 89 : BOOST_AUTO_TEST_SUITE_END()
|