Skip to content

Commit

Permalink
Merge pull request #511 from Doy-lee/SwitchStakingReqConditionalToHF
Browse files Browse the repository at this point in the history
Incorporate HF version into staking requirement algo change
  • Loading branch information
Doy-lee authored Mar 21, 2019
2 parents a362aa7 + 5a8680f commit 1380c18
Show file tree
Hide file tree
Showing 10 changed files with 30 additions and 28 deletions.
1 change: 1 addition & 0 deletions src/cryptonote_core/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct hard_fork_record
time_t time;
};

// TODO(doyle): Move this out into a globally accessible object
// version 7 from the start of the blockchain, inhereted from Monero mainnet
static const hard_fork_record mainnet_hard_forks[] =
{
Expand Down
2 changes: 1 addition & 1 deletion src/cryptonote_core/service_node_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ namespace service_nodes

// check the initial contribution exists

info.staking_requirement = get_staking_requirement(m_blockchain.nettype(), block_height);
info.staking_requirement = get_staking_requirement(m_blockchain.nettype(), block_height, hf_version);

cryptonote::account_public_address address;

Expand Down
4 changes: 2 additions & 2 deletions src/cryptonote_core/service_node_rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace service_nodes {


uint64_t get_staking_requirement(cryptonote::network_type m_nettype, uint64_t height)
uint64_t get_staking_requirement(cryptonote::network_type m_nettype, uint64_t height, int hf_version)
{
if (m_nettype == cryptonote::TESTNET || m_nettype == cryptonote::FAKECHAIN)
return COIN * 100;
Expand All @@ -19,7 +19,7 @@ uint64_t get_staking_requirement(cryptonote::network_type m_nettype, uint64_t he

uint64_t height_adjusted = height - hardfork_height;
uint64_t base = 0, variable = 0;
if (height >= 230704)
if (hf_version >= cryptonote::network_version_11_infinite_staking)
{
base = 15000 * COIN;
variable = (25007.0 * COIN) / loki::exp2(height_adjusted/129600.0);
Expand Down
2 changes: 1 addition & 1 deletion src/cryptonote_core/service_node_rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static_assert(STAKING_PORTIONS != UINT64_MAX, "UINT64_MAX is used as the invalid
uint64_t get_min_node_contribution (uint8_t version, uint64_t staking_requirement, uint64_t total_reserved, size_t num_contributions);
uint64_t get_min_node_contribution_in_portions(uint8_t version, uint64_t staking_requirement, uint64_t total_reserved, size_t num_contributions);

uint64_t get_staking_requirement(cryptonote::network_type nettype, uint64_t height);
uint64_t get_staking_requirement(cryptonote::network_type nettype, uint64_t height, int hf_version);

uint64_t portions_to_amount(uint64_t portions, uint64_t staking_requirement);

Expand Down
4 changes: 2 additions & 2 deletions src/daemon/rpc_command_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2731,8 +2731,8 @@ bool t_rpc_command_executor::prepare_registration()
}

const uint64_t staking_requirement =
std::max(service_nodes::get_staking_requirement(nettype, block_height),
service_nodes::get_staking_requirement(nettype, block_height + 30 * 24)); // allow 1 day
std::max(service_nodes::get_staking_requirement(nettype, block_height, hf_version),
service_nodes::get_staking_requirement(nettype, block_height + 30 * 24, hf_version)); // allow 1 day

// anything less than DUST will be added to operator stake
const uint64_t DUST = MAX_NUMBER_OF_CONTRIBUTORS;
Expand Down
5 changes: 3 additions & 2 deletions src/rpc/core_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2473,7 +2473,8 @@ namespace cryptonote

std::vector<std::string> args;

uint64_t staking_requirement = service_nodes::get_staking_requirement(m_core.get_nettype(), m_core.get_current_blockchain_height());
uint64_t const curr_height = m_core.get_current_blockchain_height();
uint64_t staking_requirement = service_nodes::get_staking_requirement(m_core.get_nettype(), curr_height, m_core.get_hard_fork_version(curr_height));

{
uint64_t portions_cut;
Expand Down Expand Up @@ -2650,7 +2651,7 @@ namespace cryptonote
bool core_rpc_server::on_get_staking_requirement(const COMMAND_RPC_GET_STAKING_REQUIREMENT::request& req, COMMAND_RPC_GET_STAKING_REQUIREMENT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
{
PERF_TIMER(on_get_staking_requirement);
res.staking_requirement = service_nodes::get_staking_requirement(m_core.get_nettype(), req.height);
res.staking_requirement = service_nodes::get_staking_requirement(m_core.get_nettype(), req.height, m_core.get_hard_fork_version(req.height));
res.status = CORE_RPC_STATUS_OK;
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/version.cpp.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define DEF_LOKI_VERSION_MAJOR 3
#define DEF_LOKI_VERSION_MINOR 0
#define DEF_LOKI_VERSION_PATCH 0
#define DEF_LOKI_VERSION_PATCH 1

#define LOKI_STRINGIFY2(val) #val
#define LOKI_STRINGIFY(val) LOKI_STRINGIFY2(val)
Expand Down
3 changes: 2 additions & 1 deletion src/wallet/wallet2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7375,14 +7375,15 @@ wallet2::register_service_node_result wallet2::create_register_service_node_tx(c
}
}

staking_requirement = service_nodes::get_staking_requirement(nettype(), bc_height);
boost::optional<uint8_t> hf_version = get_hard_fork_version();
if (!hf_version)
{
result.status = register_service_node_result_status::network_version_query_failed;
result.msg = ERR_MSG_NETWORK_VERSION_QUERY_FAILED;
return result;
}

staking_requirement = service_nodes::get_staking_requirement(nettype(), bc_height, *hf_version);
std::vector<std::string> const registration_args(local_args.begin(), local_args.begin() + local_args.size() - 3);
converted_args = service_nodes::convert_registration_args(nettype(), registration_args, staking_requirement, *hf_version);

Expand Down
2 changes: 1 addition & 1 deletion tests/core_tests/chaingen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ cryptonote::transaction make_registration_tx(std::vector<test_event_entry>& even
uint8_t hf_version)
{
const auto new_height = cryptonote::get_block_height(head) + 1;
const auto staking_requirement = service_nodes::get_staking_requirement(cryptonote::FAKECHAIN, new_height);
const auto staking_requirement = service_nodes::get_staking_requirement(cryptonote::FAKECHAIN, new_height, hf_version);

uint64_t amount = service_nodes::portions_to_amount(portions[0], staking_requirement);

Expand Down
33 changes: 16 additions & 17 deletions tests/unit_tests/service_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ TEST(service_nodes, staking_requirement)
// Try underflow
{
uint64_t height = 100;
uint64_t mainnet_requirement = service_nodes::get_staking_requirement(cryptonote::MAINNET, height);
uint64_t stagenet_requirement = service_nodes::get_staking_requirement(cryptonote::STAGENET, height);
uint64_t mainnet_requirement = service_nodes::get_staking_requirement(cryptonote::MAINNET, height, cryptonote::network_version_8);
uint64_t stagenet_requirement = service_nodes::get_staking_requirement(cryptonote::STAGENET, height, cryptonote::network_version_8);
ASSERT_EQ(stagenet_requirement, (45000 * COIN));
ASSERT_EQ(mainnet_requirement, (45000 * COIN));
}

// Starting height for stagenet
{
uint64_t height = 96210;
uint64_t stagenet_requirement = service_nodes::get_staking_requirement(cryptonote::STAGENET, height);
uint64_t stagenet_requirement = service_nodes::get_staking_requirement(cryptonote::STAGENET, height, cryptonote::network_version_8);
ASSERT_EQ(stagenet_requirement, (45000 * COIN));
}

Expand All @@ -66,8 +66,8 @@ TEST(service_nodes, staking_requirement)
// NOTE: The maximum staking requirement is 50,000, in atomic units is 50,000,000,000,000 < int64 range (2^63-1)
// so casting is safe.
uint64_t height = 101250;
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height);
int64_t stagenet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::STAGENET, height);
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height, cryptonote::network_version_9_service_nodes);
int64_t stagenet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::STAGENET, height, cryptonote::network_version_9_service_nodes);

ASSERT_EQ(mainnet_requirement, (45000 * COIN));

Expand All @@ -79,27 +79,27 @@ TEST(service_nodes, staking_requirement)
// Check the requirements are decreasing
{
uint64_t height = 209250;
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height);
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height, cryptonote::network_version_10_bulletproofs);

int64_t mainnet_expected = (int64_t)((29643 * COIN) + 670390000);
int64_t mainnet_delta = std::abs(mainnet_requirement - mainnet_expected);
ASSERT_LT(mainnet_delta, atomic_epsilon);
}

// On the boundary when the scheme switches over to a smooth emissions curve to 15k
// Sliftly after the boundary when the scheme switches over to a smooth emissions curve to 15k
{
uint64_t height = 230704;
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height);
uint64_t height = 235987;
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height, cryptonote::network_version_11_infinite_staking);

int64_t mainnet_expected = (int64_t)((27513 * COIN) + 267300000);
int64_t mainnet_expected = (int64_t)((27164 * COIN) + 648610000);
int64_t mainnet_delta = std::abs(mainnet_requirement - mainnet_expected);
ASSERT_LT(mainnet_delta, atomic_epsilon);
}

// Check requirements are decreasing after switching over to new requirements curve
{
uint64_t height = 706050;
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height);
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height, cryptonote::network_version_11_infinite_staking);

int64_t mainnet_expected = (int64_t)((15984 * COIN) + 588930000);
int64_t mainnet_delta = std::abs(mainnet_requirement - mainnet_expected);
Expand All @@ -109,7 +109,7 @@ TEST(service_nodes, staking_requirement)
// Check approaching 15k requirement
{
uint64_t height = 3643650;
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height);
int64_t mainnet_requirement = (int64_t)service_nodes::get_staking_requirement(cryptonote::MAINNET, height, cryptonote::network_version_11_infinite_staking);

int64_t mainnet_expected = (int64_t)((15000 * COIN) + 150000);
int64_t mainnet_delta = std::abs(mainnet_requirement - mainnet_expected);
Expand Down Expand Up @@ -400,12 +400,10 @@ TEST(service_nodes, min_portions)
// Test minimum stake contributions (should test pre and post this change)
TEST(service_nodes, min_stake_amount)
{
uint64_t height = 101250;
const uint64_t stake_requirement = service_nodes::get_staking_requirement(cryptonote::MAINNET, height);

/// pre v11
uint8_t hf_version = cryptonote::network_version_9_service_nodes;

uint64_t height = 101250;
uint8_t hf_version = cryptonote::network_version_9_service_nodes;
uint64_t stake_requirement = service_nodes::get_staking_requirement(cryptonote::MAINNET, height, hf_version);
{
const uint64_t reserved = stake_requirement / 2;
const uint64_t min_stake = service_nodes::get_min_node_contribution(hf_version, stake_requirement, reserved, 1);
Expand All @@ -420,6 +418,7 @@ TEST(service_nodes, min_stake_amount)

/// post v11
hf_version = cryptonote::network_version_11_infinite_staking;
stake_requirement = service_nodes::get_staking_requirement(cryptonote::MAINNET, height, hf_version);
{
// 50% reserved, with 1 contribution, max of 4- the minimum stake should be (50% / 3)
const uint64_t reserved = stake_requirement / 2;
Expand Down

0 comments on commit 1380c18

Please sign in to comment.