1
0
Fork 0
forked from lthn/blockchain

fixed multiple bugs related to recent refactoring

This commit is contained in:
cryptozoidberg 2021-03-10 22:35:34 +03:00
parent 9dac595b83
commit 3962e6153d
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
4 changed files with 114 additions and 59 deletions

View file

@ -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<const txin_to_key&>(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<crypto::signature>& 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<payload_items_v>& 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

View file

@ -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<crypto::signature>& 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<crypto::public_key>& 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<crypto::public_key>& 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<crypto::signature>& sig, const std::vector<const crypto::public_key*>& 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;

View file

@ -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;

View file

@ -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");