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

Add stake mining #15

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
14463ca
fix Mac build issues.
spartucus Oct 15, 2019
6f70fa1
debug: comment checkpoint for debug.
spartucus Oct 28, 2019
07fe9c1
Add command line arg of pos settings.
spartucus Oct 28, 2019
00fe75a
Add more check for pos_settings_file arg.
spartucus Oct 28, 2019
1c6998e
check duplicate tx id arg
spartucus Oct 28, 2019
b637038
Add tx extra stake
spartucus Oct 29, 2019
37983d2
progressing: Add check miner pos reward
spartucus Oct 30, 2019
5324c92
progressing: Add pos reward while miner tx
spartucus Oct 31, 2019
2886afa
progressing: Add check pos in validate_miner_tx
spartucus Oct 31, 2019
b6c4069
progressing: Add pos reward calculate(partial)
spartucus Nov 1, 2019
2502173
progressing: check amount
spartucus Nov 1, 2019
d1af4b7
progressing: Add sample code for stake time/coin
spartucus Nov 4, 2019
f4cbd7c
progressing: use staked_tx block height, instead of miner_tx block he…
spartucus Nov 5, 2019
e120ca3
progressing: refactor comment
spartucus Nov 5, 2019
469aace
progressing: refactor code
spartucus Nov 5, 2019
a0202ce
progressing: fix bug
spartucus Nov 6, 2019
e66232d
progressing: update pos settings when file modified.
spartucus Nov 6, 2019
49ad39b
progressing: refactor code
spartucus Nov 6, 2019
0fb5c23
progressing: refactor code
spartucus Nov 7, 2019
bc21bd6
revert harkforks setting
spartucus Nov 15, 2019
1575a3a
Fix windows build issue
spartucus Nov 18, 2019
b4db72b
update from master
spartucus Nov 20, 2019
1cec98d
stake reward economic model
spartucus Nov 21, 2019
22e1b50
stake reward economic model
spartucus Nov 21, 2019
5274fe7
Add new apis for GUI wallet
spartucus Nov 22, 2019
e8e78a3
Add apis for GUI wallet
spartucus Nov 22, 2019
2ef4b4b
fix bug, and add more stake amount config
spartucus Nov 24, 2019
bb5c07b
Add net type for stake reward calculation
spartucus Nov 25, 2019
1d2463f
stake minimum unit is XMC, not piconero
spartucus Nov 25, 2019
86c6c61
use day as stake time unit instead of height
spartucus Nov 25, 2019
46494be
refactor code: remove useless code
spartucus Nov 26, 2019
3c4013c
refactor code
spartucus Nov 26, 2019
fe99c64
fix bug
spartucus Nov 28, 2019
fe34678
fix bug of get_block_template
spartucus Dec 3, 2019
0e88ffe
Add stake for mining pool
spartucus Dec 9, 2019
a43323c
max stake time is 1 year.
spartucus Dec 10, 2019
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
11 changes: 7 additions & 4 deletions CMakeLists.txt
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -657,17 +657,19 @@ else()
add_cxx_flag_if_supported(-Wformat-security CXX_SECURITY_FLAGS)

# -fstack-protector
if (NOT WIN32)
if (NOT OPENBSD AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
add_c_flag_if_supported(-fstack-protector C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fstack-protector CXX_SECURITY_FLAGS)
add_c_flag_if_supported(-fstack-protector-strong C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fstack-protector-strong CXX_SECURITY_FLAGS)
endif()

# New in GCC 8.2
if (NOT WIN32)
if (NOT OPENBSD AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
add_c_flag_if_supported(-fcf-protection=full C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fcf-protection=full CXX_SECURITY_FLAGS)
endif()
if (NOT WIN32 AND NOT OPENBSD)
add_c_flag_if_supported(-fstack-clash-protection C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fstack-clash-protection CXX_SECURITY_FLAGS)
endif()
Expand All @@ -679,8 +681,8 @@ else()
endif()

# linker
if (NOT WIN32)
# Windows binaries die on startup with PIE
if (NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
# Windows binaries die on startup with PIE when compiled with GCC <9.x
add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
endif()
add_linker_flag_if_supported(-Wl,-z,relro LD_SECURITY_FLAGS)
Expand All @@ -704,6 +706,7 @@ else()
if (WIN32)
add_linker_flag_if_supported(-Wl,--dynamicbase LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,--nxcompat LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,--high-entropy-va LD_SECURITY_FLAGS)
endif()

message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}")
Expand Down
78 changes: 77 additions & 1 deletion src/cryptonote_basic/cryptonote_basic_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ using namespace epee;
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "cn"

#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])

const uint64_t BLOCK_PER_YEAR = 259200;

const uint64_t FULL_STAKE_COINS_OVER_YEAR[13] = {
300000,
600000,
900000,
1350000, // 1.5
2025000, // 1.5
2632500, // 1.3
3422250, // 1.3
4448925, // 1.3
5338710, // 1.2
6406452, // 1.2
7687742, // 1.2
9225290, // 1.2
10000000, // 1.2, XNC_INT_MAX is 10000000 * COIN, so this will hardly happen
};

namespace cryptonote {

struct integrated_address {
Expand Down Expand Up @@ -318,8 +338,64 @@ namespace cryptonote {
}

bool operator ==(const cryptonote::block& a, const cryptonote::block& b) {
return cryptonote::get_block_hash(a) == cryptonote::get_block_hash(b);
return cryptonote::get_block_hash(a) == cryptonote::get_block_hash(b);
}
//--------------------------------------------------------------------------------
double get_pos_block_reward_rate(uint64_t unlock_time, uint64_t block_height, uint64_t block_time, uint64_t staked_coins, uint64_t cur_height, network_type type)
{
double reward_rate = 0.0;

// at least staked 1 XMC
staked_coins /= COIN;
if (!staked_coins)
return reward_rate;

uint64_t start_height = (type == network_type::TESTNET ? STAKE_STATR_HEIGHT_TESTNET : STAKE_START_HEIGHT);

if (cur_height < start_height)
return reward_rate;

uint64_t full_stake_coins = FULL_STAKE_COINS_OVER_YEAR[0]; // 300'000 XMC
uint64_t elapse_index = (cur_height - start_height) / BLOCK_PER_YEAR;
if (elapse_index >= ARRAY_SIZE(FULL_STAKE_COINS_OVER_YEAR))
full_stake_coins = FULL_STAKE_COINS_OVER_YEAR[ARRAY_SIZE(FULL_STAKE_COINS_OVER_YEAR) - 1];
else
full_stake_coins = FULL_STAKE_COINS_OVER_YEAR[elapse_index];

const uint64_t FULL_STAKE_TIME_DAYS = 12 * 30; // one year

do
{
uint64_t delta_height = 0;
if (unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER){
if (unlock_time < block_height)
break;

delta_height = unlock_time - block_height;
} else {
if (unlock_time < block_time)
break;

delta_height = (unlock_time - block_time) / DIFFICULTY_TARGET_V2;
}

if (delta_height > BLOCK_PER_YEAR)
delta_height = BLOCK_PER_YEAR;

// at least staked one day
uint64_t delta_days = delta_height / MONERO_BLOCK_PER_DAY;
if (!delta_days)
break;

// This could make uint64_t overflow
//reward_rate = 1.0 * (staked_coins * delta_days * delta_days) / (full_stake_coins * FULL_STAKE_TIME_DAYS * FULL_STAKE_TIME_DAYS);
reward_rate = 1.0 * staked_coins / full_stake_coins * delta_days / FULL_STAKE_TIME_DAYS * delta_days / FULL_STAKE_TIME_DAYS;

}while (0);

return reward_rate;
}
//--------------------------------------------------------------------------------
}

//--------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_basic/cryptonote_basic_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ namespace cryptonote {
bool get_block_reward(size_t median_weight, size_t current_block_weight, uint64_t already_generated_coins, uint64_t &reward, uint8_t version);
uint8_t get_account_address_checksum(const public_address_outer_blob& bl);
uint8_t get_account_integrated_address_checksum(const public_integrated_address_outer_blob& bl);
double get_pos_block_reward_rate(uint64_t unlock_time, uint64_t block_height, uint64_t block_time, uint64_t staked_coins, uint64_t cur_height, network_type type);

std::string get_account_address_as_str(
network_type nettype
Expand Down
68 changes: 68 additions & 0 deletions src/cryptonote_basic/cryptonote_format_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ namespace cryptonote
if (!pick<tx_extra_merge_mining_tag>(nar, tx_extra_fields, TX_EXTRA_MERGE_MINING_TAG)) return false;
if (!pick<tx_extra_mysterious_minergate>(nar, tx_extra_fields, TX_EXTRA_MYSTERIOUS_MINERGATE_TAG)) return false;
if (!pick<tx_extra_padding>(nar, tx_extra_fields, TX_EXTRA_TAG_PADDING)) return false;
if (!pick<tx_extra_stake>(nar, tx_extra_fields, TX_EXTRA_TAG_STAKE)) return false;

// if not empty, someone added a new type and did not add a case above
if (!tx_extra_fields.empty())
Expand Down Expand Up @@ -769,6 +770,73 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
bool get_tx_stake_from_extra(crypto::public_key& spend_pub_key, crypto::secret_key& view_secret_key, std::vector<crypto::hash>& tx_ids, const std::vector<char>& extra_stake)
{
const size_t HASH_SIZE = sizeof(crypto::hash); // public_key, secret_key, hash has same size
if (extra_stake.size() % HASH_SIZE != 0 || extra_stake.size() < HASH_SIZE * 3)
return false;

std::copy(extra_stake.data(), extra_stake.data() + HASH_SIZE, spend_pub_key.data);

std::copy(extra_stake.data() + HASH_SIZE, extra_stake.data() + 2 * HASH_SIZE, view_secret_key.data);

size_t cnt = extra_stake.size() / HASH_SIZE - 2;
for (size_t i = 0; i < cnt; ++i)
{
crypto::hash id;
std::copy(extra_stake.data() + HASH_SIZE * (2 + i), extra_stake.data() + HASH_SIZE * (3 + i), id.data);
tx_ids.push_back(id);
}
return true;
}
//---------------------------------------------------------------
bool get_tx_stake_from_extra(crypto::public_key& spend_pub_key, crypto::secret_key& view_secret_key, std::vector<crypto::hash>& tx_ids, const std::vector<uint8_t> &tx_extra, size_t stk_index)
{
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(tx_extra, tx_extra_fields);

tx_extra_stake stake_field;
if(!find_tx_extra_field_by_type(tx_extra_fields, stake_field, stk_index))
return false;

spend_pub_key = stake_field.spend_pub_key;
view_secret_key = stake_field.view_secret_key;
tx_ids = stake_field.tx_id;

return true;
}
//---------------------------------------------------------------
bool add_stake_to_extra(std::vector<uint8_t>& tx_extra, const std::vector<char> &extra_stake)
{
crypto::public_key spk = AUTO_VAL_INIT(spk);
crypto::secret_key vsk = AUTO_VAL_INIT(vsk);
std::vector<crypto::hash> ti = AUTO_VAL_INIT(ti);

if (!get_tx_stake_from_extra(spk, vsk, ti, extra_stake))
return false;

// parse stake
tx_extra_stake stake;
stake.spend_pub_key = spk;
stake.view_secret_key = vsk;
stake.tx_id = ti;
stake.count = static_cast<uint8_t>(ti.size());

// convert to variant
tx_extra_field field = stake;
// serialize
std::ostringstream oss;
binary_archive<true> ar(oss);
bool r = ::do_serialize(ar, field);
CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to serialize tx extra stake");
// append
std::string tx_extra_str = oss.str();
size_t pos = tx_extra.size();
tx_extra.resize(tx_extra.size() + tx_extra_str.size());
memcpy(&tx_extra[pos], tx_extra_str.data(), tx_extra_str.size());
return true;
}
//---------------------------------------------------------------
bool get_inputs_money_amount(const transaction& tx, uint64_t& money)
{
money = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/cryptonote_basic/cryptonote_format_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ namespace cryptonote
void set_encrypted_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash8& payment_id);
bool get_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash& payment_id);
bool get_encrypted_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash8& payment_id);
bool add_stake_to_extra(std::vector<uint8_t>& tx_extra, const std::vector<char>& extra_stake);
bool get_tx_stake_from_extra(crypto::public_key& spend_pub_key, crypto::secret_key& view_secret_key, std::vector<crypto::hash>& tx_ids, const std::vector<char>& extra_stake);
bool get_tx_stake_from_extra(crypto::public_key& spend_pub_key, crypto::secret_key& view_secret_key, std::vector<crypto::hash>& tx_id, const std::vector<uint8_t>& tx_extra, size_t stk_index);
bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t output_index);
struct subaddress_receive_info
{
Expand Down
2 changes: 0 additions & 2 deletions src/cryptonote_basic/difficulty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
#include <vector>

#include "int-util.h"
#include "crypto/hash.h"
#include "cryptonote_config.h"
#include "difficulty.h"

#undef MONERO_DEFAULT_LOG_CATEGORY
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_basic/difficulty.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <boost/multiprecision/cpp_int.hpp>

#include "crypto/hash.h"
#include "cryptonote_config.h"

namespace cryptonote
{
Expand Down
Loading