aboutsummaryrefslogtreecommitdiff
path: root/src/simplewallet/simplewallet.cpp
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-02-28 18:26:06 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-03-16 10:32:51 +0000
commitb09e5181cc7c24fc6cf13b4a43044833bd2763fa (patch)
treeb84eb0ddb4b59cb21a1cd478db58c173444a2f1a /src/simplewallet/simplewallet.cpp
parentnew blockchain_usage tool, reports on output usage (diff)
downloadmonero-b09e5181cc7c24fc6cf13b4a43044833bd2763fa.tar.xz
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.
Diffstat (limited to 'src/simplewallet/simplewallet.cpp')
-rw-r--r--src/simplewallet/simplewallet.cpp81
1 files changed, 80 insertions, 1 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 89edee3fe..61a234317 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -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"),