Skip to content

Commit

Permalink
Difficulty calculation for RPC block_create
Browse files Browse the repository at this point in the history
  • Loading branch information
SergiySW committed Apr 4, 2020
1 parent cb112f7 commit 0394280
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 0 deletions.
35 changes: 35 additions & 0 deletions nano/node/json_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,41 @@ void nano::json_handler::block_create ()
{
if (work == 0)
{
// Difficulty calculation
if (!request.get_optional<std::string> ("difficulty").is_initialized ())
{
nano::block_details details (nano::epoch::epoch_0, false, false, false);
bool details_found (false);
auto transaction (node.store.tx_begin_read ());
// Previous block find
std::shared_ptr<nano::block> block_previous (nullptr);
if (!previous.is_zero ())
{
block_previous = node.store.block_get (transaction, previous);
}
// Send check
if (block_previous != nullptr)
{
details.is_send = node.store.block_balance (transaction, previous) > balance.number ();
details_found = true;
}
// Epoch check
if (block_previous != nullptr)
{
details.epoch = block_previous->sideband ().details.epoch;
}
if (!link.is_zero () && !details.is_send)
{
auto block_link (node.store.block_get (transaction, link));
if (block_link != nullptr && node.store.pending_exists (transaction, nano::pending_key (pub, link)))
{
details.epoch = std::max (details.epoch, block_link->sideband ().details.epoch);
details.is_receive = true;
details_found = true;
}
}
difficulty_l = details_found ? nano::work_threshold (work_version, details) : node.default_difficulty (work_version);
}
node.work_generate (work_version, root_l, difficulty_l, get_callback_l (block_l), nano::account (pub));
}
else
Expand Down
172 changes: 172 additions & 0 deletions nano/rpc_test/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5999,10 +5999,14 @@ TEST (rpc, block_create_state_open)
ASSERT_NE (nullptr, state_block);
ASSERT_EQ (nano::block_type::state, state_block->type ());
ASSERT_EQ (state_hash, state_block->hash ().to_string ());
auto difficulty (state_block->difficulty ());
ASSERT_GT (difficulty, nano::work_threshold (state_block->work_version (), nano::block_details (nano::epoch::epoch_0, false, true, false)));
ASSERT_TRUE (node->latest (key.pub).is_zero ());
scoped_thread_name_io.reset ();
auto process_result (node->process (*state_block));
ASSERT_EQ (nano::process_result::progress, process_result.code);
ASSERT_EQ (state_block->sideband ().details.epoch, nano::epoch::epoch_0);
ASSERT_TRUE (state_block->sideband ().details.is_receive);
ASSERT_FALSE (node->latest (key.pub).is_zero ());
}

Expand Down Expand Up @@ -6054,6 +6058,174 @@ TEST (rpc, block_create_state_request_work)
}
}

TEST (rpc, block_create_open_epoch_v2)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
nano::keypair key;
nano::genesis genesis;
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (*node, nano::epoch::epoch_1));
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (*node, nano::epoch::epoch_2));
auto send_block (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
ASSERT_NE (nullptr, send_block);
boost::property_tree::ptree request;
request.put ("action", "block_create");
request.put ("type", "state");
request.put ("key", key.prv.data.to_string ());
request.put ("account", key.pub.to_account ());
request.put ("previous", 0);
request.put ("representative", nano::test_genesis_key.pub.to_account ());
request.put ("balance", nano::Gxrb_ratio.convert_to<std::string> ());
request.put ("link", send_block->hash ().to_string ());
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 ();
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);
std::string state_hash (response.json.get<std::string> ("hash"));
auto state_text (response.json.get<std::string> ("block"));
std::stringstream block_stream (state_text);
boost::property_tree::ptree block_l;
boost::property_tree::read_json (block_stream, block_l);
auto state_block (nano::deserialize_block_json (block_l));
ASSERT_NE (nullptr, state_block);
ASSERT_EQ (nano::block_type::state, state_block->type ());
ASSERT_EQ (state_hash, state_block->hash ().to_string ());
auto difficulty (state_block->difficulty ());
ASSERT_GT (difficulty, nano::work_threshold (state_block->work_version (), nano::block_details (nano::epoch::epoch_2, false, true, false)));
ASSERT_TRUE (node->latest (key.pub).is_zero ());
scoped_thread_name_io.reset ();
auto process_result (node->process (*state_block));
ASSERT_EQ (nano::process_result::progress, process_result.code);
ASSERT_EQ (state_block->sideband ().details.epoch, nano::epoch::epoch_2);
ASSERT_TRUE (state_block->sideband ().details.is_receive);
ASSERT_FALSE (node->latest (key.pub).is_zero ());
}

TEST (rpc, block_create_receive_epoch_v2)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
nano::keypair key;
nano::genesis genesis;
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (*node, nano::epoch::epoch_1));
auto send_block (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
ASSERT_NE (nullptr, send_block);
nano::state_block open (key.pub, 0, nano::test_genesis_key.pub, nano::Gxrb_ratio, send_block->hash (), key.prv, key.pub, *node->work_generate_blocking (key.pub));
ASSERT_EQ (nano::process_result::progress, node->process (open).code);
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (*node, nano::epoch::epoch_2));
auto send_block_2 (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
boost::property_tree::ptree request;
request.put ("action", "block_create");
request.put ("type", "state");
request.put ("key", key.prv.data.to_string ());
request.put ("account", key.pub.to_account ());
request.put ("previous", open.hash ().to_string ());
request.put ("representative", nano::test_genesis_key.pub.to_account ());
request.put ("balance", (2 * nano::Gxrb_ratio).convert_to<std::string> ());
request.put ("link", send_block_2->hash ().to_string ());
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 ();
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);
std::string state_hash (response.json.get<std::string> ("hash"));
auto state_text (response.json.get<std::string> ("block"));
std::stringstream block_stream (state_text);
boost::property_tree::ptree block_l;
boost::property_tree::read_json (block_stream, block_l);
auto state_block (nano::deserialize_block_json (block_l));
ASSERT_NE (nullptr, state_block);
ASSERT_EQ (nano::block_type::state, state_block->type ());
ASSERT_EQ (state_hash, state_block->hash ().to_string ());
auto difficulty (state_block->difficulty ());
ASSERT_GT (difficulty, nano::work_threshold (state_block->work_version (), nano::block_details (nano::epoch::epoch_2, false, true, false)));
scoped_thread_name_io.reset ();
auto process_result (node->process (*state_block));
ASSERT_EQ (nano::process_result::progress, process_result.code);
ASSERT_EQ (state_block->sideband ().details.epoch, nano::epoch::epoch_2);
ASSERT_TRUE (state_block->sideband ().details.is_receive);
ASSERT_FALSE (node->latest (key.pub).is_zero ());
}

TEST (rpc, block_create_send_epoch_v2)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
nano::keypair key;
nano::genesis genesis;
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (*node, nano::epoch::epoch_1));
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (*node, nano::epoch::epoch_2));
auto send_block (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, nano::Gxrb_ratio));
ASSERT_NE (nullptr, send_block);
nano::state_block open (key.pub, 0, nano::test_genesis_key.pub, nano::Gxrb_ratio, send_block->hash (), key.prv, key.pub, *node->work_generate_blocking (key.pub));
ASSERT_EQ (nano::process_result::progress, node->process (open).code);
boost::property_tree::ptree request;
request.put ("action", "block_create");
request.put ("type", "state");
request.put ("key", key.prv.data.to_string ());
request.put ("account", key.pub.to_account ());
request.put ("previous", open.hash ().to_string ());
request.put ("representative", nano::test_genesis_key.pub.to_account ());
request.put ("balance", 0);
request.put ("link", nano::test_genesis_key.pub.to_string ());
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 ();
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);
std::string state_hash (response.json.get<std::string> ("hash"));
auto state_text (response.json.get<std::string> ("block"));
std::stringstream block_stream (state_text);
boost::property_tree::ptree block_l;
boost::property_tree::read_json (block_stream, block_l);
auto state_block (nano::deserialize_block_json (block_l));
ASSERT_NE (nullptr, state_block);
ASSERT_EQ (nano::block_type::state, state_block->type ());
ASSERT_EQ (state_hash, state_block->hash ().to_string ());
auto difficulty (state_block->difficulty ());
ASSERT_GT (difficulty, nano::work_threshold (state_block->work_version (), nano::block_details (nano::epoch::epoch_2, true, false, false)));
scoped_thread_name_io.reset ();
auto process_result (node->process (*state_block));
ASSERT_EQ (nano::process_result::progress, process_result.code);
ASSERT_EQ (state_block->sideband ().details.epoch, nano::epoch::epoch_2);
ASSERT_TRUE (state_block->sideband ().details.is_send);
ASSERT_FALSE (node->latest (key.pub).is_zero ());
}

TEST (rpc, block_hash)
{
nano::system system;
Expand Down

0 comments on commit 0394280

Please sign in to comment.