From a7da8208f5b26426f1562c01a06afcc775681c2b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 4 Mar 2018 13:32:35 +0000 Subject: wallet2_api: add blackball api --- src/wallet/api/CMakeLists.txt | 1 + src/wallet/api/wallet.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++ src/wallet/api/wallet.h | 2 ++ src/wallet/api/wallet2_api.h | 7 ++++++ 4 files changed, 65 insertions(+) (limited to 'src/wallet/api') diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt index 1e67495f1..d6f2bf6b7 100644 --- a/src/wallet/api/CMakeLists.txt +++ b/src/wallet/api/CMakeLists.txt @@ -69,6 +69,7 @@ target_link_libraries(wallet_api common cryptonote_core mnemonics + ${LMDB_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_SERIALIZATION_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index fb9e8b28b..64407a341 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -68,6 +68,15 @@ namespace { static const int DEFAULT_REMOTE_NODE_REFRESH_INTERVAL_MILLIS = 1000 * 10; // Connection timeout 30 sec static const int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 1000 * 30; + + std::string get_default_ringdb_path() + { + boost::filesystem::path dir = tools::get_default_data_dir(); + // remove .bitmonero, replace with .shared-ringdb + dir = dir.remove_filename(); + dir /= ".shared-ringdb"; + return dir.string(); + } } struct Wallet2CallbackImpl : public tools::i_wallet2_callback @@ -590,6 +599,7 @@ bool WalletImpl::open(const std::string &path, const std::string &password) // Rebuilding wallet cache, using refresh height from .keys file m_rebuildWalletCache = true; } + m_wallet->set_ring_database(get_default_ringdb_path()); m_wallet->load(path, password); m_password = password; @@ -1777,6 +1787,7 @@ void WalletImpl::doRefresh() if (m_history->count() == 0) { m_history->refresh(); } + m_wallet->find_and_save_rings(false); } else { LOG_PRINT_L3(__FUNCTION__ << ": skipping refresh - daemon is not synced"); } @@ -1897,6 +1908,50 @@ bool WalletImpl::useForkRules(uint8_t version, int64_t early_blocks) const return m_wallet->use_fork_rules(version,early_blocks); } +bool WalletImpl::blackballOutputs(const std::vector &pubkeys, bool add) +{ + std::vector raw_pubkeys; + raw_pubkeys.reserve(pubkeys.size()); + for (const std::string &str: pubkeys) + { + crypto::public_key pkey; + if (!epee::string_tools::hex_to_pod(str, pkey)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse output public key"); + return false; + } + raw_pubkeys.push_back(pkey); + } + bool ret = m_wallet->set_blackballed_outputs(raw_pubkeys, add); + if (!ret) + { + m_status = Status_Error; + m_errorString = tr("Failed to set blackballed outputs"); + return false; + } + return true; +} + +bool WalletImpl::unblackballOutput(const std::string &pubkey) +{ + crypto::public_key raw_pubkey; + if (!epee::string_tools::hex_to_pod(pubkey, raw_pubkey)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse output public key"); + return false; + } + bool ret = m_wallet->unblackball_output(raw_pubkey); + if (!ret) + { + m_status = Status_Error; + m_errorString = tr("Failed to unblackball output"); + return false; + } + return true; +} + } // namespace namespace Bitmonero = Monero; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 9b4a0cc12..2bc34c592 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -163,6 +163,8 @@ public: virtual std::string getDefaultDataDir() const; virtual bool lightWalletLogin(bool &isNewWallet) const; virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status); + virtual bool blackballOutputs(const std::vector &pubkeys, bool add); + virtual bool unblackballOutput(const std::string &pubkey); private: void clearStatus() const; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 87c1cccfa..df74e5885 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -756,6 +757,12 @@ struct Wallet */ virtual bool rescanSpent() = 0; + //! blackballs a set of outputs + virtual bool blackballOutputs(const std::vector &pubkeys, bool add) = 0; + + //! unblackballs an output + virtual bool unblackballOutput(const std::string &pubkey) = 0; + //! Light wallet authenticate and login virtual bool lightWalletLogin(bool &isNewWallet) const = 0; -- cgit v1.2.3 From b057a21d56a19f109a58ba873ec2fd69ee533cd5 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 5 Mar 2018 15:04:59 +0000 Subject: wallet2_api: add ring api --- src/wallet/api/wallet.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/wallet/api/wallet.h | 2 ++ src/wallet/api/wallet2_api.h | 6 ++++++ 3 files changed, 46 insertions(+) (limited to 'src/wallet/api') diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 64407a341..be3ca9853 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1952,6 +1952,44 @@ bool WalletImpl::unblackballOutput(const std::string &pubkey) return true; } +bool WalletImpl::getRing(const std::string &key_image, std::vector &ring) const +{ + crypto::key_image raw_key_image; + if (!epee::string_tools::hex_to_pod(key_image, raw_key_image)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse key image"); + return false; + } + bool ret = m_wallet->get_ring(raw_key_image, ring); + if (!ret) + { + m_status = Status_Error; + m_errorString = tr("Failed to get ring"); + return false; + } + return true; +} + +bool WalletImpl::setRing(const std::string &key_image, const std::vector &ring, bool relative) +{ + crypto::key_image raw_key_image; + if (!epee::string_tools::hex_to_pod(key_image, raw_key_image)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse key image"); + return false; + } + bool ret = m_wallet->set_ring(raw_key_image, ring, relative); + if (!ret) + { + m_status = Status_Error; + m_errorString = tr("Failed to set ring"); + return false; + } + return true; +} + } // namespace namespace Bitmonero = Monero; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 2bc34c592..9d40008d1 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -165,6 +165,8 @@ public: virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status); virtual bool blackballOutputs(const std::vector &pubkeys, bool add); virtual bool unblackballOutput(const std::string &pubkey); + virtual bool getRing(const std::string &key_image, std::vector &ring) const; + virtual bool setRing(const std::string &key_image, const std::vector &ring, bool relative); private: void clearStatus() const; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index df74e5885..b67e13ac5 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -763,6 +763,12 @@ struct Wallet //! unblackballs an output virtual bool unblackballOutput(const std::string &pubkey) = 0; + //! gets the ring used for a key image, if any + virtual bool getRing(const std::string &key_image, std::vector &ring) const = 0; + + //! sets the ring used for a key image + virtual bool setRing(const std::string &key_image, const std::vector &ring, bool relative) = 0; + //! Light wallet authenticate and login virtual bool lightWalletLogin(bool &isNewWallet) const = 0; -- cgit v1.2.3 From 798535149d85d2a1db9f6c21584fd43368cd3fe1 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 12 Mar 2018 12:33:05 +0000 Subject: wallet2_api: add key reuse mitigations API --- src/wallet/api/wallet.cpp | 15 +++++++++++++++ src/wallet/api/wallet.h | 3 +++ src/wallet/api/wallet2_api.h | 9 +++++++++ 3 files changed, 27 insertions(+) (limited to 'src/wallet/api') diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index be3ca9853..4838395cd 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1990,6 +1990,21 @@ bool WalletImpl::setRing(const std::string &key_image, const std::vectorsegregate_pre_fork_outputs(segregate); +} + +void WalletImpl::segregationHeight(uint64_t height) +{ + m_wallet->segregation_height(height); +} + +void WalletImpl::keyReuseMitigation2(bool mitigation) +{ + m_wallet->key_reuse_mitigation2(mitigation); +} + } // namespace namespace Bitmonero = Monero; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 9d40008d1..4bde20959 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -167,6 +167,9 @@ public: virtual bool unblackballOutput(const std::string &pubkey); virtual bool getRing(const std::string &key_image, std::vector &ring) const; virtual bool setRing(const std::string &key_image, const std::vector &ring, bool relative); + virtual void segregatePreForkOutputs(bool segregate); + virtual void segregationHeight(uint64_t height); + virtual void keyReuseMitigation2(bool mitigation); private: void clearStatus() const; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index b67e13ac5..c77e495a2 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -769,6 +769,15 @@ struct Wallet //! sets the ring used for a key image virtual bool setRing(const std::string &key_image, const std::vector &ring, bool relative) = 0; + //! sets whether pre-fork outs are to be segregated + virtual void segregatePreForkOutputs(bool segregate) = 0; + + //! sets the height where segregation should occur + virtual void segregationHeight(uint64_t height) = 0; + + //! secondary key reuse mitigation + virtual void keyReuseMitigation2(bool mitigation) = 0; + //! Light wallet authenticate and login virtual bool lightWalletLogin(bool &isNewWallet) const = 0; -- cgit v1.2.3 From eac3a11ed330faefa01685e98cf91e9ac1e31135 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 14 Mar 2018 19:13:55 +0000 Subject: wallet: more user friendly print_ring It can now take a txid (to display rings for all its inputs), and will print rings in a format that set_ring understands --- src/simplewallet/simplewallet.cpp | 31 +++++++++++++++++++++--------- src/wallet/api/wallet.cpp | 24 +++++++++++++++++++++++ src/wallet/api/wallet.h | 1 + src/wallet/api/wallet2_api.h | 3 +++ src/wallet/wallet2.cpp | 40 +++++++++++++++++++++++++++++++++++++-- src/wallet/wallet2.h | 15 ++++++++++++--- 6 files changed, 100 insertions(+), 14 deletions(-) (limited to 'src/wallet/api') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 61a234317..3c257979e 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1297,9 +1297,10 @@ bool simple_wallet::export_raw_multisig(const std::vector &args) bool simple_wallet::print_ring(const std::vector &args) { crypto::key_image key_image; + crypto::hash txid; if (args.size() != 1) { - fail_msg_writer() << tr("usage: print_ring "); + fail_msg_writer() << tr("usage: print_ring "); return true; } @@ -1308,20 +1309,32 @@ bool simple_wallet::print_ring(const std::vector &args) fail_msg_writer() << tr("Invalid key image"); return true; } + // this one will always work, they're all 32 byte hex + if (!epee::string_tools::hex_to_pod(args[0], txid)) + { + fail_msg_writer() << tr("Invalid txid"); + return true; + } std::vector ring; + std::vector>> rings; try { if (m_wallet->get_ring(key_image, ring)) + rings.push_back({key_image, ring}); + else if (!m_wallet->get_rings(txid, rings)) { - std::stringstream str; - for (const auto &x: ring) - str << x << " "; - success_msg_writer() << tr("Ring size ") << std::to_string(ring.size()) << ": " << str.str() << tr(" (absolute)"); + fail_msg_writer() << tr("Key image either not spent, or spent with mixin 0"); + return true; } - else + + for (const auto &ring: rings) { - fail_msg_writer() << tr("Key image either not spent, or spent with mixin 0"); + std::stringstream str; + for (const auto &x: ring.second) + str << x<< " "; + // do NOT translate this "absolute" below, the lin can be used as input to set_ring + success_msg_writer() << epee::string_tools::pod_to_hex(ring.first) << " absolute " << str.str(); } } catch (const std::exception &e) @@ -2239,8 +2252,8 @@ simple_wallet::simple_wallet() tr("Export a signed multisig transaction to a file")); m_cmd_binder.set_handler("print_ring", boost::bind(&simple_wallet::print_ring, this, _1), - tr("print_ring "), - tr("Print the ring used to spend a given key image (if the ring size is > 1)")); + tr("print_ring | "), + tr("Print the ring(s) used to spend a given key image or transaction (if the ring size is > 1)")); m_cmd_binder.set_handler("set_ring", boost::bind(&simple_wallet::set_ring, this, _1), tr("set_ring absolute|relative [...]"), diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 4838395cd..b02884f67 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1971,6 +1971,30 @@ bool WalletImpl::getRing(const std::string &key_image, std::vector &ri return true; } +bool WalletImpl::getRings(const std::string &txid, std::vector>> &rings) const +{ + crypto::hash raw_txid; + if (!epee::string_tools::hex_to_pod(txid, raw_txid)) + { + m_status = Status_Error; + m_errorString = tr("Failed to parse txid"); + return false; + } + std::vector>> raw_rings; + bool ret = m_wallet->get_rings(raw_txid, raw_rings); + if (!ret) + { + m_status = Status_Error; + m_errorString = tr("Failed to get rings"); + return false; + } + for (const auto &r: raw_rings) + { + rings.push_back(std::make_pair(epee::string_tools::pod_to_hex(r.first), r.second)); + } + return true; +} + bool WalletImpl::setRing(const std::string &key_image, const std::vector &ring, bool relative) { crypto::key_image raw_key_image; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 4bde20959..4929c9673 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -166,6 +166,7 @@ public: virtual bool blackballOutputs(const std::vector &pubkeys, bool add); virtual bool unblackballOutput(const std::string &pubkey); virtual bool getRing(const std::string &key_image, std::vector &ring) const; + virtual bool getRings(const std::string &txid, std::vector>> &rings) const; virtual bool setRing(const std::string &key_image, const std::vector &ring, bool relative); virtual void segregatePreForkOutputs(bool segregate); virtual void segregationHeight(uint64_t height); diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index c77e495a2..d4e41c5aa 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -766,6 +766,9 @@ struct Wallet //! gets the ring used for a key image, if any virtual bool getRing(const std::string &key_image, std::vector &ring) const = 0; + //! gets the rings used for a txid, if any + virtual bool getRings(const std::string &txid, std::vector>> &rings) const = 0; + //! sets the ring used for a key image virtual bool setRing(const std::string &key_image, const std::vector &ring, bool relative) = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 3d28e80ef..6d941163e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1521,6 +1521,14 @@ void wallet2::process_outgoing(const crypto::hash &txid, const cryptonote::trans entry.first->second.m_subaddr_account = subaddr_account; entry.first->second.m_subaddr_indices = subaddr_indices; } + + for (const auto &in: tx.vin) + { + if (in.type() != typeid(cryptonote::txin_to_key)) + continue; + const auto &txin = boost::get(in); + entry.first->second.m_rings.push_back(std::make_pair(txin.k_image, txin.key_offsets)); + } entry.first->second.m_block_height = height; entry.first->second.m_timestamp = ts; entry.first->second.m_unlock_time = tx.unlock_time; @@ -4390,6 +4398,13 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amo utd.m_timestamp = time(NULL); utd.m_subaddr_account = subaddr_account; utd.m_subaddr_indices = subaddr_indices; + for (const auto &in: tx.vin) + { + if (in.type() != typeid(cryptonote::txin_to_key)) + continue; + const auto &txin = boost::get(in); + utd.m_rings.push_back(std::make_pair(txin.k_image, txin.key_offsets)); + } } //---------------------------------------------------------------------------------------------------- @@ -4545,8 +4560,6 @@ void wallet2::commit_tx(pending_tx& ptx) m_additional_tx_keys.insert(std::make_pair(txid, ptx.additional_tx_keys)); } - add_rings(ptx.tx); - LOG_PRINT_L2("transaction " << txid << " generated ok and sent to daemon, key_images: [" << ptx.key_images << "]"); for(size_t idx: ptx.selected_transfers) @@ -5490,6 +5503,29 @@ bool wallet2::get_ring(const crypto::chacha_key &key, const crypto::key_image &k return m_ringdb->get_ring(key, key_image, outs); } +bool wallet2::get_rings(const crypto::hash &txid, std::vector>> &outs) +{ + for (auto i: m_confirmed_txs) + { + if (txid == i.first) + { + for (const auto &x: i.second.m_rings) + outs.push_back({x.first, cryptonote::relative_output_offsets_to_absolute(x.second)}); + return true; + } + } + for (auto i: m_unconfirmed_txs) + { + if (txid == i.first) + { + for (const auto &x: i.second.m_rings) + outs.push_back({x.first, cryptonote::relative_output_offsets_to_absolute(x.second)}); + return true; + } + } + return false; +} + bool wallet2::get_ring(const crypto::key_image &key_image, std::vector &outs) { crypto::chacha_key key; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index acccc6ca8..46f1ddc2d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -289,6 +289,7 @@ namespace tools uint64_t m_timestamp; uint32_t m_subaddr_account; // subaddress account of your wallet to be used in this transfer std::set m_subaddr_indices; // set of address indices used as inputs in this transfer + std::vector>> m_rings; // relative }; struct confirmed_transfer_details @@ -303,10 +304,11 @@ namespace tools uint64_t m_unlock_time; uint32_t m_subaddr_account; // subaddress account of your wallet to be used in this transfer std::set m_subaddr_indices; // set of address indices used as inputs in this transfer + std::vector>> m_rings; // relative confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(crypto::null_hash), m_timestamp(0), m_unlock_time(0), m_subaddr_account((uint32_t)-1) {} confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height): - m_amount_in(utd.m_amount_in), m_amount_out(utd.m_amount_out), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id), m_timestamp(utd.m_timestamp), m_unlock_time(utd.m_tx.unlock_time), m_subaddr_account(utd.m_subaddr_account), m_subaddr_indices(utd.m_subaddr_indices) {} + m_amount_in(utd.m_amount_in), m_amount_out(utd.m_amount_out), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id), m_timestamp(utd.m_timestamp), m_unlock_time(utd.m_tx.unlock_time), m_subaddr_account(utd.m_subaddr_account), m_subaddr_indices(utd.m_subaddr_indices), m_rings(utd.m_rings) {} }; struct tx_construction_data @@ -1059,6 +1061,7 @@ namespace tools void set_ring_database(const std::string &filename); const std::string get_ring_database() const { return m_ring_database; } bool get_ring(const crypto::key_image &key_image, std::vector &outs); + bool get_rings(const crypto::hash &txid, std::vector>> &outs); bool set_ring(const crypto::key_image &key_image, const std::vector &outs, bool relative); bool find_and_save_rings(bool force = true); @@ -1227,8 +1230,8 @@ BOOST_CLASS_VERSION(tools::wallet2::multisig_info::LR, 0) BOOST_CLASS_VERSION(tools::wallet2::multisig_tx_set, 1) BOOST_CLASS_VERSION(tools::wallet2::payment_details, 3) BOOST_CLASS_VERSION(tools::wallet2::pool_payment_details, 1) -BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 7) -BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 5) +BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 8) +BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 6) BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 17) BOOST_CLASS_VERSION(tools::wallet2::reserve_proof_entry, 0) BOOST_CLASS_VERSION(tools::wallet2::unsigned_tx_set, 0) @@ -1428,6 +1431,9 @@ namespace boost } a & x.m_subaddr_account; a & x.m_subaddr_indices; + if (ver < 8) + return; + a & x.m_rings; } template @@ -1472,6 +1478,9 @@ namespace boost } a & x.m_subaddr_account; a & x.m_subaddr_indices; + if (ver < 6) + return; + a & x.m_rings; } template -- cgit v1.2.3