Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trending active_transactions difficulty for an average #1858

Merged
merged 12 commits into from
Mar 30, 2019
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);
argakiig marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -122,6 +122,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 @@ -151,6 +152,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;
argakiig marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -4854,6 +4861,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/node/rpc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,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