diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/util.cpp | 39 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 34 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 16 |
4 files changed, 90 insertions, 1 deletions
diff --git a/src/common/util.cpp b/src/common/util.cpp index 1877acb57..7e77e19b1 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -43,6 +43,7 @@ using namespace epee; #include "crypto/crypto.h" #include "util.h" +#include "stack_trace.h" #include "memwipe.h" #include "cryptonote_config.h" #include "net/http_client.h" // epee::net_utils::... @@ -560,10 +561,48 @@ std::string get_nix_version_display_string() } return false; } + +#ifdef STACK_TRACE +#ifdef _WIN32 + // https://stackoverflow.com/questions/1992816/how-to-handle-seg-faults-under-windows + static LONG WINAPI windows_crash_handler(PEXCEPTION_POINTERS pExceptionInfo) + { + tools::log_stack_trace("crashing"); + exit(1); + return EXCEPTION_CONTINUE_SEARCH; + } + static void setup_crash_dump() + { + SetUnhandledExceptionFilter(windows_crash_handler); + } +#else + static void posix_crash_handler(int signal) + { + tools::log_stack_trace(("crashing with fatal signal " + std::to_string(signal)).c_str()); +#ifdef NDEBUG + _exit(1); +#else + abort(); +#endif + } + static void setup_crash_dump() + { + signal(SIGSEGV, posix_crash_handler); + signal(SIGBUS, posix_crash_handler); + signal(SIGILL, posix_crash_handler); + signal(SIGFPE, posix_crash_handler); + } +#endif +#else + static void setup_crash_dump() {} +#endif + bool on_startup() { mlog_configure("", true); + setup_crash_dump(); + sanitize_locale(); #ifdef __GLIBC__ diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 79792e387..aa5728fc3 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -2082,10 +2082,27 @@ namespace cryptonote //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp) { + PERF_TIMER(on_get_output_distribution); try { for (uint64_t amount: req.amounts) { + static struct D + { + boost::mutex mutex; + std::vector<uint64_t> cached_distribution; + uint64_t cached_from, cached_to, cached_start_height, cached_base; + bool cached; + D(): cached_from(0), cached_to(0), cached_start_height(0), cached_base(0), cached(false) {} + } d; + boost::unique_lock<boost::mutex> lock(d.mutex); + + if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req.to_height) + { + res.distributions.push_back({amount, d.cached_start_height, d.cached_distribution, d.cached_base}); + continue; + } + std::vector<uint64_t> distribution; uint64_t start_height, base; if (!m_core.get_output_distribution(amount, req.from_height, start_height, distribution, base)) @@ -2094,12 +2111,29 @@ namespace cryptonote error_resp.message = "Failed to get rct distribution"; return false; } + if (req.to_height > 0 && req.to_height >= req.from_height) + { + uint64_t offset = std::max(req.from_height, start_height); + if (offset <= req.to_height && req.to_height - offset + 1 < distribution.size()) + distribution.resize(req.to_height - offset + 1); + } if (req.cumulative) { distribution[0] += base; for (size_t n = 1; n < distribution.size(); ++n) distribution[n] += distribution[n-1]; } + + if (amount == 0) + { + d.cached_from = req.from_height; + d.cached_to = req.to_height; + d.cached_distribution = distribution; + d.cached_start_height = start_height; + d.cached_base = base; + d.cached = true; + } + res.distributions.push_back({amount, start_height, std::move(distribution), base}); } } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index df5b4893f..a97277c0e 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -2212,11 +2212,13 @@ namespace cryptonote { std::vector<uint64_t> amounts; uint64_t from_height; + uint64_t to_height; bool cumulative; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(amounts) KV_SERIALIZE_OPT(from_height, (uint64_t)0) + KV_SERIALIZE_OPT(to_height, (uint64_t)0) KV_SERIALIZE_OPT(cumulative, false) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 490c05ad3..c26aecb14 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2628,6 +2628,12 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable value2.SetUint(m_segregation_height); json.AddMember("segregation_height", value2, json.GetAllocator()); + value2.SetUint(m_subaddress_lookahead_major); + json.AddMember("subaddress_lookahead_major", value2, json.GetAllocator()); + + value2.SetUint(m_subaddress_lookahead_minor); + json.AddMember("subaddress_lookahead_minor", value2, json.GetAllocator()); + // Serialize the JSON object rapidjson::StringBuffer buffer; rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); @@ -2702,6 +2708,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_segregate_pre_fork_outputs = true; m_key_reuse_mitigation2 = true; m_segregation_height = 0; + m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR; + m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR; m_key_on_device = false; } else if(json.IsObject()) @@ -2826,6 +2834,10 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_key_reuse_mitigation2 = field_key_reuse_mitigation2; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, segregation_height, int, Uint, false, 0); m_segregation_height = field_segregation_height; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_major, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MAJOR); + m_subaddress_lookahead_major = field_subaddress_lookahead_major; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR); + m_subaddress_lookahead_minor = field_subaddress_lookahead_minor; } else { @@ -5893,9 +5905,10 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> auto end = std::unique(req_t.amounts.begin(), req_t.amounts.end()); req_t.amounts.resize(std::distance(req_t.amounts.begin(), end)); req_t.from_height = std::max<uint64_t>(segregation_fork_height, RECENT_OUTPUT_BLOCKS) - RECENT_OUTPUT_BLOCKS; + req_t.to_height = segregation_fork_height + 1; req_t.cumulative = true; m_daemon_rpc_mutex.lock(); - bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_distribution", req_t, resp_t, m_http_client, rpc_timeout); + bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_distribution", req_t, resp_t, m_http_client, rpc_timeout * 1000); m_daemon_rpc_mutex.unlock(); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "transfer_selected"); THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_distribution"); @@ -5912,6 +5925,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> { THROW_WALLET_EXCEPTION_IF(d.start_height > segregation_fork_height, error::get_output_distribution, "Distribution start_height too high"); THROW_WALLET_EXCEPTION_IF(segregation_fork_height - d.start_height >= d.distribution.size(), error::get_output_distribution, "Distribution size too small"); + THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS - d.start_height >= d.distribution.size(), error::get_output_distribution, "Distribution size too small"); THROW_WALLET_EXCEPTION_IF(segregation_fork_height <= RECENT_OUTPUT_BLOCKS, error::wallet_internal_error, "Fork height too low"); THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS < d.start_height, error::get_output_distribution, "Bad start height"); uint64_t till_fork = d.distribution[segregation_fork_height - d.start_height]; |