1
0
Fork 0
forked from lthn/blockchain

coretests: tx_key_image_pool_conflict test added

This commit is contained in:
sowle 2019-10-16 16:34:34 +03:00
parent c7004d0420
commit e9bc068bfb
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
3 changed files with 136 additions and 0 deletions

View file

@ -919,6 +919,7 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(tx_expiration_time);
GENERATE_AND_PLAY(tx_expiration_time_and_block_template);
GENERATE_AND_PLAY(tx_expiration_time_and_chain_switching);
GENERATE_AND_PLAY(tx_key_image_pool_conflict);
// Double spend
GENERATE_AND_PLAY(gen_double_spend_in_tx<false>);

View file

@ -1450,3 +1450,128 @@ bool tx_expiration_time_and_chain_switching::generate(std::vector<test_event_ent
return true;
}
//------------------------------------------------------------------
tx_key_image_pool_conflict::tx_key_image_pool_conflict()
{
REGISTER_CALLBACK_METHOD(tx_key_image_pool_conflict, c1);
REGISTER_CALLBACK_METHOD(tx_key_image_pool_conflict, c2);
}
bool tx_key_image_pool_conflict::generate(std::vector<test_event_entry>& events) const
{
bool r = false;
m_miner_acc.generate();
GENERATE_ACCOUNT(bob_acc);
MAKE_GENESIS_BLOCK(events, blk_0, m_miner_acc, test_core_time::get_time());
REWIND_BLOCKS_N(events, blk_0r, blk_0, m_miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3);
// make tx_0 : miner -> bob
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
r = fill_tx_sources_and_destinations(events, blk_0r, m_miner_acc.get_keys(), bob_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_0 = AUTO_VAL_INIT(tx_0);
r = construct_tx(m_miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
LOG_PRINT_YELLOW("tx_0 = " << get_transaction_hash(tx_0), LOG_LEVEL_0);
// do not push tx_0 into events yet
// tx_1 spends the same key image as tx_0
transaction tx_1 = tx_0;
keypair kp = keypair::generate();
// change tx pub key to end up with different tx hash
update_or_add_field_to_extra(tx_1.extra, kp.pub);
r = resign_tx(m_miner_acc.get_keys(), sources, tx_1);
CHECK_AND_ASSERT_MES(r, false, "resign_tx failed");
LOG_PRINT_YELLOW("tx_1 = " << get_transaction_hash(tx_1), LOG_LEVEL_0);
// tx_2 spends the same key image as tx_0
transaction tx_2 = tx_0;
kp = keypair::generate();
// change tx pub key to end up with different tx hash
update_or_add_field_to_extra(tx_2.extra, kp.pub);
r = resign_tx(m_miner_acc.get_keys(), sources, tx_2);
CHECK_AND_ASSERT_MES(r, false, "resign_tx failed");
LOG_PRINT_YELLOW("tx_2 = " << get_transaction_hash(tx_2), LOG_LEVEL_0);
events.push_back(tx_1);
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(1));
// as long as tx_0 is using the same key image as tx_1, tx_0 and tx_2 can't be added to the pool atm
// make sure that it's true
DO_CALLBACK(events, "mark_invalid_tx");
events.push_back(tx_0);
DO_CALLBACK(events, "mark_invalid_tx");
events.push_back(tx_2);
// however, tx_0 and tx_2 can be added with kept_by_block flag (to simulate it's going with blk_1)
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true));
events.push_back(tx_0);
events.push_back(tx_2);
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, false));
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(3));
// make a block with tx_0 and put tx_0 to the blockchain
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, m_miner_acc, tx_0);
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(2));
// tx_1 and tx_2 is still in the pool
// it can never be added to any block as long as blk_1 is in the blockchain due to key image conflict
DO_CALLBACK(events, "mark_invalid_block");
MAKE_NEXT_BLOCK_TX1(events, blk_2_bad, blk_1, m_miner_acc, tx_1);
// add tx_1 to alt block, it should go well
MAKE_NEXT_BLOCK_TX1(events, blk_1a, blk_0r, m_miner_acc, tx_1);
// however, it does not remove tx from the pool
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(2));
MAKE_NEXT_BLOCK(events, blk_2, blk_1, m_miner_acc);
DO_CALLBACK(events, "remove_stuck_txs");
// remove_stuck_txs should not remove anything, tx_1 and tx_2 should be in the pool
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(2));
// shift time by CURRENCY_MEMPOOL_TX_LIVETIME
events.push_back(event_core_time(CURRENCY_MEMPOOL_TX_LIVETIME + 1, true));
// remove_stuck_txs should remove only tx_2 and left tx_1
DO_CALLBACK(events, "remove_stuck_txs");
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(1));
DO_CALLBACK(events, "print_tx_pool");
return true;
}
bool tx_key_image_pool_conflict::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
bool r = false;
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "incorrect tx pool count = " << c.get_pool_transactions_count());
// try to mine a block and make sure tx_1 is still in the pool (was not added to the blocktemplate)
block b;
r = mine_next_pow_block_in_playtime(m_miner_acc.get_public_address(), c, &b);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
// make sure tx_1 is still here
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "incorrect tx pool count = " << c.get_pool_transactions_count());
return true;
}
bool tx_key_image_pool_conflict::c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
return true;
}

View file

@ -147,3 +147,13 @@ struct tx_expiration_time_and_chain_switching : public test_chain_unit_enchanced
{
bool generate(std::vector<test_event_entry>& events) const;
};
struct tx_key_image_pool_conflict : public test_chain_unit_enchanced
{
tx_key_image_pool_conflict();
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);
bool c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
mutable currency::account_base m_miner_acc;
};