Adding capability to disable block work for offline signing.

This commit is contained in:
clemahieu 2017-12-03 10:15:23 -06:00
commit 2a9e549277
3 changed files with 85 additions and 60 deletions

View file

@ -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 <rai::uint128_t>::max (), false));
ASSERT_NE (nullptr, block);
ASSERT_EQ (0, block->block_work ());
}

View file

@ -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::block> 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::block> 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 <rai::block> block;
@ -1009,12 +1015,12 @@ std::shared_ptr <rai::block> 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::block> 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::block> rai::wallet::change_action (rai::account const & source_a, rai::account const & representative_a)
std::shared_ptr <rai::block> rai::wallet::change_action (rai::account const & source_a, rai::account const & representative_a, bool generate_work_a)
{
std::shared_ptr <rai::block> block;
{
@ -1065,7 +1074,7 @@ std::shared_ptr <rai::block> 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::block> 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::block> rai::wallet::send_action (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a)
std::shared_ptr <rai::block> 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 <rai::block> block;
{
@ -1105,7 +1117,7 @@ std::shared_ptr <rai::block> 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::block> 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 <rai::block> 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 <void (std::shared_ptr <rai::block>)> const & action_a)
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 (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 <rai::block> block_a, rai::accou
receive_async (block_a, representative_a, amount_a, [&result] (std::shared_ptr <rai::block> block_a)
{
result.set_value (block_a == nullptr);
});
}, true);
return result.get_future ().get ();
}
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)
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 (static_cast <rai::send_block *> (block_a.get ())->hashables.destination, amount_a, [this, block_a, representative_a, amount_a, action_a] ()
node.wallets.queue_wallet_action (static_cast <rai::send_block *> (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 <rai::send_block *> (block_a.get ())->hashables.destination));
auto block (receive_action (*static_cast <rai::send_block *> (block_a.get ()), representative_a, amount_a));
auto block (receive_action (*static_cast <rai::send_block *> (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 <rai::block> 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 <void (std::shared_ptr <rai::block>)> 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 <void (std::shared_ptr <rai::block>)> 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
{

View file

@ -148,37 +148,37 @@ class node;
class wallet : public std::enable_shared_from_this <rai::wallet>
{
public:
std::shared_ptr <rai::block> change_action (rai::account const &, rai::account const &);
std::shared_ptr <rai::block> receive_action (rai::send_block const &, rai::account const &, rai::uint128_union const &);
std::shared_ptr <rai::block> 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 <rai::block> change_action (rai::account const &, rai::account const &, bool = true);
std::shared_ptr <rai::block> receive_action (rai::send_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);
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 <void (std::shared_ptr <rai::block>)> const &);
bool receive_sync (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &);
void receive_async (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &, std::function <void (std::shared_ptr <rai::block>)> const &);
void change_async (rai::account const &, rai::account const &, std::function <void (std::shared_ptr <rai::block>)> const &, bool = true);
bool receive_sync (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &);
void receive_async (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &, std::function <void (std::shared_ptr <rai::block>)> 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 <void (std::shared_ptr <rai::block>)> 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 <void (std::shared_ptr <rai::block>)> 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 <rai::account> free_accounts;
std::function <void (bool, bool)> 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 <rai::wallet> open (rai::uint256_union const &);
std::shared_ptr <rai::wallet> 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 <void ()> const &);