forked from lthn/blockchain
added first test for consensus, added alt block limitation, added traching of burned coins
This commit is contained in:
parent
b740205f02
commit
20f0b2c702
12 changed files with 334 additions and 30 deletions
|
|
@ -1514,6 +1514,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
|||
|
||||
alt_block_extended_info abei = AUTO_VAL_INIT(abei);
|
||||
abei.bl = b;
|
||||
abei.timestamp = m_core_runtime_config.get_core_time();
|
||||
abei.height = alt_chain.size() ? it_prev->second.height + 1 : *ptr_main_prev + 1;
|
||||
CHECK_AND_ASSERT_MES_CUSTOM(coinbase_height == abei.height, false, bvc.m_verification_failed = true, "block coinbase height doesn't match with altchain height, declined");
|
||||
uint64_t connection_height = alt_chain.size() ? alt_chain.front()->second.height:abei.height;
|
||||
|
|
@ -1665,6 +1666,11 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
|||
return r;
|
||||
}
|
||||
bvc.added_to_altchain = true;
|
||||
|
||||
//protect ourself from altchains container flood
|
||||
if (m_alternative_chains.size() > m_core_runtime_config.max_alt_blocks)
|
||||
prune_aged_alt_blocks();
|
||||
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
|
|
@ -4210,6 +4216,12 @@ bool blockchain_storage::prune_aged_alt_blocks()
|
|||
CRITICAL_REGION_LOCAL1(m_alternative_chains_lock);
|
||||
uint64_t current_height = get_current_blockchain_size();
|
||||
|
||||
size_t count_to_delete = 0;
|
||||
if(m_alternative_chains.size() > m_core_runtime_config.max_alt_blocks)
|
||||
count_to_delete = m_alternative_chains.size() - m_core_runtime_config.max_alt_blocks;
|
||||
|
||||
std::map<uint64_t, alt_chain_container::iterator> alts_to_delete;
|
||||
|
||||
for(auto it = m_alternative_chains.begin(); it != m_alternative_chains.end();)
|
||||
{
|
||||
if (current_height > it->second.height && current_height - it->second.height > CURRENCY_ALT_BLOCK_LIVETIME_COUNT)
|
||||
|
|
@ -4218,9 +4230,28 @@ bool blockchain_storage::prune_aged_alt_blocks()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (count_to_delete)
|
||||
{
|
||||
if (!alts_to_delete.size())
|
||||
alts_to_delete[it->second.timestamp] = it;
|
||||
else
|
||||
{
|
||||
if (it->second.timestamp >= alts_to_delete.rbegin()->first)
|
||||
alts_to_delete[it->second.timestamp] = it;
|
||||
|
||||
if (alts_to_delete.size() > count_to_delete)
|
||||
alts_to_delete.erase(alts_to_delete.begin());
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
//now, if there was count_to_delete we should erase most oldest entries of altblocks
|
||||
for (auto& itd : alts_to_delete)
|
||||
{
|
||||
m_alternative_chains.erase(itd.second);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -4357,11 +4388,11 @@ bool blockchain_storage::validate_pos_block(const block& b,
|
|||
|
||||
//check actual time if it there
|
||||
uint64_t actual_ts = get_actual_timestamp(b);
|
||||
if ((actual_ts > b.timestamp && actual_ts - b.timestamp > POS_MAC_ACTUAL_TIMESTAMP_TO_MINED) ||
|
||||
(actual_ts < b.timestamp && b.timestamp - actual_ts > POS_MAC_ACTUAL_TIMESTAMP_TO_MINED)
|
||||
if ((actual_ts > b.timestamp && actual_ts - b.timestamp > POS_MAX_ACTUAL_TIMESTAMP_TO_MINED) ||
|
||||
(actual_ts < b.timestamp && b.timestamp - actual_ts > POS_MAX_ACTUAL_TIMESTAMP_TO_MINED)
|
||||
)
|
||||
{
|
||||
LOG_PRINT_L0("PoS block actual timestamp " << actual_ts << " differs from b.timestamp " << b.timestamp << " by " << ((int64_t)actual_ts - (int64_t)b.timestamp) << " s, it's more than allowed " << POS_MAC_ACTUAL_TIMESTAMP_TO_MINED << " s.");
|
||||
LOG_PRINT_L0("PoS block actual timestamp " << actual_ts << " differs from b.timestamp " << b.timestamp << " by " << ((int64_t)actual_ts - (int64_t)b.timestamp) << " s, it's more than allowed " << POS_MAX_ACTUAL_TIMESTAMP_TO_MINED << " s.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -4677,6 +4708,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
|
||||
size_t tx_processed_count = 0;
|
||||
uint64_t fee_summary = 0;
|
||||
uint64_t burned_coins = 0;
|
||||
|
||||
for(const crypto::hash& tx_id : bl.tx_hashes)
|
||||
{
|
||||
|
|
@ -4716,6 +4748,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
return false;
|
||||
}
|
||||
TIME_MEASURE_FINISH_PD(tx_check_inputs_time);
|
||||
burned_coins += get_burned_amount(tx);
|
||||
|
||||
TIME_MEASURE_START_PD(tx_prapare_append);
|
||||
uint64_t current_bc_size = get_current_blockchain_size();
|
||||
|
|
@ -4824,7 +4857,14 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//etc
|
||||
bei.already_generated_coins = already_generated_coins + base_reward;
|
||||
if (already_generated_coins < burned_coins)
|
||||
{
|
||||
LOG_ERROR("Condition failed: already_generated_coins(" << already_generated_coins << ") >= burned_coins(" << burned_coins << ")");
|
||||
purge_block_data_from_blockchain(bl, tx_processed_count);
|
||||
bvc.m_verification_failed = true;
|
||||
return false;
|
||||
}
|
||||
bei.already_generated_coins = already_generated_coins - burned_coins + base_reward;
|
||||
|
||||
auto blocks_index_ptr = m_db_blocks_index.get(id);
|
||||
if (blocks_index_ptr)
|
||||
|
|
|
|||
|
|
@ -153,6 +153,9 @@ namespace currency
|
|||
|
||||
// {amount -> pub_keys} map of outputs' pub_keys appeared in this alt block ( index_in_vector == output_gindex - gindex_lookup_table[output_amount] )
|
||||
std::map<uint64_t, std::vector<crypto::public_key> > outputs_pub_keys;
|
||||
|
||||
//date added to alt chain storage
|
||||
uint64_t timestamp;
|
||||
};
|
||||
typedef std::unordered_map<crypto::hash, alt_block_extended_info> alt_chain_container;
|
||||
//typedef std::list<alt_chain_container::iterator> alt_chain_type;
|
||||
|
|
@ -435,6 +438,7 @@ namespace currency
|
|||
bool rebuild_tx_fee_medians();
|
||||
bool validate_all_aliases_for_new_median_mode();
|
||||
bool print_tx_outputs_lookup(const crypto::hash& tx_id) const;
|
||||
uint64_t get_last_x_block_height(bool pos)const;
|
||||
private:
|
||||
|
||||
//-------------- DB containers --------------
|
||||
|
|
@ -614,7 +618,6 @@ namespace currency
|
|||
//POS
|
||||
wide_difficulty_type get_adjusted_cumulative_difficulty_for_next_pos(wide_difficulty_type next_diff)const;
|
||||
wide_difficulty_type get_adjusted_cumulative_difficulty_for_next_alt_pos(alt_chain_type& alt_chain, uint64_t block_height, wide_difficulty_type next_diff, uint64_t connection_height)const;
|
||||
uint64_t get_last_x_block_height(bool pos)const;
|
||||
wide_difficulty_type get_last_alt_x_block_cumulative_precise_difficulty(const alt_chain_type& alt_chain, uint64_t block_height, bool pos, wide_difficulty_type& cumulative_diff_precise_adj)const;
|
||||
wide_difficulty_type get_last_alt_x_block_cumulative_precise_adj_difficulty(const alt_chain_type& alt_chain, uint64_t block_height, bool pos) const;
|
||||
size_t get_current_sequence_factor_for_alt(alt_chain_type& alt_chain, bool pos, uint64_t connection_height)const;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace currency
|
|||
uint64_t tx_pool_min_fee;
|
||||
uint64_t tx_default_fee;
|
||||
uint64_t hard_fork1_starts_after_height;
|
||||
uint64_t max_alt_blocks;
|
||||
crypto::public_key alias_validation_pubkey;
|
||||
core_time_func_t get_core_time;
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ namespace currency
|
|||
pc.pos_minimum_heigh = POS_START_HEIGHT;
|
||||
pc.tx_pool_min_fee = TX_MINIMUM_FEE;
|
||||
pc.tx_default_fee = TX_DEFAULT_FEE;
|
||||
pc.max_alt_blocks = CURRENCY_ALT_BLOCK_MAX_COUNT;
|
||||
pc.hard_fork1_starts_after_height = ZANO_HARDFORK_1_AFTER_HEIGHT;
|
||||
pc.get_core_time = &core_runtime_config::_default_core_time_function;
|
||||
bool r = epee::string_tools::hex_to_pod(ALIAS_SHORT_NAMES_VALIDATION_PUB_KEY, pc.alias_validation_pubkey);
|
||||
|
|
|
|||
|
|
@ -87,8 +87,10 @@
|
|||
|
||||
|
||||
#define CURRENCY_ALT_BLOCK_LIVETIME_COUNT (CURRENCY_BLOCKS_PER_DAY*7)//one week
|
||||
#define CURRENCY_ALT_BLOCK_MAX_COUNT 43200 //30 days
|
||||
#define CURRENCY_MEMPOOL_TX_LIVETIME 345600 //seconds, 4 days
|
||||
|
||||
|
||||
#ifndef TESTNET
|
||||
#define P2P_DEFAULT_PORT 11121
|
||||
#define RPC_DEFAULT_PORT 11211
|
||||
|
|
@ -128,7 +130,7 @@
|
|||
//PoS definitions
|
||||
#define POS_SCAN_WINDOW 60*10 //seconds // 10 minutes
|
||||
#define POS_SCAN_STEP 15 //seconds
|
||||
#define POS_MAC_ACTUAL_TIMESTAMP_TO_MINED (POS_SCAN_WINDOW+100)
|
||||
#define POS_MAX_ACTUAL_TIMESTAMP_TO_MINED (POS_SCAN_WINDOW+100)
|
||||
|
||||
#define POS_STARTER_KERNEL_HASH "00000000000000000006382a8d8f94588ce93a1351924f6ccb9e07dd287c6e4b"
|
||||
#define POS_MODFIFIER_INTERVAL 10
|
||||
|
|
@ -192,6 +194,7 @@
|
|||
#define GUI_INTERNAL_CONFIG "gui_internal_config.bin"
|
||||
|
||||
|
||||
|
||||
#define CURRENT_TRANSACTION_CHAIN_ENTRY_ARCHIVE_VER 3
|
||||
#define CURRENT_BLOCK_EXTENDED_INFO_ARCHIVE_VER 1
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,20 @@ namespace currency
|
|||
return expiration_time <= expiration_ts_median + TX_EXPIRATION_MEDIAN_SHIFT;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
uint64_t get_burned_amount(const transaction& tx)
|
||||
{
|
||||
uint64_t res = 0;
|
||||
for (auto& o : tx.vout)
|
||||
{
|
||||
if (o.target.type() == typeid(txout_to_key))
|
||||
{
|
||||
if (boost::get<txout_to_key>(o.target).key == null_pkey)
|
||||
res += o.amount;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
uint64_t get_tx_max_unlock_time(const transaction& tx)
|
||||
{
|
||||
// etc_tx_details_expiration_time have priority over etc_tx_details_expiration_time2
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ namespace currency
|
|||
|
||||
|
||||
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median);
|
||||
|
||||
uint64_t get_burned_amount(const transaction& tx);
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash);
|
||||
|
|
|
|||
|
|
@ -46,10 +46,18 @@ crypto::signature create_invalid_signature()
|
|||
const crypto::signature invalid_signature = create_invalid_signature();
|
||||
|
||||
test_generator::test_generator()
|
||||
: m_wallet_test_core_proxy(new wallet_test_core_proxy())
|
||||
: m_wallet_test_core_proxy(new wallet_test_core_proxy()),
|
||||
m_do_pos_to_low_timestamp(false),
|
||||
m_last_found_timestamp(0),
|
||||
m_hardfork_after_heigh(CURRENCY_MAX_BLOCK_NUMBER)
|
||||
{
|
||||
}
|
||||
|
||||
void test_generator::set_hardfork_height(uint64_t h)
|
||||
{
|
||||
m_hardfork_after_heigh = h;
|
||||
}
|
||||
|
||||
void test_generator::get_block_chain(std::vector<const block_info*>& blockchain, const crypto::hash& head, size_t n) const
|
||||
{
|
||||
crypto::hash curr = head;
|
||||
|
|
@ -142,6 +150,7 @@ void test_generator::add_block(const currency::block& blk,
|
|||
get_block_reward(is_pos_block(blk), misc_utils::median(block_sizes), block_size, already_generated_coins, block_reward, currency::get_block_height(blk));
|
||||
|
||||
m_blocks_info[get_block_hash(blk)] = block_info(blk, already_generated_coins + block_reward, block_size, cum_diff, tx_list, ks_hash);
|
||||
LOG_PRINT_MAGENTA("ADDED_BLOCK[" << get_block_hash(blk) << "][" << (is_pos_block(blk)? "PoS":"PoW") <<"][" << get_block_height(blk) << "][cumul_diff:" << cum_diff << "]", LOG_LEVEL_0);
|
||||
}
|
||||
|
||||
void test_generator::add_block_info(const block_info& bi)
|
||||
|
|
@ -191,7 +200,11 @@ bool test_generator::construct_block(currency::block& blk,
|
|||
const std::list<currency::transaction>& tx_list,
|
||||
const std::list<currency::account_base>& coin_stake_sources)//in case of PoS block
|
||||
{
|
||||
blk.major_version = BLOCK_MAJOR_VERSION_INITAL;
|
||||
if (height > m_hardfork_after_heigh)
|
||||
blk.major_version = CURRENT_BLOCK_MAJOR_VERSION;
|
||||
else
|
||||
blk.major_version = BLOCK_MAJOR_VERSION_INITAL;
|
||||
|
||||
blk.minor_version = CURRENT_BLOCK_MINOR_VERSION;
|
||||
blk.timestamp = timestamp;
|
||||
blk.prev_id = prev_id;
|
||||
|
|
@ -305,11 +318,13 @@ bool test_generator::construct_block(currency::block& blk,
|
|||
CHECK_AND_ASSERT_MES(r, false, "Failed to find_kernel_and_sign()");
|
||||
}
|
||||
|
||||
uint64_t last_x = get_last_block_of_type(is_pos_block(blk), blocks);
|
||||
|
||||
add_block(blk,
|
||||
txs_size,
|
||||
block_sizes,
|
||||
already_generated_coins,
|
||||
blocks.size() ? blocks.back()->cumul_difficulty + a_diffic: a_diffic,
|
||||
last_x ? blocks[last_x]->cumul_difficulty + a_diffic: a_diffic,
|
||||
tx_list,
|
||||
kernerl_hash);
|
||||
|
||||
|
|
@ -469,30 +484,44 @@ bool test_generator::find_kernel(const std::list<currency::account_base>& accs,
|
|||
uint64_t median_timestamp = get_timestamps_median(blck_chain);
|
||||
wide_difficulty_type basic_diff = 0;
|
||||
|
||||
uint64_t i_last_pow_block = get_last_block_of_type(false, blck_chain);
|
||||
uint64_t expected_avr_timestamp = blck_chain[i_last_pow_block]->b.timestamp + (blck_chain.size() - i_last_pow_block - 1)*DIFFICULTY_POW_TARGET;
|
||||
uint64_t starter_timestamp = expected_avr_timestamp - POS_SCAN_WINDOW;
|
||||
uint64_t i_last_pos_block = get_last_block_of_type(true, blck_chain);
|
||||
|
||||
uint64_t last_pos_block_timestamp = 0;
|
||||
if(i_last_pos_block)
|
||||
last_pos_block_timestamp = blck_chain[i_last_pos_block]->b.timestamp;
|
||||
else
|
||||
last_pos_block_timestamp = blck_chain.back()->b.timestamp - DIFFICULTY_POS_TARGET/2;
|
||||
|
||||
uint64_t starter_timestamp = last_pos_block_timestamp + DIFFICULTY_POS_TARGET;
|
||||
|
||||
if (starter_timestamp < median_timestamp)
|
||||
starter_timestamp = median_timestamp;
|
||||
|
||||
|
||||
m_last_found_timestamp = 0;
|
||||
basic_diff = get_difficulty_for_next_block(blck_chain, false);
|
||||
|
||||
//lets try to find block
|
||||
for (auto& w : wallets)
|
||||
if (basic_diff < 10)
|
||||
{
|
||||
currency::COMMAND_RPC_SCAN_POS::request scan_pos_entries;
|
||||
bool r = w->get_pos_entries(scan_pos_entries);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_pos_entries");
|
||||
starter_timestamp -= 90;
|
||||
}
|
||||
if (m_do_pos_to_low_timestamp)
|
||||
starter_timestamp += 60;
|
||||
|
||||
for (size_t i = 0; i != scan_pos_entries.pos_entries.size(); i++)
|
||||
//adjust timestamp starting from timestamp%POS_SCAN_STEP = 0
|
||||
//starter_timestamp = starter_timestamp - POS_SCAN_WINDOW;
|
||||
starter_timestamp = POS_SCAN_STEP - (starter_timestamp%POS_SCAN_STEP) + starter_timestamp;
|
||||
|
||||
for (uint64_t ts = starter_timestamp; ts < starter_timestamp + POS_SCAN_WINDOW/2; ts += POS_SCAN_STEP)
|
||||
{
|
||||
//lets try to find block
|
||||
for (auto& w : wallets)
|
||||
{
|
||||
//adjust timestamp starting from timestamp%POS_SCAN_STEP = 0
|
||||
starter_timestamp = starter_timestamp - POS_SCAN_WINDOW;
|
||||
starter_timestamp = POS_SCAN_STEP - (starter_timestamp%POS_SCAN_STEP) + starter_timestamp;
|
||||
currency::COMMAND_RPC_SCAN_POS::request scan_pos_entries;
|
||||
bool r = w->get_pos_entries(scan_pos_entries);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_pos_entries");
|
||||
|
||||
for (uint64_t ts = starter_timestamp; ts < expected_avr_timestamp + POS_SCAN_WINDOW; ts += POS_SCAN_STEP)
|
||||
for (size_t i = 0; i != scan_pos_entries.pos_entries.size(); i++)
|
||||
{
|
||||
|
||||
stake_kernel sk = AUTO_VAL_INIT(sk);
|
||||
uint64_t coindays_weight = 0;
|
||||
build_kernel(scan_pos_entries.pos_entries[i].amount,
|
||||
|
|
@ -509,10 +538,23 @@ bool test_generator::find_kernel(const std::list<currency::account_base>& accs,
|
|||
continue;
|
||||
else
|
||||
{
|
||||
if (m_do_pos_to_low_timestamp)
|
||||
{
|
||||
if (!m_last_found_timestamp)
|
||||
{
|
||||
m_last_found_timestamp = ts;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(m_last_found_timestamp >= ts)
|
||||
continue;
|
||||
}
|
||||
|
||||
//found kernel
|
||||
LOG_PRINT_GREEN("Found kernel: amount=" << print_money(scan_pos_entries.pos_entries[i].amount)
|
||||
<< ", index=" << scan_pos_entries.pos_entries[i].index
|
||||
<< ", key_image" << scan_pos_entries.pos_entries[i].keyimage, LOG_LEVEL_0);
|
||||
<< ", key_image" << scan_pos_entries.pos_entries[i].keyimage
|
||||
<< ", diff: " << this_coin_diff, LOG_LEVEL_0);
|
||||
pe = scan_pos_entries.pos_entries[i];
|
||||
found_wallet_index = i;
|
||||
found_kh = kernel_hash;
|
||||
|
|
@ -743,10 +785,19 @@ bool test_generator::construct_block(const std::vector<test_event_entry>& events
|
|||
const currency::block& blk_prev,
|
||||
const currency::account_base& miner_acc,
|
||||
const std::list<currency::transaction>& tx_list,
|
||||
const std::list<currency::account_base>& coin_stake_sources
|
||||
)
|
||||
const std::list<currency::account_base>& coin_stake_sources)
|
||||
{
|
||||
uint64_t height = boost::get<txin_gen>(blk_prev.miner_tx.vin.front()).height + 1;
|
||||
return construct_block(0, events, blk, blk_prev, miner_acc, tx_list, coin_stake_sources);
|
||||
}
|
||||
bool test_generator::construct_block(int64_t manual_timestamp_adjustment,
|
||||
const std::vector<test_event_entry>& events,
|
||||
currency::block& blk,
|
||||
const currency::block& blk_prev,
|
||||
const currency::account_base& miner_acc,
|
||||
const std::list<currency::transaction>& tx_list,
|
||||
const std::list<currency::account_base>& coin_stake_sources)
|
||||
{
|
||||
uint64_t height = boost::get<txin_gen>(blk_prev.miner_tx.vin[0]).height + 1;
|
||||
crypto::hash prev_id = get_block_hash(blk_prev);
|
||||
// Keep push difficulty little up to be sure about PoW hash success
|
||||
std::vector<currency::block> blockchain;
|
||||
|
|
@ -769,6 +820,7 @@ bool test_generator::construct_block(const std::vector<test_event_entry>& events
|
|||
block& prev_same_type = blockchain[prev_i];
|
||||
|
||||
timestamp = adjust_timestamp_finished ? prev_same_type.timestamp + diff_target : prev_same_type.timestamp + diff_target - diff_up_timestamp_delta;
|
||||
timestamp = timestamp + manual_timestamp_adjustment;
|
||||
|
||||
uint64_t already_generated_coins = get_already_generated_coins(prev_id);
|
||||
std::vector<size_t> block_sizes;
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ public:
|
|||
currency::wide_difficulty_type cumul_difficulty;
|
||||
std::vector<currency::transaction> m_transactions;
|
||||
crypto::hash ks_hash;
|
||||
};
|
||||
};
|
||||
|
||||
// amount vec_ind, tx_index, out index in tx
|
||||
typedef std::map<uint64_t, std::vector<std::tuple<size_t, size_t, size_t> > > outputs_index;
|
||||
|
|
@ -473,6 +473,7 @@ public:
|
|||
bool construct_genesis_block(currency::block& blk,
|
||||
const currency::account_base& miner_acc,
|
||||
uint64_t timestamp);
|
||||
|
||||
bool construct_block(const std::vector<test_event_entry>& events,
|
||||
currency::block& blk,
|
||||
const currency::block& blk_prev,
|
||||
|
|
@ -480,6 +481,14 @@ public:
|
|||
const std::list<currency::transaction>& tx_list = std::list<currency::transaction>(),
|
||||
const std::list<currency::account_base>& coin_stake_sources = std::list<currency::account_base>() //in case of PoS block
|
||||
);
|
||||
bool construct_block(int64_t manual_timestamp_adjustment,
|
||||
const std::vector<test_event_entry>& events,
|
||||
currency::block& blk,
|
||||
const currency::block& blk_prev,
|
||||
const currency::account_base& miner_acc,
|
||||
const std::list<currency::transaction>& tx_list = std::list<currency::transaction>(),
|
||||
const std::list<currency::account_base>& coin_stake_sources = std::list<currency::account_base>() //in case of PoS block
|
||||
);
|
||||
|
||||
|
||||
bool construct_block_manually(currency::block& blk, const currency::block& prev_block,
|
||||
|
|
@ -500,8 +509,15 @@ public:
|
|||
static const test_gentime_settings& get_test_gentime_settings() { return m_test_gentime_settings; }
|
||||
static void set_test_gentime_settings(const test_gentime_settings& s) { m_test_gentime_settings = s; }
|
||||
static void set_test_gentime_settings_default() { m_test_gentime_settings = m_test_gentime_settings_default; }
|
||||
void set_pos_to_low_timestamp(bool do_pos_to_low_timestamp) { m_do_pos_to_low_timestamp = do_pos_to_low_timestamp; }
|
||||
void set_hardfork_height(uint64_t h);
|
||||
|
||||
private:
|
||||
bool m_do_pos_to_low_timestamp;
|
||||
uint64_t m_last_found_timestamp;
|
||||
|
||||
uint64_t m_hardfork_after_heigh;
|
||||
|
||||
std::unordered_map<crypto::hash, block_info> m_blocks_info;
|
||||
static test_gentime_settings m_test_gentime_settings;
|
||||
static test_gentime_settings m_test_gentime_settings_default;
|
||||
|
|
@ -956,6 +972,14 @@ void append_vector_by_another_vector(U& dst, const V& src)
|
|||
VEC_EVENTS.push_back(BLK_NAME); \
|
||||
PRINT_EVENT_NO(VEC_EVENTS);
|
||||
|
||||
|
||||
|
||||
#define MAKE_NEXT_BLOCK_TIMESTAMP_ADJUSTMENT(ADJ, VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC) \
|
||||
currency::block BLK_NAME = AUTO_VAL_INIT(BLK_NAME); \
|
||||
generator.construct_block(ADJ, VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC); \
|
||||
VEC_EVENTS.push_back(BLK_NAME); \
|
||||
PRINT_EVENT_NO(VEC_EVENTS);
|
||||
|
||||
#define MAKE_NEXT_POS_BLOCK(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, MINERS_ACC_LIST) \
|
||||
currency::block BLK_NAME = AUTO_VAL_INIT(BLK_NAME); \
|
||||
generator.construct_block(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, std::list<currency::transaction>(), MINERS_ACC_LIST); \
|
||||
|
|
|
|||
|
|
@ -935,6 +935,12 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(gen_uint_overflow_1);
|
||||
GENERATE_AND_PLAY(gen_uint_overflow_2);
|
||||
|
||||
|
||||
// Hardfok1 tests
|
||||
GENERATE_AND_PLAY(before_hard_fork_1_cumulative_difficulty);
|
||||
GENERATE_AND_PLAY(inthe_middle_hard_fork_1_cumulative_difficulty);
|
||||
GENERATE_AND_PLAY(after_hard_fork_1_cumulative_difficulty);
|
||||
|
||||
//GENERATE_AND_PLAY(gen_block_reward); */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,3 +33,4 @@
|
|||
#include "escrow_wallet_altchain_test.h"
|
||||
#include "misc_tests.h"
|
||||
#include "emission_test.h"
|
||||
#include "hard_fork_1_locked_pos_test.h"
|
||||
|
|
|
|||
119
tests/core_tests/hard_fork_1_locked_pos_test.cpp
Normal file
119
tests/core_tests/hard_fork_1_locked_pos_test.cpp
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor 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_validation.h"
|
||||
#include "tx_builder.h"
|
||||
#include "hard_fork_1_locked_pos_test.h"
|
||||
#include "random_helper.h"
|
||||
|
||||
using namespace epee;
|
||||
using namespace crypto;
|
||||
using namespace currency;
|
||||
|
||||
hard_fork_1_cumulative_difficulty_base::hard_fork_1_cumulative_difficulty_base()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(hard_fork_1_cumulative_difficulty_base, c1);
|
||||
REGISTER_CALLBACK_METHOD(hard_fork_1_cumulative_difficulty_base, configure_core);
|
||||
}
|
||||
|
||||
bool hard_fork_1_cumulative_difficulty_base::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
random_state_test_restorer::reset_random();
|
||||
|
||||
GENERATE_ACCOUNT(preminer_acc);
|
||||
GENERATE_ACCOUNT(miner_acc);
|
||||
m_accounts.push_back(miner_acc);
|
||||
std::list<account_base> miner_acc_lst(1, miner_acc);
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, preminer_acc, 1564434616);
|
||||
generator.set_hardfork_height(get_hardfork_height());
|
||||
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3);
|
||||
block last_block = blk_0r;
|
||||
for (size_t i = 0; i != 20; i++)
|
||||
{
|
||||
MAKE_NEXT_POS_BLOCK(events, next_blk_pos, last_block, miner_acc, miner_acc_lst);
|
||||
MAKE_NEXT_BLOCK(events, next_blk_pow, next_blk_pos, miner_acc);
|
||||
events.push_back(event_core_time(next_blk_pow.timestamp - 10));
|
||||
|
||||
last_block = next_blk_pow;
|
||||
}
|
||||
|
||||
generator.set_pos_to_low_timestamp(true);
|
||||
last_block = blk_0r;
|
||||
for (size_t i = 0; i != 20; i++)
|
||||
{
|
||||
MAKE_NEXT_POS_BLOCK(events, next_blk_pos, last_block, miner_acc, miner_acc_lst);
|
||||
MAKE_NEXT_BLOCK_TIMESTAMP_ADJUSTMENT(-14, events, next_blk_pow, next_blk_pos, miner_acc);
|
||||
last_block = next_blk_pow;
|
||||
}
|
||||
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hard_fork_1_cumulative_difficulty_base::configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config();
|
||||
pc.min_coinstake_age = TESTS_POS_CONFIG_MIN_COINSTAKE_AGE; //four blocks
|
||||
pc.pos_minimum_heigh = TESTS_POS_CONFIG_POS_MINIMUM_HEIGH; //four blocks
|
||||
pc.hard_fork1_starts_after_height = get_hardfork_height();
|
||||
|
||||
c.get_blockchain_storage().set_core_runtime_config(pc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool before_hard_fork_1_cumulative_difficulty::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
|
||||
std::shared_ptr<block_extended_info> last_pow_block = c.get_blockchain_storage().get_last_block_of_type(false);
|
||||
std::shared_ptr<block_extended_info> last_pos_block = c.get_blockchain_storage().get_last_block_of_type(true);
|
||||
CHECK_AND_ASSERT_MES(last_pow_block->cumulative_diff_precise == 184, false, "Incorrect condition failed: last_pow_block->cumulative_diff_precise == 184");
|
||||
CHECK_AND_ASSERT_MES(last_pos_block->cumulative_diff_precise == 20, false, "Incorrect condition failed: last_pos_block->cumulative_diff_precise == 20");
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t before_hard_fork_1_cumulative_difficulty::get_hardfork_height()const
|
||||
{
|
||||
return 10000; //just big number which is obviously bigger then test blockchain
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool inthe_middle_hard_fork_1_cumulative_difficulty::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
|
||||
std::shared_ptr<block_extended_info> last_pow_block = c.get_blockchain_storage().get_last_block_of_type(false);
|
||||
std::shared_ptr<block_extended_info> last_pos_block = c.get_blockchain_storage().get_last_block_of_type(true);
|
||||
CHECK_AND_ASSERT_MES(last_pow_block->cumulative_diff_precise == 184, false, "Incorrect condition failed: last_pow_block->cumulative_diff_precise == 184");
|
||||
CHECK_AND_ASSERT_MES(last_pos_block->cumulative_diff_precise == 20, false, "Incorrect condition failed: last_pos_block->cumulative_diff_precise == 20");
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t inthe_middle_hard_fork_1_cumulative_difficulty::get_hardfork_height()const
|
||||
{
|
||||
return 15;
|
||||
}
|
||||
bool after_hard_fork_1_cumulative_difficulty::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
|
||||
std::shared_ptr<block_extended_info> last_pow_block = c.get_blockchain_storage().get_last_block_of_type(false);
|
||||
std::shared_ptr<block_extended_info> last_pos_block = c.get_blockchain_storage().get_last_block_of_type(true);
|
||||
CHECK_AND_ASSERT_MES(last_pow_block->cumulative_diff_precise == 172, false, "Incorrect condition failed: last_pow_block->cumulative_diff_precise == 184");
|
||||
CHECK_AND_ASSERT_MES(last_pos_block->cumulative_diff_precise == 199, false, "Incorrect condition failed: last_pos_block->cumulative_diff_precise == 20");
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t after_hard_fork_1_cumulative_difficulty::get_hardfork_height()const
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
40
tests/core_tests/hard_fork_1_locked_pos_test.h
Normal file
40
tests/core_tests/hard_fork_1_locked_pos_test.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
#include "chaingen.h"
|
||||
#include "wallet_tests_basic.h"
|
||||
|
||||
|
||||
struct hard_fork_1_cumulative_difficulty_base : public wallet_test
|
||||
{
|
||||
hard_fork_1_cumulative_difficulty_base();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
virtual bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)= 0;
|
||||
virtual uint64_t get_hardfork_height()const =0;
|
||||
};
|
||||
|
||||
// this test check if code still work same way as it supposed to work before hard fork point
|
||||
struct before_hard_fork_1_cumulative_difficulty : public hard_fork_1_cumulative_difficulty_base
|
||||
{
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
virtual uint64_t get_hardfork_height()const;
|
||||
};
|
||||
|
||||
// this test check if code still work same way as it supposed to work is split happened before hard fork point but finished after hard fork point
|
||||
struct inthe_middle_hard_fork_1_cumulative_difficulty : public hard_fork_1_cumulative_difficulty_base
|
||||
{
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
virtual uint64_t get_hardfork_height()const;
|
||||
};
|
||||
|
||||
// this test check if code follow the new consensus algorithm and prefer balanced branch of the blockchain tree
|
||||
struct after_hard_fork_1_cumulative_difficulty : public hard_fork_1_cumulative_difficulty_base
|
||||
{
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
virtual uint64_t get_hardfork_height()const;
|
||||
};
|
||||
|
||||
Loading…
Add table
Reference in a new issue