diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index d6defdf4..a13c9a38 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -6392,8 +6392,14 @@ bool blockchain_storage::is_hardfork_active(size_t hardfork_id) const //------------------------------------------------------------------ bool blockchain_storage::prevalidate_block(const block& bl) { + uint64_t block_height = get_block_height(bl); + + //before hard_fork1 + if (bl.major_version == BLOCK_MAJOR_VERSION_INITIAL && get_block_height(bl) <= m_core_runtime_config.hard_forks.m_height_the_hardfork_n_active_after[1]) + return true; + // HF0 if (!m_core_runtime_config.is_hardfork_active_for_height(1, block_height)) { @@ -6409,7 +6415,16 @@ bool blockchain_storage::prevalidate_block(const block& bl) return true; } - // >= HF3 + // HF3 and !HF4 + if (m_core_runtime_config.is_hardfork_active_for_height(3, block_height) && + !m_core_runtime_config.is_hardfork_active_for_height(4, block_height)) + { + CHECK_AND_ASSERT_MES(bl.major_version == HF3_BLOCK_MAJOR_VERSION, false, "HF3 incorrect block major version: " << (int)bl.major_version); + CHECK_AND_ASSERT_MES(bl.minor_version <= HF3_BLOCK_MINOR_VERSION, false, "HF3 incorrect block minor version: " << (int)bl.minor_version); + return true; + } + + // rule for unknown versions if (bl.major_version > CURRENT_BLOCK_MAJOR_VERSION) { LOG_ERROR("prevalidation failed for block " << get_block_hash(bl) << ": major block version " << static_cast(bl.major_version) << " is incorrect, " << CURRENT_BLOCK_MAJOR_VERSION << " is expected" << ENDL diff --git a/src/currency_core/core_runtime_config.h b/src/currency_core/core_runtime_config.h index 8c058ac3..583add64 100644 --- a/src/currency_core/core_runtime_config.h +++ b/src/currency_core/core_runtime_config.h @@ -5,6 +5,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once +#include "boost/serialization/array.hpp" #include "misc_language.h" #include "string_tools.h" @@ -75,6 +76,11 @@ namespace currency else return CURRENT_BLOCK_MAJOR_VERSION; } + + uint8_t get_block_minor_version_by_height(uint64_t height) const + { + return HF3_BLOCK_MINOR_VERSION; + } }; diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 8e70a2be..b229e932 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -33,6 +33,7 @@ #define TRANSACTION_VERSION_POST_HF4 2 #define HF1_BLOCK_MAJOR_VERSION 1 #define HF3_BLOCK_MAJOR_VERSION 2 +#define HF3_BLOCK_MINOR_VERSION 0 #define CURRENT_BLOCK_MAJOR_VERSION 3 #define CURRENT_BLOCK_MINOR_VERSION 0 @@ -253,9 +254,9 @@ #define ZANO_HARDFORK_04_AFTER_HEIGHT 999999999 #else /////// Zarcanum Testnet Pre-Alpha ////////////////////////////// -#define ZANO_HARDFORK_01_AFTER_HEIGHT 1 -#define ZANO_HARDFORK_02_AFTER_HEIGHT 1 -#define ZANO_HARDFORK_03_AFTER_HEIGHT 1 +#define ZANO_HARDFORK_01_AFTER_HEIGHT 0 +#define ZANO_HARDFORK_02_AFTER_HEIGHT 0 +#define ZANO_HARDFORK_03_AFTER_HEIGHT 0 #define ZANO_HARDFORK_04_AFTER_HEIGHT CURRENCY_MAX_BLOCK_NUMBER #endif diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index c5a82881..946595db 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -472,9 +472,9 @@ namespace currency tx_generation_context tx_gen_context{}; tx_gen_context.resize(zc_ins_count, destinations.size()); // auxiliary data for each output uint64_t output_index = 0; + std::set deriv_cache; for (auto& d : destinations) { - std::set deriv_cache; finalized_tx result = AUTO_VAL_INIT(result); uint8_t tx_outs_attr = 0; r = construct_tx_out(d, txkey.sec, output_index, tx, deriv_cache, account_keys(), diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index 85e9aa1f..9b235d1b 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -109,7 +109,6 @@ bool gen_block_ts_in_past::generate(std::vector& events) const bool gen_block_ts_in_future::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - block blk_1; generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_timestamp, 0, 0, time(NULL) + 60*60 + CURRENCY_BLOCK_FUTURE_TIME_LIMIT); events.push_back(blk_1); @@ -122,7 +121,6 @@ bool gen_block_ts_in_future::generate(std::vector& events) con bool gen_block_invalid_prev_id::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - block blk_1; crypto::hash prev_id = get_block_hash(blk_0); reinterpret_cast(prev_id) ^= 1; @@ -145,7 +143,6 @@ bool gen_block_invalid_prev_id::check_block_verification_context(const currency: bool gen_block_invalid_nonce::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - std::vector timestamps; std::vector commulative_difficulties; if (!lift_up_difficulty(events, timestamps, commulative_difficulties, generator, 2, blk_0, miner_account)) @@ -175,7 +172,6 @@ bool gen_block_invalid_nonce::generate(std::vector& events) co bool gen_block_no_miner_tx::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - transaction miner_tx; miner_tx = AUTO_VAL_INIT(miner_tx); @@ -207,7 +203,6 @@ bool gen_block_unlock_time_is_low::generate(std::vector& event bool gen_block_unlock_time_is_high::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); set_tx_unlock_time(miner_tx, get_tx_max_unlock_time(miner_tx) + 1); @@ -239,7 +234,6 @@ bool gen_block_unlock_time_is_timestamp_in_past::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); set_tx_unlock_time(miner_tx, blk_0.timestamp + 3 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW * DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN); @@ -255,7 +249,6 @@ bool gen_block_unlock_time_is_timestamp_in_future::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); boost::get(miner_tx.vin[0]).height--; @@ -271,7 +264,6 @@ bool gen_block_height_is_low::generate(std::vector& events) co bool gen_block_height_is_high::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); boost::get(miner_tx.vin[0]).height++; @@ -287,7 +279,6 @@ bool gen_block_height_is_high::generate(std::vector& events) c bool gen_block_miner_tx_has_2_tx_gen_in::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); txin_gen in; @@ -348,7 +339,7 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector& events } bool gen_block_miner_tx_with_txin_to_key::generate(std::vector& events) const -{ +{ BLOCK_VALIDATION_INIT_GENERATE(); // This block has only one output @@ -397,7 +388,6 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector bool gen_block_miner_tx_out_is_small::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); boost::get( miner_tx.vout[0]).amount /= 2; @@ -413,7 +403,6 @@ boost::get( miner_tx.vout[0]).amount /= 2; bool gen_block_miner_tx_out_is_big::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); boost::get( miner_tx.vout[0]).amount *= 2; @@ -429,7 +418,6 @@ boost::get( miner_tx.vout[0]).amount *= 2; bool gen_block_miner_tx_has_no_out::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); miner_tx.vout.clear(); @@ -445,7 +433,6 @@ bool gen_block_miner_tx_has_no_out::generate(std::vector& even bool gen_block_miner_tx_has_out_to_alice::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - GENERATE_ACCOUNT(alice); keypair txkey; @@ -474,7 +461,6 @@ boost::get( miner_tx.vout[0]).amount -= out_to_alice.amo bool gen_block_has_invalid_tx::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - std::vector tx_hashes; tx_hashes.push_back(crypto::hash()); @@ -490,7 +476,6 @@ bool gen_block_has_invalid_tx::generate(std::vector& events) c bool gen_block_is_too_big::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - // Creating a huge miner_tx, it will have a lot of outs MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); static const size_t tx_out_count = CURRENCY_BLOCK_GRANTED_FULL_REWARD_ZONE / 2; @@ -537,7 +522,6 @@ gen_block_invalid_binary_format::gen_block_invalid_binary_format() bool gen_block_invalid_binary_format::generate(std::vector& events) const { BLOCK_VALIDATION_INIT_GENERATE(); - //wide_difficulty_type cummulative_diff = 1; // Unlock blk_0 outputs diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h index 0ce700ba..37bb075e 100644 --- a/tests/core_tests/block_validation.h +++ b/tests/core_tests/block_validation.h @@ -13,7 +13,10 @@ class gen_block_verification_base : public test_chain_unit_base public: gen_block_verification_base() { - m_hardforks.m_height_the_hardfork_n_active_after.fill(0); + m_hardforks.m_height_the_hardfork_n_active_after[1] = 1440; + m_hardforks.m_height_the_hardfork_n_active_after[2] = 1800; + m_hardforks.m_height_the_hardfork_n_active_after[3] = 1801; + m_hardforks.m_height_the_hardfork_n_active_after[4] = 50000000000; REGISTER_CALLBACK("check_block_purged", gen_block_verification_base::check_block_purged); } @@ -26,6 +29,12 @@ public: return !bvc.m_verification_failed; } +// currency::core_runtime_config get_runtime_info_for_core() const +// { +// currency::core_runtime_config res = test_chain_unit_base::get_runtime_info_for_core(); +// +// } + bool check_block_purged(currency::core& c, size_t ev_index, const std::vector& events) { @@ -35,7 +44,7 @@ public: return true; } - currency::hard_forks_descriptor m_hardforks; + //mutable currency::hard_forks_descriptor m_hardforks; }; template @@ -192,4 +201,4 @@ struct gen_block_invalid_binary_format : public test_chain_unit_base private: size_t m_corrupt_blocks_begin_idx; -}; +}; \ No newline at end of file diff --git a/tests/core_tests/chain_switch_pow_pos.cpp b/tests/core_tests/chain_switch_pow_pos.cpp index 73673098..2b7f0079 100644 --- a/tests/core_tests/chain_switch_pow_pos.cpp +++ b/tests/core_tests/chain_switch_pow_pos.cpp @@ -15,6 +15,11 @@ gen_chain_switch_pow_pos::gen_chain_switch_pow_pos() : m_enormous_fee(0) , m_invalid_block_index(std::numeric_limits::max()) { + m_hardforks.m_height_the_hardfork_n_active_after[1] = 1440; + m_hardforks.m_height_the_hardfork_n_active_after[2] = 1800; + m_hardforks.m_height_the_hardfork_n_active_after[3] = 1801; + m_hardforks.m_height_the_hardfork_n_active_after[4] = 50000000000; + REGISTER_CALLBACK_METHOD(gen_chain_switch_pow_pos, configure_core); REGISTER_CALLBACK_METHOD(gen_chain_switch_pow_pos, check_height1); REGISTER_CALLBACK_METHOD(gen_chain_switch_pow_pos, check_chains_1); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 21bb1fe7..4a537851 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -906,8 +906,8 @@ bool test_generator::construct_block(int64_t manual_timestamp_adjustment, size_t txs_sizes/* = 0*/) { size_t height = get_block_height(prev_block) + 1; - blk.major_version = actual_params & bf_major_ver ? major_ver : BLOCK_MAJOR_VERSION_INITIAL; - blk.minor_version = actual_params & bf_minor_ver ? minor_ver : CURRENT_BLOCK_MINOR_VERSION; + blk.major_version = actual_params & bf_major_ver ? major_ver : m_hardforks.get_block_major_version_by_height(height); + blk.minor_version = actual_params & bf_minor_ver ? minor_ver : m_hardforks.get_block_minor_version_by_height(height); blk.timestamp = actual_params & bf_timestamp ? timestamp : (height > 10 ? prev_block.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN: prev_block.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN-POW_DIFF_UP_TIMESTAMP_DELTA); // Keep difficulty unchanged blk.prev_id = actual_params & bf_prev_id ? prev_id : get_block_hash(prev_block); blk.tx_hashes = actual_params & bf_tx_hashes ? tx_hashes : std::vector(); @@ -2267,6 +2267,15 @@ void test_chain_unit_base::on_test_generator_created(test_generator& gen) const gen.set_hardforks(m_hardforks); } +currency::core_runtime_config test_chain_unit_base::get_runtime_info_for_core() const +{ + currency::core_runtime_config crc = currency::get_default_core_runtime_config(); + crc.get_core_time = &test_core_time::get_time; + crc.tx_pool_min_fee = TESTS_DEFAULT_FEE; + crc.tx_default_fee = TESTS_DEFAULT_FEE; + crc.hard_forks = m_hardforks; + return crc; +} //------------------------------------------------------------------------------ test_chain_unit_enchanced::test_chain_unit_enchanced() diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index a6222192..ad689177 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -201,6 +201,17 @@ private: } }; +struct core_hardforks_config +{ + std::array hardforks; + + template + void serialize(Archive & ar, const unsigned int /*version*/) + { + ar & hardforks; + } +}; + VARIANT_TAG(binary_archive, callback_entry, 0xcb); VARIANT_TAG(binary_archive, currency::account_base, 0xcc); VARIANT_TAG(binary_archive, serialized_block, 0xcd); @@ -208,8 +219,10 @@ VARIANT_TAG(binary_archive, serialized_transaction, 0xce); VARIANT_TAG(binary_archive, event_visitor_settings, 0xcf); VARIANT_TAG(binary_archive, event_special_block, 0xd0); VARIANT_TAG(binary_archive, event_core_time, 0xd1); +VARIANT_TAG(binary_archive, core_hardforks_config, 0xd2); -typedef boost::variant test_event_entry; + +typedef boost::variant test_event_entry; typedef std::unordered_map map_hash2tx_t; enum test_tx_split_strategy { tests_void_split_strategy, tests_null_split_strategy, tests_digits_split_strategy, tests_random_split_strategy }; @@ -243,12 +256,14 @@ public: uint64_t get_tx_version_from_events(const std::vector &events) const; void on_test_generator_created(test_generator& generator) const; // tests can override this for special initialization + + currency::core_runtime_config get_runtime_info_for_core() const; // tests can override this for special initialization private: callbacks_map m_callbacks; protected: - currency::hard_forks_descriptor m_hardforks; + mutable currency::hard_forks_descriptor m_hardforks; }; struct offers_count_param @@ -568,7 +583,7 @@ public: private: bool m_ignore_last_pow_in_wallets; - currency::hard_forks_descriptor m_hardforks; + mutable currency::hard_forks_descriptor m_hardforks; std::unordered_map m_blocks_info; static test_gentime_settings m_test_gentime_settings; @@ -938,7 +953,11 @@ bool test_generator::construct_block_gentime_with_coinbase_cb(const currency::bl return false; currency::wide_difficulty_type diff = get_difficulty_for_next_block(prev_id, true); - r = construct_block_manually(b, prev_block, acc, test_generator::block_fields::bf_miner_tx, 0, 0, 0, prev_id, diff, miner_tx); + r = construct_block_manually(b, prev_block, acc, + test_generator::block_fields::bf_miner_tx| test_generator::block_fields::bf_major_ver | test_generator::block_fields::bf_minor_ver, + m_hardforks.get_block_major_version_by_height(height), + m_hardforks.get_block_minor_version_by_height(height), + 0, prev_id, diff, miner_tx); CHECK_AND_ASSERT_MES(r, false, "construct_block_manually failed"); return true; @@ -1238,6 +1257,19 @@ void append_vector_by_another_vector(U& dst, const V& src) #define ADD_CUSTOM_EVENT(VEC_EVENTS, EVENT_OBJ) PRINT_EVENT_N_TEXT(VEC_EVENTS, #EVENT_OBJ); VEC_EVENTS.push_back(EVENT_OBJ) + +#define SET_HARDFORKS_TO_OLD_TESTS() \ + core_hardforks_config hardforks_update = AUTO_VAL_INIT(hardforks_update); \ + hardforks_update.hardforks = get_default_core_runtime_config().hard_forks.m_height_the_hardfork_n_active_after; \ + hardforks_update.hardforks[1] = 1440; \ + hardforks_update.hardforks[2] = 1800; \ + hardforks_update.hardforks[3] = 1801; \ + currency::hard_forks_descriptor hardforks_desc = AUTO_VAL_INIT(hardforks_desc); \ + hardforks_desc.m_height_the_hardfork_n_active_after = hardforks_update.hardforks; \ + generator.set_hardforks(hardforks_desc); \ + m_hardforks.m_height_the_hardfork_n_active_after = hardforks_desc.m_height_the_hardfork_n_active_after; \ + events.push_back(hardforks_update); + // --- gentime wallet helpers ----------------------------------------------------------------------- #define CREATE_TEST_WALLET(WLT_VAR, ACCOUNT, GENESIS_BLOCK) \ diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 7e0c0169..b163e524 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -526,6 +526,20 @@ public: return true; } + bool operator()(const core_hardforks_config& e) const + { + currency::core_runtime_config crc = m_c.get_blockchain_storage().get_core_runtime_config(); + crc.hard_forks.m_height_the_hardfork_n_active_after = e.hardforks; + m_c.get_blockchain_storage().set_core_runtime_config(crc); + std::stringstream ss; ss << "core_hardforks updated:" << ENDL; + for (size_t i = 0; i != crc.hard_forks.m_height_the_hardfork_n_active_after.size(); i++) + { + ss << i << ": " << crc.hard_forks.m_height_the_hardfork_n_active_after[i] << ENDL; + } + log_event(ss.str()); + return true; + } + private: void log_event(const std::string& event_type) const { @@ -613,11 +627,7 @@ inline bool do_replay_events(const std::vector& events, t_test bc_services::bc_offers_service offers_service(nullptr); c.get_blockchain_storage().get_attachment_services_manager().add_service(&offers_service); - currency::core_runtime_config crc = c.get_blockchain_storage().get_core_runtime_config(); - crc.get_core_time = &test_core_time::get_time; - crc.tx_pool_min_fee = TESTS_DEFAULT_FEE; - crc.tx_default_fee = TESTS_DEFAULT_FEE; - c.get_blockchain_storage().set_core_runtime_config(crc); + c.get_blockchain_storage().set_core_runtime_config(validator.get_runtime_info_for_core()); if (validator.need_core_proxy()) { @@ -790,6 +800,7 @@ int main(int argc, char* argv[]) // TODO // GENERATE_AND_PLAY(wallet_spend_form_auditable_and_track); + GENERATE_AND_PLAY(gen_block_big_major_version); GENERATE_AND_PLAY(pos_minting_tx_packing); diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index 42665344..d0f31171 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -47,7 +47,9 @@ bool mine_next_pos_block_in_playtime_sign_cb(currency::core& c, const currency:: pb.step1_init_header(bcs.get_core_runtime_config().hard_forks, height, prev_id); pb.step2_set_txs(std::vector()); pb.step3_build_stake_kernel(stake_output_amount, stake_output_gidx, stake_output_key_image, difficulty, prev_id, null_hash, prev_block.timestamp); - pb.step4_generate_coinbase_tx(block_size_median, bei.already_generated_coins, acc.get_public_address()); + keypair tx_onetime_kp; + tx_onetime_kp = keypair::generate(); + pb.step4_generate_coinbase_tx(block_size_median, bei.already_generated_coins, acc.get_public_address(), currency::blobdata(), CURRENCY_MINER_TX_MAX_OUTS, &tx_onetime_kp); if (!before_sign_cb(pb.m_block)) return false; @@ -667,6 +669,11 @@ bool gen_checkpoints_pos_validation_on_altchain::init_runtime_config(currency::c gen_no_attchments_in_coinbase::gen_no_attchments_in_coinbase() { + m_hardforks.m_height_the_hardfork_n_active_after[1] = 1440; + m_hardforks.m_height_the_hardfork_n_active_after[2] = 1800; + m_hardforks.m_height_the_hardfork_n_active_after[3] = 1801; + m_hardforks.m_height_the_hardfork_n_active_after[4] = 50000000000; + generator.set_hardforks(m_hardforks); // NOTE: This test is made deterministic to be able to correctly set up checkpoint. random_state_test_restorer::reset_random(); // random generator's state was previously stored, will be restore on dtor (see also m_random_state_test_restorer) @@ -701,7 +708,7 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t crc.pos_minimum_heigh = 1; c.get_blockchain_storage().set_core_runtime_config(crc); - m_checkpoints.add_checkpoint(12, "ac57db2582acdd076f92aa8dfcb88d216f60e35b805c16b6256ca26e023bfc3c"); + m_checkpoints.add_checkpoint(12, "2a6e13df811eccce121c0de4dbdcc640de1d37c8459c2c8ea02af39717779836"); c.set_checkpoints(currency::checkpoints(m_checkpoints)); return true;