wallet: factor multisig info parsing
This commit is contained in:
parent
31a97e761e
commit
98db7ee467
|
@ -771,61 +771,13 @@ bool simple_wallet::make_multisig(const std::vector<std::string> &args)
|
||||||
return true;
|
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();
|
LOCK_IDLE_SCOPE();
|
||||||
|
|
||||||
try
|
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())
|
if (!multisig_extra_info.empty())
|
||||||
{
|
{
|
||||||
success_msg_writer() << tr("Another step is needed");
|
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;
|
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: ")
|
success_msg_writer() << std::to_string(threshold) << "/" << total << tr(" multisig address: ")
|
||||||
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
<< m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||||
|
|
||||||
|
|
|
@ -2895,6 +2895,60 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
|
||||||
return extra_multisig_info;
|
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)
|
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");
|
CHECK_AND_ASSERT_THROW_MES(!pkeys.empty(), "empty pkeys");
|
||||||
|
|
|
@ -471,6 +471,14 @@ namespace tools
|
||||||
* \return empty if done, non empty if we need to send another string
|
* \return empty if done, non empty if we need to send another string
|
||||||
* to other participants
|
* 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,
|
std::string make_multisig(const epee::wipeable_string &password,
|
||||||
const std::vector<crypto::secret_key> &view_keys,
|
const std::vector<crypto::secret_key> &view_keys,
|
||||||
const std::vector<crypto::public_key> &spend_keys,
|
const std::vector<crypto::public_key> &spend_keys,
|
||||||
|
|
|
@ -2539,58 +2539,9 @@ namespace tools
|
||||||
return false;
|
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
|
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());
|
res.address = m_wallet->get_account().get_public_address_str(m_wallet->testnet());
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
|
|
Loading…
Reference in New Issue