aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2015-12-30 12:43:15 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2015-12-30 12:43:15 +0000
commit92ef6b54fe00d6b2e065b9a50884418ecaa76d93 (patch)
tree48d8a579c7cb4d786692c2b6356b4df42188b1b5 /src/wallet
parentnet_peerlist: move a couple functions from public to private (diff)
downloadmonero-92ef6b54fe00d6b2e065b9a50884418ecaa76d93.tar.xz
wallet: protect against exceptions in the block pull thread
This can happen when the daemon exits, which would also cause the wallet to crash via unhandled exception
Diffstat (limited to '')
-rw-r--r--src/wallet/wallet2.cpp42
-rw-r--r--src/wallet/wallet2.h2
2 files changed, 30 insertions, 14 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index cfa33b283..19b598af8 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -648,21 +648,30 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched)
refresh(start_height, blocks_fetched, received_money);
}
//----------------------------------------------------------------------------------------------------
-void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::list<cryptonote::block_complete_entry> &prev_blocks, std::list<cryptonote::block_complete_entry> &blocks)
+void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::list<cryptonote::block_complete_entry> &prev_blocks, std::list<cryptonote::block_complete_entry> &blocks, bool &error)
{
- // prepend the last 3 blocks, should be enough to guard against a block or two's reorg
- cryptonote::block bl;
- std::list<cryptonote::block_complete_entry>::const_reverse_iterator i = prev_blocks.rbegin();
- for (size_t n = 0; n < std::min((size_t)3, prev_blocks.size()); ++n)
+ error = false;
+
+ try
{
- bool ok = cryptonote::parse_and_validate_block_from_blob(i->block, bl);
- THROW_WALLET_EXCEPTION_IF(!ok, error::block_parse_error, i->block);
- short_chain_history.push_front(cryptonote::get_block_hash(bl));
- ++i;
- }
+ // prepend the last 3 blocks, should be enough to guard against a block or two's reorg
+ cryptonote::block bl;
+ std::list<cryptonote::block_complete_entry>::const_reverse_iterator i = prev_blocks.rbegin();
+ for (size_t n = 0; n < std::min((size_t)3, prev_blocks.size()); ++n)
+ {
+ bool ok = cryptonote::parse_and_validate_block_from_blob(i->block, bl);
+ THROW_WALLET_EXCEPTION_IF(!ok, error::block_parse_error, i->block);
+ short_chain_history.push_front(cryptonote::get_block_hash(bl));
+ ++i;
+ }
- // pull the new blocks
- pull_blocks(start_height, blocks_start_height, short_chain_history, blocks);
+ // pull the new blocks
+ pull_blocks(start_height, blocks_start_height, short_chain_history, blocks);
+ }
+ catch(...)
+ {
+ error = true;
+ }
}
//----------------------------------------------------------------------------------------------------
void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& received_money)
@@ -689,7 +698,8 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
// pull the next set of blocks while we're processing the current one
uint64_t next_blocks_start_height;
std::list<cryptonote::block_complete_entry> next_blocks;
- pull_thread = std::thread([&]{pull_next_blocks(start_height, next_blocks_start_height, short_chain_history, blocks, next_blocks);});
+ bool error = false;
+ pull_thread = std::thread([&]{pull_next_blocks(start_height, next_blocks_start_height, short_chain_history, blocks, next_blocks, error);});
process_blocks(blocks_start_height, blocks, added_blocks);
blocks_fetched += added_blocks;
@@ -700,6 +710,12 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
// switch to the new blocks from the daemon
blocks_start_height = next_blocks_start_height;
blocks = next_blocks;
+
+ // handle error from async fetching thread
+ if (error)
+ {
+ throw std::runtime_error("proxy exception in refresh thread");
+ }
}
catch (const std::exception&)
{
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index adb7b13e2..77a9fd18e 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -359,7 +359,7 @@ namespace tools
bool is_transfer_unlocked(const transfer_details& td) const;
bool clear();
void pull_blocks(uint64_t start_height, uint64_t& blocks_start_height, const std::list<crypto::hash> &short_chain_history, std::list<cryptonote::block_complete_entry> &blocks);
- void pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::list<cryptonote::block_complete_entry> &prev_blocks, std::list<cryptonote::block_complete_entry> &blocks);
+ void pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::list<cryptonote::block_complete_entry> &prev_blocks, std::list<cryptonote::block_complete_entry> &blocks, bool &error);
void process_blocks(uint64_t start_height, const std::list<cryptonote::block_complete_entry> &blocks, uint64_t& blocks_added);
uint64_t select_transfers(uint64_t needed_money, bool add_dust, uint64_t dust, std::list<transfer_container::iterator>& selected_transfers);
bool prepare_file_names(const std::string& file_path);