1
0
Fork 0
forked from lthn/blockchain

inital implementation of PoS improvements: comparing function, diff tracing, block version

This commit is contained in:
cryptozoidberg 2019-06-18 01:15:33 +03:00
parent 3e39512ec4
commit 667a4dec8a
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
6 changed files with 161 additions and 45 deletions

View file

@ -251,6 +251,23 @@ DISABLE_VS_WARNINGS(4100)
custom_code; \
}
#define CATCH_ENTRY_WITH_FORWARDING_EXCEPTION() \
catch(const std::exception& ex) \
{ \
(void)(ex); \
LOG_ERROR("Exception at [" << LOCATION_SS << "], what=" << ex.what()); \
throw std::runtime_error(std::string("[EXCEPTION FORWARDED]: ") + ex.what()); \
} \
catch(...) \
{ \
LOG_ERROR("Exception at [" << LOCATION_SS << "], generic unknown exception \"...\""); \
throw std::runtime_error("[EXCEPTION FORWARDED]"); \
custom_code; \
}
#define NESTED_TRY_ENTRY() try { TRY_ENTRY();
#define NESTED_CATCH_ENTRY(location) \

View file

@ -69,6 +69,16 @@ using namespace currency;
#define BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION 18000
#endif
#define BLOCK_MAJOR_VERSION_INITAL 1
#ifndef TESTNET
#define ZANO_HARDFORK_1_AFTER_HEIGHT ??
#else
#define ZANO_HARDFORK_1_AFTER_HEIGHT ??
#endif
DISABLE_VS_WARNINGS(4267)
namespace
@ -1557,7 +1567,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
<< ENDL << "HEIGHT " << abei.height << ", difficulty: " << abei.difficulty << ", cumul_diff_precise: " << abei.cumulative_diff_precise << ", cumul_diff_adj: " << abei.cumulative_diff_adjusted << " (current mainchain cumul_diff_adj: " << m_db_blocks.back()->cumulative_diff_adjusted << ", ki lookup total: " << ki_lookup_total <<")"
, LOG_LEVEL_0);
if (is_reorganize_required(*m_db_blocks.back(), abei, proof))
if (is_reorganize_required(*m_db_blocks.back(), alt_chain, proof))
{
auto a = epee::misc_utils::create_scope_leave_handler([&]() { m_is_reorganize_in_process = false; });
CHECK_AND_ASSERT_THROW_MES(!m_is_reorganize_in_process, "Detected recursive reorganzie");
@ -1586,26 +1596,43 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
CATCH_ENTRY_CUSTOM("blockchain_storage::handle_alternative_block", bvc.m_verification_failed = true, false);
}
//------------------------------------------------------------------
bool blockchain_storage::is_reorganize_required(const block_extended_info& main_chain_bei, const block_extended_info& alt_chain_bei, const crypto::hash& proof_alt)
bool blockchain_storage::is_reorganize_required(const block_extended_info& main_chain_bei, const alt_chain_type& alt_chain, const crypto::hash& proof_alt)
{
if (main_chain_bei.cumulative_diff_adjusted < alt_chain_bei.cumulative_diff_adjusted)
return true;
else if (main_chain_bei.cumulative_diff_adjusted > alt_chain_bei.cumulative_diff_adjusted)
return false;
else // main_chain_bei.cumulative_diff_adjusted == alt_chain_bei.cumulative_diff_adjusted
{
if (!is_pos_block(main_chain_bei.bl))
return false; // do not reorganize on the same cummul diff if it's a PoW block
//alt_chain - back is latest(top), first - connection with main chain
const block_extended_info& alt_chain_bei = alt_chain.back()->second;
//in case of simultaneous PoS blocks are happened on the same height (quite common for PoS)
//we also try to weight them to guarantee consensus in network
if (std::memcmp(&main_chain_bei.stake_hash, &proof_alt, sizeof(main_chain_bei.stake_hash)) >= 0)
if (alt_chain_bei.bl.major_version == BLOCK_MAJOR_VERSION_INITAL)
{
if (main_chain_bei.cumulative_diff_adjusted < alt_chain_bei.cumulative_diff_adjusted)
return true;
else if (main_chain_bei.cumulative_diff_adjusted > alt_chain_bei.cumulative_diff_adjusted)
return false;
LOG_PRINT_L2("[is_reorganize_required]:TRUE, \"by order of memcmp\" main_stake_hash:" << &main_chain_bei.stake_hash << ", alt_stake_hash" << proof_alt);
return true;
else // main_chain_bei.cumulative_diff_adjusted == alt_chain_bei.cumulative_diff_adjusted
{
if (!is_pos_block(main_chain_bei.bl))
return false; // do not reorganize on the same cummul diff if it's a PoW block
//in case of simultaneous PoS blocks are happened on the same height (quite common for PoS)
//we also try to weight them to guarantee consensus in network
if (std::memcmp(&main_chain_bei.stake_hash, &proof_alt, sizeof(main_chain_bei.stake_hash)) >= 0)
return false;
LOG_PRINT_L2("[is_reorganize_required]:TRUE, \"by order of memcmp\" main_stake_hash:" << &main_chain_bei.stake_hash << ", alt_stake_hash" << proof_alt);
return true;
}
}
else if (alt_chain_bei.bl.major_version == CURRENT_BLOCK_MAJOR_VERSION)
{
//figure out connection point
const block_extended_info& connection_point = alt_chain.front()->second;
}
else
{
ASSERT_MES_AND_THROW("Unknown version of block");
}
}
//------------------------------------------------------------------
bool blockchain_storage::pre_validate_relayed_block(block& bl, block_verification_context& bvc, const crypto::hash& id)const
{
@ -4446,40 +4473,70 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
if (is_pos_bl)
bei.stake_hash = proof_hash;
//precise difficulty - difficulty used to calculate next difficulty
uint64_t last_x_h = get_last_x_block_height(is_pos_bl);
if (!last_x_h)
bei.cumulative_diff_precise = current_diffic;
else
bei.cumulative_diff_precise = m_db_blocks[last_x_h]->cumulative_diff_precise + current_diffic;
if (m_db_blocks.size())
//////////////////////////////////////////////////////////////////////////
if (bei.bl.major_version == BLOCK_MAJOR_VERSION_INITAL)
{
bei.cumulative_diff_adjusted = m_db_blocks.back()->cumulative_diff_adjusted;
}
//precise difficulty - difficulty used to calculate next difficulty
uint64_t last_x_h = get_last_x_block_height(is_pos_bl);
if (!last_x_h)
bei.cumulative_diff_precise = current_diffic;
else
bei.cumulative_diff_precise = m_db_blocks[last_x_h]->cumulative_diff_precise + current_diffic;
//adjusted difficulty - difficulty used to switch blockchain
wide_difficulty_type cumulative_diff_delta = 0;
if (is_pos_bl)
cumulative_diff_delta = get_adjusted_cumulative_difficulty_for_next_pos(current_diffic);
else
cumulative_diff_delta = current_diffic;
if (m_db_blocks.size())
{
bei.cumulative_diff_adjusted = m_db_blocks.back()->cumulative_diff_adjusted;
}
//adjusted difficulty - difficulty used to switch blockchain
wide_difficulty_type cumulative_diff_delta = 0;
if (is_pos_bl)
cumulative_diff_delta = get_adjusted_cumulative_difficulty_for_next_pos(current_diffic);
else
cumulative_diff_delta = current_diffic;
size_t sequence_factor = get_current_sequence_factor(is_pos_bl);
if (bei.height >= m_core_runtime_config.pos_minimum_heigh)
cumulative_diff_delta = correct_difficulty_with_sequence_factor(sequence_factor, cumulative_diff_delta);
if (bei.height > BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION && is_pos_bl && sequence_factor > 20)
size_t sequence_factor = get_current_sequence_factor(is_pos_bl);
if (bei.height >= m_core_runtime_config.pos_minimum_heigh)
cumulative_diff_delta = correct_difficulty_with_sequence_factor(sequence_factor, cumulative_diff_delta);
if (bei.height > BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION && is_pos_bl && sequence_factor > 20)
{
LOG_PRINT_L0("Block with id: " << id
<< " has too big sequence_factor = " << sequence_factor);
purge_block_data_from_blockchain(bl, tx_processed_count);
bvc.m_verification_failed = true;
return false;
}
bei.cumulative_diff_adjusted += cumulative_diff_delta;
}else if(bei.bl.major_version == CURRENT_BLOCK_MAJOR_VERSION)
{
LOG_PRINT_L0("Block with id: " << id
<< " has too big sequence_factor = " << sequence_factor);
purge_block_data_from_blockchain(bl, tx_processed_count);
bvc.m_verification_failed = true;
return false;
}
//precise difficulty - difficulty used to calculate next difficulty
uint64_t last_x_h = get_last_x_block_height(is_pos_bl);
if (!last_x_h)
bei.cumulative_diff_precise = current_diffic;
else
bei.cumulative_diff_precise = m_db_blocks[last_x_h]->cumulative_diff_precise + current_diffic;
if (m_db_blocks.size())
{
bei.cumulative_diff_adjusted = m_db_blocks[last_x_h]->cumulative_diff_adjusted;
}
//adjusted difficulty - difficulty used to switch blockchain
wide_difficulty_type cumulative_diff_delta = current_diffic;
size_t sequence_factor = get_current_sequence_factor(is_pos_bl);
if (bei.height >= m_core_runtime_config.pos_minimum_heigh)
cumulative_diff_delta = correct_difficulty_with_sequence_factor(sequence_factor, cumulative_diff_delta);
bei.cumulative_diff_adjusted += cumulative_diff_delta;
}
//////////////////////////////////////////////////////////////////////////
bei.cumulative_diff_adjusted += cumulative_diff_delta;
//etc
bei.already_generated_coins = already_generated_coins + base_reward;

View file

@ -537,7 +537,7 @@ namespace currency
bool handle_block_to_main_chain(const block& bl, const crypto::hash& id, block_verification_context& bvc);
std::string print_alt_chain(alt_chain_type alt_chain);
bool handle_alternative_block(const block& b, const crypto::hash& id, block_verification_context& bvc);
bool is_reorganize_required(const block_extended_info& main_chain_bei, const block_extended_info& alt_chain_bei, const crypto::hash& proof_alt);
bool is_reorganize_required(const block_extended_info& main_chain_bei, const alt_chain_type& alt_chain, const crypto::hash& proof_alt);
bool purge_keyimage_from_big_heap(const crypto::key_image& ki, const crypto::hash& id);
bool purge_altblock_keyimages_from_big_heap(const block& b, const crypto::hash& id);
bool append_altblock_keyimages_to_big_heap(const crypto::hash& block_id, const std::set<crypto::key_image>& alt_block_keyimages);

View file

@ -19,7 +19,7 @@
#define CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX 0x3678 // integrated addresses start with 'iZ'
#define CURRENCY_MINED_MONEY_UNLOCK_WINDOW 10
#define CURRENT_TRANSACTION_VERSION 1
#define CURRENT_BLOCK_MAJOR_VERSION 1
#define CURRENT_BLOCK_MAJOR_VERSION 2
#define CURRENT_BLOCK_MINOR_VERSION 0
#define CURRENCY_BLOCK_FUTURE_TIME_LIMIT 60*60*2
#define CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT 60*20

View file

@ -2667,4 +2667,37 @@ namespace currency
return false;
}
wide_difficulty_type get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point,
const wide_difficulty_type& difficulty_pow_at_split_point,
const wide_difficulty_type& a_pos_cumulative_difficulty,
const wide_difficulty_type& b_pos_cumulative_difficulty,
const wide_difficulty_type& a_pow_cumulative_difficulty,
const wide_difficulty_type& b_pow_cumulative_difficulty)
{
boost::multiprecision::uint1024_t basic_sum = boost::multiprecision::uint1024_t(a_pow_cumulative_difficulty) + (boost::multiprecision::uint1024_t(a_pos_cumulative_difficulty)*difficulty_pow_at_split_point) / difficulty_pos_at_split_point;
boost::multiprecision::uint1024_t res =
(basic_sum * a_pow_cumulative_difficulty * a_pos_cumulative_difficulty) / (boost::multiprecision::uint1024_t(a_pow_cumulative_difficulty)*a_pos_cumulative_difficulty);
if (res > boost::math::tools::max_value<wide_difficulty_type>())
{
ASSERT_MES_AND_THROW("[INTERNAL ERROR]: Failed to get_a_to_b_relative_cumulative_difficulty, res = " << res << ENDL
<< ", difficulty_pos_at_split_point: " << difficulty_pos_at_split_point << ENDL
<< ", difficulty_pow_at_split_point:" << difficulty_pow_at_split_point << ENDL
<< ", a_pos_cumulative_difficulty:" << a_pos_cumulative_difficulty << ENDL
<< ", b_pos_cumulative_difficulty:" << b_pos_cumulative_difficulty << ENDL
<< ", a_pow_cumulative_difficulty:" << a_pow_cumulative_difficulty << ENDL
<< ", b_pow_cumulative_difficulty:" << b_pow_cumulative_difficulty << ENDL
);
}
TRY_ENTRY();
wide_difficulty_type short_res = res.convert_to<wide_difficulty_type>();
return short_res;
CATCH_ENTRY_WITH_FORWARDING_EXCEPTION();
}
} // namespace currency

View file

@ -317,6 +317,7 @@ namespace currency
bool parse_amount(uint64_t& amount, const std::string& str_amount);
bool unserialize_block_complete_entry(const COMMAND_RPC_GET_BLOCKS_FAST::response& serialized,
COMMAND_RPC_GET_BLOCKS_DIRECT::response& unserialized);
@ -670,6 +671,14 @@ namespace currency
std::string utf8_to_upper(const std::string& s);
std::string utf8_to_lower(const std::string& s);
bool utf8_substring_test_case_insensitive(const std::string& match, const std::string& s); // Returns true is 's' contains 'match' (case-insensitive)
wide_difficulty_type get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point,
const wide_difficulty_type& difficulty_pow_at_split_point,
const wide_difficulty_type& a_pos_cumulative_difficulty,
const wide_difficulty_type& b_pos_cumulative_difficulty,
const wide_difficulty_type& a_pow_cumulative_difficulty,
const wide_difficulty_type& b_pow_cumulative_difficulty);
} // namespace currency