forked from lthn/blockchain
htlc: added hardfork2 rules, improved core tests for atomics
This commit is contained in:
parent
2e18f85c2e
commit
f0e41e1980
8 changed files with 186 additions and 58 deletions
|
|
@ -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;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue