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

Use max config difficulty internally #2218

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions nano/core_test/toml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ TEST (toml, daemon_config_deserialize_defaults)
ASSERT_EQ (c.opencl.platform, defaults.opencl.platform);
ASSERT_EQ (c.opencl.threads, defaults.opencl.threads);
ASSERT_EQ (c.rpc.enable_sign_hash, false);
ASSERT_EQ (c.rpc.max_work_generate_difficulty, 0xffffffffc0000000);
ASSERT_EQ (c.rpc.child_process.enable, false);
}

Expand Down Expand Up @@ -257,6 +256,7 @@ TEST (toml, daemon_config_deserialize_no_defaults)
work_peers = ["test.org:999"]
work_threads = 999
work_watcher_period = 999
max_work_generate_multiplier = 1.0
[node.diagnostics.txn_tracking]
enable = true
ignore_writes_below_block_processor_max_time = false
Expand Down Expand Up @@ -331,7 +331,6 @@ TEST (toml, daemon_config_deserialize_no_defaults)
[rpc]
enable = true
enable_sign_hash = true
max_work_generate_difficulty = "ffffffffc9999999"

[rpc.child_process]
enable = true
Expand All @@ -352,7 +351,6 @@ TEST (toml, daemon_config_deserialize_no_defaults)
ASSERT_NE (conf.opencl.threads, defaults.opencl.threads);
ASSERT_NE (conf.rpc_enable, defaults.rpc_enable);
ASSERT_NE (conf.rpc.enable_sign_hash, defaults.rpc.enable_sign_hash);
ASSERT_NE (conf.rpc.max_work_generate_difficulty, defaults.rpc.max_work_generate_difficulty);
ASSERT_NE (conf.rpc.child_process.enable, defaults.rpc.child_process.enable);
ASSERT_NE (conf.rpc.child_process.rpc_path, defaults.rpc.child_process.rpc_path);

Expand All @@ -370,6 +368,7 @@ TEST (toml, daemon_config_deserialize_no_defaults)
ASSERT_NE (conf.node.external_port, defaults.node.external_port);
ASSERT_NE (conf.node.io_threads, defaults.node.io_threads);
ASSERT_NE (conf.node.lmdb_max_dbs, defaults.node.lmdb_max_dbs);
ASSERT_NE (conf.node.max_work_generate_multiplier, defaults.node.max_work_generate_multiplier);
ASSERT_NE (conf.node.network_threads, defaults.node.network_threads);
ASSERT_NE (conf.node.work_watcher_period, defaults.node.work_watcher_period);
ASSERT_NE (conf.node.online_weight_minimum, defaults.node.online_weight_minimum);
Expand Down Expand Up @@ -485,3 +484,20 @@ TEST (toml, rpc_config_deserialize_no_defaults)
ASSERT_NE (conf.rpc_process.ipc_port, defaults.rpc_process.ipc_port);
ASSERT_NE (conf.rpc_process.num_ipc_connections, defaults.rpc_process.num_ipc_connections);
}

/** Deserialize a node config with incorrect values */
TEST (toml, daemon_config_deserialize_errors)
{
std::stringstream ss_max_work_generate_multiplier;
ss_max_work_generate_multiplier << R"toml(
[node]
max_work_generate_multiplier = 0.9
)toml";

nano::tomlconfig toml;
toml.read (ss_max_work_generate_multiplier);
nano::daemon_config conf;
conf.deserialize_toml (toml);

ASSERT_EQ (toml.get_error ().get_message (), "max_work_generate_multiplier must be greater than or equal to 1");
}
5 changes: 5 additions & 0 deletions nano/node/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,11 @@ uint64_t nano::active_transactions::active_difficulty ()
return trended_active_difficulty;
}

uint64_t nano::active_transactions::limited_active_difficulty ()
{
return std::min (active_difficulty (), node.config.max_work_generate_difficulty);
}

// List of active blocks in elections
std::deque<std::shared_ptr<nano::block>> nano::active_transactions::list_blocks (bool single_lock)
{
Expand Down
1 change: 1 addition & 0 deletions nano/node/active_transactions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class active_transactions final
void adjust_difficulty (nano::block_hash const &);
void update_active_difficulty (std::unique_lock<std::mutex> &);
uint64_t active_difficulty ();
uint64_t limited_active_difficulty ();
std::deque<std::shared_ptr<nano::block>> list_blocks (bool = false);
void erase (nano::block const &);
//drop 2 from roots based on adjusted_difficulty
Expand Down
2 changes: 1 addition & 1 deletion nano/node/json_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4440,7 +4440,7 @@ void nano::json_handler::work_generate ()
auto difficulty (difficulty_optional_impl ());
auto multiplier (multiplier_optional_impl (difficulty));
(void)multiplier;
if (!ec && (difficulty > node_rpc_config.max_work_generate_difficulty || difficulty < node.network_params.network.publish_threshold))
if (!ec && (difficulty > node.config.max_work_generate_difficulty || difficulty < node.network_params.network.publish_threshold))
{
ec = nano::error_rpc::difficulty_limit;
}
Expand Down
15 changes: 0 additions & 15 deletions nano/node/node_rpc_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ nano::error nano::node_rpc_config::serialize_json (nano::jsonconfig & json) cons
{
json.put ("version", json_version ());
json.put ("enable_sign_hash", enable_sign_hash);
json.put ("max_work_generate_difficulty", nano::to_string_hex (max_work_generate_difficulty));

nano::jsonconfig child_process_l;
child_process_l.put ("enable", child_process.enable);
Expand All @@ -21,7 +20,6 @@ nano::error nano::node_rpc_config::serialize_json (nano::jsonconfig & json) cons
nano::error nano::node_rpc_config::serialize_toml (nano::tomlconfig & toml) const
{
toml.put ("enable_sign_hash", enable_sign_hash, "Allow or disallow signing of hashes\ntype:bool");
toml.put ("max_work_generate_difficulty", nano::to_string_hex (max_work_generate_difficulty), "Maximum allowed difficulty request for work generation\ntype:string,hex");

nano::tomlconfig child_process_l;
child_process_l.put ("enable", child_process.enable, "Enable or disable RPC child process. If false, an in-process RPC server is used.\ntype:bool");
Expand All @@ -34,12 +32,6 @@ nano::error nano::node_rpc_config::deserialize_toml (nano::tomlconfig & toml)
{
toml.get_optional ("enable_sign_hash", enable_sign_hash);
toml.get_optional<bool> ("enable_sign_hash", enable_sign_hash);
std::string max_work_generate_difficulty_text;
toml.get_optional<std::string> ("max_work_generate_difficulty", max_work_generate_difficulty_text);
if (!max_work_generate_difficulty_text.empty ())
{
nano::from_string_hex (max_work_generate_difficulty_text, max_work_generate_difficulty);
}

auto child_process_l (toml.get_optional_child ("child_process"));
if (child_process_l)
Expand Down Expand Up @@ -68,7 +60,6 @@ nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::js
migrate (json, data_path);

json.put ("enable_sign_hash", enable_sign_hash);
json.put ("max_work_generate_difficulty", nano::to_string_hex (max_work_generate_difficulty));

// Remove options no longer needed after migration
json.erase ("enable_control");
Expand All @@ -88,12 +79,6 @@ nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::js
}

json.get_optional<bool> ("enable_sign_hash", enable_sign_hash);
std::string max_work_generate_difficulty_text;
json.get_optional<std::string> ("max_work_generate_difficulty", max_work_generate_difficulty_text);
if (!max_work_generate_difficulty_text.empty ())
{
nano::from_string_hex (max_work_generate_difficulty_text, max_work_generate_difficulty);
}

auto child_process_l (json.get_optional_child ("child_process"));
if (child_process_l)
Expand Down
1 change: 0 additions & 1 deletion nano/node/node_rpc_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class node_rpc_config final
nano::error deserialize_toml (nano::tomlconfig & toml);

bool enable_sign_hash{ false };
uint64_t max_work_generate_difficulty{ 0xffffffffc0000000 };
nano::rpc_child_process_config child_process;
static unsigned json_version ()
{
Expand Down
11 changes: 10 additions & 1 deletion nano/node/nodeconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ logging (logging_a)
const char * epoch_message ("epoch v1 block");
strncpy ((char *)epoch_block_link.bytes.data (), epoch_message, epoch_block_link.bytes.size ());
epoch_block_signer = network_params.ledger.genesis_account;
max_work_generate_difficulty = nano::difficulty::from_multiplier (max_work_generate_multiplier, network_params.network.publish_threshold);
switch (network_params.network.network ())
{
case nano::nano_networks::nano_test_network:
Expand Down Expand Up @@ -96,6 +97,7 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const
toml.put ("bandwidth_limit", bandwidth_limit, "Outbound traffic limit in bytes/sec after which messages will be dropped\ntype:uint64");
toml.put ("backup_before_upgrade", backup_before_upgrade, "Backup the ledger database before performing upgrades\ntype:bool");
toml.put ("work_watcher_period", work_watcher_period.count (), "Time between checks for confirmation and re-generating higher difficulty work if unconfirmed, for blocks in the work watcher.\ntype:seconds");
toml.put ("max_work_generate_multiplier", max_work_generate_multiplier, "Maximum allowed difficulty multiplier for work generation\ntype:double,[1..]");

auto work_peers_l (toml.create_array ("work_peers", "A list of \"address:port\" entries to identify work peers"));
for (auto i (work_peers.begin ()), n (work_peers.end ()); i != n; ++i)
Expand Down Expand Up @@ -300,6 +302,9 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
conf_height_processor_batch_min_time = std::chrono::milliseconds (conf_height_processor_batch_min_time_l);

nano::network_constants network;
toml.get<double> ("max_work_generate_multiplier", max_work_generate_multiplier);
max_work_generate_difficulty = nano::difficulty::from_multiplier (max_work_generate_multiplier, network.publish_threshold);

// Validate ranges
if (online_weight_quorum > 100)
{
Expand Down Expand Up @@ -329,6 +334,10 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
{
toml.get_error ().set ("work_watcher_period must be equal or larger than 1");
}
if (max_work_generate_multiplier < 1)
{
toml.get_error ().set ("max_work_generate_multiplier must be greater than or equal to 1");
}
}
catch (std::runtime_error const & ex)
{
Expand Down Expand Up @@ -716,7 +725,7 @@ nano::error nano::node_config::deserialize_json (bool & upgraded_a, nano::jsonco
}
if (active_elections_size <= 250 && !network.is_test_network ())
{
json.get_error ().set ("active_elections_size must be grater than 250");
json.get_error ().set ("active_elections_size must be greater than 250");
}
if (bandwidth_limit > std::numeric_limits<size_t>::max ())
{
Expand Down
2 changes: 2 additions & 0 deletions nano/node/nodeconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class node_config
std::chrono::milliseconds conf_height_processor_batch_min_time{ 50 };
bool backup_before_upgrade{ false };
std::chrono::seconds work_watcher_period{ std::chrono::seconds (5) };
double max_work_generate_multiplier{ 64. };
uint64_t max_work_generate_difficulty{ nano::network_constants::publish_full_threshold };
static unsigned json_version ()
{
return 18;
Expand Down
11 changes: 6 additions & 5 deletions nano/node/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block const & s
if (nano::work_validate (*block))
{
wallets.node.logger.try_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.active.active_difficulty ());
wallets.node.work_generate_blocking (*block, wallets.node.active.limited_active_difficulty ());
}
wallets.watcher.add (block);
bool error (wallets.node.process_local (block).code != nano::process_result::progress);
Expand Down Expand Up @@ -1027,7 +1027,7 @@ std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const &
if (nano::work_validate (*block))
{
wallets.node.logger.try_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.active.active_difficulty ());
wallets.node.work_generate_blocking (*block, wallets.node.active.limited_active_difficulty ());
}
wallets.watcher.add (block);
bool error (wallets.node.process_local (block).code != nano::process_result::progress);
Expand Down Expand Up @@ -1141,7 +1141,7 @@ std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & so
if (nano::work_validate (*block))
{
wallets.node.logger.try_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.active.active_difficulty ());
wallets.node.work_generate_blocking (*block, wallets.node.active.limited_active_difficulty ());
}
wallets.watcher.add (block);
error = (wallets.node.process_local (block).code != nano::process_result::progress);
Expand Down Expand Up @@ -1470,15 +1470,16 @@ void nano::work_watcher::run ()
root = i.second->root ();
nano::work_validate (root, i.second->block_work (), &difficulty);
}
if (node.active.active_difficulty () > difficulty && i.second != nullptr)
auto active_difficulty (node.active.limited_active_difficulty ());
if (active_difficulty > difficulty && i.second != nullptr)
{
auto qualified_root = i.second->qualified_root ();
auto hash = i.second->hash ();
nano::state_block_builder builder;
std::error_code ec;
builder.from (*i.second);
lock.unlock ();
builder.work (node.work_generate_blocking (root, node.active.active_difficulty ()));
builder.work (node.work_generate_blocking (root, active_difficulty));
std::shared_ptr<state_block> block (builder.build (ec));
if (!ec)
{
Expand Down
16 changes: 10 additions & 6 deletions nano/rpc_test/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2623,8 +2623,10 @@ TEST (rpc, work_generate)

TEST (rpc, work_generate_difficulty)
{
nano::system system (24000, 1);
auto node (system.nodes[0]);
nano::system system;
nano::node_config node_config (24000, system.logging);
node_config.max_work_generate_difficulty = 0xffff000000000000;
auto node = system.add_node (node_config);
scoped_io_thread_name_change scoped_thread_name_io;
enable_ipc_transport_tcp (node->config.ipc_config.transport_tcp);
nano::node_rpc_config node_rpc_config;
Expand Down Expand Up @@ -2679,7 +2681,7 @@ TEST (rpc, work_generate_difficulty)
ASSERT_GE (result_difficulty, difficulty);
}
{
uint64_t difficulty (node_rpc_config.max_work_generate_difficulty + 1);
uint64_t difficulty (node->config.max_work_generate_difficulty + 1);
request.put ("difficulty", nano::to_string_hex (difficulty));
test_response response (request, rpc.config.port, system.io_ctx);
system.deadline_set (5s);
Expand All @@ -2695,8 +2697,10 @@ TEST (rpc, work_generate_difficulty)

TEST (rpc, work_generate_multiplier)
{
nano::system system (24000, 1);
auto node (system.nodes[0]);
nano::system system;
nano::node_config node_config (24000, system.logging);
node_config.max_work_generate_difficulty = 0xffff000000000000;
auto node = system.add_node (node_config);
scoped_io_thread_name_change scoped_thread_name_io;
enable_ipc_transport_tcp (node->config.ipc_config.transport_tcp);
nano::node_rpc_config node_rpc_config;
Expand Down Expand Up @@ -2747,7 +2751,7 @@ TEST (rpc, work_generate_multiplier)
ASSERT_EQ (response.json.get<std::string> ("error"), ec.message ());
}
{
double max_multiplier (nano::difficulty::to_multiplier (node_rpc_config.max_work_generate_difficulty, node->network_params.network.publish_threshold));
double max_multiplier (nano::difficulty::to_multiplier (node->config.max_work_generate_difficulty, node->network_params.network.publish_threshold));
request.put ("multiplier", max_multiplier + 1);
test_response response (request, rpc.config.port, system.io_ctx);
system.deadline_set (5s);
Expand Down