aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/simplewallet/simplewallet.cpp57
-rw-r--r--src/wallet/wallet2.cpp54
-rw-r--r--src/wallet/wallet2.h8
-rw-r--r--src/wallet/wallet_rpc_server.cpp51
4 files changed, 68 insertions, 102 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 5c94f1704..64e665fb3 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -771,61 +771,13 @@ bool simple_wallet::make_multisig(const std::vector<std::string> &args)
return true;
}
- // parse all multisig info
- std::vector<crypto::secret_key> secret_keys(args.size() - 1);
- std::vector<crypto::public_key> public_keys(args.size() - 1);
- for (size_t i = 1; i < args.size(); ++i)
- {
- if (!tools::wallet2::verify_multisig_info(args[i], secret_keys[i - 1], public_keys[i - 1]))
- {
- fail_msg_writer() << tr("Bad multisig info: ") << args[i];
- return true;
- }
- }
-
- // remove duplicates
- for (size_t i = 0; i < secret_keys.size(); ++i)
- {
- for (size_t j = i + 1; j < secret_keys.size(); ++j)
- {
- if (rct::sk2rct(secret_keys[i]) == rct::sk2rct(secret_keys[j]))
- {
- message_writer() << tr("Duplicate key found, ignoring");
- secret_keys[j] = secret_keys.back();
- public_keys[j] = public_keys.back();
- secret_keys.pop_back();
- public_keys.pop_back();
- --j;
- }
- }
- }
-
- // people may include their own, weed it out
- const crypto::secret_key local_skey = cryptonote::get_multisig_blinded_secret_key(m_wallet->get_account().get_keys().m_view_secret_key);
- const crypto::public_key local_pkey = m_wallet->get_multisig_signer_public_key(m_wallet->get_account().get_keys().m_spend_secret_key);
- for (size_t i = 0; i < secret_keys.size(); ++i)
- {
- if (secret_keys[i] == local_skey)
- {
- message_writer() << tr("Local key is present, ignoring");
- secret_keys[i] = secret_keys.back();
- public_keys[i] = public_keys.back();
- secret_keys.pop_back();
- public_keys.pop_back();
- --i;
- }
- else if (public_keys[i] == local_pkey)
- {
- fail_msg_writer() << tr("Found local spend public key, but not local view secret key - something very weird");
- return true;
- }
- }
-
LOCK_IDLE_SCOPE();
try
{
- std::string multisig_extra_info = m_wallet->make_multisig(orig_pwd_container->password(), secret_keys, public_keys, threshold);
+ auto local_args = args;
+ local_args.erase(local_args.begin());
+ std::string multisig_extra_info = m_wallet->make_multisig(orig_pwd_container->password(), local_args, threshold);
if (!multisig_extra_info.empty())
{
success_msg_writer() << tr("Another step is needed");
@@ -840,7 +792,8 @@ bool simple_wallet::make_multisig(const std::vector<std::string> &args)
return true;
}
- uint32_t total = secret_keys.size() + 1;
+ uint32_t total;
+ m_wallet->multisig(NULL, &threshold, &total);
success_msg_writer() << std::to_string(threshold) << "/" << total << tr(" multisig address: ")
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 635264d70..70180e080 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2895,6 +2895,60 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
return extra_multisig_info;
}
+std::string wallet2::make_multisig(const epee::wipeable_string &password,
+ const std::vector<std::string> &info,
+ uint32_t threshold)
+{
+ // parse all multisig info
+ std::vector<crypto::secret_key> secret_keys(info.size());
+ std::vector<crypto::public_key> public_keys(info.size());
+ for (size_t i = 0; i < info.size(); ++i)
+ {
+ THROW_WALLET_EXCEPTION_IF(!verify_multisig_info(info[i], secret_keys[i], public_keys[i]),
+ error::wallet_internal_error, "Bad multisig info: " + info[i]);
+ }
+
+ // remove duplicates
+ for (size_t i = 0; i < secret_keys.size(); ++i)
+ {
+ for (size_t j = i + 1; j < secret_keys.size(); ++j)
+ {
+ if (rct::sk2rct(secret_keys[i]) == rct::sk2rct(secret_keys[j]))
+ {
+ MDEBUG("Duplicate key found, ignoring");
+ secret_keys[j] = secret_keys.back();
+ public_keys[j] = public_keys.back();
+ secret_keys.pop_back();
+ public_keys.pop_back();
+ --j;
+ }
+ }
+ }
+
+ // people may include their own, weed it out
+ const crypto::secret_key local_skey = cryptonote::get_multisig_blinded_secret_key(get_account().get_keys().m_view_secret_key);
+ const crypto::public_key local_pkey = get_multisig_signer_public_key(get_account().get_keys().m_spend_secret_key);
+ for (size_t i = 0; i < secret_keys.size(); ++i)
+ {
+ if (secret_keys[i] == local_skey)
+ {
+ MDEBUG("Local key is present, ignoring");
+ secret_keys[i] = secret_keys.back();
+ public_keys[i] = public_keys.back();
+ secret_keys.pop_back();
+ public_keys.pop_back();
+ --i;
+ }
+ else
+ {
+ THROW_WALLET_EXCEPTION_IF(public_keys[i] == local_pkey, error::wallet_internal_error,
+ "Found local spend public key, but not local view secret key - something very weird");
+ }
+ }
+
+ return make_multisig(password, secret_keys, public_keys, threshold);
+}
+
bool wallet2::finalize_multisig(const epee::wipeable_string &password, std::unordered_set<crypto::public_key> pkeys, std::vector<crypto::public_key> signers)
{
CHECK_AND_ASSERT_THROW_MES(!pkeys.empty(), "empty pkeys");
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index cb9d7e980..399287c3e 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -472,6 +472,14 @@ namespace tools
* to other participants
*/
std::string make_multisig(const epee::wipeable_string &password,
+ const std::vector<std::string> &info,
+ uint32_t threshold);
+ /*!
+ * \brief Creates a multisig wallet
+ * \return empty if done, non empty if we need to send another string
+ * to other participants
+ */
+ std::string make_multisig(const epee::wipeable_string &password,
const std::vector<crypto::secret_key> &view_keys,
const std::vector<crypto::public_key> &spend_keys,
uint32_t threshold);
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 4c14433f4..0482b9dd6 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -2539,58 +2539,9 @@ namespace tools
return false;
}
- // parse all multisig info
- std::vector<crypto::secret_key> secret_keys(req.multisig_info.size());
- std::vector<crypto::public_key> public_keys(req.multisig_info.size());
- for (size_t i = 0; i < req.multisig_info.size(); ++i)
- {
- if (!m_wallet->verify_multisig_info(req.multisig_info[i], secret_keys[i], public_keys[i]))
- {
- er.code = WALLET_RPC_ERROR_CODE_BAD_MULTISIG_INFO;
- er.message = "Bad multisig info: " + req.multisig_info[i];
- return false;
- }
- }
-
- // remove duplicates
- for (size_t i = 1; i < secret_keys.size(); ++i)
- {
- for (size_t j = i + 1; j < secret_keys.size(); ++j)
- {
- if (rct::sk2rct(secret_keys[i]) == rct::sk2rct(secret_keys[j]))
- {
- secret_keys[j] = secret_keys.back();
- public_keys[j] = public_keys.back();
- secret_keys.pop_back();
- public_keys.pop_back();
- --j;
- }
- }
- }
-
- // people may include their own, weed it out
- crypto::secret_key local_skey = cryptonote::get_multisig_blinded_secret_key(m_wallet->get_account().get_keys().m_view_secret_key);
- for (size_t i = 0; i < secret_keys.size(); ++i)
- {
- if (rct::sk2rct(secret_keys[i]) == rct::sk2rct(local_skey))
- {
- secret_keys[i] = secret_keys.back();
- public_keys[i] = public_keys.back();
- secret_keys.pop_back();
- public_keys.pop_back();
- --i;
- }
- else if (public_keys[i] == m_wallet->get_account().get_keys().m_account_address.m_spend_public_key)
- {
- er.code = WALLET_RPC_ERROR_CODE_BAD_MULTISIG_INFO;
- er.message = "Found local spend public key, but not local view secret key - something very weird";
- return false;
- }
- }
-
try
{
- res.multisig_info = m_wallet->make_multisig(req.password, secret_keys, public_keys, req.threshold);
+ res.multisig_info = m_wallet->make_multisig(req.password, req.multisig_info, req.threshold);
res.address = m_wallet->get_account().get_public_address_str(m_wallet->testnet());
}
catch (const std::exception &e)