From 98db7ee467fb4f73ce5e748d4891326b84a4c93a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 18 Nov 2017 11:24:38 +0000 Subject: [PATCH] wallet: factor multisig info parsing --- src/simplewallet/simplewallet.cpp | 57 +++---------------------------- src/wallet/wallet2.cpp | 54 +++++++++++++++++++++++++++++ src/wallet/wallet2.h | 8 +++++ src/wallet/wallet_rpc_server.cpp | 51 +-------------------------- 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 &args) return true; } - // parse all multisig info - std::vector secret_keys(args.size() - 1); - std::vector 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 &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 &info, + uint32_t threshold) +{ + // parse all multisig info + std::vector secret_keys(info.size()); + std::vector 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 pkeys, std::vector 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 @@ -471,6 +471,14 @@ namespace tools * \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 &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 &view_keys, const std::vector &spend_keys, 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 secret_keys(req.multisig_info.size()); - std::vector 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)