wallet: add a set_ring command

This is so one can set rings for spent key images in case the
attackers don't merge the ring matching patch set.
This commit is contained in:
moneromooo-monero 2018-02-28 18:26:06 +00:00
parent 0590f62ab6
commit b09e5181cc
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
6 changed files with 124 additions and 1 deletions

View file

@ -1317,7 +1317,7 @@ bool simple_wallet::print_ring(const std::vector<std::string> &args)
std::stringstream str;
for (const auto &x: ring)
str << x << " ";
success_msg_writer() << tr("Ring size ") << std::to_string(ring.size()) << ": " << str.str();
success_msg_writer() << tr("Ring size ") << std::to_string(ring.size()) << ": " << str.str() << tr(" (absolute)");
}
else
{
@ -1332,6 +1332,81 @@ bool simple_wallet::print_ring(const std::vector<std::string> &args)
return true;
}
bool simple_wallet::set_ring(const std::vector<std::string> &args)
{
crypto::key_image key_image;
if (args.size() < 3)
{
fail_msg_writer() << tr("usage: set_ring <key_image> absolute|relative <index> [<index>...]");
return true;
}
if (!epee::string_tools::hex_to_pod(args[0], key_image))
{
fail_msg_writer() << tr("Invalid key image");
return true;
}
bool relative;
if (args[1] == "absolute")
{
relative = false;
}
else if (args[1] == "relative")
{
relative = true;
}
else
{
fail_msg_writer() << tr("Missing absolute or relative keyword");
return true;
}
std::vector<uint64_t> ring;
for (size_t n = 2; n < args.size(); ++n)
{
ring.resize(ring.size() + 1);
if (!string_tools::get_xtype_from_string(ring.back(), args[n]))
{
fail_msg_writer() << tr("invalid index: must be a strictly positive unsigned integer");
return true;
}
if (relative)
{
if (ring.size() > 1 && !ring.back())
{
fail_msg_writer() << tr("invalid index: must be a strictly positive unsigned integer");
return true;
}
uint64_t sum = 0;
for (uint64_t out: ring)
{
if (out > std::numeric_limits<uint64_t>::max() - sum)
{
fail_msg_writer() << tr("invalid index: indices wrap");
return true;
}
sum += out;
}
}
else
{
if (ring.size() > 1 && ring[ring.size() - 2] >= ring[ring.size() - 1])
{
fail_msg_writer() << tr("invalid index: indices should be in strictly ascending order");
return true;
}
}
}
if (!m_wallet->set_ring(key_image, ring, relative))
{
fail_msg_writer() << tr("failed to set ring");
return true;
}
return true;
}
bool simple_wallet::blackball(const std::vector<std::string> &args)
{
crypto::public_key output;
@ -2166,6 +2241,10 @@ simple_wallet::simple_wallet()
boost::bind(&simple_wallet::print_ring, this, _1),
tr("print_ring <key_image>"),
tr("Print the ring used to spend a given key image (if the ring size is > 1)"));
m_cmd_binder.set_handler("set_ring",
boost::bind(&simple_wallet::set_ring, this, _1),
tr("set_ring <key_image> absolute|relative <index> [<index>...]"),
tr("Set the ring used for a given key image, so it can be reused in a fork"));
m_cmd_binder.set_handler("save_known_rings",
boost::bind(&simple_wallet::save_known_rings, this, _1),
tr("save_known_rings"),