1
0
Fork 0
forked from lthn/blockchain

coretests: ionic_swap_exact_amounts_test added which uncovers a bug in separately signed tx creation

This commit is contained in:
sowle 2023-10-21 23:40:39 +02:00
parent f1e064f600
commit 87831eaf1a
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
3 changed files with 173 additions and 1 deletions

View file

@ -1250,7 +1250,8 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(zarcanum_basic_test);
GENERATE_AND_PLAY_HF(multiassets_basic_test, "4-*");
GENERATE_AND_PLAY(ionic_swap_basic_test);
GENERATE_AND_PLAY(ionic_swap_basic_test);
GENERATE_AND_PLAY_HF(ionic_swap_exact_amounts_test, "4-*");
GENERATE_AND_PLAY(zarcanum_test_n_inputs_validation);
GENERATE_AND_PLAY(zarcanum_gen_time_balance);
GENERATE_AND_PLAY(zarcanum_txs_with_big_shuffled_decoy_set_shuffled);

View file

@ -293,3 +293,167 @@ bool ionic_swap_basic_test::c1(currency::core& c, size_t ev_index, const std::ve
return true;
}
//----------------------------------------------------------------------------------------------------
ionic_swap_exact_amounts_test::ionic_swap_exact_amounts_test()
{
REGISTER_CALLBACK_METHOD(ionic_swap_exact_amounts_test, c1);
}
bool ionic_swap_exact_amounts_test::generate(std::vector<test_event_entry>& events) const
{
uint64_t ts = test_core_time::get_time();
m_accounts.resize(TOTAL_ACCS_COUNT);
currency::account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts);
currency::account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts);
currency::account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts);
currency::account_base& carol_acc = m_accounts[CAROL_ACC_IDX]; carol_acc.generate(); carol_acc.set_createtime(ts);
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
// rebuild genesis miner tx
std::vector<tx_destination_entry> destinations;
destinations.emplace_back(MK_TEST_COINS(21), alice_acc.get_public_address());
destinations.emplace_back(MK_TEST_COINS(21), miner_acc.get_public_address()); // decoy (later Alice will spend her output using mixins)
destinations.emplace_back(MK_TEST_COINS(21), miner_acc.get_public_address()); // decoy
destinations.emplace_back(COIN, miner_acc.get_public_address());
// leftover amount will be also send to miner
CHECK_AND_ASSERT_MES(replace_coinbase_in_genesis_block(destinations, generator, events, blk_0), false, "");
DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1);
DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
DO_CALLBACK(events, "c1");
return true;
}
bool ionic_swap_exact_amounts_test::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
bool r = false;
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
miner_wlt->refresh();
asset_descriptor_base adb{};
adb.total_max_supply = 10000000000;
adb.full_name = "test";
adb.ticker = "TEST";
std::vector<currency::tx_destination_entry> destinations;
destinations.emplace_back(7070000000, m_accounts[BOB_ACC_IDX].get_public_address(), null_pkey);
destinations.emplace_back(2930000000, m_accounts[BOB_ACC_IDX].get_public_address(), null_pkey);
destinations.emplace_back(MK_TEST_COINS(21), m_accounts[CAROL_ACC_IDX].get_public_address()); // Carol will get coins with non-explicit asset id
currency::transaction tx{};
crypto::public_key asset_id = currency::null_pkey;
miner_wlt->deploy_new_asset(adb, destinations, tx, asset_id);
LOG_PRINT_L0("Deployed new asset: " << asset_id << ", tx_id: " << currency::get_transaction_hash(tx));
CHECK_AND_ASSERT_MES(tx.vout.size() >= 2, false, "Unexpected vout size: " << tx.vout.size());
for(auto& out : tx.vout)
{
CHECK_AND_ASSERT_MES(out.type() == typeid(tx_out_zarcanum), false, "invalid out type");
CHECK_AND_ASSERT_MES(boost::get<tx_out_zarcanum>(out).blinded_asset_id != native_coin_asset_id_1div8, false, "One of outputs has explicit native asset id, which is unexpected");
}
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
alice_wlt->refresh();
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
bob_wlt->refresh();
std::shared_ptr<tools::wallet2> carol_wlt = init_playtime_test_wallet(events, c, CAROL_ACC_IDX);
carol_wlt->refresh();
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", MK_TEST_COINS(21), MK_TEST_COINS(21), MK_TEST_COINS(21), 0, 0), false, "");
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", adb.total_max_supply, 0, adb.total_max_supply, 0, 0, asset_id), false, "");
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*carol_wlt, "Carol", MK_TEST_COINS(21), 0, MK_TEST_COINS(21), 0, 0), false, "");
size_t current_blockchain_size = c.get_current_blockchain_size();
// Normal ionic swap between Alice and Bob: (Alice has only coins with explicit asset id)
// before:
// Alice (initiator): 0.21 ZANO < - > Bob (finalizer): 0.01 TEST
// after:
// Alice (initiator): 0.01 TEST Bob (finalizer): 0.20 ZANO
view::ionic_swap_proposal_info proposal_details{};
proposal_details.to_initiator.push_back(view::asset_funds{ asset_id, adb.total_max_supply });
proposal_details.to_finalizer.push_back(view::asset_funds{ native_coin_asset_id, MK_TEST_COINS(20) });
proposal_details.fee_paid_by_a = MK_TEST_COINS(1);
proposal_details.mixins = 2;
tools::wallet_public::ionic_swap_proposal proposal{};
alice_wlt->create_ionic_swap_proposal(proposal_details, m_accounts[BOB_ACC_IDX].get_public_address(), proposal);
view::ionic_swap_proposal_info proposal_decoded_info{};
bob_wlt->get_ionic_swap_proposal_info(proposal, proposal_decoded_info);
CHECK_AND_ASSERT_MES(
proposal_decoded_info.to_finalizer == proposal_details.to_finalizer &&
proposal_decoded_info.to_initiator == proposal_details.to_initiator &&
proposal_decoded_info.fee_paid_by_a == proposal_details.fee_paid_by_a &&
proposal_decoded_info.mixins == proposal_details.mixins,
false, "actual and decoded proposal mismatch");
currency::transaction tx_is{};
r = bob_wlt->accept_ionic_swap_proposal(proposal, tx_is);
CHECK_AND_ASSERT_MES(r, false, "Failed to accept ionic proposal");
//CHECK_AND_ASSERT_MES(check_ionic_swap_tx_outs(m_accounts, tx_is, bob_wlt, proposal), false, "");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
alice_wlt->refresh();
bob_wlt->refresh();
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", adb.total_max_supply, 0, adb.total_max_supply, 0, 0, asset_id), false, "");
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", MK_TEST_COINS(20), 0, MK_TEST_COINS(20), 0, 0), false, "");
// Normal ionic swap between Carol and Alice: (Carol has only coins with non-explicit asset id)
// before:
// Carol (initiator): 0.21 Zano Alice (finalizer): 0.01 TEST
// after:
// Carol (initiator): 0.01 TEST Alice (finalizer): 0.2 ZANO
proposal_details = view::ionic_swap_proposal_info{};
proposal_details.to_initiator.push_back(view::asset_funds{ asset_id, adb.total_max_supply });
proposal_details.to_finalizer.push_back(view::asset_funds{ native_coin_asset_id, MK_TEST_COINS(20) });
proposal_details.fee_paid_by_a = MK_TEST_COINS(1);
proposal_details.mixins = 2;
proposal = tools::wallet_public::ionic_swap_proposal{};
carol_wlt->create_ionic_swap_proposal(proposal_details, m_accounts[ALICE_ACC_IDX].get_public_address(), proposal);
proposal_decoded_info = view::ionic_swap_proposal_info{};
alice_wlt->get_ionic_swap_proposal_info(proposal, proposal_decoded_info);
CHECK_AND_ASSERT_MES(
proposal_decoded_info.to_finalizer == proposal_details.to_finalizer &&
proposal_decoded_info.to_initiator == proposal_details.to_initiator &&
proposal_decoded_info.fee_paid_by_a == proposal_details.fee_paid_by_a &&
proposal_decoded_info.mixins == proposal_details.mixins,
false, "actual and decoded proposal mismatch");
currency::transaction tx_is2{};
r = alice_wlt->accept_ionic_swap_proposal(proposal, tx_is2);
CHECK_AND_ASSERT_MES(r, false, "Failed to accept ionic proposal");
//CHECK_AND_ASSERT_MES(check_ionic_swap_tx_outs(m_accounts, tx_is2, bob_wlt, proposal), false, "");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
carol_wlt->refresh();
alice_wlt->refresh();
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*carol_wlt, "Carol", adb.total_max_supply, 0, adb.total_max_supply, 0, 0, asset_id), false, "");
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", MK_TEST_COINS(20), 0, MK_TEST_COINS(20), 0, 0), false, "");
return true;
}

View file

@ -4,6 +4,7 @@
#pragma once
#include "chaingen.h"
#include "wallet_tests_basic.h"
#include "random_helper.h"
struct ionic_swap_basic_test : public wallet_test
{
@ -12,3 +13,9 @@ struct ionic_swap_basic_test : public wallet_test
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
};
struct ionic_swap_exact_amounts_test : public wallet_test
{
ionic_swap_exact_amounts_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);
};