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