Skip to content

Commit

Permalink
Trending active_transactions difficulty for an average (#1858)
Browse files Browse the repository at this point in the history
* difficulty polled into a circular buffer
active_difficulty stored as atomic instead of function call

* Adjust for 5 min trend

* rpc to expose active_difficulty

* use qualified root
simplify roots avg calculation
initialize circular buffer with threshold

* remove deadline and system poll
init active_difficulty and difficulty_cb
use std::accumulate
rework test for active_difficulty polling
cleanup and assert if not threshold

* missed usage of accumulate

* use nano::uint128_t when applicable

* merge cleanup

* correct initialization order.
  • Loading branch information
argakiig authored Mar 30, 2019
1 parent 232cb55 commit dd46609
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 0 deletions.
37 changes: 37 additions & 0 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <nano/node/testing.hpp>
#include <nano/node/transport/udp.hpp>
#include <nano/node/working.hpp>
#include <numeric>

#include <boost/make_shared.hpp>
#include <boost/polymorphic_cast.hpp>
Expand Down Expand Up @@ -2434,6 +2435,42 @@ TEST (node, unchecked_cleanup)
}
}

TEST (active_difficulty, recalculate_work)
{
nano::system system (24000, 1);
auto & node1 (*system.nodes[0]);
nano::genesis genesis;
nano::keypair key1;
ASSERT_EQ (node1.network_params.network.publish_threshold, node1.active.active_difficulty.load ());
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key1.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
uint64_t difficulty1;
nano::work_validate (*send1, &difficulty1);
// Process as local block
node1.process_active (send1);
system.deadline_set (2s);
while (node1.active.empty ())
{
ASSERT_NO_ERROR (system.poll ());
}
auto sum = std::accumulate (node1.active.difficulty_cb.begin (), node1.active.difficulty_cb.end (), nano::uint128_t (0));
std::unique_lock<std::mutex> lock (node1.active.mutex);
ASSERT_EQ (node1.active.active_difficulty.load (), static_cast<uint64_t> (sum / node1.active.difficulty_cb.size ()));
// Fake history records to force work recalculation
for (auto i (0); i < node1.active.difficulty_cb.size (); i++)
{
node1.active.difficulty_cb.push_back (difficulty1 + 10000);
}
node1.work_generate_blocking (*send1);
uint64_t difficulty2;
nano::work_validate (*send1, &difficulty2);
node1.process_active (send1);
node1.active.update_active_difficulty ();
lock.unlock ();
sum = std::accumulate (node1.active.difficulty_cb.begin (), node1.active.difficulty_cb.end (), nano::uint128_t (0));
ASSERT_EQ (node1.active.active_difficulty.load (), static_cast<uint64_t> (sum / node1.active.difficulty_cb.size ()));
}

namespace
{
void add_required_children_node_config_tree (nano::jsonconfig & tree)
Expand Down
24 changes: 24 additions & 0 deletions nano/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <algorithm>
#include <cstdlib>
#include <future>
#include <numeric>
#include <sstream>

#include <boost/polymorphic_cast.hpp>
Expand Down Expand Up @@ -3050,6 +3051,7 @@ void nano::active_transactions::request_confirm (std::unique_lock<std::mutex> &
}
roots.erase (*i);
}
update_active_difficulty ();
if (unconfirmed_count > 0)
{
node.logger.try_log (boost::str (boost::format ("%1% blocks have been unconfirmed averaging %2% announcements") % unconfirmed_count % (unconfirmed_announcements / unconfirmed_count)));
Expand Down Expand Up @@ -3269,6 +3271,26 @@ void nano::active_transactions::adjust_difficulty (nano::block_hash const & hash
}
}

void nano::active_transactions::update_active_difficulty ()
{
assert (!mutex.try_lock ());
uint64_t difficulty (node.network_params.network.publish_threshold);
if (!roots.empty ())
{
uint128_t min = roots.get<1> ().begin ()->adjusted_difficulty;
assert (min >= node.network_params.network.publish_threshold);
uint128_t max = (--roots.get<1> ().end ())->adjusted_difficulty;
assert (max >= node.network_params.network.publish_threshold);
difficulty = static_cast<uint64_t> ((min + max) / 2);
}
assert (difficulty >= node.network_params.network.publish_threshold);
difficulty_cb.push_front (difficulty);
auto sum = std::accumulate (node.active.difficulty_cb.begin (), node.active.difficulty_cb.end (), uint128_t (0));
difficulty = static_cast<uint64_t> (sum / difficulty_cb.size ());
assert (difficulty >= node.network_params.network.publish_threshold);
active_difficulty.store (difficulty);
}

// List of active blocks in elections
std::deque<std::shared_ptr<nano::block>> nano::active_transactions::list_blocks (bool single_lock)
{
Expand Down Expand Up @@ -3315,6 +3337,8 @@ size_t nano::active_transactions::size ()

nano::active_transactions::active_transactions (nano::node & node_a) :
node (node_a),
difficulty_cb (20, node.network_params.network.publish_threshold),
active_difficulty (node.network_params.network.publish_threshold),
started (false),
stopped (false),
thread ([this]() {
Expand Down
3 changes: 3 additions & 0 deletions nano/node/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class active_transactions final
bool active (nano::block const &);
void update_difficulty (nano::block const &);
void adjust_difficulty (nano::block_hash const &);
void update_active_difficulty ();
std::deque<std::shared_ptr<nano::block>> list_blocks (bool = false);
void erase (nano::block const &);
bool empty ();
Expand Down Expand Up @@ -142,6 +143,8 @@ class active_transactions final
static unsigned constexpr announcement_long = 20;
static size_t constexpr election_history_size = 2048;
static size_t constexpr max_broadcast_queue = 1000;
boost::circular_buffer<uint64_t> difficulty_cb;
std::atomic<uint64_t> active_difficulty;

private:
// Call action with confirmed block, may be different than what we started with
Expand Down
8 changes: 8 additions & 0 deletions nano/node/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,13 @@ void nano::rpc_handler::accounts_pending ()
response_errors ();
}

void nano::rpc_handler::active_difficulty ()
{
response_l.put ("difficulty_threshold", nano::to_string_hex (node.network_params.network.publish_threshold));
response_l.put ("difficulty_active", nano::to_string_hex (node.active.active_difficulty));
response_errors ();
}

void nano::rpc_handler::available_supply ()
{
auto genesis_balance (node.balance (node.network_params.ledger.genesis_account)); // Cold storage genesis
Expand Down Expand Up @@ -4697,6 +4704,7 @@ rpc_handler_no_arg_func_map create_rpc_handler_no_arg_func_map ()
no_arg_funcs.emplace ("accounts_create", &nano::rpc_handler::accounts_create);
no_arg_funcs.emplace ("accounts_frontiers", &nano::rpc_handler::accounts_frontiers);
no_arg_funcs.emplace ("accounts_pending", &nano::rpc_handler::accounts_pending);
no_arg_funcs.emplace ("active_difficulty", &nano::rpc_handler::active_difficulty);
no_arg_funcs.emplace ("available_supply", &nano::rpc_handler::available_supply);
no_arg_funcs.emplace ("block_info", &nano::rpc_handler::block_info);
no_arg_funcs.emplace ("block", &nano::rpc_handler::block_info);
Expand Down
1 change: 1 addition & 0 deletions nano/rpc/rpc_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class rpc_handler : public std::enable_shared_from_this<nano::rpc_handler>
void accounts_create ();
void accounts_frontiers ();
void accounts_pending ();
void active_difficulty ();
void available_supply ();
void block_info ();
void block_confirm ();
Expand Down

0 comments on commit dd46609

Please sign in to comment.