|
|
@ -1317,7 +1317,7 @@ bool simple_wallet::print_ring(const std::vector<std::string> &args)
|
|
|
|
std::stringstream str;
|
|
|
|
std::stringstream str;
|
|
|
|
for (const auto &x: ring)
|
|
|
|
for (const auto &x: ring)
|
|
|
|
str << x << " ";
|
|
|
|
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
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1332,6 +1332,81 @@ bool simple_wallet::print_ring(const std::vector<std::string> &args)
|
|
|
|
return true;
|
|
|
|
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)
|
|
|
|
bool simple_wallet::blackball(const std::vector<std::string> &args)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
crypto::public_key output;
|
|
|
|
crypto::public_key output;
|
|
|
@ -2166,6 +2241,10 @@ simple_wallet::simple_wallet()
|
|
|
|
boost::bind(&simple_wallet::print_ring, this, _1),
|
|
|
|
boost::bind(&simple_wallet::print_ring, this, _1),
|
|
|
|
tr("print_ring <key_image>"),
|
|
|
|
tr("print_ring <key_image>"),
|
|
|
|
tr("Print the ring used to spend a given key image (if the ring size is > 1)"));
|
|
|
|
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",
|
|
|
|
m_cmd_binder.set_handler("save_known_rings",
|
|
|
|
boost::bind(&simple_wallet::save_known_rings, this, _1),
|
|
|
|
boost::bind(&simple_wallet::save_known_rings, this, _1),
|
|
|
|
tr("save_known_rings"),
|
|
|
|
tr("save_known_rings"),
|
|
|
|