Holding reference to wallets instead of node as a first step to decoupling wallets and node logic.

This commit is contained in:
clemahieu 2018-08-23 20:59:26 +01:00
commit 16afb2d85c
3 changed files with 70 additions and 69 deletions

View file

@ -743,17 +743,17 @@ void rai::kdf::phs (rai::raw_key & result_a, std::string const & password_a, rai
(void)success;
}
rai::wallet::wallet (bool & init_a, rai::mdb_env & environment_a, rai::transaction & transaction_a, rai::node & node_a, std::string const & wallet_a) :
rai::wallet::wallet (bool & init_a, rai::mdb_env & environment_a, rai::transaction & transaction_a, rai::wallets & wallets_a, std::string const & wallet_a) :
lock_observer ([](bool, bool) {}),
store (init_a, node_a.wallets.kdf, environment_a, transaction_a, node_a.config.random_representative (), node_a.config.password_fanout, wallet_a),
node (node_a)
store (init_a, wallets_a.kdf, environment_a, transaction_a, wallets_a.node.config.random_representative (), wallets_a.node.config.password_fanout, wallet_a),
wallets (wallets_a)
{
}
rai::wallet::wallet (bool & init_a, rai::mdb_env & environment_a, rai::transaction & transaction_a, rai::node & node_a, std::string const & wallet_a, std::string const & json) :
rai::wallet::wallet (bool & init_a, rai::mdb_env & environment_a, rai::transaction & transaction_a, rai::wallets & wallets_a, std::string const & wallet_a, std::string const & json) :
lock_observer ([](bool, bool) {}),
store (init_a, node_a.wallets.kdf, environment_a, transaction_a, node_a.config.random_representative (), node_a.config.password_fanout, wallet_a, json),
node (node_a)
store (init_a, wallets_a.kdf, environment_a, transaction_a, wallets_a.node.config.random_representative (), wallets_a.node.config.password_fanout, wallet_a, json),
wallets (wallets_a)
{
}
@ -788,7 +788,7 @@ bool rai::wallet::enter_password (std::string const & password_a)
if (!result)
{
auto this_l (shared_from_this ());
node.background ([this_l]() {
wallets.node.background ([this_l]() {
this_l->search_pending ();
});
}
@ -825,7 +825,7 @@ rai::public_key rai::wallet::insert_adhoc (MDB_txn * transaction_a, rai::raw_key
key = store.insert_adhoc (transaction_a, key_a);
if (generate_work_a)
{
work_ensure (key, node.ledger.latest_root (transaction_a, key));
work_ensure (key, wallets.node.ledger.latest_root (transaction_a, key));
}
}
return key;
@ -857,7 +857,7 @@ bool rai::wallet::import (std::string const & json_a, std::string const & passwo
rai::transaction transaction (store.environment, true);
rai::uint256_union id;
random_pool.GenerateBlock (id.bytes.data (), id.bytes.size ());
temp.reset (new rai::wallet_store (error, node.wallets.kdf, store.environment, transaction, 0, 1, id.to_string (), json_a));
temp.reset (new rai::wallet_store (error, wallets.node.wallets.kdf, store.environment, transaction, 0, 1, id.to_string (), json_a));
}
if (!error)
{
@ -890,14 +890,14 @@ std::shared_ptr<rai::block> rai::wallet::receive_action (rai::block const & send
rai::account account;
auto hash (send_a.hash ());
std::shared_ptr<rai::block> block;
if (node.config.receive_minimum.number () <= amount_a.number ())
if (wallets.node.config.receive_minimum.number () <= amount_a.number ())
{
rai::transaction transaction (node.ledger.store.environment, false);
rai::transaction transaction (wallets.node.ledger.store.environment, false);
rai::pending_info pending_info;
if (node.store.block_exists (transaction, hash))
if (wallets.node.store.block_exists (transaction, hash))
{
account = node.ledger.block_destination (transaction, send_a);
if (!node.ledger.store.pending_get (transaction, rai::pending_key (account, hash), pending_info))
account = wallets.node.ledger.block_destination (transaction, send_a);
if (!wallets.node.ledger.store.pending_get (transaction, rai::pending_key (account, hash), pending_info))
{
rai::raw_key prv;
if (!store.fetch (transaction, account, prv))
@ -905,10 +905,10 @@ std::shared_ptr<rai::block> rai::wallet::receive_action (rai::block const & send
uint64_t cached_work (0);
store.work_get (transaction, account, cached_work);
rai::account_info info;
auto new_account (node.ledger.store.account_get (transaction, account, info));
auto new_account (wallets.node.ledger.store.account_get (transaction, account, info));
if (!new_account)
{
std::shared_ptr<rai::block> rep_block = node.ledger.store.block_get (transaction, info.rep_block);
std::shared_ptr<rai::block> rep_block = wallets.node.ledger.store.block_get (transaction, info.rep_block);
assert (rep_block != nullptr);
block.reset (new rai::state_block (account, info.head, rep_block->representative (), info.balance.number () + pending_info.amount.number (), hash, prv, account, cached_work));
}
@ -919,7 +919,7 @@ std::shared_ptr<rai::block> rai::wallet::receive_action (rai::block const & send
}
else
{
BOOST_LOG (node.log) << "Unable to receive, wallet locked";
BOOST_LOG (wallets.node.log) << "Unable to receive, wallet locked";
}
}
else
@ -934,17 +934,17 @@ std::shared_ptr<rai::block> rai::wallet::receive_action (rai::block const & send
}
else
{
BOOST_LOG (node.log) << boost::str (boost::format ("Not receiving block %1% due to minimum receive threshold") % hash.to_string ());
BOOST_LOG (wallets.node.log) << boost::str (boost::format ("Not receiving block %1% due to minimum receive threshold") % hash.to_string ());
// Someone sent us something below the threshold of receiving
}
if (block != nullptr)
{
if (rai::work_validate (*block))
{
node.work_generate_blocking (*block);
wallets.node.work_generate_blocking (*block);
}
node.process_active (block);
node.block_processor.flush ();
wallets.node.process_active (block);
wallets.node.block_processor.flush ();
if (generate_work_a)
{
work_ensure (account, block->hash ());
@ -961,10 +961,10 @@ std::shared_ptr<rai::block> rai::wallet::change_action (rai::account const & sou
if (store.valid_password (transaction))
{
auto existing (store.find (transaction, source_a));
if (existing != store.end () && !node.ledger.latest (transaction, source_a).is_zero ())
if (existing != store.end () && !wallets.node.ledger.latest (transaction, source_a).is_zero ())
{
rai::account_info info;
auto error1 (node.ledger.store.account_get (transaction, source_a, info));
auto error1 (wallets.node.ledger.store.account_get (transaction, source_a, info));
assert (!error1);
rai::raw_key prv;
auto error2 (store.fetch (transaction, source_a, prv));
@ -979,10 +979,10 @@ std::shared_ptr<rai::block> rai::wallet::change_action (rai::account const & sou
{
if (rai::work_validate (*block))
{
node.work_generate_blocking (*block);
wallets.node.work_generate_blocking (*block);
}
node.process_active (block);
node.block_processor.flush ();
wallets.node.process_active (block);
wallets.node.block_processor.flush ();
if (generate_work_a)
{
work_ensure (source_a, block->hash ());
@ -1006,15 +1006,15 @@ std::shared_ptr<rai::block> rai::wallet::send_action (rai::account const & sourc
if (id_mdb_val)
{
rai::mdb_val result;
auto status (mdb_get (transaction, node.wallets.send_action_ids, *id_mdb_val, result));
auto status (mdb_get (transaction, wallets.node.wallets.send_action_ids, *id_mdb_val, result));
if (status == 0)
{
rai::uint256_union hash (result);
block = node.store.block_get (transaction, hash);
block = wallets.node.store.block_get (transaction, hash);
if (block != nullptr)
{
cached_block = true;
node.network.republish_block (transaction, block);
wallets.node.network.republish_block (transaction, block);
}
}
else if (status != MDB_NOTFOUND)
@ -1029,23 +1029,23 @@ std::shared_ptr<rai::block> rai::wallet::send_action (rai::account const & sourc
auto existing (store.find (transaction, source_a));
if (existing != store.end ())
{
auto balance (node.ledger.account_balance (transaction, source_a));
auto balance (wallets.node.ledger.account_balance (transaction, source_a));
if (!balance.is_zero () && balance >= amount_a)
{
rai::account_info info;
auto error1 (node.ledger.store.account_get (transaction, source_a, info));
auto error1 (wallets.node.ledger.store.account_get (transaction, source_a, info));
assert (!error1);
rai::raw_key prv;
auto error2 (store.fetch (transaction, source_a, prv));
assert (!error2);
std::shared_ptr<rai::block> rep_block = node.ledger.store.block_get (transaction, info.rep_block);
std::shared_ptr<rai::block> rep_block = wallets.node.ledger.store.block_get (transaction, info.rep_block);
assert (rep_block != nullptr);
uint64_t cached_work (0);
store.work_get (transaction, source_a, cached_work);
block.reset (new rai::state_block (source_a, info.head, rep_block->representative (), balance - amount_a, account_a, prv, source_a, cached_work));
if (id_mdb_val && block != nullptr)
{
auto status (mdb_put (transaction, node.wallets.send_action_ids, *id_mdb_val, rai::mdb_val (block->hash ()), 0));
auto status (mdb_put (transaction, wallets.node.wallets.send_action_ids, *id_mdb_val, rai::mdb_val (block->hash ()), 0));
if (status != 0)
{
block = nullptr;
@ -1061,10 +1061,10 @@ std::shared_ptr<rai::block> rai::wallet::send_action (rai::account const & sourc
{
if (rai::work_validate (*block))
{
node.work_generate_blocking (*block);
wallets.node.work_generate_blocking (*block);
}
node.process_active (block);
node.block_processor.flush ();
wallets.node.process_active (block);
wallets.node.block_processor.flush ();
if (generate_work_a)
{
work_ensure (source_a, block->hash ());
@ -1085,7 +1085,7 @@ bool rai::wallet::change_sync (rai::account const & source_a, rai::account const
void rai::wallet::change_async (rai::account const & source_a, rai::account const & representative_a, std::function<void(std::shared_ptr<rai::block>)> const & action_a, bool generate_work_a)
{
node.wallets.queue_wallet_action (rai::wallets::high_priority, [this, source_a, representative_a, action_a, generate_work_a]() {
wallets.node.wallets.queue_wallet_action (rai::wallets::high_priority, [this, source_a, representative_a, action_a, generate_work_a]() {
auto block (change_action (source_a, representative_a, generate_work_a));
action_a (block);
});
@ -1104,7 +1104,7 @@ bool rai::wallet::receive_sync (std::shared_ptr<rai::block> block_a, rai::accoun
void rai::wallet::receive_async (std::shared_ptr<rai::block> block_a, rai::account const & representative_a, rai::uint128_t const & amount_a, std::function<void(std::shared_ptr<rai::block>)> const & action_a, bool generate_work_a)
{
//assert (dynamic_cast<rai::send_block *> (block_a.get ()) != nullptr);
node.wallets.queue_wallet_action (amount_a, [this, block_a, representative_a, amount_a, action_a, generate_work_a]() {
wallets.node.wallets.queue_wallet_action (amount_a, [this, block_a, representative_a, amount_a, action_a, generate_work_a]() {
auto block (receive_action (*static_cast<rai::block *> (block_a.get ()), representative_a, amount_a, generate_work_a));
action_a (block);
});
@ -1122,7 +1122,7 @@ rai::block_hash rai::wallet::send_sync (rai::account const & source_a, rai::acco
void rai::wallet::send_async (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a, std::function<void(std::shared_ptr<rai::block>)> const & action_a, bool generate_work_a, boost::optional<std::string> id_a)
{
this->node.wallets.queue_wallet_action (rai::wallets::high_priority, [this, source_a, account_a, amount_a, action_a, generate_work_a, id_a]() {
wallets.node.wallets.queue_wallet_action (rai::wallets::high_priority, [this, source_a, account_a, amount_a, action_a, generate_work_a, id_a]() {
auto block (send_action (source_a, account_a, amount_a, generate_work_a, id_a));
action_a (block);
});
@ -1133,21 +1133,21 @@ void rai::wallet::work_update (MDB_txn * transaction_a, rai::account const & acc
{
assert (!rai::work_validate (root_a, work_a));
assert (store.exists (transaction_a, account_a));
auto latest (node.ledger.latest_root (transaction_a, account_a));
auto latest (wallets.node.ledger.latest_root (transaction_a, account_a));
if (latest == root_a)
{
store.work_put (transaction_a, account_a, work_a);
}
else
{
BOOST_LOG (node.log) << "Cached work no longer valid, discarding";
BOOST_LOG (wallets.node.log) << "Cached work no longer valid, discarding";
}
}
void rai::wallet::work_ensure (rai::account const & account_a, rai::block_hash const & hash_a)
{
auto this_l (shared_from_this ());
node.wallets.queue_wallet_action (rai::wallets::generate_priority, [this_l, account_a, hash_a] {
wallets.node.wallets.queue_wallet_action (rai::wallets::generate_priority, [this_l, account_a, hash_a] {
this_l->work_cache_blocking (account_a, hash_a);
});
}
@ -1158,33 +1158,33 @@ bool rai::wallet::search_pending ()
auto result (!store.valid_password (transaction));
if (!result)
{
BOOST_LOG (node.log) << "Beginning pending block search";
BOOST_LOG (wallets.node.log) << "Beginning pending block search";
for (auto i (store.begin (transaction)), n (store.end ()); i != n; ++i)
{
rai::transaction transaction (node.store.environment, false);
rai::transaction transaction (wallets.node.store.environment, false);
rai::account account (i->first);
// Don't search pending for watch-only accounts
if (!rai::wallet_value (i->second).key.is_zero ())
{
for (auto j (node.store.pending_begin (transaction, rai::pending_key (account, 0))), m (node.store.pending_begin (transaction, rai::pending_key (account.number () + 1, 0))); j != m; ++j)
for (auto j (wallets.node.store.pending_begin (transaction, rai::pending_key (account, 0))), m (wallets.node.store.pending_begin (transaction, rai::pending_key (account.number () + 1, 0))); j != m; ++j)
{
rai::pending_key key (j->first);
auto hash (key.hash);
rai::pending_info pending (j->second);
auto amount (pending.amount.number ());
if (node.config.receive_minimum.number () <= amount)
if (wallets.node.config.receive_minimum.number () <= amount)
{
BOOST_LOG (node.log) << boost::str (boost::format ("Found a pending block %1% for account %2%") % hash.to_string () % pending.source.to_account ());
node.block_confirm (node.store.block_get (transaction, hash));
BOOST_LOG (wallets.node.log) << boost::str (boost::format ("Found a pending block %1% for account %2%") % hash.to_string () % pending.source.to_account ());
wallets.node.block_confirm (wallets.node.store.block_get (transaction, hash));
}
}
}
}
BOOST_LOG (node.log) << "Pending block search phase complete";
BOOST_LOG (wallets.node.log) << "Pending block search phase complete";
}
else
{
BOOST_LOG (node.log) << "Stopping search, wallet is locked";
BOOST_LOG (wallets.node.log) << "Stopping search, wallet is locked";
}
return result;
}
@ -1209,7 +1209,7 @@ rai::public_key rai::wallet::change_seed (MDB_txn * transaction_a, rai::raw_key
store.deterministic_key (prv, transaction_a, i);
rai::keypair pair (prv.data.to_string ());
// Check if account received at least 1 block
auto latest (node.ledger.latest (transaction_a, pair.pub));
auto latest (wallets.node.ledger.latest (transaction_a, pair.pub));
if (!latest.is_zero ())
{
count = i;
@ -1221,7 +1221,7 @@ rai::public_key rai::wallet::change_seed (MDB_txn * transaction_a, rai::raw_key
{
// Check if there are pending blocks for account
rai::account end (pair.pub.number () + 1);
for (auto ii (node.store.pending_begin (transaction_a, rai::pending_key (pair.pub, 0))), nn (node.store.pending_begin (transaction_a, rai::pending_key (end, 0))); ii != nn; ++ii)
for (auto ii (wallets.node.store.pending_begin (transaction_a, rai::pending_key (pair.pub, 0))), nn (wallets.node.store.pending_begin (transaction_a, rai::pending_key (end, 0))); ii != nn; ++ii)
{
count = i;
n = i + 64 + (i / 64);
@ -1241,10 +1241,10 @@ rai::public_key rai::wallet::change_seed (MDB_txn * transaction_a, rai::raw_key
void rai::wallet::work_cache_blocking (rai::account const & account_a, rai::block_hash const & root_a)
{
auto begin (std::chrono::steady_clock::now ());
auto work (node.work_generate_blocking (root_a));
if (node.config.logging.work_generation_time ())
auto work (wallets.node.work_generate_blocking (root_a));
if (wallets.node.config.logging.work_generation_time ())
{
BOOST_LOG (node.log) << "Work generation complete: " << (std::chrono::duration_cast<std::chrono::microseconds> (std::chrono::steady_clock::now () - begin).count ()) << " us";
BOOST_LOG (wallets.node.log) << "Work generation complete: " << (std::chrono::duration_cast<std::chrono::microseconds> (std::chrono::steady_clock::now () - begin).count ()) << " us";
}
rai::transaction transaction (store.environment, true);
if (store.exists (transaction, account_a))
@ -1276,7 +1276,7 @@ thread ([this]() { do_wallet_actions (); })
auto error (id.decode_hex (text));
assert (!error);
assert (items.find (id) == items.end ());
auto wallet (std::make_shared<rai::wallet> (error, node.store.environment, transaction, node_a, text));
auto wallet (std::make_shared<rai::wallet> (error, node.store.environment, transaction, *this, text));
if (!error)
{
items[id] = wallet;
@ -1316,7 +1316,7 @@ std::shared_ptr<rai::wallet> rai::wallets::create (rai::uint256_union const & id
bool error;
{
rai::transaction transaction (node.store.environment, true);
result = std::make_shared<rai::wallet> (error, node.store.environment, transaction, node, id_a.to_string ());
result = std::make_shared<rai::wallet> (error, node.store.environment, transaction, *this, id_a.to_string ());
}
if (!error)
{

View file

@ -122,7 +122,7 @@ public:
MDB_dbi handle;
std::recursive_mutex mutex;
};
class node;
class wallets;
// A wallet is a set of account keys encrypted by a common encryption key
class wallet : public std::enable_shared_from_this<rai::wallet>
{
@ -130,8 +130,8 @@ public:
std::shared_ptr<rai::block> change_action (rai::account const &, rai::account const &, bool = true);
std::shared_ptr<rai::block> receive_action (rai::block const &, rai::account const &, rai::uint128_union const &, bool = true);
std::shared_ptr<rai::block> send_action (rai::account const &, rai::account const &, rai::uint128_t const &, bool = true, boost::optional<std::string> = {});
wallet (bool &, rai::mdb_env &, rai::transaction &, rai::node &, std::string const &);
wallet (bool &, rai::mdb_env &, rai::transaction &, rai::node &, std::string const &, std::string const &);
wallet (bool &, rai::mdb_env &, rai::transaction &, rai::wallets &, std::string const &);
wallet (bool &, rai::mdb_env &, rai::transaction &, rai::wallets &, std::string const &, std::string const &);
void enter_initial_password ();
bool valid_password ();
bool enter_password (std::string const &);
@ -160,8 +160,9 @@ public:
std::unordered_set<rai::account> free_accounts;
std::function<void(bool, bool)> lock_observer;
rai::wallet_store store;
rai::node & node;
rai::wallets & wallets;
};
class node;
// The wallets set is all the wallets a node controls. A node may contain multiple wallets independently encrypted and operated.
class wallets
{

View file

@ -706,7 +706,7 @@ refresh (new QPushButton ("Refresh")),
balance_window (new QWidget),
balance_layout (new QHBoxLayout),
balance_label (new QLabel),
history (wallet_a.wallet_m->node.ledger, account, wallet_a),
history (wallet_a.node.ledger, account, wallet_a),
back (new QPushButton ("Back")),
account (wallet_a.account),
wallet (wallet_a)
@ -870,9 +870,9 @@ std::string rai_qt::status::text ()
size_t unchecked (0);
std::string count_string;
{
rai::transaction transaction (wallet.wallet_m->node.store.environment, false);
auto size (wallet.wallet_m->node.store.block_count (transaction));
unchecked = wallet.wallet_m->node.store.unchecked_count (transaction);
rai::transaction transaction (wallet.node.store.environment, false);
auto size (wallet.node.store.block_count (transaction));
unchecked = wallet.node.store.unchecked_count (transaction);
count_string = std::to_string (size.sum ());
}
@ -905,7 +905,7 @@ std::string rai_qt::status::text ()
}
result += ", Block: ";
if (unchecked != 0 && wallet.wallet_m->node.bootstrap_initiator.in_progress ())
if (unchecked != 0 && wallet.node.bootstrap_initiator.in_progress ())
{
count_string += " (" + std::to_string (unchecked) + ")";
}
@ -1624,12 +1624,12 @@ wallet (wallet_a)
void rai_qt::settings::refresh_representative ()
{
rai::transaction transaction (this->wallet.wallet_m->node.store.environment, false);
rai::transaction transaction (wallet.node.store.environment, false);
rai::account_info info;
auto error (this->wallet.wallet_m->node.store.account_get (transaction, this->wallet.account, info));
auto error (wallet.node.store.account_get (transaction, this->wallet.account, info));
if (!error)
{
auto block (this->wallet.wallet_m->node.store.block_get (transaction, info.rep_block));
auto block (wallet.node.store.block_get (transaction, info.rep_block));
assert (block != nullptr);
current_representative->setText (QString (block->representative ().to_account ().c_str ()));
}