Skip to content

Commit

Permalink
[QT] Automatic full check after leaving the synchronisation state (#1589
Browse files Browse the repository at this point in the history
)

if after an importing seed.
Completing #70
  • Loading branch information
SergiySW authored and zhyatt committed Jan 27, 2019
1 parent 4abcb7e commit 09bff5a
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 28 deletions.
59 changes: 59 additions & 0 deletions nano/core_test/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,3 +969,62 @@ TEST (wallet, password_race_corrupt_seed)
}
}
}

TEST (wallet, change_seed)
{
nano::system system (24000, 1);
auto wallet (system.wallet (0));
wallet->enter_initial_password ();
nano::raw_key seed1;
seed1.data = 1;
nano::public_key pub;
uint32_t index (4);
nano::raw_key prv;
nano::deterministic_key (seed1.data, index, prv.data);
pub = nano::pub_key (prv.data);
wallet->insert_adhoc (nano::test_genesis_key.prv, false);
auto block (wallet->send_action (nano::test_genesis_key.pub, pub, 100));
ASSERT_NE (nullptr, block);
system.nodes[0]->block_processor.flush ();
{
auto transaction (wallet->wallets.tx_begin_write ());
wallet->change_seed (transaction, seed1);
nano::raw_key seed2;
wallet->store.seed (seed2, transaction);
ASSERT_EQ (seed1, seed2);
ASSERT_EQ (index + 1, wallet->store.deterministic_index_get (transaction));
}
ASSERT_TRUE (wallet->exists (pub));
}

TEST (wallet, deterministic_restore)
{
nano::system system (24000, 1);
auto wallet (system.wallet (0));
wallet->enter_initial_password ();
nano::raw_key seed1;
seed1.data = 1;
nano::public_key pub;
uint32_t index (4);
{
auto transaction (wallet->wallets.tx_begin_write ());
wallet->change_seed (transaction, seed1);
nano::raw_key seed2;
wallet->store.seed (seed2, transaction);
ASSERT_EQ (seed1, seed2);
ASSERT_EQ (1, wallet->store.deterministic_index_get (transaction));
nano::raw_key prv;
nano::deterministic_key (seed1.data, index, prv.data);
pub = nano::pub_key (prv.data);
}
wallet->insert_adhoc (nano::test_genesis_key.prv, false);
auto block (wallet->send_action (nano::test_genesis_key.pub, pub, 100));
ASSERT_NE (nullptr, block);
system.nodes[0]->block_processor.flush ();
{
auto transaction (wallet->wallets.tx_begin_write ());
wallet->deterministic_restore (transaction);
ASSERT_EQ (index + 1, wallet->store.deterministic_index_get (transaction));
}
ASSERT_TRUE (wallet->exists (pub));
}
68 changes: 42 additions & 26 deletions nano/node/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,48 +1221,64 @@ void nano::wallet::init_free_accounts (nano::transaction const & transaction_a)
}
}

nano::public_key nano::wallet::change_seed (nano::transaction const & transaction_a, nano::raw_key const & prv_a, uint32_t count)
uint32_t nano::wallet::deterministic_check (nano::transaction const & transaction_a, uint32_t index)
{
store.seed_set (transaction_a, prv_a);
auto account = deterministic_insert (transaction_a);
if (count == 0)
auto block_transaction (wallets.node.store.tx_begin_read ());
for (uint32_t i (index + 1), n (index + 64); i < n; ++i)
{
for (uint32_t i (1), n (64); i < n; ++i)
nano::raw_key prv;
store.deterministic_key (prv, transaction_a, i);
nano::keypair pair (prv.data.to_string ());
// Check if account received at least 1 block
auto latest (wallets.node.ledger.latest (block_transaction, pair.pub));
if (!latest.is_zero ())
{
nano::raw_key prv;
store.deterministic_key (prv, transaction_a, i);
nano::keypair pair (prv.data.to_string ());
// Check if account received at least 1 block
auto block_transaction (wallets.node.store.tx_begin_read ());
auto latest (wallets.node.ledger.latest (block_transaction, pair.pub));
if (!latest.is_zero ())
index = i;
// i + 64 - Check additional 64 accounts
// i/64 - Check additional accounts for large wallets. I.e. 64000/64 = 1000 accounts to check
n = i + 64 + (i / 64);
}
else
{
// Check if there are pending blocks for account
for (auto ii (wallets.node.store.pending_begin (block_transaction, nano::pending_key (pair.pub, 0))); nano::pending_key (ii->first).account == pair.pub; ++ii)
{
count = i;
// i + 64 - Check additional 64 accounts
// i/64 - Check additional accounts for large wallets. I.e. 64000/64 = 1000 accounts to check
index = i;
n = i + 64 + (i / 64);
}
else
{
// Check if there are pending blocks for account
for (auto ii (wallets.node.store.pending_begin (block_transaction, nano::pending_key (pair.pub, 0))); nano::pending_key (ii->first).account == pair.pub; ++ii)
{
count = i;
n = i + 64 + (i / 64);
break;
}
break;
}
}
}
return index;
}

nano::public_key nano::wallet::change_seed (nano::transaction const & transaction_a, nano::raw_key const & prv_a, uint32_t count)
{
store.seed_set (transaction_a, prv_a);
auto account = deterministic_insert (transaction_a);
if (count == 0)
{
count = deterministic_check (transaction_a, 0);
}
for (uint32_t i (0); i < count; ++i)
{
// Disable work generation to prevent weak CPU nodes stuck
account = deterministic_insert (transaction_a, false);
}

return account;
}

void nano::wallet::deterministic_restore (nano::transaction const & transaction_a)
{
auto index (store.deterministic_index_get (transaction_a));
auto new_index (deterministic_check (transaction_a, index));
for (uint32_t i (index); i <= new_index && index != new_index; ++i)
{
// Disable work generation to prevent weak CPU nodes stuck
deterministic_insert (transaction_a, false);
}
}

bool nano::wallet::live ()
{
return store.handle != 0;
Expand Down
4 changes: 3 additions & 1 deletion nano/node/wallet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,10 @@ class wallet : public std::enable_shared_from_this<nano::wallet>
void work_ensure (nano::account const &, nano::block_hash const &);
bool search_pending ();
void init_free_accounts (nano::transaction const &);
uint32_t deterministic_check (nano::transaction const & transaction_a, uint32_t index);
/** Changes the wallet seed and returns the first account */
nano::public_key change_seed (nano::transaction const & transaction_a, nano::raw_key const & prv_a, uint32_t = 0);
nano::public_key change_seed (nano::transaction const & transaction_a, nano::raw_key const & prv_a, uint32_t count = 0);
void deterministic_restore (nano::transaction const & transaction_a);
bool live ();
std::unordered_set<nano::account> free_accounts;
std::function<void(bool, bool)> lock_observer;
Expand Down
15 changes: 14 additions & 1 deletion nano/qt/qt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,11 @@ wallet (wallet_a)
{
this->wallet.account = this->wallet.wallet_m->change_seed (transaction, seed_l);
successful = true;
// Pending check for accounts to restore if bootstrap is in progress
if (this->wallet.node.bootstrap_initiator.in_progress ())
{
this->wallet.needs_deterministic_restore = true;
}
}
else
{
Expand Down Expand Up @@ -999,7 +1004,8 @@ send_count_label (new QLabel ("Amount:")),
send_count (new QLineEdit),
send_blocks_send (new QPushButton ("Send")),
send_blocks_back (new QPushButton ("Back")),
active_status (*this)
active_status (*this),
needs_deterministic_restore (false)
{
update_connected ();
empty_password ();
Expand Down Expand Up @@ -1353,6 +1359,13 @@ void nano_qt::wallet::start ()
else
{
this_l->active_status.erase (nano_qt::status_types::synchronizing);
// Check for accounts to restore
if (this_l->needs_deterministic_restore)
{
this_l->needs_deterministic_restore = false;
auto transaction (this_l->wallet_m->wallets.tx_begin_write ());
this_l->wallet_m->deterministic_restore (transaction);
}
}
}
}));
Expand Down
1 change: 1 addition & 0 deletions nano/qt/qt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,5 +353,6 @@ class wallet : public std::enable_shared_from_this<nano_qt::wallet>
void push_main_stack (QWidget *);
void ongoing_refresh ();
std::atomic<bool> needs_balance_refresh;
std::atomic<bool> needs_deterministic_restore;
};
}

0 comments on commit 09bff5a

Please sign in to comment.