Bitcoin ABC 0.31.1
P2P Digital Currency
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
delegation_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2020 The Bitcoin developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
9#include <util/strencodings.h>
10#include <util/translation.h>
11#include <validation.h>
12
13#include <test/util/setup_common.h>
14
15#include <boost/test/unit_test.hpp>
16
17using namespace avalanche;
18
19BOOST_FIXTURE_TEST_SUITE(delegation_tests, TestingSetup)
20
21static void CheckDelegation(const Delegation &dg, const ProofRef &p,
22 const CPubKey &expected_pubkey) {
23 DelegationState state;
24 CPubKey pubkey;
25 BOOST_CHECK(dg.verify(state, pubkey));
27 BOOST_CHECK(pubkey == expected_pubkey);
28
29 BOOST_CHECK(dg.getProofId() == p->getId());
30}
31
32BOOST_AUTO_TEST_CASE(verify_random) {
33 auto key = CKey::MakeCompressedKey();
34
35 auto p = buildRandomProof(Assert(m_node.chainman)->ActiveChainstate(),
36 123456, 1234, key);
37 DelegationBuilder dgb(*p);
38
39 {
40 Delegation dg = dgb.build();
41 BOOST_CHECK_EQUAL(dg.getId(), p->getId());
42 CheckDelegation(dg, p, p->getMaster());
43 }
44
45 auto l1key = CKey::MakeCompressedKey();
46 BOOST_CHECK(!dgb.addLevel(l1key, key.GetPubKey()));
47
48 dgb.addLevel(key, l1key.GetPubKey());
49 CheckDelegation(dgb.build(), p, l1key.GetPubKey());
50
51 auto l2key = CKey::MakeCompressedKey();
52 BOOST_CHECK(!dgb.addLevel(key, l2key.GetPubKey()));
53 BOOST_CHECK(!dgb.addLevel(l2key, l2key.GetPubKey()));
54
55 dgb.addLevel(l1key, l2key.GetPubKey());
56 CheckDelegation(dgb.build(), p, l2key.GetPubKey());
57}
58
59// Proof master priv:
60// L4J6gEE4wL9ji2EQbzS5dPMTTsw8LRvcMst1Utij4e3X5ccUSdqW
61// Proof master pub:
62// 023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3
63// Stake priv:
64// KydYrKDNsVnY5uhpLyC4UmazuJvUjNoKJhEEv9f1mdK1D5zcnMSM
65// Stake pub:
66// 02449fb5237efe8f647d32e8b64f06c22d1d40368eaca2a71ffc6a13ecc8bce680
67// Level 1 priv:
68// KzzLLtiYiyFcTXPWUzywt2yEKk5FxkGbMfKhWgBd4oZdt8t8kk77
69// Level 1 pub:
70// 03e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645ef
71// Level 2 priv:
72// KwM6hV6hxZt3Kt4NHMtWQGH5T2SwhpyswodUQC2zmSjg6KWFWkQU
73// Level 2 pub:
74// 03aac52f4cfca700e7e9824298e0184755112e32f359c832f5f6ad2ef62a2c024a
75
76struct TestVector {
77 std::string name;
78 std::string hex;
79 std::string dgid;
80 std::string pubkey;
82};
83
84BOOST_AUTO_TEST_CASE(deserialization) {
85 std::vector<TestVector> testcases{
86 {"Empty delegation",
87 "46116afa1abaab88b96c115c248b77c7d8e099565c5fb40731482c6655ca450d21"
88 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3"
89 "00",
90 "afc74900c1f28b69e466461fb1e0663352da6153be0fcd59280e27f2446391d5",
91 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3",
93 {"One delegation",
94 "46116afa1abaab88b96c115c248b77c7d8e099565c5fb40731482c6655ca450d21"
95 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3"
96 "012103e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645e"
97 "f7d51"
98 "2ddbea7c88dcf38412b58374856a466e165797a69321c0928a89c64521f7e2e767c93"
99 "de645ef5125ec901dcd51347787ca29771e7786bbe402d2d5ead0dc",
100 "ffcd49dc98ebdbc90e731a7b0c89939bfe082f15f3aa82aca657176b83669185",
101 "03e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645ef",
103 {"Two delegation",
104 "46116afa1abaab88b96c115c248b77c7d8e099565c5fb40731482c6655ca450d21"
105 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3"
106 "022103e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645e"
107 "f7d512ddbea7c88dcf38412b58374856a466e165797a69321c0928a89c64521f7e2e7"
108 "67c93de645ef5125ec901dcd51347787ca29771e7786bbe402d2d5ead0dc2103aac52"
109 "f4cfca700e7e9824298e0184755112e32f359c832f5f6ad2ef62a2c024a5cddd0ffe8"
110 "4e12e4bf49e4c0af7c8548e618a24e12495d659f5ba75e114e1526a618aa305b1e69b"
111 "f6ae20b2557999f2e3fec25d5f2271f8b9de0d06ba7344550",
112 "a3f98e6b5ec330219493d109e5c11ed8e302315df4604b5462e9fb80cb0fde89",
113 "03aac52f4cfca700e7e9824298e0184755112e32f359c832f5f6ad2ef62a2c024a",
115 {"Invalid pubkey",
116 "46116afa1abaab88b96c115c248b77c7d8e099565c5fb40731482c6655ca450d21"
117 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3012"
118 "103e49f9df53de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645ef7d"
119 "512ddbea7c88dcf38412b58374856a466e165797a69321c0928a89c64521f7e2e767c"
120 "93de645ef5125ec901dcd51347787ca29771e7786bbe402d2d5ead0dc",
121 "af7e82716489c3cf3f361d449ed815112ff619f7fc34a4803bd958c68d1e2684",
122 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3",
123 DelegationResult::INVALID_SIGNATURE},
124 {"Invalid signature",
125 "46116afa1abaab88b96c115c248b77c7d8e099565c5fb40731482c6655ca450d21"
126 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3"
127 "012103e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645e"
128 "f7d512ddbea7c88dcf38412c58374856a466e165797a69321c0928a89c64521f7e2e7"
129 "67c93de645ef5125ec901dcd51347787ca29771e7786bbe402d2d5ead0dc",
130 "ffcd49dc98ebdbc90e731a7b0c89939bfe082f15f3aa82aca657176b83669185",
131 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3",
132 DelegationResult::INVALID_SIGNATURE},
133 {"Second invalid key",
134 "46116afa1abaab88b96c115c248b77c7d8e099565c5fb40731482c6655ca450d21"
135 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3"
136 "022103e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645e"
137 "f7d512ddbea7c88dcf38412b58374856a466e165797a69321c0928a89c64521f7e2e7"
138 "67c93de645ef5125ec901dcd51347787ca29771e7786bbe402d2d5ead0dc2103aac52"
139 "f4dfca700e7e9824298e0184755112e32f359c832f5f6ad2ef62a2c024a5cddd0ffe8"
140 "4e12e4bf49e4c0af7c8548e618a24e12495d659f5ba75e114e1526a618aa305b1e69b"
141 "f6ae20b2557999f2e3fec25d5f2271f8b9de0d06ba7344550",
142 "b474512f71a3f5a6e94cc3b958fd658ece0d0632ace58c8c8f9f65c2b9ad5fad",
143 "03e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645ef",
144 DelegationResult::INVALID_SIGNATURE},
145 {"Second invalid signature",
146 "46116afa1abaab88b96c115c248b77c7d8e099565c5fb40731482c6655ca450d21"
147 "023beefdde700a6bc02036335b4df141c8bc67bb05a971f5ac2745fd683797dde3"
148 "022103e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645e"
149 "f7d512ddbea7c88dcf38412b58374856a466e165797a69321c0928a89c64521f7e2e7"
150 "67c93de645ef5125ec901dcd51347787ca29771e7786bbe402d2d5ead0dc2103aac52"
151 "f4cfca700e7e9824298e0184755112e32f359c832f5f6ad2ef62a2c024a5cddd0ffe8"
152 "4e12e4bf49e4c0af7c8548e618a24e12495d659f5ba75e114e1526a618aa305b1e69b"
153 "f6ae20b2557999f2e3fec25d5f2271f8b9de0d06ba7344551",
154 "a3f98e6b5ec330219493d109e5c11ed8e302315df4604b5462e9fb80cb0fde89",
155 "03e49f9df52de2dea81cf7838b82521b69f2ea360f1c4eed9e6c89b7d0f9e645ef",
156 DelegationResult::INVALID_SIGNATURE},
157 };
158
159 for (auto &c : testcases) {
160 Delegation dg;
162 BOOST_CHECK(Delegation::FromHex(dg, c.hex, error));
163 BOOST_CHECK_EQUAL(dg.getId(), DelegationId::fromHex(c.dgid));
164
165 DelegationState state;
166 CPubKey pubkey;
167 BOOST_CHECK_EQUAL(dg.verify(state, pubkey),
168 c.result == DelegationResult::NONE);
169 BOOST_CHECK(state.GetResult() == c.result);
170 BOOST_CHECK(pubkey == CPubKey(ParseHex(c.pubkey)));
171 }
172}
173
175 auto proofKey = CKey::MakeCompressedKey();
176 auto p = buildRandomProof(Assert(m_node.chainman)->ActiveChainstate(),
177 123456, 1234, proofKey);
178
179 DelegationBuilder dgb(*p);
180
181 CKey delegatorKey = proofKey;
182 for (size_t i = 0; i < MAX_DELEGATION_LEVELS; i++) {
183 CKey delegatedKey = CKey::MakeCompressedKey();
184 BOOST_CHECK(dgb.addLevel(delegatorKey, delegatedKey.GetPubKey()));
185 delegatorKey = delegatedKey;
186 }
187
188 Delegation dgGood = dgb.build();
189 // Up to MAX_DELEGATION_LEVELS the delegation is verified valid
190 CheckDelegation(dgGood, p, delegatorKey.GetPubKey());
191
192 // Let's add one more delegation level
193 DelegationBuilder dgb2(dgGood);
194 CKey delegatedKey = CKey::MakeCompressedKey();
195 BOOST_CHECK(dgb2.addLevel(delegatorKey, delegatedKey.GetPubKey()));
196 Delegation dgBad = dgb2.build();
197
198 // The delegation is now expected to fail due to too many levels
199 DelegationState state;
200 CPubKey auth;
201 BOOST_CHECK(!dgBad.verify(state, auth));
202 BOOST_CHECK(state.GetResult() == DelegationResult::TOO_MANY_LEVELS);
203}
204
205BOOST_AUTO_TEST_SUITE_END()
#define Assert(val)
Identity function.
Definition: check.h:84
An encapsulated secp256k1 private key.
Definition: key.h:28
static CKey MakeCompressedKey()
Produce a valid compressed key.
Definition: key.cpp:466
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:210
An encapsulated public key.
Definition: pubkey.h:31
Result GetResult() const
Definition: validation.h:122
bool addLevel(const CKey &delegatorKey, const CPubKey &delegatedPubKey)
bool verify(DelegationState &state, CPubKey &auth) const
Definition: delegation.cpp:73
const DelegationId & getId() const
Definition: delegation.h:60
BOOST_AUTO_TEST_CASE(verify_random)
static void CheckDelegation(const Delegation &dg, const ProofRef &p, const CPubKey &expected_pubkey)
bool error(const char *fmt, const Args &...args)
Definition: logging.h:263
@ NONE
Definition: logging.h:39
constexpr size_t MAX_DELEGATION_LEVELS
The maximum number of delegation levels we are willing to verify.
Definition: delegation.h:26
ProofRef buildRandomProof(Chainstate &active_chainstate, uint32_t score, int height, const CKey &masterKey)
Definition: util.cpp:20
DelegationResult
Definition: validation.h:37
NodeContext & m_node
Definition: interfaces.cpp:809
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
std::string dgid
std::string name
std::string pubkey
std::string hex
DelegationResult result
Bilingual messages:
Definition: translation.h:17
template std::vector< std::byte > ParseHex(std::string_view)