diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 624cdfb8..3eae004a 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -3331,9 +3331,9 @@ bool blockchain_storage::push_transaction_to_global_outs_index(const transaction { m_db_outputs.push_back_item(ot.amount, global_output_entry::construct(tx_id, i)); global_indexes.push_back(m_db_outputs.get_item_size(ot.amount) - 1); - if (ot.target.type() == typeid(txout_htlc) && !is_in_hardfork_2_zone()) + if (ot.target.type() == typeid(txout_htlc) && !is_after_hardfork_2_zone()) { - LOG_ERROR("Error: Transaction with txout_htlc before is_in_hardfork_2_zone(before height " << m_core_runtime_config.hard_fork_02_starts_after_height <<")"); + LOG_ERROR("Error: Transaction with txout_htlc before is_after_hardfork_2_zone(before height " << m_core_runtime_config.hard_fork_02_starts_after_height <<")"); return false; } } @@ -3849,9 +3849,9 @@ namespace currency } bool operator()(const txin_htlc& in) const { - if (!m_bcs.is_in_hardfork_2_zone()) + if (!m_bcs.is_after_hardfork_2_zone()) { - LOG_ERROR("Error: Transaction with txin_htlc before is_in_hardfork_2_zone(before height " << m_bcs.get_core_runtime_config().hard_fork_02_starts_after_height << ")"); + LOG_ERROR("Error: Transaction with txin_htlc before is_after_hardfork_2_zone(before height " << m_bcs.get_core_runtime_config().hard_fork_02_starts_after_height << ")"); return false; } return this->operator()(static_cast(in)); @@ -4272,9 +4272,9 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha } else if (txin.type() == typeid(txin_htlc)) { - if (!is_in_hardfork_2_zone()) + if (!is_after_hardfork_2_zone()) { - LOG_ERROR("Error: Transaction with txin_htlc before is_in_hardfork_2_zone(before height " << m_core_runtime_config.hard_fork_02_starts_after_height << ")"); + LOG_ERROR("Error: Transaction with txin_htlc before is_after_hardfork_2_zone(before height " << m_core_runtime_config.hard_fork_02_starts_after_height << ")"); return false; } @@ -4316,29 +4316,6 @@ bool blockchain_storage::is_tx_spendtime_unlocked(uint64_t unlock_time) const return currency::is_tx_spendtime_unlocked(unlock_time, get_current_blockchain_size(), m_core_runtime_config.get_core_time()); } //------------------------------------------------------------------ -bool blockchain_storage::check_tx_fit_hardfork(const transaction& tx) -{ - //inputs - for (const auto in : tx.vin) - { - if (in.type() == typeid(txin_htlc)) - { - if (!is_in_hardfork_2_zone()) - return false; - } - } - //outputs - for (const auto out : tx.vout) - { - if (out.target.type() == typeid(txout_htlc)) - { - if (!is_in_hardfork_2_zone()) - return false; - } - } - return true; -} -//------------------------------------------------------------------ bool blockchain_storage::check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector& sig, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase) const { CRITICAL_REGION_LOCAL(m_read_lock); @@ -4942,37 +4919,93 @@ void blockchain_storage::get_pos_mining_estimate(uint64_t amount_coins, estimate_result = current_amount; } //------------------------------------------------------------------ +// bool check_tx_fit_hardfork(const transaction& tx); + +/* +//------------------------------------------------------------------ +bool blockchain_storage::check_tx_fit_hardfork(const transaction& tx) +{ + //inputs + for (const auto in : tx.vin) + { + if (in.type() == typeid(txin_htlc)) + { + if (!is_after_hardfork_2_zone()) + return false; + } + } + //outputs + for (const auto out : tx.vout) + { + if (out.target.type() == typeid(txout_htlc)) + { + if (!is_after_hardfork_2_zone()) + return false; + } + } + return true; +} +*/ +//------------------------------------------------------------------ +bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id) const +{ + uint64_t block_height = m_db_blocks.size(); + return validate_tx_for_hardfork_specific_terms(tx, tx_id, block_height); +} +//------------------------------------------------------------------ bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id, uint64_t block_height) const { - if (block_height <= m_core_runtime_config.hard_fork_01_starts_after_height) - { - // before hardfork 1 - for (const auto& el : tx.extra) - { - // etc_tx_details_unlock_time2 is not allowed in txs in blocks prior to hardfork 1 - CHECK_AND_ASSERT_MES(el.type() != typeid(etc_tx_details_unlock_time2), false, "tx " << tx_id << " contains etc_tx_details_unlock_time2 which is not allowed on height " << block_height); - } + auto is_allowed_before_hardfork2 = [&](const payload_items_v& el) -> bool + { + CHECK_AND_ASSERT_MES(el.type() != typeid(tx_payer), false, "tx " << tx_id << " contains tx_payer which is not allowed on height " << block_height); + CHECK_AND_ASSERT_MES(el.type() != typeid(tx_receiver), false, "tx " << tx_id << " contains tx_receiver which is not allowed on height " << block_height); + CHECK_AND_ASSERT_MES(el.type() != typeid(extra_alias_entry), false, "tx " << tx_id << " contains extra_alias_entry which is not allowed on height " << block_height); return true; + }; + + auto is_allowed_before_hardfork1 = [&](const payload_items_v& el) -> bool + { + CHECK_AND_ASSERT_MES(el.type() != typeid(etc_tx_details_unlock_time2), false, "tx " << tx_id << " contains etc_tx_details_unlock_time2 which is not allowed on height " << block_height); + return true; + }; + + bool var_is_after_hardfork_1_zone = is_after_hardfork_1_zone(block_height); + bool var_is_after_hardfork_2_zone = is_after_hardfork_2_zone(block_height); + + //inputs + for (const auto in : tx.vin) + { + if (in.type() == typeid(txin_htlc)) + { + if (!var_is_after_hardfork_2_zone) + return false; + } + } + //outputs + for (const auto out : tx.vout) + { + if (out.target.type() == typeid(txout_htlc)) + { + if (!var_is_after_hardfork_2_zone) + return false; + } } - if (block_height <= m_core_runtime_config.hard_fork_02_starts_after_height) + //extra + for (const auto el : tx.extra) { - // before hardfork 2 + if (!var_is_after_hardfork_1_zone && !is_allowed_before_hardfork1(el)) + return false; + if (!var_is_after_hardfork_2_zone && !is_allowed_before_hardfork2(el)) + return false; + } - auto check_lambda = [&](const std::vector& container) -> bool - { - for (const auto& el : container) - { - const auto& type = el.type(); - CHECK_AND_ASSERT_MES(type != typeid(tx_payer), false, "tx " << tx_id << " contains tx_payer which is not allowed on height " << block_height); - CHECK_AND_ASSERT_MES(type != typeid(tx_receiver), false, "tx " << tx_id << " contains tx_receiver which is not allowed on height " << block_height); - CHECK_AND_ASSERT_MES(type != typeid(extra_alias_entry), false, "tx " << tx_id << " contains extra_alias_entry which is not allowed on height " << block_height); - } - return true; - }; - - return check_lambda(tx.extra) && check_lambda(tx.attachment); + //attachments + for (const auto el : tx.attachment) + { + if (!var_is_after_hardfork_2_zone && !is_allowed_before_hardfork2(el)) + return false; } @@ -5724,9 +5757,26 @@ bool blockchain_storage::update_next_comulative_size_limit() return true; } //------------------------------------------------------------------ -bool blockchain_storage::is_in_hardfork_2_zone()const +bool blockchain_storage::is_after_hardfork_1_zone()const { - if (m_db_blocks.size() > m_core_runtime_config.hard_fork_02_starts_after_height) + return is_after_hardfork_1_zone(m_db_blocks.size()); +} +//------------------------------------------------------------------ +bool blockchain_storage::is_after_hardfork_1_zone(uint64_t height)const +{ + if (height > m_core_runtime_config.hard_fork_01_starts_after_height) + return true; + return false; +} +//------------------------------------------------------------------ +bool blockchain_storage::is_after_hardfork_2_zone()const +{ + return is_after_hardfork_2_zone(m_db_blocks.size()); +} +//------------------------------------------------------------------ +bool blockchain_storage::is_after_hardfork_2_zone(uint64_t height)const +{ + if (height > m_core_runtime_config.hard_fork_02_starts_after_height) return true; return false; } @@ -5751,7 +5801,7 @@ bool blockchain_storage::prevalidate_block(const block& bl) return false; } - if (is_in_hardfork_2_zone() && bl.minor_version > CURRENT_BLOCK_MINOR_VERSION) + if (is_after_hardfork_2_zone() && bl.minor_version > CURRENT_BLOCK_MINOR_VERSION) { //this means that binary block is compatible, but semantics got changed due to hardfork, daemon should be updated LOG_PRINT_MAGENTA("Block's MINOR_VERSION is: " << bl.minor_version diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 8db91a00..d750fe59 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -292,6 +292,7 @@ namespace currency bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t& max_used_block_height, crypto::hash& max_used_block_id)const; bool check_ms_input(const transaction& tx, size_t in_index, const txin_multisig& txin, const crypto::hash& tx_prefix_hash, const std::vector& sig, const transaction& source_tx, size_t out_n) const; bool validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id, uint64_t block_height) const; + bool validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id) const; bool get_output_keys_for_input_with_checks(const transaction& tx, const txin_v& verified_input, std::vector& output_keys, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase, scan_for_keys_context& scan_context) const; bool get_output_keys_for_input_with_checks(const transaction& tx, const txin_v& verified_input, std::vector& output_keys, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase) const; bool check_input_signature(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector& sig, const std::vector& output_keys_ptrs) const; @@ -470,7 +471,6 @@ namespace currency bool print_tx_outputs_lookup(const crypto::hash& tx_id) const; uint64_t get_last_x_block_height(bool pos)const; bool is_tx_spendtime_unlocked(uint64_t unlock_time)const; - bool check_tx_fit_hardfork(const transaction& tx); private: //-------------- DB containers -------------- @@ -659,7 +659,10 @@ namespace currency bool is_output_allowed_for_input(const output_key_or_htlc_v& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const; bool is_output_allowed_for_input(const txout_to_key& out_v, const txin_v& in_v)const; bool is_output_allowed_for_input(const txout_htlc& out_v, const txin_v& in_v, uint64_t top_minus_source_height)const; - bool is_in_hardfork_2_zone()const; + bool is_after_hardfork_1_zone()const; + bool is_after_hardfork_1_zone(uint64_t height)const; + bool is_after_hardfork_2_zone()const; + bool is_after_hardfork_2_zone(uint64_t height)const; diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 1a7fcb72..7c014f2a 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1157,12 +1157,14 @@ namespace currency ftp.attachments = attachments; ftp.unlock_time = unlock_time; ftp.crypt_address = crypt_destination_addr; - ftp.expiration_time = 0; + ftp.expiration_time = expiration_time; ftp.tx_outs_attr = tx_outs_attr; ftp.shuffle = shuffle; ftp.flags = flags; finalized_tx ft = AUTO_VAL_INIT(ft); + ft.tx = tx; + ft.one_time_key = one_time_secret_key; bool r = construct_tx(sender_account_keys, ftp, ft); tx = ft.tx; one_time_secret_key = ft.one_time_key; diff --git a/src/currency_core/tx_pool.cpp b/src/currency_core/tx_pool.cpp index d7a5c17d..7a65990e 100644 --- a/src/currency_core/tx_pool.cpp +++ b/src/currency_core/tx_pool.cpp @@ -102,7 +102,7 @@ namespace currency return false; } - if (!m_blockchain.check_tx_fit_hardfork(tx)) + if (!m_blockchain.validate_tx_for_hardfork_specific_terms(tx, id)) { // LOG_ERROR("Transaction " << id <<" doesn't fit current hardfork");