Skip to content

Commit

Permalink
test, stagenets: add hardfork blocks, diardi: fix mining without view…
Browse files Browse the repository at this point in the history
… tags
  • Loading branch information
hayzamjs committed Aug 7, 2023
1 parent 30afe32 commit c7c3249
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 137 deletions.
17 changes: 15 additions & 2 deletions src/cryptonote_basic/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const command_line::arg_descriptor<std::string> arg_spendkey = {

miner::miner(i_miner_handler *phandler, const get_block_hash_t &gbh)
: m_stop(1), m_template{}, m_template_no(0), m_diffic(0), m_thread_index(0),
m_phandler(phandler), m_gbh(gbh), m_height(0), m_threads_active(0),
m_phandler(phandler), m_gbh(gbh), m_height(0), m_last_mined(0), m_threads_active(0),
m_pausers_count(0), m_threads_total(0), m_starter_nonce(0),
m_last_hr_merge_time(0), m_hashes(0), m_total_hashes(0),
m_do_print_hashrate(false), m_do_mining(false), m_current_hash_rate(0),
Expand Down Expand Up @@ -545,6 +545,15 @@ void miner::resume() {
MDEBUG("MINING RESUMED");
}
//-----------------------------------------------------------------------------------------------------
void miner::stop_mining_for(uint64_t seconds) {
CRITICAL_REGION_LOCAL(m_miners_count_lock);
MGINFO("Mining paused for "
<< seconds << " seconds, since we mined the last diardi block");
++m_pausers_count;
misc_utils::sleep_no_w(seconds * 1000);
--m_pausers_count;
}
//-----------------------------------------------------------------------------------------------------
bool miner::worker_thread() {
const uint32_t th_local_index =
m_thread_index++; // atomically increment, getting value before increment
Expand Down Expand Up @@ -610,6 +619,10 @@ bool miner::worker_thread() {
continue;
}

if(m_last_mined == height) {
continue;
}

b.nonce = nonce;
crypto::hash h;

Expand All @@ -621,8 +634,8 @@ bool miner::worker_thread() {
m_gbh(b, height, NULL, tools::get_max_concurrency(), h);

if (check_hash(h, local_diff)) {
// we lucky!
++m_config.current_extra_message_index;
m_last_mined = height;
MGINFO_GREEN("Found block " << get_block_hash(b) << " at height "
<< height
<< " for difficulty: " << local_diff);
Expand Down
2 changes: 2 additions & 0 deletions src/cryptonote_basic/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class miner {
uint32_t get_threads_count() const;
void send_stop_signal();
bool stop();
void stop_mining_for(uint64_t seconds);
bool is_mining() const;
const account_public_address &get_mining_address() const;
bool on_idle();
Expand Down Expand Up @@ -149,6 +150,7 @@ class miner {
std::atomic<uint32_t> m_starter_nonce;
difficulty_type m_diffic;
uint64_t m_height;
uint64_t m_last_mined;
std::atomic<uint32_t> m_thread_index;
volatile uint32_t m_threads_total;
std::atomic<uint32_t> m_threads_active;
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_basic/verification_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct tx_verification_context {
struct block_verification_context {
bool m_added_to_main_chain;
bool m_verifivation_failed; // bad block, should drop connection
bool m_last_diardi_mined;
bool m_marked_as_orphaned;
bool m_already_exists;
bool m_partial_block_reward;
Expand Down
2 changes: 1 addition & 1 deletion src/cryptonote_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@
#define HF_VERSION_CLSAG 13
#define HF_VERSION_DETERMINISTIC_UNLOCK_TIME 13
#define HF_VERSION_BULLETPROOF_PLUS 15
#define HF_VERSION_VIEW_TAGS 15
#define HF_VERSION_VIEW_TAGS 17
#define HF_VERSION_2021_SCALING 15

#define PER_KB_FEE_QUANTIZATION_DECIMALS 1
Expand Down
202 changes: 118 additions & 84 deletions src/cryptonote_core/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,10 +859,10 @@ difficulty_type Blockchain::get_difficulty_for_next_block() {
return (difficulty_type)120000000;
}

// Stagenet will start with difficulty of 1 KH/s
// Stagenet will start with difficulty of 33.3 H/s
if (m_nettype == STAGENET && (uint64_t)height >= 20 &&
(uint64_t)height <= 20 + (uint64_t)DIFFICULTY_BLOCKS_COUNT) {
return (difficulty_type)40000;
return (difficulty_type)4000;
}

// Testnet will start with difficulty of 16 KH/s
Expand Down Expand Up @@ -1441,72 +1441,59 @@ bool Blockchain::validate_diardi_miner_v2(const block &b) {
b.miner_tx.vin[0].type() != typeid(txin_gen))
? m_db->height()
: boost::get<txin_gen>(b.miner_tx.vin[0]).height;
bool isDiardiBlock = (version >= 13 && block_height % 4 == 0);

if (!isDiardiBlock) {
if (!(version >= 13 && block_height % 4 == 0)) {
return true;
}

std::list<std::string> diardi_miners_list = diardi_addresses_v2(m_nettype);

std::string tM;
std::string dM;
std::string vM;
cryptonote::address_parse_info pVm;

cryptonote::address_parse_info temp_miner_address;
cryptonote::address_parse_info diardi_miner_address;

for (auto const &sM : diardi_miners_list) {
cryptonote::get_account_address_from_str(temp_miner_address, m_nettype, tM);
cryptonote::get_account_address_from_str(diardi_miner_address, m_nettype,
sM);
for(auto const& sM : diardi_miners_list) {
public_key pKey = boost::get<txout_to_key>(b.miner_tx.vout.back().target).key;
if(validate_diardi_reward_key(block_height, sM, 0, pKey, m_nettype)) {
vM = sM;
cryptonote::get_account_address_from_str(pVm, m_nettype, vM);
break;
}
}

if (temp_miner_address.address == diardi_miner_address.address) {
if (temp_miner_address.address.m_view_public_key ==
diardi_miner_address.address.m_view_public_key) {
crypto::hash sig_data = get_sig_data(block_height);
crypto::signature signature = b.signature;
crypto::public_key o_pspendkey =
diardi_miner_address.address.m_spend_public_key;
if (vM.empty()) {
return true;
}

vM = sM;
crypto::hash sig_data = get_sig_data(block_height);
crypto::signature signature = b.signature;

if (!crypto::check_signature(sig_data, o_pspendkey, signature)) {
LOG_PRINT_L1("Diardi: Miner Signature incorrect");
return false;
}
if (!crypto::check_signature(sig_data, pVm.address.m_spend_public_key, signature)) {
LOG_PRINT_L1("Diardi: Miner signature incorrect");
return false;
}

cryptonote::block oDb;
bool oOb = false;
bool getOldBlock = get_block_by_hash(
cryptonote::block oDb;
bool oOb = false;
bool getOldBlock = get_block_by_hash(
m_db->get_block_hash_from_height((block_height - 4)), oDb, &oOb);

if (!getOldBlock) {
LOG_PRINT_L1("Diardi: Could not get old block");
return false;
}

if (check_last_diardi_miner(this, vM, m_nettype)) {
LOG_PRINT_L1("Diardi: Miner already mined a block < 4 blocks ago");
return false;
}
if (!getOldBlock) {
LOG_PRINT_L1("Diardi: Could not get old block");
return false;
}

return true;
}
}
if (check_last_diardi_miner(this, vM, m_nettype)) {
LOG_PRINT_L1("Diardi: Miner already mined a block < 4 blocks ago");
return false;
}

LOG_PRINT_L1("Diardi: Miner not in list");
return false;
return true;
}
//------------------------------------------------------------------
// This function validates the miner transaction reward
bool Blockchain::validate_miner_transaction(const block &b,
size_t cumulative_block_weight,
uint64_t fee, uint64_t &base_reward,
uint64_t already_generated_coins,
bool &partial_block_reward,
uint8_t version) {
bool Blockchain::validate_miner_transaction(
const block &b, size_t cumulative_block_weight, uint64_t fee,
uint64_t &base_reward, uint64_t already_generated_coins,
bool &partial_block_reward, uint8_t version, bool &last_diardi_mined) {
LOG_PRINT_L3("Blockchain::" << __func__);
// validate reward
uint64_t money_in_use = 0;
Expand Down Expand Up @@ -1544,33 +1531,6 @@ bool Blockchain::validate_miner_transaction(const block &b,
return false;
}

if ((version >= 2) && (version <= 12) && (block_height >= 16)) {
std::string diardi_maintainer_address;
diardi_maintainer_address = diardi_index_to_reward_v1(block_height);

if (already_generated_coins != 0) {
uint64_t diardi_reward = get_diardi_reward(block_height, base_reward);
if (b.miner_tx.vout.back().amount != diardi_reward) {
MERROR("Diardi V1 reward amount incorrect. Should be: "
<< print_money(diardi_reward)
<< ", is: " << print_money(b.miner_tx.vout.back().amount));
return false;
}

if (m_nettype == cryptonote::MAINNET) {
if (!validate_diardi_reward_key(
block_height, diardi_maintainer_address,
b.miner_tx.vout.size() - 1,
boost::get<txout_to_key>(b.miner_tx.vout.back().target).key)) {
MERROR("Diardi V1 reward public key incorrect.");
return false;
}
} else {
return true;
}
}
}

if (base_reward + fee < money_in_use) {
MERROR_VER("coinbase transaction spend too much money ("
<< print_money(money_in_use) << "). Block reward is "
Expand Down Expand Up @@ -1601,6 +1561,73 @@ bool Blockchain::validate_miner_transaction(const block &b,
partial_block_reward = true;
base_reward = money_in_use - fee;
}

if ((version >= 2) && (version <= 12) && (block_height >= 16)) {
std::string diardi_maintainer_address;
diardi_maintainer_address = diardi_index_to_reward_v1(block_height);

if (already_generated_coins != 0) {
uint64_t diardi_reward = get_diardi_reward(block_height, base_reward);
if (b.miner_tx.vout.back().amount != diardi_reward) {
MERROR("Diardi V1 reward amount incorrect. Should be: "
<< print_money(diardi_reward)
<< ", is: " << print_money(b.miner_tx.vout.back().amount));
return false;
}

if (m_nettype == cryptonote::MAINNET) {
if (!validate_diardi_reward_key(
block_height, diardi_maintainer_address,
b.miner_tx.vout.size() - 1,
boost::get<txout_to_key>(b.miner_tx.vout.back().target).key)) {
MERROR("Diardi V1 reward public key incorrect.");
return false;
}
} else {
return true;
}
}
}

if (version >= HF_VERSION_DIARDI_V2 && m_db->height() % 4 == 0) {
std::string vM;
std::list<std::string> diardi_miners_list = diardi_addresses_v2(m_nettype);
cryptonote::address_parse_info diardi_miner_address;

for (auto const &sM : diardi_miners_list) {
if (validate_diardi_reward_key(
m_db->height(), sM, b.miner_tx.vout.size() - 1,
boost::get<txout_to_key>(b.miner_tx.vout.back().target).key,
m_nettype)) {
vM = sM;
break;
}
}

if (vM.empty()) {
MERROR("Diardi: V2 reward public key incorrect");
return false;
}

cryptonote::get_account_address_from_str(diardi_miner_address, m_nettype,
vM);

crypto::hash sig_data = get_sig_data(m_db->height());
crypto::signature signature = b.signature;
if (!crypto::check_signature(
sig_data, diardi_miner_address.address.m_spend_public_key,
signature)) {
MERROR("Diardi: Block signature incorrect");
return false;
}

if (check_last_diardi_miner(this, vM, m_nettype)) {
last_diardi_mined = true;
MERROR("Diardi: Cannot mine 2 diardi blocks in a row");
return false;
}
}

return true;
}
//------------------------------------------------------------------
Expand Down Expand Up @@ -4712,12 +4739,18 @@ bool Blockchain::handle_block_to_main_chain(const block &bl,
blockchain_height
? m_db->get_block_already_generated_coins(blockchain_height - 1)
: 0;
if (!validate_miner_transaction(bl, cumulative_block_weight, fee_summary,
base_reward, already_generated_coins,
bvc.m_partial_block_reward,
m_hardfork->get_current_version())) {
MERROR_VER("Block with id: " << id << " has incorrect miner transaction");
bvc.m_verifivation_failed = true;
bool last_diardi_miner = false;
if (!validate_miner_transaction(
bl, cumulative_block_weight, fee_summary, base_reward,
already_generated_coins, bvc.m_partial_block_reward,
m_hardfork->get_current_version(), last_diardi_miner)) {
if (last_diardi_miner) {
bvc.m_last_diardi_mined = true;
} else {
MERROR_VER("Block with id: " << id << " has incorrect miner transaction");
bvc.m_verifivation_failed = true;
}

return_tx_to_pool(txs);
goto leave;
}
Expand Down Expand Up @@ -5030,10 +5063,11 @@ bool Blockchain::add_new_block(const block &bl,
}

if (!validate_diardi_miner_v2(bl)) {
LOG_PRINT_L1("Diardi validation failed for block with id <" << id << ">");
LOG_PRINT_L1("Diardi: validation failed for block with id <" << id
<< ">");
bvc.m_added_to_main_chain = false;
m_blocks_txs_check.clear();
return true;
return false;
}

// check that block refers to chain tail
Expand Down
3 changes: 2 additions & 1 deletion src/cryptonote_core/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -1654,7 +1654,8 @@ class Blockchain {
size_t cumulative_block_weight, uint64_t fee,
uint64_t &base_reward,
uint64_t already_generated_coins,
bool &partial_block_reward, uint8_t version);
bool &partial_block_reward, uint8_t version,
bool &last_diardi_mined);

/**
* @brief reverts the blockchain to its previous state following a failed
Expand Down
5 changes: 5 additions & 0 deletions src/cryptonote_core/cryptonote_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,11 @@ bool core::handle_block_found(block &b, block_verification_context &bvc) {

CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false,
"mined block failed verification");

if (bvc.m_last_diardi_mined) {
m_miner.stop_mining_for(550);
}

if (bvc.m_added_to_main_chain) {
cryptonote_connection_context exclude_context = {};
NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg);
Expand Down
3 changes: 3 additions & 0 deletions src/cryptonote_core/cryptonote_tx_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,11 @@ bool construct_miner_tx(size_t height, size_t median_weight,
tk.key = out_eph_public_key;

tx_out out;
uint64_t amount = out_amounts[no];
summary_amounts += out.amount = out_amounts[no];

out.target = tk;

tx.vout.push_back(out);

if (hard_fork_version >= 2 && hard_fork_version <= 12 && (height >= 16)) {
Expand Down
2 changes: 1 addition & 1 deletion src/cryptonote_core/tx_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
#define scala_DEFAULT_LOG_CATEGORY "txpool"

DISABLE_VS_WARNINGS(4244 4345 4503) //'boost::foreach_detail_::or_' : decorated
//name length exceeded, name was truncated
// name length exceeded, name was truncated

using namespace crypto;

Expand Down
Loading

0 comments on commit c7c3249

Please sign in to comment.