From 2a9e549277ad9664ff890fe246b09c005c108dcf Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sun, 3 Dec 2017 10:15:23 -0600 Subject: [PATCH] Adding capability to disable block work for offline signing. --- rai/core_test/wallet.cpp | 10 +++++ rai/node/wallet.cpp | 89 +++++++++++++++++++++++----------------- rai/node/wallet.hpp | 46 ++++++++++----------- 3 files changed, 85 insertions(+), 60 deletions(-) diff --git a/rai/core_test/wallet.cpp b/rai/core_test/wallet.cpp index 397f2997..30613b60 100644 --- a/rai/core_test/wallet.cpp +++ b/rai/core_test/wallet.cpp @@ -854,3 +854,13 @@ TEST (wallet, version_2_3_upgrade) ASSERT_TRUE (wallet->store.exists (transaction, rai::wallet_store::seed_special)); ASSERT_FALSE (wallet->deterministic_insert ().is_zero ()); } + +TEST (wallet, no_work) +{ + rai::system system (24000, 1); + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + rai::keypair key2; + auto block (system.wallet (0)->send_action (rai::test_genesis_key.pub, key2.pub, std::numeric_limits ::max (), false)); + ASSERT_NE (nullptr, block); + ASSERT_EQ (0, block->block_work ()); +} diff --git a/rai/node/wallet.cpp b/rai/node/wallet.cpp index 1ec6bf1b..293291ef 100644 --- a/rai/node/wallet.cpp +++ b/rai/node/wallet.cpp @@ -907,39 +907,45 @@ bool rai::wallet::enter_password (std::string const & password_a) return result; } -rai::public_key rai::wallet::deterministic_insert (MDB_txn * transaction_a) +rai::public_key rai::wallet::deterministic_insert (MDB_txn * transaction_a, bool generate_work_a) { rai::public_key key (0); if (store.valid_password (transaction_a)) { key = store.deterministic_insert (transaction_a); - work_ensure (transaction_a, key); + if (generate_work_a) + { + work_ensure (transaction_a, key); + } } return key; } -rai::public_key rai::wallet::deterministic_insert () +rai::public_key rai::wallet::deterministic_insert (bool generate_work_a) { rai::transaction transaction (store.environment, nullptr, true); auto result (deterministic_insert (transaction)); return result; } -rai::public_key rai::wallet::insert_adhoc (MDB_txn * transaction_a, rai::raw_key const & key_a) +rai::public_key rai::wallet::insert_adhoc (MDB_txn * transaction_a, rai::raw_key const & key_a, bool generate_work_a) { rai::public_key key (0); if (store.valid_password (transaction_a)) { key = store.insert_adhoc (transaction_a, key_a); - work_ensure (transaction_a, key); + if (generate_work_a) + { + work_ensure (transaction_a, key); + } } return key; } -rai::public_key rai::wallet::insert_adhoc (rai::raw_key const & account_a) +rai::public_key rai::wallet::insert_adhoc (rai::raw_key const & account_a, bool generate_work_a) { rai::transaction transaction (store.environment, nullptr, true); - auto result (insert_adhoc (transaction, account_a)); + auto result (insert_adhoc (transaction, account_a, generate_work_a)); return result; } @@ -993,7 +999,7 @@ bool check_ownership (rai::wallets & wallets_a, rai::account const & account_a) } } -std::shared_ptr rai::wallet::receive_action (rai::send_block const & send_a, rai::account const & representative_a, rai::uint128_union const & amount_a) +std::shared_ptr rai::wallet::receive_action (rai::send_block const & send_a, rai::account const & representative_a, rai::uint128_union const & amount_a, bool generate_work_a) { auto hash (send_a.hash ()); std::shared_ptr block; @@ -1009,12 +1015,12 @@ std::shared_ptr rai::wallet::receive_action (rai::send_block const auto new_account (node.ledger.store.account_get (transaction, send_a.hashables.destination, info)); if (!new_account) { - auto receive (new rai::receive_block (info.head, hash, prv, send_a.hashables.destination, work_fetch (transaction, send_a.hashables.destination, info.head))); + auto receive (new rai::receive_block (info.head, hash, prv, send_a.hashables.destination, generate_work_a ? work_fetch (transaction, send_a.hashables.destination, info.head) : 0)); block.reset (receive); } else { - block.reset (new rai::open_block (hash, representative_a, send_a.hashables.destination, prv, send_a.hashables.destination, work_fetch (transaction, send_a.hashables.destination, send_a.hashables.destination))); + block.reset (new rai::open_block (hash, representative_a, send_a.hashables.destination, prv, send_a.hashables.destination, generate_work_a ? work_fetch (transaction, send_a.hashables.destination, send_a.hashables.destination) : 0)); } } else @@ -1039,15 +1045,18 @@ std::shared_ptr rai::wallet::receive_action (rai::send_block const auto hash (block->hash ()); auto this_l (shared_from_this ()); auto source (send_a.hashables.destination); - node.wallets.queue_wallet_action (source, rai::wallets::generate_priority, [this_l, source, hash] + if (generate_work_a) { - this_l->work_generate (source, hash); - }); + node.wallets.queue_wallet_action (source, rai::wallets::generate_priority, [this_l, source, hash] + { + this_l->work_generate (source, hash); + }); + } } return block; } -std::shared_ptr rai::wallet::change_action (rai::account const & source_a, rai::account const & representative_a) +std::shared_ptr rai::wallet::change_action (rai::account const & source_a, rai::account const & representative_a, bool generate_work_a) { std::shared_ptr block; { @@ -1065,7 +1074,7 @@ std::shared_ptr rai::wallet::change_action (rai::account const & so rai::raw_key prv; auto error2 (store.fetch (transaction, source_a, prv)); assert (!error2); - block.reset (new rai::change_block (info.head, representative_a, prv, source_a, work_fetch (transaction, source_a, info.head))); + block.reset (new rai::change_block (info.head, representative_a, prv, source_a, generate_work_a ? work_fetch (transaction, source_a, info.head) : 0)); } } } @@ -1076,15 +1085,18 @@ std::shared_ptr rai::wallet::change_action (rai::account const & so node.process_active (block); auto hash (block->hash ()); auto this_l (shared_from_this ()); - node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash] + if (generate_work_a) { - this_l->work_generate (source_a, hash); - }); + node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash] + { + this_l->work_generate (source_a, hash); + }); + } } return block; } -std::shared_ptr rai::wallet::send_action (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a) +std::shared_ptr rai::wallet::send_action (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a, bool generate_work_a) { std::shared_ptr block; { @@ -1105,7 +1117,7 @@ std::shared_ptr rai::wallet::send_action (rai::account const & sour rai::raw_key prv; auto error2 (store.fetch (transaction, source_a, prv)); assert (!error2); - block.reset (new rai::send_block (info.head, account_a, balance - amount_a, prv, source_a, work_fetch (transaction, source_a, info.head))); + block.reset (new rai::send_block (info.head, account_a, balance - amount_a, prv, source_a, generate_work_a ? work_fetch (transaction, source_a, info.head) : 0)); } } } @@ -1117,10 +1129,13 @@ std::shared_ptr rai::wallet::send_action (rai::account const & sour node.process_active (block); auto hash (block->hash ()); auto this_l (shared_from_this ()); - node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash] + if (generate_work_a) { - this_l->work_generate (source_a, hash); - }); + node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash] + { + this_l->work_generate (source_a, hash); + }); + } } return block; } @@ -1131,16 +1146,16 @@ bool rai::wallet::change_sync (rai::account const & source_a, rai::account const change_async (source_a, representative_a, [this, source_a, representative_a, &result] (std::shared_ptr block_a) { result.set_value (block_a == nullptr); - }); + }, true); return result.get_future ().get (); } -void rai::wallet::change_async (rai::account const & source_a, rai::account const & representative_a, std::function )> const & action_a) +void rai::wallet::change_async (rai::account const & source_a, rai::account const & representative_a, std::function )> const & action_a, bool generate_work_a) { - node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, representative_a, action_a] () + node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, representative_a, action_a, generate_work_a] () { assert (!check_ownership (node.wallets, source_a)); - auto block (change_action (source_a, representative_a)); + auto block (change_action (source_a, representative_a, generate_work_a)); action_a (block); }); } @@ -1151,17 +1166,17 @@ bool rai::wallet::receive_sync (std::shared_ptr block_a, rai::accou receive_async (block_a, representative_a, amount_a, [&result] (std::shared_ptr block_a) { result.set_value (block_a == nullptr); - }); + }, true); return result.get_future ().get (); } -void rai::wallet::receive_async (std::shared_ptr block_a, rai::account const & representative_a, rai::uint128_t const & amount_a, std::function )> const & action_a) +void rai::wallet::receive_async (std::shared_ptr block_a, rai::account const & representative_a, rai::uint128_t const & amount_a, std::function )> const & action_a, bool generate_work_a) { assert (dynamic_cast (block_a.get ()) != nullptr); - node.wallets.queue_wallet_action (static_cast (block_a.get ())->hashables.destination, amount_a, [this, block_a, representative_a, amount_a, action_a] () + node.wallets.queue_wallet_action (static_cast (block_a.get ())->hashables.destination, amount_a, [this, block_a, representative_a, amount_a, action_a, generate_work_a] () { assert (!check_ownership (node.wallets, static_cast (block_a.get ())->hashables.destination)); - auto block (receive_action (*static_cast (block_a.get ()), representative_a, amount_a)); + auto block (receive_action (*static_cast (block_a.get ()), representative_a, amount_a, generate_work_a)); action_a (block); }); } @@ -1172,18 +1187,18 @@ rai::block_hash rai::wallet::send_sync (rai::account const & source_a, rai::acco send_async (source_a, account_a, amount_a, [&result] (std::shared_ptr block_a) { result.set_value (block_a->hash ()); - }); + }, true); return result.get_future ().get (); } -void rai::wallet::send_async (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a, std::function )> const & action_a) +void rai::wallet::send_async (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a, std::function )> const & action_a, bool generate_work_a) { - node.background ([this, source_a, account_a, amount_a, action_a] () + node.background ([this, source_a, account_a, amount_a, action_a, generate_work_a] () { - this->node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, account_a, amount_a, action_a] () + this->node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, account_a, amount_a, action_a, generate_work_a] () { assert (!check_ownership (node.wallets, source_a)); - auto block (send_action (source_a, account_a, amount_a)); + auto block (send_action (source_a, account_a, amount_a, generate_work_a)); action_a (block); }); }); @@ -1325,7 +1340,7 @@ public: { BOOST_LOG (wallet_l->node.log) << boost::str (boost::format ("Error receiving block %1%") % block->hash ().to_string ()); } - }); + }, true); } else { diff --git a/rai/node/wallet.hpp b/rai/node/wallet.hpp index 4a9bf54d..4b4e34aa 100644 --- a/rai/node/wallet.hpp +++ b/rai/node/wallet.hpp @@ -148,37 +148,37 @@ class node; class wallet : public std::enable_shared_from_this { public: - std::shared_ptr change_action (rai::account const &, rai::account const &); - std::shared_ptr receive_action (rai::send_block const &, rai::account const &, rai::uint128_union const &); - std::shared_ptr send_action (rai::account const &, rai::account const &, rai::uint128_t const &); - wallet (bool &, rai::transaction &, rai::node &, std::string const &); - wallet (bool &, rai::transaction &, rai::node &, std::string const &, std::string const &); + std::shared_ptr change_action (rai::account const &, rai::account const &, bool = true); + std::shared_ptr receive_action (rai::send_block const &, rai::account const &, rai::uint128_union const &, bool = true); + std::shared_ptr send_action (rai::account const &, rai::account const &, rai::uint128_t const &, bool = true); + wallet (bool &, rai::transaction &, rai::node &, std::string const &); + wallet (bool &, rai::transaction &, rai::node &, std::string const &, std::string const &); void enter_initial_password (); - bool valid_password (); - bool enter_password (std::string const &); - rai::public_key insert_adhoc (rai::raw_key const &); - rai::public_key insert_adhoc (MDB_txn *, rai::raw_key const &); - rai::public_key deterministic_insert (MDB_txn *); - rai::public_key deterministic_insert (); - bool exists (rai::public_key const &); + bool valid_password (); + bool enter_password (std::string const &); + rai::public_key insert_adhoc (rai::raw_key const &, bool = true); + rai::public_key insert_adhoc (MDB_txn *, rai::raw_key const &, bool = true); + rai::public_key deterministic_insert (MDB_txn *, bool = true); + rai::public_key deterministic_insert (bool = true); + bool exists (rai::public_key const &); bool import (std::string const &, std::string const &); void serialize (std::string &); bool change_sync (rai::account const &, rai::account const &); - void change_async (rai::account const &, rai::account const &, std::function )> const &); - bool receive_sync (std::shared_ptr , rai::account const &, rai::uint128_t const &); - void receive_async (std::shared_ptr , rai::account const &, rai::uint128_t const &, std::function )> const &); + void change_async (rai::account const &, rai::account const &, std::function )> const &, bool = true); + bool receive_sync (std::shared_ptr , rai::account const &, rai::uint128_t const &); + void receive_async (std::shared_ptr , rai::account const &, rai::uint128_t const &, std::function )> const &, bool = true); rai::block_hash send_sync (rai::account const &, rai::account const &, rai::uint128_t const &); - void send_async (rai::account const &, rai::account const &, rai::uint128_t const &, std::function )> const &); - void work_generate (rai::account const &, rai::block_hash const &); - void work_update (MDB_txn *, rai::account const &, rai::block_hash const &, uint64_t); - uint64_t work_fetch (MDB_txn *, rai::account const &, rai::block_hash const &); + void send_async (rai::account const &, rai::account const &, rai::uint128_t const &, std::function )> const &, bool = true); + void work_generate (rai::account const &, rai::block_hash const &); + void work_update (MDB_txn *, rai::account const &, rai::block_hash const &, uint64_t); + uint64_t work_fetch (MDB_txn *, rai::account const &, rai::block_hash const &); void work_ensure (MDB_txn *, rai::account const &); bool search_pending (); void init_free_accounts (MDB_txn *); std::unordered_set free_accounts; std::function lock_observer; - rai::wallet_store store; - rai::node & node; + rai::wallet_store store; + rai::node & node; }; // The wallets set is all the wallets a node controls. A node may contain multiple wallets independently encrypted and operated. class wallets @@ -187,8 +187,8 @@ public: wallets (bool &, rai::node &); std::shared_ptr open (rai::uint256_union const &); std::shared_ptr create (rai::uint256_union const &); - bool search_pending (rai::uint256_union const &); - void search_pending_all (); + bool search_pending (rai::uint256_union const &); + void search_pending_all (); void destroy (rai::uint256_union const &); void do_wallet_actions (rai::account const &); void queue_wallet_action (rai::account const &, rai::uint128_t const &, std::function const &);