Electroneum
Loading...
Searching...
No Matches
multisig.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-2019, The Monero Project
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification, are
6// permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this list of
9// conditions and the following disclaimer.
10//
11// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12// of conditions and the following disclaimer in the documentation and/or other
13// materials provided with the distribution.
14//
15// 3. Neither the name of the copyright holder nor the names of its contributors may be
16// used to endorse or promote products derived from this software without specific
17// prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29#include "gtest/gtest.h"
30
31#include <cstdint>
32
33#include "wallet/wallet2.h"
34
35static const struct
36{
37 const char *address;
38 const char *spendkey;
39} test_addresses[] =
40{
41 {
42 "etnkQfrWyE18qgir1RPR31Vcm8ibph8a4TArBzp9hx6qG5AtWJ4cg9BYcVmDkbLsqvag2xZuBVtzATMbGENvhbEr2GpNu7NkqX",
43 "23a662c983674c3654d2f2d7c72e055523ef6bdb8bb8290d626268e73c5b4600"
44 },
45 {
46 "etnkByEHsraTqRBdDrrV2m1kDCHa1NyBpDWJ1XeB5ZGRGtdbUcteBLwN9LBpiDF6EjDj8qEUFqasKC6RNwLHuUju7PCaanugxk",
47 "77dbbfaa83fa79c9280340893dca48a868c23a1b9f8835ec421ce7281e882509"
48 },
49 {
50 "etnkQNki9u1KyZvnh4WRDsLPQbZgcRo8WFo7JfAftDU7FZhyuxmxxHQMkkxLt8y7RwTKeH1hdMZ1V7ACPDm4HwEw1tLMWjW8Lv",
51 "5f17f13c96c6fcc8ec3f9f539ea00e8087224cd9071fbecfec07441b9e64b60b"
52 },
53 {
54 "etnk3G6WfJqgTMuuAZXcKxMmv7WpVGC977okK94spzsWc3acWLjebL1MdWN2uNqLygGEHCQWtzf81Phbz952LmK35vx7iuF2zV",
55 "7083f2c357c0fc2f2fabc5d6751d989141aad8361899d427bbc0d03ca2f2850d"
56 },
57 {
58 "etnkAo9GFotYKPmgKbEXBAHhvuwcUU1vDaedMf9TLMdQ3p7tiyE6mr1BNWtyrxDoGs9dPAJ9nKJ5jLt2Gk8oGcYE4JoSB2EreS",
59 "4b754c17b2788826bf57eb028ac8af014c3a9c126a94920c1e00924a4a98cf0d"
60 }
61};
62
63static const size_t KEYS_COUNT = 5;
64
65static void make_wallet(unsigned int idx, tools::wallet2 &wallet)
66{
67 ASSERT_TRUE(idx < sizeof(test_addresses) / sizeof(test_addresses[0]));
68
71
72 try
73 {
74 wallet.init("", boost::none, boost::asio::ip::tcp::endpoint{}, 0, true, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
75 wallet.set_subaddress_lookahead(1, 1);
76 wallet.generate("", "", spendkey, true, false);
79 }
80 catch (const std::exception &e)
81 {
82 MFATAL("Error creating test wallet: " << e.what());
83 ASSERT_TRUE(0);
84 }
85}
86
87static std::vector<std::string> exchange_round(std::vector<tools::wallet2>& wallets, const std::vector<std::string>& mis)
88{
89 std::vector<std::string> new_infos;
90 for (size_t i = 0; i < wallets.size(); ++i) {
91 new_infos.push_back(wallets[i].exchange_multisig_keys("", mis));
92 }
93
94 return new_infos;
95}
96
97static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
98{
99 ASSERT_TRUE(wallets.size() > 1 && wallets.size() <= KEYS_COUNT);
100 ASSERT_TRUE(M <= wallets.size());
101
102 std::vector<std::string> mis(wallets.size());
103
104 for (size_t i = 0; i < wallets.size(); ++i) {
105 make_wallet(i, wallets[i]);
106
107 mis[i] = wallets[i].get_multisig_info();
108 }
109
110 for (auto& wallet: wallets) {
111 ASSERT_FALSE(wallet.multisig());
112 }
113
114 std::vector<std::string> mxis;
115 for (size_t i = 0; i < wallets.size(); ++i) {
116 // it's ok to put all of multisig keys in this function. it throws in case of error
117 mxis.push_back(wallets[i].make_multisig("", mis, M));
118 }
119
120 while (!mxis[0].empty()) {
121 mxis = exchange_round(wallets, mxis);
122 }
123
124 for (size_t i = 0; i < wallets.size(); ++i) {
125 ASSERT_TRUE(mxis[i].empty());
126 bool ready;
127 uint32_t threshold, total;
128 ASSERT_TRUE(wallets[i].multisig(&ready, &threshold, &total));
129 ASSERT_TRUE(ready);
131 ASSERT_TRUE(total == wallets.size());
132
133 if (i != 0) {
134 // "equals" is transitive relation so we need only to compare first wallet's address to each others' addresses. no need to compare 0's address with itself.
135 ASSERT_TRUE(wallets[0].get_account().get_public_address_str(cryptonote::TESTNET) == wallets[i].get_account().get_public_address_str(cryptonote::TESTNET));
136 }
137 }
138}
139
140TEST(multisig, make_2_2)
141{
142 std::vector<tools::wallet2> wallets(2);
143 make_wallets(wallets, 2);
144}
145
146TEST(multisig, make_3_3)
147{
148 std::vector<tools::wallet2> wallets(3);
149 make_wallets(wallets, 3);
150}
151
152TEST(multisig, make_2_3)
153{
154 std::vector<tools::wallet2> wallets(3);
155 make_wallets(wallets, 2);
156}
157
158TEST(multisig, make_2_4)
159{
160 std::vector<tools::wallet2> wallets(4);
161 make_wallets(wallets, 2);
162}
163
164TEST(multisig, make_2_5)
165{
166 std::vector<tools::wallet2> wallets(5);
167 make_wallets(wallets, 2);
168}
uint8_t threshold
std::string get_public_address_str(network_type nettype) const
Definition account.cpp:269
const account_keys & get_keys() const
Definition account.cpp:264
cryptonote::account_base & get_account()
Definition wallet2.h:734
bool init(std::string daemon_address="http://localhost:8080", boost::optional< epee::net_utils::http::login > daemon_login=boost::none, boost::asio::ip::tcp::endpoint proxy={}, uint64_t upper_transaction_weight_limit=0, bool trusted_daemon=true, epee::net_utils::ssl_options_t ssl_options=epee::net_utils::ssl_support_t::e_ssl_support_autodetect, std::string blockchain_db_path="")
Definition wallet2.cpp:1282
void set_subaddress_lookahead(size_t major, size_t minor)
Definition wallet2.cpp:1535
bool multisig(bool *ready=NULL, uint32_t *threshold=NULL, uint32_t *total=NULL) const
Definition wallet2.cpp:5634
void generate(const std::string &wallet_, const epee::wipeable_string &password, const epee::wipeable_string &multisig_data, bool create_address_file=false)
Generates a wallet or restores one.
Definition wallet2.cpp:4869
#define ASSERT_FALSE(condition)
Definition gtest.h:1868
#define TEST(test_case_name, test_name)
Definition gtest.h:2187
#define ASSERT_TRUE(condition)
Definition gtest.h:1865
#define MFATAL(x)
Definition misc_log_ex.h:72
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition crypto.h:82
std::string pod_to_hex(const t_pod_type &s)
bool hex_to_pod(const std::string &hex_str, t_pod_type &s)
unsigned int uint32_t
Definition stdint.h:126
crypto::secret_key m_spend_secret_key
Definition account.h:44
const char * address
Definition multisig.cpp:37
const char * spendkey
Definition multisig.cpp:38