Line data Source code
1 : // Copyright (c) 2012-2021 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 146 : 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 149 : 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 149 : BOOST_AUTO_TEST_CASE(compress_script_to_ckey_id) 66 : { 67 : // case CKeyID 68 1 : CKey key = GenerateRandomKey(); 69 1 : CPubKey pubkey = key.GetPubKey(); 70 : 71 1 : CScript script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; 72 1 : BOOST_CHECK_EQUAL(script.size(), 25U); 73 : 74 1 : CompressedScript out; 75 1 : bool done = CompressScript(script, out); 76 1 : BOOST_CHECK_EQUAL(done, true); 77 : 78 : // Check compressed script 79 1 : BOOST_CHECK_EQUAL(out.size(), 21U); 80 1 : BOOST_CHECK_EQUAL(out[0], 0x00); 81 1 : BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 3, 20), 0); // compare the 20 relevant chars of the CKeyId in the script 82 1 : } 83 : 84 149 : BOOST_AUTO_TEST_CASE(compress_script_to_cscript_id) 85 : { 86 : // case CScriptID 87 1 : CScript script, redeemScript; 88 1 : script << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL; 89 1 : BOOST_CHECK_EQUAL(script.size(), 23U); 90 : 91 1 : CompressedScript out; 92 1 : bool done = CompressScript(script, out); 93 1 : BOOST_CHECK_EQUAL(done, true); 94 : 95 : // Check compressed script 96 1 : BOOST_CHECK_EQUAL(out.size(), 21U); 97 1 : BOOST_CHECK_EQUAL(out[0], 0x01); 98 1 : BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 2, 20), 0); // compare the 20 relevant chars of the CScriptId in the script 99 1 : } 100 : 101 149 : BOOST_AUTO_TEST_CASE(compress_script_to_compressed_pubkey_id) 102 : { 103 1 : CKey key = GenerateRandomKey(); // case compressed PubKeyID 104 : 105 1 : CScript script = CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // COMPRESSED_PUBLIC_KEY_SIZE (33) 106 1 : BOOST_CHECK_EQUAL(script.size(), 35U); 107 : 108 1 : CompressedScript out; 109 1 : bool done = CompressScript(script, out); 110 1 : BOOST_CHECK_EQUAL(done, true); 111 : 112 : // Check compressed script 113 1 : BOOST_CHECK_EQUAL(out.size(), 33U); 114 1 : BOOST_CHECK_EQUAL(memcmp(out.data(), script.data() + 1, 1), 0); 115 1 : BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 2, 32), 0); // compare the 32 chars of the compressed CPubKey 116 1 : } 117 : 118 149 : BOOST_AUTO_TEST_CASE(compress_script_to_uncompressed_pubkey_id) 119 : { 120 1 : CKey key = GenerateRandomKey(/*compressed=*/false); // case uncompressed PubKeyID 121 1 : CScript script = CScript() << ToByteVector(key.GetPubKey()) << OP_CHECKSIG; // PUBLIC_KEY_SIZE (65) 122 1 : BOOST_CHECK_EQUAL(script.size(), 67U); // 1 char code + 65 char pubkey + OP_CHECKSIG 123 : 124 1 : CompressedScript out; 125 1 : bool done = CompressScript(script, out); 126 1 : BOOST_CHECK_EQUAL(done, true); 127 : 128 : // Check compressed script 129 1 : BOOST_CHECK_EQUAL(out.size(), 33U); 130 1 : BOOST_CHECK_EQUAL(memcmp(out.data() + 1, script.data() + 2, 32), 0); // first 32 chars of CPubKey are copied into out[1:] 131 1 : BOOST_CHECK_EQUAL(out[0], 0x04 | (script[65] & 0x01)); // least significant bit (lsb) of last char of pubkey is mapped into out[0] 132 1 : } 133 : 134 146 : BOOST_AUTO_TEST_SUITE_END()