Reload wallets list from disk each 5 minutes (#1619)
* Add mutexes for all wallets functions * Reload wallets list from disk each 5 minutes * Test wallets.reload
This commit is contained in:
parent
e4d61e6bbe
commit
88afc90f81
4 changed files with 76 additions and 1 deletions
|
@ -1,6 +1,7 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include <nano/core_test/testutil.hpp>
|
||||
#include <nano/node/node.hpp>
|
||||
#include <nano/node/testing.hpp>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
@ -95,3 +96,23 @@ TEST (wallets, DISABLED_wallet_create_max)
|
|||
auto existing = wallets.items.find (key.pub);
|
||||
ASSERT_TRUE (existing == wallets.items.end ());
|
||||
}
|
||||
|
||||
TEST (wallets, reload)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
nano::uint256_union one (1);
|
||||
bool error (false);
|
||||
ASSERT_FALSE (error);
|
||||
ASSERT_EQ (1, system.nodes[0]->wallets.items.size ());
|
||||
{
|
||||
nano::inactive_node node (system.nodes[0]->application_path, 24001);
|
||||
auto wallet (node.node->wallets.create (one));
|
||||
ASSERT_NE (wallet, nullptr);
|
||||
}
|
||||
system.deadline_set (5s);
|
||||
while (system.nodes[0]->wallets.open (one) == nullptr)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (2, system.nodes[0]->wallets.items.size ());
|
||||
}
|
||||
|
|
|
@ -2276,6 +2276,9 @@ void nano::node::backup_wallet ()
|
|||
|
||||
void nano::node::search_pending ()
|
||||
{
|
||||
// Reload wallets from disk
|
||||
wallets.reload ();
|
||||
// Search pending
|
||||
wallets.search_pending_all ();
|
||||
auto this_l (shared ());
|
||||
alarm.add (std::chrono::steady_clock::now () + search_pending_interval, [this_l]() {
|
||||
|
|
|
@ -1299,6 +1299,7 @@ thread ([this]() {
|
|||
do_wallet_actions ();
|
||||
})
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
if (!error_a)
|
||||
{
|
||||
auto transaction (tx_begin_write ());
|
||||
|
@ -1340,6 +1341,7 @@ nano::wallets::~wallets ()
|
|||
|
||||
std::shared_ptr<nano::wallet> nano::wallets::open (nano::uint256_union const & id_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
std::shared_ptr<nano::wallet> result;
|
||||
auto existing (items.find (id_a));
|
||||
if (existing != items.end ())
|
||||
|
@ -1351,6 +1353,7 @@ std::shared_ptr<nano::wallet> nano::wallets::open (nano::uint256_union const & i
|
|||
|
||||
std::shared_ptr<nano::wallet> nano::wallets::create (nano::uint256_union const & id_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
assert (items.find (id_a) == items.end ());
|
||||
std::shared_ptr<nano::wallet> result;
|
||||
bool error;
|
||||
|
@ -1368,6 +1371,7 @@ std::shared_ptr<nano::wallet> nano::wallets::create (nano::uint256_union const &
|
|||
|
||||
bool nano::wallets::search_pending (nano::uint256_union const & wallet_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
auto result (false);
|
||||
auto existing (items.find (wallet_a));
|
||||
result = existing == items.end ();
|
||||
|
@ -1381,6 +1385,7 @@ bool nano::wallets::search_pending (nano::uint256_union const & wallet_a)
|
|||
|
||||
void nano::wallets::search_pending_all ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
for (auto i : items)
|
||||
{
|
||||
i.second->search_pending ();
|
||||
|
@ -1398,6 +1403,49 @@ void nano::wallets::destroy (nano::uint256_union const & id_a)
|
|||
wallet->store.destroy (transaction);
|
||||
}
|
||||
|
||||
void nano::wallets::reload ()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
auto transaction (tx_begin_write ());
|
||||
std::unordered_set<nano::uint256_union> stored_items;
|
||||
std::string beginning (nano::uint256_union (0).to_string ());
|
||||
std::string end ((nano::uint256_union (nano::uint256_t (0) - nano::uint256_t (1))).to_string ());
|
||||
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> i (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction, handle, nano::mdb_val (beginning.size (), const_cast<char *> (beginning.c_str ()))));
|
||||
nano::store_iterator<std::array<char, 64>, nano::mdb_val::no_value> n (std::make_unique<nano::mdb_iterator<std::array<char, 64>, nano::mdb_val::no_value>> (transaction, handle, nano::mdb_val (end.size (), const_cast<char *> (end.c_str ()))));
|
||||
for (; i != n; ++i)
|
||||
{
|
||||
nano::uint256_union id;
|
||||
std::string text (i->first.data (), i->first.size ());
|
||||
auto error (id.decode_hex (text));
|
||||
assert (!error);
|
||||
// New wallet
|
||||
if (items.find (id) == items.end ())
|
||||
{
|
||||
auto wallet (std::make_shared<nano::wallet> (error, transaction, *this, text));
|
||||
if (!error)
|
||||
{
|
||||
items[id] = wallet;
|
||||
}
|
||||
}
|
||||
// List of wallets on disk
|
||||
stored_items.insert (id);
|
||||
}
|
||||
// Delete non existing wallets from memory
|
||||
std::vector<nano::uint256_union> deleted_items;
|
||||
for (auto i : items)
|
||||
{
|
||||
if (stored_items.find (i.first) == stored_items.end ())
|
||||
{
|
||||
deleted_items.push_back (i.first);
|
||||
}
|
||||
}
|
||||
for (auto & i : deleted_items)
|
||||
{
|
||||
assert (items.find (i) == items.end ());
|
||||
items.erase (i);
|
||||
}
|
||||
}
|
||||
|
||||
void nano::wallets::do_wallet_actions ()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (mutex);
|
||||
|
@ -1436,11 +1484,12 @@ void nano::wallets::queue_wallet_action (nano::uint128_t const & amount_a, std::
|
|||
|
||||
void nano::wallets::foreach_representative (nano::transaction const & transaction_a, std::function<void(nano::public_key const & pub_a, nano::raw_key const & prv_a)> const & action_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
auto transaction_l (node.wallets.tx_begin_read ());
|
||||
for (auto i (items.begin ()), n (items.end ()); i != n; ++i)
|
||||
{
|
||||
auto & wallet (*i->second);
|
||||
std::lock_guard<std::recursive_mutex> lock (wallet.store.mutex);
|
||||
std::lock_guard<std::recursive_mutex> store_lock (wallet.store.mutex);
|
||||
for (auto j (wallet.store.begin (transaction_l)), m (wallet.store.end ()); j != m; ++j)
|
||||
{
|
||||
nano::account account (j->first);
|
||||
|
@ -1469,6 +1518,7 @@ void nano::wallets::foreach_representative (nano::transaction const & transactio
|
|||
|
||||
bool nano::wallets::exists (nano::transaction const & transaction_a, nano::public_key const & account_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
auto result (false);
|
||||
for (auto i (items.begin ()), n (items.end ()); !result && i != n; ++i)
|
||||
{
|
||||
|
|
|
@ -171,6 +171,7 @@ public:
|
|||
bool search_pending (nano::uint256_union const &);
|
||||
void search_pending_all ();
|
||||
void destroy (nano::uint256_union const &);
|
||||
void reload ();
|
||||
void do_wallet_actions ();
|
||||
void queue_wallet_action (nano::uint128_t const &, std::shared_ptr<nano::wallet>, std::function<void(nano::wallet &)> const &);
|
||||
void foreach_representative (nano::transaction const &, std::function<void(nano::public_key const &, nano::raw_key const &)> const &);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue