Add callback for confirmed block in RPC block_confirm (#1898)
* Add callback for confirmed block in RPC block_confirm * rpc.block_confirm_confirmed test * Add lock_guard for active.confirmed changes
This commit is contained in:
parent
e63a5bdf89
commit
d2ecede34f
2 changed files with 80 additions and 2 deletions
|
@ -836,7 +836,38 @@ void nano::rpc_handler::block_confirm ()
|
|||
auto block_l (node.store.block_get (transaction, hash));
|
||||
if (block_l != nullptr)
|
||||
{
|
||||
node.block_confirm (std::move (block_l));
|
||||
if (!node.ledger.block_confirmed (transaction, hash))
|
||||
{
|
||||
// Start new confirmation for unconfirmed block
|
||||
node.block_confirm (std::move (block_l));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add record in confirmation history for confirmed block
|
||||
nano::election_status status;
|
||||
status.winner = block_l;
|
||||
status.tally = 0;
|
||||
status.election_end = std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ());
|
||||
status.election_duration = std::chrono::milliseconds::zero ();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (node.active.mutex);
|
||||
node.active.confirmed.push_back (status);
|
||||
if (node.active.confirmed.size () > node.active.election_history_size)
|
||||
{
|
||||
node.active.confirmed.pop_front ();
|
||||
}
|
||||
}
|
||||
// Trigger callback for confirmed block
|
||||
node.block_arrival.add (hash);
|
||||
auto account (node.ledger.account (transaction, hash));
|
||||
auto amount (node.ledger.amount (transaction, hash));
|
||||
bool is_state_send (false);
|
||||
if (auto state = dynamic_cast<nano::state_block *> (block_l.get ()))
|
||||
{
|
||||
is_state_send = node.ledger.is_send (transaction, *state);
|
||||
}
|
||||
node.observers.blocks.notify (block_l, account, amount, is_state_send);
|
||||
}
|
||||
response_l.put ("started", "1");
|
||||
}
|
||||
else
|
||||
|
|
|
@ -4637,7 +4637,6 @@ TEST (rpc, block_confirm)
|
|||
nano::system system (24000, 1);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::genesis genesis;
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
auto send1 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.nodes[0]->work_generate_blocking (genesis.hash ())));
|
||||
{
|
||||
auto transaction (system.nodes[0]->store.tx_begin (true));
|
||||
|
@ -4677,6 +4676,54 @@ TEST (rpc, block_confirm_absent)
|
|||
ASSERT_EQ ("Block not found", response.json.get<std::string> ("error"));
|
||||
}
|
||||
|
||||
TEST (rpc, block_confirm_confirmed)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
nano::node_init init;
|
||||
auto path (nano::unique_path ());
|
||||
nano::node_config config;
|
||||
config.peering_port = 24001;
|
||||
config.callback_address = "localhost";
|
||||
config.callback_port = 24002;
|
||||
config.callback_target = "/";
|
||||
config.logging.init (path);
|
||||
auto node (std::make_shared<nano::node> (init, system.io_ctx, path, system.alarm, config, system.work));
|
||||
node->start ();
|
||||
system.nodes.push_back (node);
|
||||
nano::genesis genesis;
|
||||
{
|
||||
auto transaction (node->store.tx_begin_read ());
|
||||
ASSERT_TRUE (node->ledger.block_confirmed (transaction, genesis.hash ()));
|
||||
}
|
||||
ASSERT_EQ (0, node->stats.count (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out));
|
||||
nano::rpc rpc (system.io_ctx, *node, nano::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "block_confirm");
|
||||
request.put ("hash", genesis.hash ().to_string ());
|
||||
test_response response (request, rpc, system.io_ctx);
|
||||
system.deadline_set (5s);
|
||||
while (response.status == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
ASSERT_EQ ("1", response.json.get<std::string> ("started"));
|
||||
// Check confirmation history
|
||||
auto confirmed (node->active.list_confirmed ());
|
||||
ASSERT_EQ (1, confirmed.size ());
|
||||
ASSERT_EQ (genesis.hash (), confirmed.begin ()->winner->hash ());
|
||||
// Check callback
|
||||
system.deadline_set (5s);
|
||||
while (node->stats.count (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out) == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
// Callback result is error because callback target port isn't listening
|
||||
ASSERT_EQ (1, node->stats.count (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out));
|
||||
node->stop ();
|
||||
}
|
||||
|
||||
TEST (rpc, node_id)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue