Skip to content

Commit

Permalink
Improve provided "work" for RPC (#1560)
Browse files Browse the repository at this point in the history
  • Loading branch information
SergiySW authored and rkeene committed Jan 23, 2019
1 parent 3e87c6f commit 1734c25
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 58 deletions.
2 changes: 1 addition & 1 deletion nano/core_test/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ TEST (rpc, send_fail)
ASSERT_NO_ERROR (system.poll ());
}
done = true;
ASSERT_EQ (response.json.get<std::string> ("error"), "Error generating block");
ASSERT_EQ (response.json.get<std::string> ("error"), "Account not found in wallet");
thread2.join ();
}

Expand Down
55 changes: 26 additions & 29 deletions nano/node/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,11 +623,7 @@ void nano::rpc_handler::account_representative_set ()
nano::account_info info;
if (!node.store.account_get (transaction, account, info))
{
if (!nano::work_validate (info.head, work))
{
wallet->store.work_put (transaction, account, work);
}
else
if (nano::work_validate (info.head, work))
{
ec = nano::error_common::invalid_work;
}
Expand All @@ -644,6 +640,7 @@ void nano::rpc_handler::account_representative_set ()
}
if (!ec)
{
bool generate_work (work == 0); // Disable work generation if "work" option is provided
auto response_a (response);
wallet->change_async (account, representative, [response_a](std::shared_ptr<nano::block> block) {
nano::block_hash hash (0);
Expand All @@ -655,7 +652,7 @@ void nano::rpc_handler::account_representative_set ()
response_l.put ("block", hash.to_string ());
response_a (response_l);
},
work == 0);
work, generate_work);
}
}
else
Expand Down Expand Up @@ -2526,18 +2523,14 @@ void nano::rpc_handler::receive ()
{
head = account;
}
if (!nano::work_validate (head, work))
{
auto transaction_a (node.store.tx_begin_write ());
wallet->store.work_put (transaction_a, account, work);
}
else
if (nano::work_validate (head, work))
{
ec = nano::error_common::invalid_work;
}
}
if (!ec)
{
bool generate_work (work == 0); // Disable work generation if "work" option is provided
auto response_a (response);
wallet->receive_async (std::move (block), account, nano::genesis_amount, [response_a](std::shared_ptr<nano::block> block_a) {
nano::uint256_union hash_a (0);
Expand All @@ -2549,7 +2542,7 @@ void nano::rpc_handler::receive ()
response_l.put ("block", hash_a.to_string ());
response_a (response_l);
},
work == 0);
work, generate_work);
}
}
else
Expand Down Expand Up @@ -2850,29 +2843,32 @@ void nano::rpc_handler::send ()
nano::uint128_t balance (0);
if (!ec)
{
auto transaction (node.wallets.tx_begin (work != 0)); // false if no "work" in request, true if work > 0
auto transaction (node.wallets.tx_begin_read ());
auto block_transaction (node.store.tx_begin_read ());
if (wallet->store.valid_password (transaction))
{
nano::account_info info;
if (!node.store.account_get (block_transaction, source, info))
{
balance = (info.balance).number ();
}
else
if (wallet->store.find (transaction, source) != wallet->store.end ())
{
ec = nano::error_common::account_not_found;
}
if (!ec && work)
{
if (!nano::work_validate (info.head, work))
nano::account_info info;
if (!node.store.account_get (block_transaction, source, info))
{
wallet->store.work_put (transaction, source, work);
balance = (info.balance).number ();
}
else
{
ec = nano::error_common::invalid_work;
ec = nano::error_common::account_not_found;
}
if (!ec && work)
{
if (nano::work_validate (info.head, work))
{
ec = nano::error_common::invalid_work;
}
}
}
else
{
ec = nano::error_common::account_not_found_wallet;
}
}
else
Expand All @@ -2882,6 +2878,7 @@ void nano::rpc_handler::send ()
}
if (!ec)
{
bool generate_work (work == 0); // Disable work generation if "work" option is provided
boost::optional<std::string> send_id (request.get_optional<std::string> ("id"));
auto rpc_l (shared_from_this ());
auto response_a (response);
Expand All @@ -2906,7 +2903,7 @@ void nano::rpc_handler::send ()
}
}
},
work == 0, send_id);
work, generate_work, send_id);
}
}
else
Expand Down Expand Up @@ -3537,7 +3534,7 @@ void nano::rpc_handler::wallet_representative_set ()
}
for (auto & account : accounts)
{
wallet->change_async (account, representative, [](std::shared_ptr<nano::block>) {}, false);
wallet->change_async (account, representative, [](std::shared_ptr<nano::block>) {}, 0, false);
}
}
response_l.put ("set", "1");
Expand Down
53 changes: 31 additions & 22 deletions nano/node/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ void nano::wallet_store::destroy (nano::transaction const & transaction_a)
handle = 0;
}

std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block const & send_a, nano::account const & representative_a, nano::uint128_union const & amount_a, bool generate_work_a)
std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block const & send_a, nano::account const & representative_a, nano::uint128_union const & amount_a, uint64_t work_a, bool generate_work_a)
{
nano::account account;
auto hash (send_a.hash ());
Expand All @@ -914,19 +914,21 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block const & s
nano::raw_key prv;
if (!store.fetch (transaction, account, prv))
{
uint64_t cached_work (0);
store.work_get (transaction, account, cached_work);
if (work_a == 0)
{
store.work_get (transaction, account, work_a);
}
nano::account_info info;
auto new_account (wallets.node.ledger.store.account_get (block_transaction, account, info));
if (!new_account)
{
std::shared_ptr<nano::block> rep_block = wallets.node.ledger.store.block_get (block_transaction, info.rep_block);
assert (rep_block != nullptr);
block.reset (new nano::state_block (account, info.head, rep_block->representative (), info.balance.number () + pending_info.amount.number (), hash, prv, account, cached_work));
block.reset (new nano::state_block (account, info.head, rep_block->representative (), info.balance.number () + pending_info.amount.number (), hash, prv, account, work_a));
}
else
{
block.reset (new nano::state_block (account, 0, representative_a, pending_info.amount, hash, prv, account, cached_work));
block.reset (new nano::state_block (account, 0, representative_a, pending_info.amount, hash, prv, account, work_a));
}
}
else
Expand All @@ -953,6 +955,7 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block const & s
{
if (nano::work_validate (*block))
{
BOOST_LOG (wallets.node.log) << boost::str (boost::format ("Cached or provided work for block %1% account %2% is invalid, regenerating") % block->hash ().to_string () % account.to_account ());
wallets.node.work_generate_blocking (*block);
}
wallets.node.process_active (block);
Expand All @@ -965,7 +968,7 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block const & s
return block;
}

std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const & source_a, nano::account const & representative_a, bool generate_work_a)
std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const & source_a, nano::account const & representative_a, uint64_t work_a, bool generate_work_a)
{
std::shared_ptr<nano::block> block;
{
Expand All @@ -982,16 +985,19 @@ std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const &
nano::raw_key prv;
auto error2 (store.fetch (transaction, source_a, prv));
assert (!error2);
uint64_t cached_work (0);
store.work_get (transaction, source_a, cached_work);
block.reset (new nano::state_block (source_a, info.head, representative_a, info.balance, 0, prv, source_a, cached_work));
if (work_a == 0)
{
store.work_get (transaction, source_a, work_a);
}
block.reset (new nano::state_block (source_a, info.head, representative_a, info.balance, 0, prv, source_a, work_a));
}
}
}
if (block != nullptr)
{
if (nano::work_validate (*block))
{
BOOST_LOG (wallets.node.log) << boost::str (boost::format ("Cached or provided work for block %1% account %2% is invalid, regenerating") % block->hash ().to_string () % source_a.to_account ());
wallets.node.work_generate_blocking (*block);
}
wallets.node.process_active (block);
Expand All @@ -1004,7 +1010,7 @@ std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const &
return block;
}

std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & source_a, nano::account const & account_a, nano::uint128_t const & amount_a, bool generate_work_a, boost::optional<std::string> id_a)
std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & source_a, nano::account const & account_a, nano::uint128_t const & amount_a, uint64_t work_a, bool generate_work_a, boost::optional<std::string> id_a)
{
std::shared_ptr<nano::block> block;
boost::optional<nano::mdb_val> id_mdb_val;
Expand Down Expand Up @@ -1054,9 +1060,11 @@ std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & so
assert (!error2);
std::shared_ptr<nano::block> rep_block = wallets.node.ledger.store.block_get (block_transaction, info.rep_block);
assert (rep_block != nullptr);
uint64_t cached_work (0);
store.work_get (transaction, source_a, cached_work);
block.reset (new nano::state_block (source_a, info.head, rep_block->representative (), balance - amount_a, account_a, prv, source_a, cached_work));
if (work_a == 0)
{
store.work_get (transaction, source_a, work_a);
}
block.reset (new nano::state_block (source_a, info.head, rep_block->representative (), balance - amount_a, account_a, prv, source_a, work_a));
if (id_mdb_val && block != nullptr)
{
auto status (mdb_put (wallets.env.tx (transaction), wallets.node.wallets.send_action_ids, *id_mdb_val, nano::mdb_val (block->hash ()), 0));
Expand All @@ -1075,6 +1083,7 @@ std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & so
{
if (nano::work_validate (*block))
{
BOOST_LOG (wallets.node.log) << boost::str (boost::format ("Cached or provided work for block %1% account %2% is invalid, regenerating") % block->hash ().to_string () % account_a.to_account ());
wallets.node.work_generate_blocking (*block);
}
wallets.node.process_active (block);
Expand All @@ -1097,10 +1106,10 @@ bool nano::wallet::change_sync (nano::account const & source_a, nano::account co
return result.get_future ().get ();
}

void nano::wallet::change_async (nano::account const & source_a, nano::account const & representative_a, std::function<void(std::shared_ptr<nano::block>)> const & action_a, bool generate_work_a)
void nano::wallet::change_async (nano::account const & source_a, nano::account const & representative_a, std::function<void(std::shared_ptr<nano::block>)> const & action_a, uint64_t work_a, bool generate_work_a)
{
wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, shared_from_this (), [source_a, representative_a, action_a, generate_work_a](nano::wallet & wallet_a) {
auto block (wallet_a.change_action (source_a, representative_a, generate_work_a));
wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, shared_from_this (), [source_a, representative_a, action_a, work_a, generate_work_a](nano::wallet & wallet_a) {
auto block (wallet_a.change_action (source_a, representative_a, work_a, generate_work_a));
action_a (block);
});
}
Expand All @@ -1115,11 +1124,11 @@ bool nano::wallet::receive_sync (std::shared_ptr<nano::block> block_a, nano::acc
return result.get_future ().get ();
}

void nano::wallet::receive_async (std::shared_ptr<nano::block> block_a, nano::account const & representative_a, nano::uint128_t const & amount_a, std::function<void(std::shared_ptr<nano::block>)> const & action_a, bool generate_work_a)
void nano::wallet::receive_async (std::shared_ptr<nano::block> block_a, nano::account const & representative_a, nano::uint128_t const & amount_a, std::function<void(std::shared_ptr<nano::block>)> const & action_a, uint64_t work_a, bool generate_work_a)
{
//assert (dynamic_cast<nano::send_block *> (block_a.get ()) != nullptr);
wallets.node.wallets.queue_wallet_action (amount_a, shared_from_this (), [block_a, representative_a, amount_a, action_a, generate_work_a](nano::wallet & wallet_a) {
auto block (wallet_a.receive_action (*static_cast<nano::block *> (block_a.get ()), representative_a, amount_a, generate_work_a));
wallets.node.wallets.queue_wallet_action (amount_a, shared_from_this (), [block_a, representative_a, amount_a, action_a, work_a, generate_work_a](nano::wallet & wallet_a) {
auto block (wallet_a.receive_action (*static_cast<nano::block *> (block_a.get ()), representative_a, amount_a, work_a, generate_work_a));
action_a (block);
});
}
Expand All @@ -1134,10 +1143,10 @@ nano::block_hash nano::wallet::send_sync (nano::account const & source_a, nano::
return result.get_future ().get ();
}

void nano::wallet::send_async (nano::account const & source_a, nano::account const & account_a, nano::uint128_t const & amount_a, std::function<void(std::shared_ptr<nano::block>)> const & action_a, bool generate_work_a, boost::optional<std::string> id_a)
void nano::wallet::send_async (nano::account const & source_a, nano::account const & account_a, nano::uint128_t const & amount_a, std::function<void(std::shared_ptr<nano::block>)> const & action_a, uint64_t work_a, bool generate_work_a, boost::optional<std::string> id_a)
{
wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, shared_from_this (), [source_a, account_a, amount_a, action_a, generate_work_a, id_a](nano::wallet & wallet_a) {
auto block (wallet_a.send_action (source_a, account_a, amount_a, generate_work_a, id_a));
wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, shared_from_this (), [source_a, account_a, amount_a, action_a, work_a, generate_work_a, id_a](nano::wallet & wallet_a) {
auto block (wallet_a.send_action (source_a, account_a, amount_a, work_a, generate_work_a, id_a));
action_a (block);
});
}
Expand Down
12 changes: 6 additions & 6 deletions nano/node/wallet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ class wallets;
class wallet : public std::enable_shared_from_this<nano::wallet>
{
public:
std::shared_ptr<nano::block> change_action (nano::account const &, nano::account const &, bool = true);
std::shared_ptr<nano::block> receive_action (nano::block const &, nano::account const &, nano::uint128_union const &, bool = true);
std::shared_ptr<nano::block> send_action (nano::account const &, nano::account const &, nano::uint128_t const &, bool = true, boost::optional<std::string> = {});
std::shared_ptr<nano::block> change_action (nano::account const &, nano::account const &, uint64_t = 0, bool = true);
std::shared_ptr<nano::block> receive_action (nano::block const &, nano::account const &, nano::uint128_union const &, uint64_t = 0, bool = true);
std::shared_ptr<nano::block> send_action (nano::account const &, nano::account const &, nano::uint128_t const &, uint64_t = 0, bool = true, boost::optional<std::string> = {});
wallet (bool &, nano::transaction &, nano::wallets &, std::string const &);
wallet (bool &, nano::transaction &, nano::wallets &, std::string const &, std::string const &);
void enter_initial_password ();
Expand All @@ -136,11 +136,11 @@ class wallet : public std::enable_shared_from_this<nano::wallet>
bool import (std::string const &, std::string const &);
void serialize (std::string &);
bool change_sync (nano::account const &, nano::account const &);
void change_async (nano::account const &, nano::account const &, std::function<void(std::shared_ptr<nano::block>)> const &, bool = true);
void change_async (nano::account const &, nano::account const &, std::function<void(std::shared_ptr<nano::block>)> const &, uint64_t = 0, bool = true);
bool receive_sync (std::shared_ptr<nano::block>, nano::account const &, nano::uint128_t const &);
void receive_async (std::shared_ptr<nano::block>, nano::account const &, nano::uint128_t const &, std::function<void(std::shared_ptr<nano::block>)> const &, bool = true);
void receive_async (std::shared_ptr<nano::block>, nano::account const &, nano::uint128_t const &, std::function<void(std::shared_ptr<nano::block>)> const &, uint64_t = 0, bool = true);
nano::block_hash send_sync (nano::account const &, nano::account const &, nano::uint128_t const &);
void send_async (nano::account const &, nano::account const &, nano::uint128_t const &, std::function<void(std::shared_ptr<nano::block>)> const &, bool = true, boost::optional<std::string> = {});
void send_async (nano::account const &, nano::account const &, nano::uint128_t const &, std::function<void(std::shared_ptr<nano::block>)> const &, uint64_t = 0, bool = true, boost::optional<std::string> = {});
void work_apply (nano::account const &, std::function<void(uint64_t)>);
void work_cache_blocking (nano::account const &, nano::block_hash const &);
void work_update (nano::transaction const &, nano::account const &, nano::block_hash const &, uint64_t);
Expand Down

0 comments on commit 1734c25

Please sign in to comment.