Epoch 2 started flag in ledger cache (#2684)
* Epoch 2 started flag in ledger cache This flag is flipped when the first epoch 2 block is successfully processed. Differences in behavior after the flag is flipped: - RPC `work_generate` uses the new epoch 2 threshold as default - RPC `work_validate` validates for the new threshold as default (breaking behavior in previous PR) - RPC `block_create` uses the new threshold as default - Node wallet pre-caches work at the new threshold * Adjust tests for node default difficulty * Also affect work websocket multiplier, and change default test work generate difficulty * Fix rpc.work_validate test * Ensure state is kept on ledger initialization (node restart)
This commit is contained in:
parent
d1d2a1d51c
commit
ed10a6fb6b
11 changed files with 182 additions and 21 deletions
|
|
@ -3056,3 +3056,32 @@ TEST (ledger, work_validation)
|
||||||
process_block (open, {});
|
process_block (open, {});
|
||||||
process_block (epoch, nano::block_details (nano::epoch::epoch_1, false, false, true));
|
process_block (epoch, nano::block_details (nano::epoch::epoch_1, false, false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST (ledger, epoch_2_started_flag)
|
||||||
|
{
|
||||||
|
nano::system system (2);
|
||||||
|
|
||||||
|
auto & node1 = *system.nodes[0];
|
||||||
|
ASSERT_FALSE (node1.ledger.cache.epoch_2_started.load ());
|
||||||
|
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (node1, nano::epoch::epoch_1));
|
||||||
|
ASSERT_FALSE (node1.ledger.cache.epoch_2_started.load ());
|
||||||
|
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (node1, nano::epoch::epoch_2));
|
||||||
|
ASSERT_TRUE (node1.ledger.cache.epoch_2_started.load ());
|
||||||
|
|
||||||
|
auto & node2 = *system.nodes[1];
|
||||||
|
nano::keypair key;
|
||||||
|
auto epoch1 = system.upgrade_genesis_epoch (node2, nano::epoch::epoch_1);
|
||||||
|
ASSERT_NE (nullptr, epoch1);
|
||||||
|
ASSERT_FALSE (node2.ledger.cache.epoch_2_started.load ());
|
||||||
|
nano::state_block send (nano::test_genesis_key.pub, epoch1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 1, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (epoch1->hash ()));
|
||||||
|
ASSERT_EQ (nano::process_result::progress, node2.process (send).code);
|
||||||
|
ASSERT_FALSE (node2.ledger.cache.epoch_2_started.load ());
|
||||||
|
nano::state_block epoch2 (key.pub, 0, 0, 0, node2.ledger.epoch_link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (key.pub));
|
||||||
|
ASSERT_EQ (nano::process_result::progress, node2.process (epoch2).code);
|
||||||
|
ASSERT_TRUE (node2.ledger.cache.epoch_2_started.load ());
|
||||||
|
|
||||||
|
// Ensure state is kept on ledger initialization
|
||||||
|
nano::stat stats;
|
||||||
|
nano::ledger ledger (node1.store, stats);
|
||||||
|
ASSERT_TRUE (ledger.cache.epoch_2_started.load ());
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -649,7 +649,7 @@ TEST (wallet, work)
|
||||||
uint64_t work (0);
|
uint64_t work (0);
|
||||||
if (!wallet->store.work_get (transaction, nano::test_genesis_key.pub, work))
|
if (!wallet->store.work_get (transaction, nano::test_genesis_key.pub, work))
|
||||||
{
|
{
|
||||||
done = nano::work_difficulty (genesis.open->work_version (), genesis.hash (), work) >= nano::work_threshold_base (genesis.open->work_version ());
|
done = nano::work_difficulty (genesis.open->work_version (), genesis.hash (), work) >= system.nodes[0]->default_difficulty ();
|
||||||
}
|
}
|
||||||
ASSERT_NO_ERROR (system.poll ());
|
ASSERT_NO_ERROR (system.poll ());
|
||||||
}
|
}
|
||||||
|
|
@ -683,7 +683,7 @@ TEST (wallet, work_generate)
|
||||||
ASSERT_NO_ERROR (system.poll ());
|
ASSERT_NO_ERROR (system.poll ());
|
||||||
auto block_transaction (node1.store.tx_begin_read ());
|
auto block_transaction (node1.store.tx_begin_read ());
|
||||||
auto transaction (system.wallet (0)->wallets.tx_begin_read ());
|
auto transaction (system.wallet (0)->wallets.tx_begin_read ());
|
||||||
again = wallet->store.work_get (transaction, account1, work1) || nano::work_difficulty (block->work_version (), node1.ledger.latest_root (block_transaction, account1), work1) < nano::work_threshold_base (block->work_version ());
|
again = wallet->store.work_get (transaction, account1, work1) || nano::work_difficulty (block->work_version (), node1.ledger.latest_root (block_transaction, account1), work1) < node1.default_difficulty ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -680,15 +680,15 @@ TEST (websocket, work)
|
||||||
auto & request = contents.get_child ("request");
|
auto & request = contents.get_child ("request");
|
||||||
ASSERT_EQ (request.get<std::string> ("version"), nano::to_string (nano::work_version::work_1));
|
ASSERT_EQ (request.get<std::string> ("version"), nano::to_string (nano::work_version::work_1));
|
||||||
ASSERT_EQ (request.get<std::string> ("hash"), hash.to_string ());
|
ASSERT_EQ (request.get<std::string> ("hash"), hash.to_string ());
|
||||||
ASSERT_EQ (request.get<std::string> ("difficulty"), nano::to_string_hex (node1->network_params.network.publish_thresholds.base));
|
ASSERT_EQ (request.get<std::string> ("difficulty"), nano::to_string_hex (node1->default_difficulty ()));
|
||||||
ASSERT_EQ (request.get<double> ("multiplier"), 1.0);
|
ASSERT_EQ (request.get<double> ("multiplier"), 1.0);
|
||||||
|
|
||||||
ASSERT_EQ (1, contents.count ("result"));
|
ASSERT_EQ (1, contents.count ("result"));
|
||||||
auto & result = contents.get_child ("result");
|
auto & result = contents.get_child ("result");
|
||||||
uint64_t result_difficulty;
|
uint64_t result_difficulty;
|
||||||
nano::from_string_hex (result.get<std::string> ("difficulty"), result_difficulty);
|
nano::from_string_hex (result.get<std::string> ("difficulty"), result_difficulty);
|
||||||
ASSERT_GE (result_difficulty, node1->network_params.network.publish_thresholds.base);
|
ASSERT_GE (result_difficulty, node1->default_difficulty ());
|
||||||
ASSERT_NEAR (result.get<double> ("multiplier"), nano::difficulty::to_multiplier (result_difficulty, node1->network_params.network.publish_thresholds.base), 1e-6);
|
ASSERT_NEAR (result.get<double> ("multiplier"), nano::difficulty::to_multiplier (result_difficulty, node1->default_difficulty ()), 1e-6);
|
||||||
ASSERT_EQ (result.get<std::string> ("work"), nano::to_string_hex (work.get ()));
|
ASSERT_EQ (result.get<std::string> ("work"), nano::to_string_hex (work.get ()));
|
||||||
|
|
||||||
ASSERT_EQ (1, contents.count ("bad_peers"));
|
ASSERT_EQ (1, contents.count ("bad_peers"));
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,15 @@ nano::distributed_work::~distributed_work ()
|
||||||
nano::websocket::message_builder builder;
|
nano::websocket::message_builder builder;
|
||||||
if (status == work_generation_status::success)
|
if (status == work_generation_status::success)
|
||||||
{
|
{
|
||||||
node_l->websocket_server->broadcast (builder.work_generation (request.version, request.root, work_result, request.difficulty, node_l->network_params.network.publish_thresholds.base, elapsed.value (), winner, bad_peers));
|
node_l->websocket_server->broadcast (builder.work_generation (request.version, request.root, work_result, request.difficulty, node_l->default_difficulty (), elapsed.value (), winner, bad_peers));
|
||||||
}
|
}
|
||||||
else if (status == work_generation_status::cancelled)
|
else if (status == work_generation_status::cancelled)
|
||||||
{
|
{
|
||||||
node_l->websocket_server->broadcast (builder.work_cancelled (request.version, request.root, request.difficulty, node_l->network_params.network.publish_thresholds.base, elapsed.value (), bad_peers));
|
node_l->websocket_server->broadcast (builder.work_cancelled (request.version, request.root, request.difficulty, node_l->default_difficulty (), elapsed.value (), bad_peers));
|
||||||
}
|
}
|
||||||
else if (status == work_generation_status::failure_local || status == work_generation_status::failure_peers)
|
else if (status == work_generation_status::failure_local || status == work_generation_status::failure_peers)
|
||||||
{
|
{
|
||||||
node_l->websocket_server->broadcast (builder.work_failed (request.version, request.root, request.difficulty, node_l->network_params.network.publish_thresholds.base, elapsed.value (), bad_peers));
|
node_l->websocket_server->broadcast (builder.work_failed (request.version, request.root, request.difficulty, node_l->default_difficulty (), elapsed.value (), bad_peers));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stop_once (true);
|
stop_once (true);
|
||||||
|
|
|
||||||
|
|
@ -345,7 +345,7 @@ uint64_t nano::json_handler::work_optional_impl ()
|
||||||
|
|
||||||
uint64_t nano::json_handler::difficulty_optional_impl ()
|
uint64_t nano::json_handler::difficulty_optional_impl ()
|
||||||
{
|
{
|
||||||
uint64_t difficulty (node.network_params.network.publish_thresholds.base);
|
auto difficulty (node.default_difficulty ());
|
||||||
boost::optional<std::string> difficulty_text (request.get_optional<std::string> ("difficulty"));
|
boost::optional<std::string> difficulty_text (request.get_optional<std::string> ("difficulty"));
|
||||||
if (!ec && difficulty_text.is_initialized ())
|
if (!ec && difficulty_text.is_initialized ())
|
||||||
{
|
{
|
||||||
|
|
@ -5085,7 +5085,7 @@ void nano::json_handler::work_validate ()
|
||||||
auto result_difficulty (nano::work_difficulty (work_version, hash, work));
|
auto result_difficulty (nano::work_difficulty (work_version, hash, work));
|
||||||
response_l.put ("valid", (result_difficulty >= difficulty) ? "1" : "0");
|
response_l.put ("valid", (result_difficulty >= difficulty) ? "1" : "0");
|
||||||
response_l.put ("difficulty", nano::to_string_hex (result_difficulty));
|
response_l.put ("difficulty", nano::to_string_hex (result_difficulty));
|
||||||
auto result_multiplier = nano::difficulty::to_multiplier (result_difficulty, node.network_params.network.publish_thresholds.base);
|
auto result_multiplier = nano::difficulty::to_multiplier (result_difficulty, node.default_difficulty ());
|
||||||
response_l.put ("multiplier", nano::to_string (result_multiplier));
|
response_l.put ("multiplier", nano::to_string (result_multiplier));
|
||||||
}
|
}
|
||||||
response_errors ();
|
response_errors ();
|
||||||
|
|
|
||||||
|
|
@ -1004,6 +1004,11 @@ int nano::node::price (nano::uint128_t const & balance_a, int amount_a)
|
||||||
return static_cast<int> (result * 100.0);
|
return static_cast<int> (result * 100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t nano::node::default_difficulty () const
|
||||||
|
{
|
||||||
|
return ledger.cache.epoch_2_started ? network_params.network.publish_thresholds.base : network_params.network.publish_thresholds.epoch_1;
|
||||||
|
}
|
||||||
|
|
||||||
bool nano::node::local_work_generation_enabled () const
|
bool nano::node::local_work_generation_enabled () const
|
||||||
{
|
{
|
||||||
return config.work_threads > 0 || work.opencl;
|
return config.work_threads > 0 || work.opencl;
|
||||||
|
|
@ -1053,13 +1058,13 @@ boost::optional<uint64_t> nano::node::work_generate_blocking (nano::work_version
|
||||||
boost::optional<uint64_t> nano::node::work_generate_blocking (nano::block & block_a)
|
boost::optional<uint64_t> nano::node::work_generate_blocking (nano::block & block_a)
|
||||||
{
|
{
|
||||||
debug_assert (network_params.network.is_test_network ());
|
debug_assert (network_params.network.is_test_network ());
|
||||||
return work_generate_blocking (block_a, network_params.network.publish_thresholds.base);
|
return work_generate_blocking (block_a, default_difficulty ());
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<uint64_t> nano::node::work_generate_blocking (nano::root const & root_a)
|
boost::optional<uint64_t> nano::node::work_generate_blocking (nano::root const & root_a)
|
||||||
{
|
{
|
||||||
debug_assert (network_params.network.is_test_network ());
|
debug_assert (network_params.network.is_test_network ());
|
||||||
return work_generate_blocking (root_a, network_params.network.publish_thresholds.base);
|
return work_generate_blocking (root_a, default_difficulty ());
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<uint64_t> nano::node::work_generate_blocking (nano::root const & root_a, uint64_t difficulty_a)
|
boost::optional<uint64_t> nano::node::work_generate_blocking (nano::root const & root_a, uint64_t difficulty_a)
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,8 @@ public:
|
||||||
void bootstrap_wallet ();
|
void bootstrap_wallet ();
|
||||||
void unchecked_cleanup ();
|
void unchecked_cleanup ();
|
||||||
int price (nano::uint128_t const &, int);
|
int price (nano::uint128_t const &, int);
|
||||||
|
// The default difficulty updates to base only when the first epoch_2 block is processed
|
||||||
|
uint64_t default_difficulty () const;
|
||||||
bool local_work_generation_enabled () const;
|
bool local_work_generation_enabled () const;
|
||||||
bool work_generation_enabled () const;
|
bool work_generation_enabled () const;
|
||||||
bool work_generation_enabled (std::vector<std::pair<std::string, uint16_t>> const &) const;
|
bool work_generation_enabled (std::vector<std::pair<std::string, uint16_t>> const &) const;
|
||||||
|
|
|
||||||
|
|
@ -1383,7 +1383,8 @@ void nano::wallet::work_cache_blocking (nano::account const & account_a, nano::r
|
||||||
{
|
{
|
||||||
if (wallets.node.work_generation_enabled ())
|
if (wallets.node.work_generation_enabled ())
|
||||||
{
|
{
|
||||||
auto opt_work_l (wallets.node.work_generate_blocking (nano::work_version::work_1, root_a, wallets.node.network_params.network.publish_thresholds.base, account_a));
|
auto difficulty (wallets.node.default_difficulty ());
|
||||||
|
auto opt_work_l (wallets.node.work_generate_blocking (nano::work_version::work_1, root_a, difficulty, account_a));
|
||||||
if (opt_work_l.is_initialized ())
|
if (opt_work_l.is_initialized ())
|
||||||
{
|
{
|
||||||
auto transaction_l (wallets.tx_begin_write ());
|
auto transaction_l (wallets.tx_begin_write ());
|
||||||
|
|
|
||||||
|
|
@ -2310,7 +2310,7 @@ TEST (rpc, payment_begin_end)
|
||||||
ASSERT_LT (work, 50);
|
ASSERT_LT (work, 50);
|
||||||
}
|
}
|
||||||
system.deadline_set (10s);
|
system.deadline_set (10s);
|
||||||
while (nano::work_difficulty (nano::work_version::work_1, root1, work) < nano::work_threshold_base (nano::work_version::work_1))
|
while (nano::work_difficulty (nano::work_version::work_1, root1, work) < node1->default_difficulty ())
|
||||||
{
|
{
|
||||||
auto ec = system.poll ();
|
auto ec = system.poll ();
|
||||||
auto transaction (wallet->wallets.tx_begin_read ());
|
auto transaction (wallet->wallets.tx_begin_read ());
|
||||||
|
|
@ -3073,6 +3073,67 @@ TEST (rpc, work_generate_multiplier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST (rpc, work_generate_epoch_2)
|
||||||
|
{
|
||||||
|
nano::system system;
|
||||||
|
auto node = add_ipc_enabled_node (system);
|
||||||
|
auto epoch1 = system.upgrade_genesis_epoch (*node, nano::epoch::epoch_1);
|
||||||
|
ASSERT_NE (nullptr, epoch1);
|
||||||
|
scoped_io_thread_name_change scoped_thread_name_io;
|
||||||
|
nano::node_rpc_config node_rpc_config;
|
||||||
|
nano::ipc::ipc_server ipc_server (*node, node_rpc_config);
|
||||||
|
nano::rpc_config rpc_config (nano::get_available_port (), true);
|
||||||
|
rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port;
|
||||||
|
nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
|
||||||
|
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
|
||||||
|
rpc.start ();
|
||||||
|
boost::property_tree::ptree request;
|
||||||
|
auto verify_response = [node, &rpc, &system](auto & request, nano::block_hash const & hash, uint64_t & out_difficulty) {
|
||||||
|
request.put ("hash", hash.to_string ());
|
||||||
|
test_response response (request, rpc.config.port, system.io_ctx);
|
||||||
|
system.deadline_set (5s);
|
||||||
|
while (response.status == 0)
|
||||||
|
{
|
||||||
|
ASSERT_NO_ERROR (system.poll ());
|
||||||
|
}
|
||||||
|
ASSERT_EQ (200, response.status);
|
||||||
|
auto work_text (response.json.get<std::string> ("work"));
|
||||||
|
uint64_t work{ 0 };
|
||||||
|
ASSERT_FALSE (nano::from_string_hex (work_text, work));
|
||||||
|
out_difficulty = nano::work_difficulty (nano::work_version::work_1, hash, work);
|
||||||
|
};
|
||||||
|
request.put ("action", "work_generate");
|
||||||
|
// Before upgrading to epoch 2 should use epoch_1 difficulty as default
|
||||||
|
{
|
||||||
|
unsigned const max_tries = 30;
|
||||||
|
uint64_t difficulty{ 0 };
|
||||||
|
unsigned tries = 0;
|
||||||
|
while (++tries < max_tries)
|
||||||
|
{
|
||||||
|
verify_response (request, epoch1->hash (), difficulty);
|
||||||
|
if (difficulty < node->network_params.network.publish_thresholds.base)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT_LT (tries, max_tries);
|
||||||
|
}
|
||||||
|
// After upgrading, should always use the higher difficulty by default
|
||||||
|
ASSERT_EQ (node->network_params.network.publish_thresholds.epoch_2, node->network_params.network.publish_thresholds.base);
|
||||||
|
scoped_thread_name_io.reset ();
|
||||||
|
auto epoch2 = system.upgrade_genesis_epoch (*node, nano::epoch::epoch_2);
|
||||||
|
ASSERT_NE (nullptr, epoch2);
|
||||||
|
scoped_thread_name_io.renew ();
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
uint64_t difficulty{ 0 };
|
||||||
|
verify_response (request, epoch1->hash (), difficulty);
|
||||||
|
ASSERT_GE (difficulty, node->network_params.network.publish_thresholds.base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST (rpc, work_cancel)
|
TEST (rpc, work_cancel)
|
||||||
{
|
{
|
||||||
nano::system system;
|
nano::system system;
|
||||||
|
|
@ -3917,7 +3978,6 @@ TEST (rpc, wallet_frontiers)
|
||||||
|
|
||||||
TEST (rpc, work_validate)
|
TEST (rpc, work_validate)
|
||||||
{
|
{
|
||||||
nano::network_params params;
|
|
||||||
nano::system system;
|
nano::system system;
|
||||||
auto & node1 = *add_ipc_enabled_node (system);
|
auto & node1 = *add_ipc_enabled_node (system);
|
||||||
nano::keypair key;
|
nano::keypair key;
|
||||||
|
|
@ -3950,9 +4010,9 @@ TEST (rpc, work_validate)
|
||||||
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
|
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
|
||||||
uint64_t difficulty;
|
uint64_t difficulty;
|
||||||
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
|
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
|
||||||
ASSERT_GE (difficulty, params.network.publish_thresholds.base);
|
ASSERT_GE (difficulty, node1.default_difficulty ());
|
||||||
double multiplier (response.json.get<double> ("multiplier"));
|
double multiplier (response.json.get<double> ("multiplier"));
|
||||||
ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, params.network.publish_thresholds.base), 1e-6);
|
ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, node1.default_difficulty ()), 1e-6);
|
||||||
}
|
}
|
||||||
uint64_t work2 (0);
|
uint64_t work2 (0);
|
||||||
request.put ("work", nano::to_string_hex (work2));
|
request.put ("work", nano::to_string_hex (work2));
|
||||||
|
|
@ -3969,12 +4029,12 @@ TEST (rpc, work_validate)
|
||||||
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
|
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
|
||||||
uint64_t difficulty;
|
uint64_t difficulty;
|
||||||
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
|
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
|
||||||
ASSERT_GE (params.network.publish_thresholds.base, difficulty);
|
ASSERT_GE (node1.default_difficulty (), difficulty);
|
||||||
double multiplier (response.json.get<double> ("multiplier"));
|
double multiplier (response.json.get<double> ("multiplier"));
|
||||||
ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, params.network.publish_thresholds.base), 1e-6);
|
ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, node1.default_difficulty ()), 1e-6);
|
||||||
}
|
}
|
||||||
auto result_difficulty (nano::work_difficulty (nano::work_version::work_1, hash, work1));
|
auto result_difficulty (nano::work_difficulty (nano::work_version::work_1, hash, work1));
|
||||||
ASSERT_GE (result_difficulty, params.network.publish_thresholds.base);
|
ASSERT_GE (result_difficulty, node1.default_difficulty ());
|
||||||
request.put ("work", nano::to_string_hex (work1));
|
request.put ("work", nano::to_string_hex (work1));
|
||||||
request.put ("difficulty", nano::to_string_hex (result_difficulty));
|
request.put ("difficulty", nano::to_string_hex (result_difficulty));
|
||||||
{
|
{
|
||||||
|
|
@ -4017,6 +4077,62 @@ TEST (rpc, work_validate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST (rpc, work_validate_epoch_2)
|
||||||
|
{
|
||||||
|
nano::system system;
|
||||||
|
auto node = add_ipc_enabled_node (system);
|
||||||
|
auto epoch1 = system.upgrade_genesis_epoch (*node, nano::epoch::epoch_1);
|
||||||
|
ASSERT_NE (nullptr, epoch1);
|
||||||
|
ASSERT_EQ (node->network_params.network.publish_thresholds.epoch_2, node->network_params.network.publish_thresholds.base);
|
||||||
|
auto work = system.work_generate_limited (epoch1->hash (), node->network_params.network.publish_thresholds.epoch_1, node->network_params.network.publish_thresholds.base);
|
||||||
|
scoped_io_thread_name_change scoped_thread_name_io;
|
||||||
|
nano::node_rpc_config node_rpc_config;
|
||||||
|
nano::ipc::ipc_server ipc_server (*node, node_rpc_config);
|
||||||
|
nano::rpc_config rpc_config (nano::get_available_port (), true);
|
||||||
|
rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port;
|
||||||
|
nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
|
||||||
|
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
|
||||||
|
rpc.start ();
|
||||||
|
boost::property_tree::ptree request;
|
||||||
|
request.put ("action", "work_validate");
|
||||||
|
request.put ("hash", epoch1->hash ().to_string ());
|
||||||
|
request.put ("work", nano::to_string_hex (work));
|
||||||
|
{
|
||||||
|
test_response response (request, rpc.config.port, system.io_ctx);
|
||||||
|
system.deadline_set (5s);
|
||||||
|
while (response.status == 0)
|
||||||
|
{
|
||||||
|
ASSERT_NO_ERROR (system.poll ());
|
||||||
|
}
|
||||||
|
ASSERT_EQ (200, response.status);
|
||||||
|
ASSERT_TRUE (response.json.get<bool> ("valid"));
|
||||||
|
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
|
||||||
|
uint64_t difficulty{ 0 };
|
||||||
|
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
|
||||||
|
double multiplier (response.json.get<double> ("multiplier"));
|
||||||
|
ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, node->network_params.network.publish_thresholds.epoch_1), 1e-6);
|
||||||
|
};
|
||||||
|
// After upgrading, the higher difficulty is used to validate and calculate the multiplier
|
||||||
|
scoped_thread_name_io.reset ();
|
||||||
|
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (*node, nano::epoch::epoch_2));
|
||||||
|
scoped_thread_name_io.renew ();
|
||||||
|
{
|
||||||
|
test_response response (request, rpc.config.port, system.io_ctx);
|
||||||
|
system.deadline_set (5s);
|
||||||
|
while (response.status == 0)
|
||||||
|
{
|
||||||
|
ASSERT_NO_ERROR (system.poll ());
|
||||||
|
}
|
||||||
|
ASSERT_EQ (200, response.status);
|
||||||
|
ASSERT_FALSE (response.json.get<bool> ("valid"));
|
||||||
|
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
|
||||||
|
uint64_t difficulty{ 0 };
|
||||||
|
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
|
||||||
|
double multiplier (response.json.get<double> ("multiplier"));
|
||||||
|
ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, node->network_params.network.publish_thresholds.base), 1e-6);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
TEST (rpc, successors)
|
TEST (rpc, successors)
|
||||||
{
|
{
|
||||||
nano::system system;
|
nano::system system;
|
||||||
|
|
@ -5911,7 +6027,7 @@ TEST (rpc, block_create_state_request_work)
|
||||||
boost::property_tree::read_json (block_stream, block_l);
|
boost::property_tree::read_json (block_stream, block_l);
|
||||||
auto block (nano::deserialize_block_json (block_l));
|
auto block (nano::deserialize_block_json (block_l));
|
||||||
ASSERT_NE (nullptr, block);
|
ASSERT_NE (nullptr, block);
|
||||||
ASSERT_GE (block->difficulty (), nano::work_threshold_base (nano::work_version::work_1));
|
ASSERT_GE (block->difficulty (), node->default_difficulty ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -508,6 +508,7 @@ public:
|
||||||
std::atomic<uint64_t> block_count{ 0 };
|
std::atomic<uint64_t> block_count{ 0 };
|
||||||
std::atomic<uint64_t> unchecked_count{ 0 };
|
std::atomic<uint64_t> unchecked_count{ 0 };
|
||||||
std::atomic<uint64_t> account_count{ 0 };
|
std::atomic<uint64_t> account_count{ 0 };
|
||||||
|
std::atomic<bool> epoch_2_started{ 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Defines the possible states for an election to stop in */
|
/* Defines the possible states for an election to stop in */
|
||||||
|
|
|
||||||
|
|
@ -439,6 +439,10 @@ void ledger_processor::epoch_block_impl (nano::state_block & block_a)
|
||||||
{
|
{
|
||||||
ledger.store.frontier_del (transaction, info.head);
|
ledger.store.frontier_del (transaction, info.head);
|
||||||
}
|
}
|
||||||
|
if (epoch == nano::epoch::epoch_2)
|
||||||
|
{
|
||||||
|
ledger.cache.epoch_2_started.store (true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -725,12 +729,15 @@ check_bootstrap_weights (true)
|
||||||
auto transaction = store.tx_begin_read ();
|
auto transaction = store.tx_begin_read ();
|
||||||
if (generate_cache_a.reps || generate_cache_a.account_count)
|
if (generate_cache_a.reps || generate_cache_a.account_count)
|
||||||
{
|
{
|
||||||
|
bool epoch_2_started_l{ false };
|
||||||
for (auto i (store.latest_begin (transaction)), n (store.latest_end ()); i != n; ++i)
|
for (auto i (store.latest_begin (transaction)), n (store.latest_end ()); i != n; ++i)
|
||||||
{
|
{
|
||||||
nano::account_info const & info (i->second);
|
nano::account_info const & info (i->second);
|
||||||
cache.rep_weights.representation_add (info.representative, info.balance.number ());
|
cache.rep_weights.representation_add (info.representative, info.balance.number ());
|
||||||
++cache.account_count;
|
++cache.account_count;
|
||||||
|
epoch_2_started_l = epoch_2_started_l || info.epoch () == nano::epoch::epoch_2;
|
||||||
}
|
}
|
||||||
|
cache.epoch_2_started.store (epoch_2_started_l);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generate_cache_a.cemented_count)
|
if (generate_cache_a.cemented_count)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue