diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/wallet2.cpp | 21 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 4 | ||||
-rw-r--r-- | src/wallet/wallet_errors.h | 10 |
3 files changed, 35 insertions, 0 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 063c493ce..949e2d451 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1158,6 +1158,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std m_explicit_refresh_from_block_height(true), m_confirm_non_default_ring_size(true), m_ask_password(AskPasswordToDecrypt), + m_max_reorg_depth(ORPHANED_BLOCKS_MAX_COUNT), m_min_output_count(0), m_min_output_value(0), m_merge_destinations(false), @@ -3465,6 +3466,15 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo throw std::runtime_error("proxy exception in refresh thread"); } + if (!next_blocks.empty()) + { + const uint64_t expected_start_height = std::max(static_cast<uint64_t>(m_blockchain.size()), uint64_t(1)) - 1; + const uint64_t reorg_depth = expected_start_height - std::min(expected_start_height, next_blocks_start_height); + THROW_WALLET_EXCEPTION_IF(reorg_depth > m_max_reorg_depth, error::reorg_depth_error, + tr("reorg exceeds maximum allowed depth, use 'set max-reorg-depth N' to allow it, reorg depth: ") + + std::to_string(reorg_depth)); + } + // if we've got at least 10 blocks to refresh, assume we're starting // a long refresh, and setup a tracking output cache if we need to if (m_track_uses && (!output_tracker_cache || output_tracker_cache->empty()) && next_blocks.size() >= 10) @@ -3487,6 +3497,11 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool"); throw; } + catch (const error::reorg_depth_error&) + { + THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool"); + throw; + } catch (const std::exception&) { blocks_fetched += added_blocks; @@ -3863,6 +3878,9 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const epee: value2.SetInt(m_ask_password); json.AddMember("ask_password", value2, json.GetAllocator()); + value2.SetUint64(m_max_reorg_depth); + json.AddMember("max_reorg_depth", value2, json.GetAllocator()); + value2.SetUint(m_min_output_count); json.AddMember("min_output_count", value2, json.GetAllocator()); @@ -4081,6 +4099,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_confirm_non_default_ring_size = true; m_ask_password = AskPasswordToDecrypt; cryptonote::set_default_decimal_point(CRYPTONOTE_DISPLAY_DECIMAL_POINT); + m_max_reorg_depth = ORPHANED_BLOCKS_MAX_COUNT; m_min_output_count = 0; m_min_output_value = 0; m_merge_destinations = false; @@ -4233,6 +4252,8 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st m_ask_password = field_ask_password; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, default_decimal_point, int, Int, false, CRYPTONOTE_DISPLAY_DECIMAL_POINT); cryptonote::set_default_decimal_point(field_default_decimal_point); + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, max_reorg_depth, uint64_t, Uint64, false, ORPHANED_BLOCKS_MAX_COUNT); + m_max_reorg_depth = field_max_reorg_depth; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, min_output_count, uint32_t, Uint, false, 0); m_min_output_count = field_min_output_count; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, min_output_value, uint64_t, Uint64, false, 0); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index eac99185c..1c9cca9d8 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -853,6 +853,9 @@ private: void explicit_refresh_from_block_height(bool expl) {m_explicit_refresh_from_block_height = expl;} bool explicit_refresh_from_block_height() const {return m_explicit_refresh_from_block_height;} + void max_reorg_depth(uint64_t depth) {m_max_reorg_depth = depth;} + uint64_t max_reorg_depth() const {return m_max_reorg_depth;} + bool deinit(); bool init(std::string daemon_address = "http://localhost:8080", boost::optional<epee::net_utils::http::login> daemon_login = boost::none, @@ -1726,6 +1729,7 @@ private: bool m_explicit_refresh_from_block_height; bool m_confirm_non_default_ring_size; AskPasswordType m_ask_password; + uint64_t m_max_reorg_depth; uint32_t m_min_output_count; uint64_t m_min_output_value; bool m_merge_destinations; diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index e889ed7d1..4a89ed81a 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -428,6 +428,16 @@ namespace tools std::string to_string() const { return refresh_error::to_string(); } }; //---------------------------------------------------------------------------------------------------- + struct reorg_depth_error : public refresh_error + { + explicit reorg_depth_error(std::string&& loc, const std::string& message) + : refresh_error(std::move(loc), message) + { + } + + std::string to_string() const { return refresh_error::to_string(); } + }; + //---------------------------------------------------------------------------------------------------- struct signature_check_failed : public wallet_logic_error { explicit signature_check_failed(std::string&& loc, const std::string& message) |