diff options
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 24 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 1 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 66 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 5 |
4 files changed, 87 insertions, 9 deletions
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 54132d9ca..b5a568a14 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1968,6 +1968,23 @@ bool simple_wallet::set_subaddress_lookahead(const std::vector<std::string> &arg return true; } +bool simple_wallet::set_segregation_height(const std::vector<std::string> &args/* = std::vector<std::string>()*/) +{ + const auto pwd_container = get_and_verify_password(); + if (pwd_container) + { + uint64_t height; + if (!epee::string_tools::get_xtype_from_string(height, args[1])) + { + fail_msg_writer() << tr("Invalid height"); + return true; + } + m_wallet->segregation_height(height); + m_wallet->rewrite(m_wallet_file, pwd_container->password()); + } + return true; +} + bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/) { if(args.empty()) @@ -2148,7 +2165,10 @@ simple_wallet::simple_wallet() "key-reuse-mitigation2 <1|0>\n " " Set this if you are not sure whether you will spend on a key reusing Monero fork later.\n" "subaddress-lookahead <major>:<minor>\n " - " Set the lookahead sizes for the subaddress hash table.")); + " Set the lookahead sizes for the subaddress hash table.\n " + " Set this if you are not sure whether you will spend on a key reusing Monero fork later.\n " + "segregation-height <n>\n " + " Set to the height of a key reusing fork you want to use, 0 to use default.")); m_cmd_binder.set_handler("encrypted_seed", boost::bind(&simple_wallet::encrypted_seed, this, _1), tr("Display the encrypted Electrum-style mnemonic seed.")); @@ -2344,6 +2364,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) success_msg_writer() << "key-reuse-mitigation2 = " << m_wallet->key_reuse_mitigation2(); const std::pair<size_t, size_t> lookahead = m_wallet->get_subaddress_lookahead(); success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second; + success_msg_writer() << "segregation-height = " << m_wallet->segregation_height(); return true; } else @@ -2397,6 +2418,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) CHECK_SIMPLE_VARIABLE("segregate-pre-fork-outputs", set_segregate_pre_fork_outputs, tr("0 or 1")); CHECK_SIMPLE_VARIABLE("key-reuse-mitigation2", set_key_reuse_mitigation2, tr("0 or 1")); CHECK_SIMPLE_VARIABLE("subaddress-lookahead", set_subaddress_lookahead, tr("<major>:<minor>")); + CHECK_SIMPLE_VARIABLE("segregation-height", set_segregation_height, tr("unsigned integer")); } fail_msg_writer() << tr("set: unrecognized argument(s)"); return true; diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index b2630c75e..f45018b60 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -136,6 +136,7 @@ namespace cryptonote bool set_segregate_pre_fork_outputs(const std::vector<std::string> &args = std::vector<std::string>()); bool set_key_reuse_mitigation2(const std::vector<std::string> &args = std::vector<std::string>()); bool set_subaddress_lookahead(const std::vector<std::string> &args = std::vector<std::string>()); + bool set_segregation_height(const std::vector<std::string> &args = std::vector<std::string>()); bool help(const std::vector<std::string> &args = std::vector<std::string>()); bool start_mining(const std::vector<std::string> &args); bool stop_mining(const std::vector<std::string> &args); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d6fb1edb8..4b7e6dd93 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -65,6 +65,7 @@ using namespace epee; #include "common/json_util.h" #include "memwipe.h" #include "common/base58.h" +#include "common/dns_utils.h" #include "ringct/rctSigs.h" #include "ringdb.h" @@ -662,6 +663,7 @@ wallet2::wallet2(network_type nettype, bool restricted): m_auto_low_priority(true), m_segregate_pre_fork_outputs(true), m_key_reuse_mitigation2(true), + m_segregation_height(0), m_is_initialized(false), m_restricted(restricted), is_old_file_format(false), @@ -2594,6 +2596,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable value2.SetInt(m_key_reuse_mitigation2 ? 1 : 0); json.AddMember("key_reuse_mitigation2", value2, json.GetAllocator()); + value2.SetUint(m_segregation_height); + json.AddMember("segregation_height", value2, json.GetAllocator()); + // Serialize the JSON object rapidjson::StringBuffer buffer; rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); @@ -5774,14 +5779,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> if (fake_outputs_count > 0) { - uint64_t segregation_fork_height; - switch (m_nettype) - { - case TESTNET: segregation_fork_height = TESTNET_SEGREGATION_FORK_HEIGHT; break; - case STAGENET: segregation_fork_height = STAGENET_SEGREGATION_FORK_HEIGHT; break; - case MAINNET: segregation_fork_height = SEGREGATION_FORK_HEIGHT; break; - default: THROW_WALLET_EXCEPTION(error::wallet_internal_error, "Invalid network type"); - } + uint64_t segregation_fork_height = get_segregation_fork_height(); // check whether we're shortly after the fork uint64_t height; boost::optional<std::string> result = m_node_rpc_proxy.get_height(height); @@ -10324,6 +10322,58 @@ std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(uint64_t mi return estimate_backlog(fee_levels); } //---------------------------------------------------------------------------------------------------- +uint64_t wallet2::get_segregation_fork_height() const +{ + if (m_nettype == TESTNET) + return TESTNET_SEGREGATION_FORK_HEIGHT; + if (m_nettype == STAGENET) + return STAGENET_SEGREGATION_FORK_HEIGHT; + THROW_WALLET_EXCEPTION_IF(m_nettype != MAINNET, tools::error::wallet_internal_error, "Invalid network type"); + + if (m_segregation_height > 0) + return m_segregation_height; + + static const bool use_dns = true; + if (use_dns) + { + // All four MoneroPulse domains have DNSSEC on and valid + static const std::vector<std::string> dns_urls = { + "segheights.moneropulse.org", + "segheights.moneropulse.net", + "segheights.moneropulse.co", + "segheights.moneropulse.se" + }; + + const uint64_t current_height = get_blockchain_current_height(); + uint64_t best_diff = std::numeric_limits<uint64_t>::max(), best_height = 0; + std::vector<std::string> records; + if (tools::dns_utils::load_txt_records_from_dns(records, dns_urls)) + { + for (const auto& record : records) + { + std::vector<std::string> fields; + boost::split(fields, record, boost::is_any_of(":")); + if (fields.size() != 2) + continue; + uint64_t height; + if (!string_tools::get_xtype_from_string(height, fields[1])) + continue; + + MINFO("Found segregation height via DNS: " << fields[0] << " fork height at " << height); + uint64_t diff = height > current_height ? height - current_height : current_height - height; + if (diff < best_diff) + { + best_diff = diff; + best_height = height; + } + } + if (best_height) + return best_height; + } + } + return SEGREGATION_FORK_HEIGHT; +} +//---------------------------------------------------------------------------------------------------- void wallet2::generate_genesis(cryptonote::block& b) const { if (m_nettype == TESTNET) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 11edfd316..abc7bb538 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -872,6 +872,8 @@ namespace tools void segregate_pre_fork_outputs(bool value) { m_segregate_pre_fork_outputs = value; } bool key_reuse_mitigation2() const { return m_key_reuse_mitigation2; } void key_reuse_mitigation2(bool value) { m_key_reuse_mitigation2 = value; } + uint64_t segregation_height() const { return m_segregation_height; } + void segregation_height(uint64_t height) { m_segregation_height = height; } bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const; void check_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations); @@ -1134,6 +1136,8 @@ namespace tools bool get_output_distribution(uint64_t &start_height, std::vector<uint64_t> &distribution); + uint64_t get_segregation_fork_height() const; + cryptonote::account_base m_account; boost::optional<epee::net_utils::http::login> m_daemon_login; std::string m_daemon_address; @@ -1200,6 +1204,7 @@ namespace tools bool m_auto_low_priority; bool m_segregate_pre_fork_outputs; bool m_key_reuse_mitigation2; + uint64_t m_segregation_height; bool m_is_initialized; NodeRPCProxy m_node_rpc_proxy; std::unordered_set<crypto::hash> m_scanned_pool_txs[2]; |