Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
test
compress_tests.cpp
Go to the documentation of this file.
1
// Copyright (c) 2012-present 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/script.h
>
7
#include <
test/util/random.h
>
8
#include <
test/util/setup_common.h
>
9
10
#include <cstdint>
11
12
#include <boost/test/unit_test.hpp>
13
14
// amounts 0.00000001 .. 0.00100000
15
#define NUM_MULTIPLES_UNIT 100000
16
17
// amounts 0.01 .. 100.00
18
#define NUM_MULTIPLES_CENT 10000
19
20
// amounts 1 .. 10000
21
#define NUM_MULTIPLES_1BTC 10000
22
23
// amounts 50 .. 21000000
24
#define NUM_MULTIPLES_50BTC 420000
25
26
BOOST_FIXTURE_TEST_SUITE
(compress_tests,
BasicTestingSetup
)
27
28
bool static
TestEncode
(uint64_t in) {
29
return
in ==
DecompressAmount
(
CompressAmount
(in));
30
}
31
32
bool
static
TestDecode
(uint64_t in) {
33
return
in ==
CompressAmount
(
DecompressAmount
(in));
34
}
35
36
bool
static
TestPair
(uint64_t dec, uint64_t enc) {
37
return
CompressAmount
(dec) == enc &&
38
DecompressAmount
(enc) == dec;
39
}
40
41
BOOST_AUTO_TEST_CASE
(compress_amounts)
42
{
43
BOOST_CHECK
(
TestPair
( 0, 0x0));
44
BOOST_CHECK
(
TestPair
( 1, 0x1));
45
BOOST_CHECK
(
TestPair
( CENT, 0x7));
46
BOOST_CHECK
(
TestPair
( COIN, 0x9));
47
BOOST_CHECK
(
TestPair
( 50*COIN, 0x32));
48
BOOST_CHECK
(
TestPair
(21000000*COIN, 0x1406f40));
49
50
for
(uint64_t i = 1; i <=
NUM_MULTIPLES_UNIT
; i++)
51
BOOST_CHECK
(
TestEncode
(i));
52
53
for
(uint64_t i = 1; i <=
NUM_MULTIPLES_CENT
; i++)
54
BOOST_CHECK
(
TestEncode
(i * CENT));
55
56
for
(uint64_t i = 1; i <=
NUM_MULTIPLES_1BTC
; i++)
57
BOOST_CHECK
(
TestEncode
(i * COIN));
58
59
for
(uint64_t i = 1; i <=
NUM_MULTIPLES_50BTC
; i++)
60
BOOST_CHECK
(
TestEncode
(i * 50 * COIN));
61
62
for
(uint64_t i = 0; i < 100000; i++)
63
BOOST_CHECK
(
TestDecode
(i));
64
}
65
66
BOOST_AUTO_TEST_CASE
(compress_script_to_ckey_id)
67
{
68
// case CKeyID
69
CKey
key =
GenerateRandomKey
();
70
CPubKey
pubkey = key.
GetPubKey
();
71
72
CScript
script
=
CScript
() <<
OP_DUP
<<
OP_HASH160
<<
ToByteVector
(pubkey.
GetID
()) <<
OP_EQUALVERIFY
<<
OP_CHECKSIG
;
73
BOOST_CHECK_EQUAL
(
script
.size(), 25U);
74
75
CompressedScript
out;
76
bool
done =
CompressScript
(
script
, out);
77
BOOST_CHECK_EQUAL
(done,
true
);
78
79
// Check compressed script
80
BOOST_CHECK_EQUAL
(out.size(), 21U);
81
BOOST_CHECK_EQUAL
(out[0], 0x00);
82
BOOST_CHECK_EQUAL
(memcmp(out.data() + 1,
script
.data() + 3, 20), 0);
// compare the 20 relevant chars of the CKeyId in the script
83
}
84
85
BOOST_AUTO_TEST_CASE
(compress_script_to_cscript_id)
86
{
87
// case CScriptID
88
CScript
script
, redeemScript;
89
script
<<
OP_HASH160
<<
ToByteVector
(
CScriptID
(redeemScript)) <<
OP_EQUAL
;
90
BOOST_CHECK_EQUAL
(
script
.size(), 23U);
91
92
CompressedScript
out;
93
bool
done =
CompressScript
(
script
, out);
94
BOOST_CHECK_EQUAL
(done,
true
);
95
96
// Check compressed script
97
BOOST_CHECK_EQUAL
(out.size(), 21U);
98
BOOST_CHECK_EQUAL
(out[0], 0x01);
99
BOOST_CHECK_EQUAL
(memcmp(out.data() + 1,
script
.data() + 2, 20), 0);
// compare the 20 relevant chars of the CScriptId in the script
100
}
101
102
BOOST_AUTO_TEST_CASE
(compress_script_to_compressed_pubkey_id)
103
{
104
CKey
key =
GenerateRandomKey
();
// case compressed PubKeyID
105
106
CScript
script
=
CScript
() <<
ToByteVector
(key.
GetPubKey
()) <<
OP_CHECKSIG
;
// COMPRESSED_PUBLIC_KEY_SIZE (33)
107
BOOST_CHECK_EQUAL
(
script
.size(), 35U);
108
109
CompressedScript
out;
110
bool
done =
CompressScript
(
script
, out);
111
BOOST_CHECK_EQUAL
(done,
true
);
112
113
// Check compressed script
114
BOOST_CHECK_EQUAL
(out.size(), 33U);
115
BOOST_CHECK_EQUAL
(memcmp(out.data(),
script
.data() + 1, 1), 0);
116
BOOST_CHECK_EQUAL
(memcmp(out.data() + 1,
script
.data() + 2, 32), 0);
// compare the 32 chars of the compressed CPubKey
117
}
118
119
BOOST_AUTO_TEST_CASE
(compress_script_to_uncompressed_pubkey_id)
120
{
121
CKey
key =
GenerateRandomKey
(
/*compressed=*/
false
);
// case uncompressed PubKeyID
122
CScript
script
=
CScript
() <<
ToByteVector
(key.
GetPubKey
()) <<
OP_CHECKSIG
;
// PUBLIC_KEY_SIZE (65)
123
BOOST_CHECK_EQUAL
(
script
.size(), 67U);
// 1 char code + 65 char pubkey + OP_CHECKSIG
124
125
CompressedScript
out;
126
bool
done =
CompressScript
(
script
, out);
127
BOOST_CHECK_EQUAL
(done,
true
);
128
129
// Check compressed script
130
BOOST_CHECK_EQUAL
(out.size(), 33U);
131
BOOST_CHECK_EQUAL
(memcmp(out.data() + 1,
script
.data() + 2, 32), 0);
// first 32 chars of CPubKey are copied into out[1:]
132
BOOST_CHECK_EQUAL
(out[0], 0x04 | (
script
[65] & 0x01));
// least significant bit (lsb) of last char of pubkey is mapped into out[0]
133
}
134
135
BOOST_AUTO_TEST_CASE
(compress_p2pk_scripts_not_on_curve)
136
{
137
XOnlyPubKey
x_not_on_curve;
138
do
{
139
x_not_on_curve =
XOnlyPubKey
(m_rng.randbytes(32));
140
}
while
(x_not_on_curve.
IsFullyValid
());
141
142
// Check that P2PK script with uncompressed pubkey [=> OP_PUSH65 <0x04 .....> OP_CHECKSIG]
143
// which is not fully valid (i.e. point is not on curve) can't be compressed
144
std::vector<unsigned char> pubkey_raw(65, 0);
145
pubkey_raw[0] = 4;
146
std::copy(x_not_on_curve.
begin
(), x_not_on_curve.
end
(), &pubkey_raw[1]);
147
CPubKey
pubkey_not_on_curve(pubkey_raw);
148
assert
(pubkey_not_on_curve.
IsValid
());
149
assert
(!pubkey_not_on_curve.
IsFullyValid
());
150
CScript
script
=
CScript
() <<
ToByteVector
(pubkey_not_on_curve) <<
OP_CHECKSIG
;
151
BOOST_CHECK_EQUAL
(
script
.size(), 67U);
152
153
CompressedScript
out;
154
bool
done =
CompressScript
(
script
, out);
155
BOOST_CHECK_EQUAL
(done,
false
);
156
157
// Check that compressed P2PK script with uncompressed pubkey that is not fully
158
// valid (i.e. x coordinate of the pubkey is not on curve) can't be decompressed
159
CompressedScript
compressed_script(x_not_on_curve.
begin
(), x_not_on_curve.
end
());
160
for
(
unsigned
int
compression_id : {4, 5}) {
161
CScript
uncompressed_script;
162
bool
success =
DecompressScript
(uncompressed_script, compression_id, compressed_script);
163
BOOST_CHECK_EQUAL
(success,
false
);
164
}
165
}
166
167
BOOST_AUTO_TEST_SUITE_END
()
CKey
An encapsulated private key.
Definition
key.h:36
CKey::GetPubKey
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition
key.cpp:183
CPubKey
An encapsulated public key.
Definition
pubkey.h:34
CPubKey::GetID
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization).
Definition
pubkey.h:160
CPubKey::IsValid
bool IsValid() const
Definition
pubkey.h:185
CPubKey::IsFullyValid
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition
pubkey.cpp:320
CScript
Serialized script, used inside transaction inputs and outputs.
Definition
script.h:405
CScript::CScript
CScript()=default
CScriptID::CScriptID
CScriptID()
Definition
script.h:596
XOnlyPubKey
Definition
pubkey.h:227
XOnlyPubKey::end
const unsigned char * end() const
Definition
pubkey.h:296
XOnlyPubKey::begin
const unsigned char * begin() const
Definition
pubkey.h:295
XOnlyPubKey::IsFullyValid
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition
pubkey.cpp:230
XOnlyPubKey::XOnlyPubKey
XOnlyPubKey()=default
Construct an empty x-only pubkey.
TestEncode
static bool TestEncode(uint64_t in)
Definition
compress_tests.cpp:28
TestPair
static bool TestPair(uint64_t dec, uint64_t enc)
Definition
compress_tests.cpp:36
NUM_MULTIPLES_CENT
#define NUM_MULTIPLES_CENT
Definition
compress_tests.cpp:18
NUM_MULTIPLES_1BTC
#define NUM_MULTIPLES_1BTC
Definition
compress_tests.cpp:21
NUM_MULTIPLES_UNIT
#define NUM_MULTIPLES_UNIT
Definition
compress_tests.cpp:15
TestDecode
static bool TestDecode(uint64_t in)
Definition
compress_tests.cpp:32
NUM_MULTIPLES_50BTC
#define NUM_MULTIPLES_50BTC
Definition
compress_tests.cpp:24
DecompressScript
bool DecompressScript(CScript &script, unsigned int nSize, const CompressedScript &in)
Definition
compressor.cpp:95
CompressScript
bool CompressScript(const CScript &script, CompressedScript &out)
Definition
compressor.cpp:55
DecompressAmount
uint64_t DecompressAmount(uint64_t x)
Definition
compressor.cpp:168
CompressAmount
uint64_t CompressAmount(uint64_t n)
Compress amount.
Definition
compressor.cpp:149
compressor.h
CompressedScript
prevector< 33, unsigned char > CompressedScript
This saves us from making many heap allocations when serializing and deserializing compressed scripts...
Definition
compressor.h:23
BOOST_FIXTURE_TEST_SUITE
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(ipc_tests)
Definition
ipc_tests.cpp:13
GenerateRandomKey
CKey GenerateRandomKey(bool compressed) noexcept
Definition
key.cpp:475
script
Definition
parsing.cpp:13
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition
object.cpp:17
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition
object.cpp:16
script.h
OP_CHECKSIG
@ OP_CHECKSIG
Definition
script.h:190
OP_EQUAL
@ OP_EQUAL
Definition
script.h:146
OP_DUP
@ OP_DUP
Definition
script.h:125
OP_HASH160
@ OP_HASH160
Definition
script.h:187
OP_EQUALVERIFY
@ OP_EQUALVERIFY
Definition
script.h:147
ToByteVector
std::vector< unsigned char > ToByteVector(const T &in)
Definition
script.h:67
setup_common.h
BasicTestingSetup
Basic testing setup.
Definition
setup_common.h:64
random.h
assert
assert(!tx.IsCoinBase())
Generated on
for Bitcoin Core by
1.18.0