Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
sowle committed May 13, 2024
2 parents 5342440 + df6fa3f commit b91d902
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 33 deletions.
99 changes: 70 additions & 29 deletions src/currency_core/blockchain_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ using namespace currency;
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_LAST_WORKED_VERSION 2
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MAJOR_COMPATIBILITY_VERSION 3 //DON'T CHANGE THIS, if you need to resync db change BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MINOR_COMPATIBILITY_VERSION 4 //mismatch here means some reinitializations
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_MAJOR_FAILURE 5 //if not blocks should ever be added with this condition


#define TARGETDATA_CACHE_SIZE DIFFICULTY_WINDOW + 10

Expand Down Expand Up @@ -96,6 +98,7 @@ blockchain_storage::blockchain_storage(tx_memory_pool& tx_pool) :m_db(nullptr, m
m_db_last_worked_version(BLOCKCHAIN_STORAGE_OPTIONS_ID_LAST_WORKED_VERSION, m_db_solo_options),
m_db_storage_major_compatibility_version(BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MAJOR_COMPATIBILITY_VERSION, m_db_solo_options),
m_db_storage_minor_compatibility_version(BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MINOR_COMPATIBILITY_VERSION, m_db_solo_options),
m_db_major_failure(BLOCKCHAIN_STORAGE_OPTIONS_ID_MAJOR_FAILURE, m_db_solo_options),
m_db_per_block_gindex_incs(m_db),
m_tx_pool(tx_pool),
m_is_in_checkpoint_zone(false),
Expand Down Expand Up @@ -507,7 +510,8 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
<< " last block: " << m_db_blocks.size() - 1 << ", " << misc_utils::get_time_interval_string(timestamp_diff) << " ago" << ENDL
<< " current pos difficulty: " << get_next_diff_conditional(true) << ENDL
<< " current pow difficulty: " << get_next_diff_conditional(false) << ENDL
<< " total transactions: " << m_db_transactions.size(),
<< " total transactions: " << m_db_transactions.size() << ENDL
<< " major failure: " << (m_db_major_failure ? "true" : "false"),
LOG_LEVEL_0);

return true;
Expand Down Expand Up @@ -1181,14 +1185,9 @@ bool blockchain_storage::switch_to_alternative_blockchain(alt_chain_type& alt_ch
return true;
}
//------------------------------------------------------------------
wide_difficulty_type blockchain_storage::get_next_diff_conditional(bool pos) const
void blockchain_storage::collect_timestamps_and_c_difficulties_main(std::vector<uint64_t>& timestamps, std::vector<wide_difficulty_type>& commulative_difficulties, bool pos) const
{
CRITICAL_REGION_LOCAL(m_read_lock);
std::vector<uint64_t> timestamps;
std::vector<wide_difficulty_type> commulative_difficulties;
if (!m_db_blocks.size())
return DIFFICULTY_POW_STARTER;
//skip genesis timestamp
TIME_MEASURE_START_PD(target_calculating_enum_blocks);
CRITICAL_REGION_BEGIN(m_targetdata_cache_lock);
std::list<std::pair<wide_difficulty_type, uint64_t>>& targetdata_cache = pos ? m_pos_targetdata_cache : m_pow_targetdata_cache;
Expand All @@ -1203,34 +1202,51 @@ wide_difficulty_type blockchain_storage::get_next_diff_conditional(bool pos) con
++count;
}
CRITICAL_REGION_END();

wide_difficulty_type& dif = pos ? m_cached_next_pos_difficulty : m_cached_next_pow_difficulty;
TIME_MEASURE_FINISH_PD(target_calculating_enum_blocks);
}
//------------------------------------------------------------------
wide_difficulty_type blockchain_storage::calc_diff_at_h_from_timestamps(std::vector<uint64_t>& timestamps, std::vector<wide_difficulty_type>& commulative_difficulties, uint64_t h, bool pos) const
{
wide_difficulty_type dif;
TIME_MEASURE_START_PD(target_calculating_calc);
if (m_core_runtime_config.is_hardfork_active_for_height(1, m_db_blocks.size()))
if (m_core_runtime_config.is_hardfork_active_for_height(1, h))
{
dif = next_difficulty_2(timestamps, commulative_difficulties, pos ? global_difficulty_pos_target : global_difficulty_pow_target, pos ? global_difficulty_pos_starter : global_difficulty_pow_starter);
}
else
{
dif = next_difficulty_1(timestamps, commulative_difficulties, pos ? global_difficulty_pos_target : global_difficulty_pow_target, pos ? global_difficulty_pos_starter : global_difficulty_pow_starter);
}


TIME_MEASURE_FINISH_PD(target_calculating_calc);
return dif;
}
//------------------------------------------------------------------
wide_difficulty_type blockchain_storage::get_next_diff_conditional2(bool pos, const alt_chain_type& alt_chain, uint64_t split_height, const alt_block_extended_info& abei) const
wide_difficulty_type blockchain_storage::get_next_diff_conditional(bool pos) const
{
CRITICAL_REGION_LOCAL(m_read_lock);
{
//skip genesis timestamp
CRITICAL_REGION_LOCAL(m_read_lock);
if (!m_db_blocks.size())
return DIFFICULTY_POW_STARTER;
}

std::vector<uint64_t> timestamps;
std::vector<wide_difficulty_type> commulative_difficulties;
collect_timestamps_and_c_difficulties_main(timestamps, commulative_difficulties, pos);


wide_difficulty_type& dif = pos ? m_cached_next_pos_difficulty : m_cached_next_pow_difficulty;
dif = calc_diff_at_h_from_timestamps(timestamps, commulative_difficulties, m_db_blocks.size(), pos);

return dif;
}
//------------------------------------------------------------------
void blockchain_storage::collect_timestamps_and_c_difficulties_alt(std::vector<uint64_t>& timestamps, std::vector<wide_difficulty_type>& commulative_difficulties, bool pos, const alt_chain_type& alt_chain, uint64_t split_height) const
{
CRITICAL_REGION_LOCAL(m_read_lock);
size_t count = 0;
if (!m_db_blocks.size())
return DIFFICULTY_POW_STARTER;

auto cb = [&](const block_extended_info& bei, bool is_main){
auto cb = [&](const block_extended_info& bei, bool is_main) {
if (!bei.height)
return false;
bool is_pos_bl = is_pos_block(bei.bl);
Expand All @@ -1242,15 +1258,22 @@ wide_difficulty_type blockchain_storage::get_next_diff_conditional2(bool pos, co
if (count >= DIFFICULTY_WINDOW)
return false;
return true;
};
};
enum_blockchain(cb, alt_chain, split_height);
}
//------------------------------------------------------------------
wide_difficulty_type blockchain_storage::get_next_diff_conditional_alt(bool pos, const alt_chain_type& alt_chain, uint64_t split_height, const alt_block_extended_info& abei) const
{
{
CRITICAL_REGION_LOCAL(m_read_lock);
if (!m_db_blocks.size())
return DIFFICULTY_POW_STARTER;
}
std::vector<uint64_t> timestamps;
std::vector<wide_difficulty_type> commulative_difficulties;
collect_timestamps_and_c_difficulties_alt(timestamps, commulative_difficulties, pos, alt_chain, split_height);

wide_difficulty_type diff = 0;
if(m_core_runtime_config.is_hardfork_active_for_height(1, abei.height))
diff = next_difficulty_2(timestamps, commulative_difficulties, pos ? global_difficulty_pos_target : global_difficulty_pow_target, pos ? global_difficulty_pos_starter : global_difficulty_pow_starter);
else
diff = next_difficulty_1(timestamps, commulative_difficulties, pos ? global_difficulty_pos_target : global_difficulty_pow_target, pos ? global_difficulty_pos_starter : global_difficulty_pow_starter);
return diff;
return calc_diff_at_h_from_timestamps(timestamps, commulative_difficulties, abei.height, pos);
}
//------------------------------------------------------------------
wide_difficulty_type blockchain_storage::get_cached_next_difficulty(bool pos) const
Expand Down Expand Up @@ -1865,7 +1888,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
}

// PoW / PoS validation (heavy checks)
wide_difficulty_type current_diff = get_next_diff_conditional2(pos_block, alt_chain, connection_height, abei);
wide_difficulty_type current_diff = get_next_diff_conditional_alt(pos_block, alt_chain, connection_height, abei);
CHECK_AND_ASSERT_MES_CUSTOM(current_diff, false, bvc.m_verification_failed = true, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");

crypto::hash proof_of_work = null_hash;
Expand Down Expand Up @@ -5751,6 +5774,12 @@ void blockchain_storage::get_pos_mining_estimate(uint64_t amount_coins,
//------------------------------------------------------------------
bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id) const
{
if (m_db_major_failure)
{
LOG_ERROR("MAJOR FAILURE: POS DIFFICULTY IS GOT TO HIGH! Contact the team immediately if you see this error in logs and watch them having panic attack.");
return false;
}

uint64_t block_height = m_db_blocks.size();
return validate_tx_for_hardfork_specific_terms(tx, tx_id, block_height);
}
Expand Down Expand Up @@ -6780,6 +6809,13 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
<< range_proofs_agregated.size()
<< ")"
<< "))");
if (is_pos_bl && current_diffic > m_core_runtime_config.max_pos_difficulty)
{
m_db_major_failure = true; //burn safety fuse
LOG_ERROR("MAJOR FAILURE: POS DIFFICULTY IS GOT TO HIGH! Contact the team immediately if you see this error in logs and watch them having panic attack."
<< ENDL << "Block id:" << id);
}


{
static epee::math_helper::average<uint64_t, 30> blocks_processing_time_avg_pos, blocks_processing_time_avg_pow;
Expand Down Expand Up @@ -6956,6 +6992,15 @@ bool blockchain_storage::add_new_block(const block& bl, block_verification_conte
{
try
{

if (m_db_major_failure)
{
LOG_PRINT_RED_L0("Block processing is stoped due to MAJOR FAILURE fuse burned");
bvc.m_added_to_main_chain = false;
bvc.m_verification_failed = true;
return false;
}

m_db.begin_transaction();

//block bl = bl_;
Expand All @@ -6979,10 +7024,6 @@ bool blockchain_storage::add_new_block(const block& bl, block_verification_conte
m_db.commit_transaction();
return false;
}


//check that block refers to chain tail


if (!(bl.prev_id == get_top_block_id()))
{
Expand Down
8 changes: 7 additions & 1 deletion src/currency_core/blockchain_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,12 @@ namespace currency
crypto::hash get_top_block_id(uint64_t& height) const;
bool get_top_block(block& b) const;
wide_difficulty_type get_next_diff_conditional(bool pos) const;
wide_difficulty_type get_next_diff_conditional2(bool pos, const alt_chain_type& alt_chain, uint64_t split_height, const alt_block_extended_info& abei) const;
wide_difficulty_type get_next_diff_conditional_alt(bool pos, const alt_chain_type& alt_chain, uint64_t split_height, const alt_block_extended_info& abei) const;
wide_difficulty_type get_cached_next_difficulty(bool pos) const;
wide_difficulty_type calc_diff_at_h_from_timestamps(std::vector<uint64_t>& timestamps, std::vector<wide_difficulty_type>& commulative_difficulties, uint64_t h, bool pos) const;
void collect_timestamps_and_c_difficulties_main(std::vector<uint64_t>& timestamps, std::vector<wide_difficulty_type>& commulative_difficulties, bool pos) const;
void collect_timestamps_and_c_difficulties_alt(std::vector<uint64_t>& timestamps, std::vector<wide_difficulty_type>& commulative_difficulties, bool pos, const alt_chain_type& alt_chain, uint64_t split_height) const;



bool create_block_template(const account_public_address& miner_address, const blobdata& ex_nonce, block& b, wide_difficulty_type& di, uint64_t& height) const;
Expand Down Expand Up @@ -551,6 +555,8 @@ namespace currency
tools::db::solo_db_value<uint64_t, std::string, solo_options_container, true> m_db_last_worked_version;
tools::db::solo_db_value<uint64_t, uint64_t, solo_options_container> m_db_storage_major_compatibility_version;
tools::db::solo_db_value<uint64_t, uint64_t, solo_options_container> m_db_storage_minor_compatibility_version;
tools::db::solo_db_value<uint64_t, bool, solo_options_container> m_db_major_failure; //safety fuse

outputs_container m_db_outputs;
multisig_outs_container m_db_multisig_outs;
aliases_container m_db_aliases;
Expand Down
2 changes: 2 additions & 0 deletions src/currency_core/core_runtime_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ namespace currency
crypto::public_key alias_validation_pubkey;
core_time_func_t get_core_time;
uint64_t hf4_minimum_mixins;
wide_difficulty_type max_pos_difficulty;

hard_forks_descriptor hard_forks;

Expand All @@ -129,6 +130,7 @@ namespace currency
pc.tx_default_fee = TX_DEFAULT_FEE;
pc.max_alt_blocks = CURRENCY_ALT_BLOCK_MAX_COUNT;
pc.hf4_minimum_mixins = CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE;
pc.max_pos_difficulty = wide_difficulty_type(POS_MAX_DIFFICULTY_ALLOWED);

// TODO: refactor the following
pc.hard_forks.set_hardfork_height(1, ZANO_HARDFORK_01_AFTER_HEIGHT);
Expand Down
2 changes: 2 additions & 0 deletions src/currency_core/currency_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@
#define POS_MODFIFIER_INTERVAL 10
#define POS_WALLET_MINING_SCAN_INTERVAL POS_SCAN_STEP //seconds
#define POS_MINIMUM_COINSTAKE_AGE 10 // blocks count
#define POS_MAX_DIFFICULTY_ALLOWED "25000000000000000000000" // maximum expected PoS difficuty (need to change it probaly in 20 years)


#ifndef TESTNET
# define BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION 57000
Expand Down
2 changes: 1 addition & 1 deletion src/version.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
#define PROJECT_REVISION "0"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION

#define PROJECT_VERSION_BUILD_NO 313
#define PROJECT_VERSION_BUILD_NO 314
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
5 changes: 3 additions & 2 deletions src/wallet/wallet2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4887,15 +4887,16 @@ bool wallet2::try_mint_pos(const currency::account_public_address& miner_address
return true;
}, m_core_runtime_config);

bool res = true;
if (ctx.status == API_RETURN_CODE_OK)
{
build_minted_block(ctx, miner_address);
res = build_minted_block(ctx, miner_address);
}
TIME_MEASURE_FINISH_MS(mining_duration_ms);

WLT_LOG_L0("PoS mining: " << ctx.iterations_processed << " iterations finished (" << std::fixed << std::setprecision(2) << (mining_duration_ms / 1000.0f) << "s), status: " << ctx.status << ", " << ctx.total_items_checked << " entries with total amount: " << print_money_brief(ctx.total_amount_checked));

return true;
return res;
}
//------------------------------------------------------------------
void wallet2::do_pos_mining_prepare_entry(mining_context& context, size_t transfer_index)
Expand Down
3 changes: 3 additions & 0 deletions tests/core_tests/chaingen_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,9 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(zarcanum_block_with_txs);
GENERATE_AND_PLAY(asset_depoyment_and_few_zc_utxos);
GENERATE_AND_PLAY_HF(assets_and_pos_mining, "4-*");

GENERATE_AND_PLAY_HF(pos_fuse_test, "4-*");



GENERATE_AND_PLAY_HF(attachment_isolation_test, "4-*");
Expand Down
1 change: 1 addition & 0 deletions tests/core_tests/chaingen_tests_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@
#include "multiassets_test.h"
#include "ionic_swap_tests.h"
#include "attachment_isolation_encryption_test.h"
#include "pos_fuse_test.h"
98 changes: 98 additions & 0 deletions tests/core_tests/pos_fuse_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) 2014-2022 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "chaingen.h"
#include "pos_fuse_test.h"
#include "wallet_test_core_proxy.h"

#include "random_helper.h"
#include "wallet/wallet_debug_events_definitions.h"
using namespace currency;


using namespace currency;
pos_fuse_test::pos_fuse_test()
{
REGISTER_CALLBACK_METHOD(pos_fuse_test, c1);
REGISTER_CALLBACK_METHOD(pos_fuse_test, configure_core);
}

bool pos_fuse_test::configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
wallet_test::configure_core(c, ev_index, events);
currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config();
pc.max_pos_difficulty = wide_difficulty_type(1);
//currency::core_runtime_config pc2;
//pc2 = pc;
c.get_blockchain_storage().set_core_runtime_config(pc);


currency::core_runtime_config pc2 = c.get_blockchain_storage().get_core_runtime_config();
LOG_PRINT_L1("Difficulty: " << pc2.max_pos_difficulty);

return true;
}

bool pos_fuse_test::generate(std::vector<test_event_entry>& events) const
{
uint64_t ts = test_core_time::get_time();
m_accounts.resize(TOTAL_ACCS_COUNT);
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts);
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts);
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
DO_CALLBACK(events, "configure_core"); // necessary to set m_hardforks

REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 10);

DO_CALLBACK(events, "c1");
return true;
}

bool pos_fuse_test::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
bool r = false;
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
miner_wlt->refresh();



while (true)
{
miner_wlt->refresh();
wide_difficulty_type pos_diff = c.get_blockchain_storage().get_next_diff_conditional(true);

r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");

bool r = miner_wlt->try_mint_pos();
CHECK_AND_ASSERT_MES(r, false, "Failed ot mint pos block");

currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config();
LOG_PRINT_MAGENTA("POS Difficulty: " << pos_diff << ", max allowed diff: " << pc.max_pos_difficulty, LOG_LEVEL_0);
if (pos_diff > pc.max_pos_difficulty)
{
break;
}
}

//check that PoW blocks not going
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
CHECK_AND_ASSERT_MES(!r, false, "PoW block unexpectedly generated");

//check that PoS blocks not going
r = miner_wlt->try_mint_pos();
CHECK_AND_ASSERT_MES(!r, false, "PoS block unexpectedly mined");

try
{
miner_wlt->transfer(1000000, m_accounts[ALICE_ACC_IDX].get_public_address());
CHECK_AND_ASSERT_MES(false, false, "Transaction unexpectedly sent");
}
catch (...)
{
LOG_PRINT_L0("Expected exception catched");
}

return true;
}
Loading

0 comments on commit b91d902

Please sign in to comment.