1
0
Fork 0
forked from lthn/blockchain

htlc: added hardfork2 rules, improved core tests for atomics

This commit is contained in:
cryptozoidberg 2021-03-08 02:09:08 +03:00
parent 2e18f85c2e
commit f0e41e1980
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
8 changed files with 186 additions and 58 deletions

View file

@ -3331,6 +3331,11 @@ 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())
{
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 <<")");
return false;
}
}
else if (ot.target.type() == typeid(txout_multisig))
{
@ -3844,6 +3849,11 @@ namespace currency
}
bool operator()(const txin_htlc& in) const
{
if (!m_bcs.is_in_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 << ")");
return false;
}
return this->operator()(static_cast<const txin_to_key&>(in));
}
bool operator()(const txin_gen& in) const { return true; }
@ -4262,6 +4272,12 @@ 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())
{
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 << ")");
return false;
}
const txin_htlc& in_htlc = boost::get<txin_htlc>(txin);
CHECK_AND_ASSERT_MES(in_htlc.key_offsets.size(), false, "Empty in_to_key.key_offsets for input #" << sig_index << " tx: " << tx_prefix_hash);
TIME_MEASURE_START_PD(tx_check_inputs_loop_kimage_check);
@ -4299,7 +4315,29 @@ 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
{
@ -5686,16 +5724,43 @@ bool blockchain_storage::update_next_comulative_size_limit()
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::is_in_hardfork_2_zone()const
{
if (m_db_blocks.size() > m_core_runtime_config.hard_fork_02_starts_after_height)
return true;
return false;
}
//------------------------------------------------------------------
bool blockchain_storage::prevalidate_block(const block& bl)
{
if (bl.major_version == BLOCK_MAJOR_VERSION_INITAL && get_block_height(bl) <= m_core_runtime_config.hard_fork_01_starts_after_height)
return true;
if (bl.major_version != CURRENT_BLOCK_MAJOR_VERSION)
if (bl.major_version == HF1_BLOCK_MAJOR_VERSION
&& get_block_height(bl) > m_core_runtime_config.hard_fork_01_starts_after_height
&& get_block_height(bl) <= m_core_runtime_config.hard_fork_02_starts_after_height
)
{
return true;
}
if (bl.major_version > CURRENT_BLOCK_MAJOR_VERSION)
{
LOG_ERROR("prevalidation failed for block " << get_block_hash(bl) << ": major block version " << static_cast<size_t>(bl.major_version) << " is incorrect, " << CURRENT_BLOCK_MAJOR_VERSION << " is expected" << ENDL
<< obj_to_json_str(bl));
return false;
}
if (is_in_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
<< ", while current build supports not bigger then " << CURRENT_BLOCK_MINOR_VERSION
<< ", please make sure you using latest version.", LOG_LEVEL_0
);
return false;
}
return true;
}
//------------------------------------------------------------------

View file

@ -470,6 +470,7 @@ 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 --------------
@ -658,6 +659,7 @@ 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;

View file

@ -27,7 +27,9 @@
#define CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX 0x8a49 // auditable integrated addresses start with 'aiZX'
#define CURRENCY_MINED_MONEY_UNLOCK_WINDOW 10
#define CURRENT_TRANSACTION_VERSION 1
#define CURRENT_BLOCK_MAJOR_VERSION 1
#define HF1_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

@ -1660,7 +1660,6 @@ namespace currency
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key) || in.type() == typeid(txin_multisig) || in.type() == typeid(txin_htlc), false, "wrong variant type: "
<< in.type().name()
<< ", in transaction id=" << get_transaction_hash(tx));
}
return true;
}

View file

@ -102,6 +102,14 @@ namespace currency
return false;
}
if (!m_blockchain.check_tx_fit_hardfork(tx))
{
//
LOG_ERROR("Transaction " << id <<" doesn't fit current hardfork");
tvc.m_verification_failed = true;
return false;
}
TIME_MEASURE_START_PD(tx_processing_time);
TIME_MEASURE_START_PD(check_inputs_types_supported_time);
if(!check_inputs_types_supported(tx))

View file

@ -1392,7 +1392,11 @@ void wallet2::process_htlc_triggers_on_block_added(uint64_t height)
tr.m_flags &= ~(WALLET_TRANSFER_DETAIL_FLAG_SPENT); //reset spent flag
m_found_free_amounts.clear(); //reset free amounts cache
tr.m_spent_height = 0;
}
}
//reset cache
m_found_free_amounts.clear();
//remove it from active contracts
auto it_active_htlc = m_active_htlcs.find(std::make_pair(tr.m_ptx_wallet_info->m_tx.vout[tr.m_internal_output_index].amount, tr.m_global_output_index));
if (it_active_htlc == m_active_htlcs.end())

View file

@ -31,12 +31,16 @@ struct wallet_tests_callback_handler : public tools::i_wallet2_callback
std::vector<tools::wallet_public::wallet_transfer_info> all_wtis;
};
atomic_simple_test::atomic_simple_test()
//////////////////////////////////////////////////////////////////////////
atomic_base_test::atomic_base_test()
{
REGISTER_CALLBACK_METHOD(atomic_simple_test, c1);
REGISTER_CALLBACK_METHOD(atomic_base_test, c1);
REGISTER_CALLBACK_METHOD(atomic_base_test, configure_core);
}
bool atomic_simple_test::generate(std::vector<test_event_entry>& events) const
bool atomic_base_test::generate(std::vector<test_event_entry>& events) const
{
epee::debug::get_set_enable_assert(true, true);
@ -48,7 +52,7 @@ bool atomic_simple_test::generate(std::vector<test_event_entry>& events) const
block blk_0 = AUTO_VAL_INIT(blk_0);
generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
events.push_back(blk_0);
DO_CALLBACK(events, "configure_core");
REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
DO_CALLBACK(events, "c1");
@ -56,6 +60,45 @@ bool atomic_simple_test::generate(std::vector<test_event_entry>& events) const
return true;
}
bool atomic_base_test::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_fork_01_starts_after_height = 10;
pc.hard_fork_01_starts_after_height = 12;
c.get_blockchain_storage().set_core_runtime_config(pc);
return true;
}
/************************************************************************/
/* */
/************************************************************************/
atomic_simple_test::atomic_simple_test()
{
//REGISTER_CALLBACK_METHOD(atomic_simple_test, c1);
}
// bool atomic_simple_test::generate(std::vector<test_event_entry>& events) const
// {
// epee::debug::get_set_enable_assert(true, true);
//
// currency::account_base genesis_acc;
// genesis_acc.generate();
// m_mining_accunt.generate();
//
//
// block blk_0 = AUTO_VAL_INIT(blk_0);
// generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
// events.push_back(blk_0);
//
// REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
//
// DO_CALLBACK(events, "c1");
// epee::debug::get_set_enable_assert(true, false);
// return true;
// }
bool atomic_simple_test::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
@ -287,28 +330,28 @@ bool atomic_simple_test::c1(currency::core& c, size_t ev_index, const std::vecto
atomic_test_wrong_redeem_wrong_refund::atomic_test_wrong_redeem_wrong_refund()
{
REGISTER_CALLBACK_METHOD(atomic_test_wrong_redeem_wrong_refund, c1);
//REGISTER_CALLBACK_METHOD(atomic_test_wrong_redeem_wrong_refund, c1);
}
bool atomic_test_wrong_redeem_wrong_refund::generate(std::vector<test_event_entry>& events) const
{
epee::debug::get_set_enable_assert(true, true);
currency::account_base genesis_acc;
genesis_acc.generate();
m_mining_accunt.generate();
block blk_0 = AUTO_VAL_INIT(blk_0);
generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
events.push_back(blk_0);
REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
DO_CALLBACK(events, "c1");
epee::debug::get_set_enable_assert(true, false);
return true;
}
// bool atomic_test_wrong_redeem_wrong_refund::generate(std::vector<test_event_entry>& events) const
// {
// epee::debug::get_set_enable_assert(true, true);
//
// currency::account_base genesis_acc;
// genesis_acc.generate();
// m_mining_accunt.generate();
//
//
// block blk_0 = AUTO_VAL_INIT(blk_0);
// generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
// events.push_back(blk_0);
//
// REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
//
// DO_CALLBACK(events, "c1");
// epee::debug::get_set_enable_assert(true, false);
// return true;
// }
@ -463,28 +506,28 @@ bool atomic_test_wrong_redeem_wrong_refund::c1(currency::core& c, size_t ev_inde
atomic_test_altchain_simple::atomic_test_altchain_simple()
{
REGISTER_CALLBACK_METHOD(atomic_test_altchain_simple, c1);
//REGISTER_CALLBACK_METHOD(atomic_test_altchain_simple, c1);
}
bool atomic_test_altchain_simple::generate(std::vector<test_event_entry>& events) const
{
epee::debug::get_set_enable_assert(true, true);
currency::account_base genesis_acc;
genesis_acc.generate();
m_mining_accunt.generate();
block blk_0 = AUTO_VAL_INIT(blk_0);
generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
events.push_back(blk_0);
REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
DO_CALLBACK(events, "c1");
epee::debug::get_set_enable_assert(true, false);
return true;
}
// bool atomic_test_altchain_simple::generate(std::vector<test_event_entry>& events) const
// {
// epee::debug::get_set_enable_assert(true, true);
//
// currency::account_base genesis_acc;
// genesis_acc.generate();
// m_mining_accunt.generate();
//
//
// block blk_0 = AUTO_VAL_INIT(blk_0);
// generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
// events.push_back(blk_0);
//
// REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
//
// DO_CALLBACK(events, "c1");
// epee::debug::get_set_enable_assert(true, false);
// return true;
// }

View file

@ -7,31 +7,36 @@
#include "wallet_tests_basic.h"
struct atomic_simple_test : public wallet_test
struct atomic_base_test : public wallet_test
{
atomic_base_test();
bool generate(std::vector<test_event_entry>& events) const;
virtual bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)=0;
bool configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
private:
mutable currency::account_base m_mining_accunt;
};
struct atomic_simple_test : public atomic_base_test
{
atomic_simple_test();
bool generate(std::vector<test_event_entry>& events) const;
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
private:
mutable currency::account_base m_mining_accunt;
};
struct atomic_test_wrong_redeem_wrong_refund : public wallet_test
struct atomic_test_wrong_redeem_wrong_refund : public atomic_base_test
{
atomic_test_wrong_redeem_wrong_refund();
bool generate(std::vector<test_event_entry>& events) const;
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
private:
mutable currency::account_base m_mining_accunt;
};
struct atomic_test_altchain_simple : public wallet_test
struct atomic_test_altchain_simple : public atomic_base_test
{
atomic_test_altchain_simple();
bool generate(std::vector<test_event_entry>& events) const;
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
private:
mutable currency::account_base m_mining_accunt;
};