forked from lthn/blockchain
coretests: escrow_balance test added for more careful balance checking in contracts (related to #47)
This commit is contained in:
parent
db38a029fd
commit
c8138225d2
4 changed files with 542 additions and 0 deletions
|
|
@ -765,6 +765,7 @@ int main(int argc, char* argv[])
|
|||
// GENERATE_AND_PLAY(escrow_proposal_acceptance_in_alt_chain); -- work in progress
|
||||
GENERATE_AND_PLAY(escrow_zero_amounts);
|
||||
GENERATE_AND_PLAY(escrow_acceptance_and_balance);
|
||||
GENERATE_AND_PLAY(escrow_balance);
|
||||
|
||||
GENERATE_AND_PLAY(escrow_altchain_meta_test<0>);
|
||||
GENERATE_AND_PLAY(escrow_altchain_meta_test<1>);
|
||||
|
|
|
|||
|
|
@ -3292,3 +3292,490 @@ bool escrow_acceptance_and_balance::check_balance_after_acceptance_confirmed(cur
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
escrow_balance::escrow_balance()
|
||||
: m_alice_bob_start_amount(0)
|
||||
, m_alice_bob_start_chunk_amount(0)
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(escrow_balance, c1);
|
||||
}
|
||||
|
||||
bool escrow_balance::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
// Test idea: carefull check balances on each stage of escrow contract (including cancellation req and acc):
|
||||
// 1) within wallet callback in the middle of contract function call
|
||||
// 2) after tx was sent to network but not yet confirmed
|
||||
// 3) after tx was confirmed
|
||||
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate();
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate();
|
||||
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate();
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
m_alice_bob_start_amount = MK_TEST_COINS(200);
|
||||
uint64_t amount_chunks = 10;
|
||||
m_alice_bob_start_chunk_amount = m_alice_bob_start_amount / 10;
|
||||
|
||||
transaction tx_0 = AUTO_VAL_INIT(tx_0);
|
||||
bool r = construct_tx_with_many_outputs(events, blk_0r, miner_acc.get_keys(), alice_acc.get_public_address(), m_alice_bob_start_amount, 10, TESTS_DEFAULT_FEE, tx_0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx_with_many_outputs failed");
|
||||
events.push_back(tx_0);
|
||||
|
||||
transaction tx_1 = AUTO_VAL_INIT(tx_1);
|
||||
r = construct_tx_with_many_outputs(events, blk_0r, miner_acc.get_keys(), bob_acc.get_public_address(), m_alice_bob_start_amount, 10, TESTS_DEFAULT_FEE, tx_1);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx_with_many_outputs failed");
|
||||
events.push_back(tx_1);
|
||||
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_1, blk_0r, miner_acc, std::list<transaction>({tx_0, tx_1}));
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool escrow_balance::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false, stub_bool = false;
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]);
|
||||
auto alice_bc = std::make_shared<wallet_callback_balance_checker>("Alice");
|
||||
alice_wlt->callback(alice_bc);
|
||||
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, m_accounts[BOB_ACC_IDX]);
|
||||
auto bob_bc = std::make_shared<wallet_callback_balance_checker>("Bob");
|
||||
bob_wlt->callback(bob_bc);
|
||||
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount, 0);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awainted out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount, 0);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
//
|
||||
// escrow proposal
|
||||
//
|
||||
bc_services::contract_private_details cpd = AUTO_VAL_INIT(cpd);
|
||||
cpd.amount_a_pledge = MK_TEST_COINS(7);
|
||||
cpd.amount_b_pledge = MK_TEST_COINS(5);
|
||||
cpd.amount_to_pay = MK_TEST_COINS(3);
|
||||
cpd.a_addr = m_accounts[ALICE_ACC_IDX].get_public_address();
|
||||
cpd.b_addr = m_accounts[BOB_ACC_IDX].get_public_address();
|
||||
uint64_t alice_proposal_fee = MK_TEST_COINS(4);
|
||||
uint64_t bob_acceptace_fee = MK_TEST_COINS(2);
|
||||
uint64_t bob_release_fee = MK_TEST_COINS(9); // Alice states that Bob should pay this much money for upcoming contract release (which will be sent by Alice)
|
||||
uint64_t alice_cancellation_request_fee = MK_TEST_COINS(1);
|
||||
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount); // balace after sending the proposal
|
||||
|
||||
transaction proposal_tx = AUTO_VAL_INIT(proposal_tx);
|
||||
transaction escrow_template_tx = AUTO_VAL_INIT(escrow_template_tx);
|
||||
uint64_t expiration_time = test_core_time::get_time() + 60;
|
||||
LOG_PRINT_GREEN("\n" "alice_wlt->send_escrow_proposal()", LOG_LEVEL_0);
|
||||
alice_wlt->send_escrow_proposal(cpd, 0, 0, expiration_time, alice_proposal_fee, bob_release_fee, "", proposal_tx, escrow_template_tx);
|
||||
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
tools::wallet2::escrow_contracts_container contracts;
|
||||
r = alice_wlt->get_contracts(contracts);
|
||||
CHECK_AND_ASSERT_MES(r && contracts.size() == 1, false, "get_contracts() for Alice failed");
|
||||
crypto::hash contract_id = contracts.begin()->first;
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// proposal tx is not confirmed yet
|
||||
alice_bc->expect_balance();
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awainted out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(!alice_bc->called(), false, "balance callback check failed");
|
||||
|
||||
// Bob's balance should not change
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount, m_alice_bob_start_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
// mine a block to confirm escrow proposal tx
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// proposal tx is confirmed (balances should stay the same)
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awainted out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount, m_alice_bob_start_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
//
|
||||
// proposal acceptance
|
||||
//
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - m_alice_bob_start_chunk_amount);
|
||||
|
||||
LOG_PRINT_GREEN("\n" "bob_wlt->accept_proposal()", LOG_LEVEL_0);
|
||||
bob_wlt->accept_proposal(contract_id, bob_acceptace_fee);
|
||||
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// acceptance tx is not confirmed yet
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
cpd.amount_a_pledge + cpd.amount_to_pay // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance();
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
cpd.amount_b_pledge + bob_release_fee // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(!bob_bc->called(), false, "balance callback check failed");
|
||||
|
||||
// mine a block containing contract acceptance
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// acceptance tx is confirmed
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
//
|
||||
// cancellation request
|
||||
//
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay - alice_cancellation_request_fee, m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount);
|
||||
|
||||
LOG_PRINT_GREEN("\n" "alice_wlt->request_cancel_contract()", LOG_LEVEL_0);
|
||||
alice_wlt->request_cancel_contract(contract_id, alice_cancellation_request_fee, 60 * 60);
|
||||
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// cancellation request is not confirmed yet
|
||||
alice_bc->expect_balance();
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay - alice_cancellation_request_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(!alice_bc->called(), false, "balance callback check failed");
|
||||
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
// mine a block containing cancellation request
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// cancellation request is confirmed
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay - alice_cancellation_request_fee, m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay - alice_cancellation_request_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
//
|
||||
// cancellation acceptance
|
||||
//
|
||||
bob_bc->expect_balance();
|
||||
|
||||
LOG_PRINT_GREEN("\n" "bob_wlt->accept_cancel_contract()", LOG_LEVEL_0);
|
||||
bob_wlt->accept_cancel_contract(contract_id);
|
||||
|
||||
CHECK_AND_ASSERT_MES(!bob_bc->called(), false, "balance callback check failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// cancellation acceptance is not confirmed yet
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee - alice_cancellation_request_fee, m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee - alice_cancellation_request_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
cpd.amount_a_pledge + cpd.amount_to_pay, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - bob_release_fee - bob_acceptace_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
cpd.amount_b_pledge, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
// mine a block containing cancellation acceptance
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// cancellation acceptance is confirmed
|
||||
alice_bc->expect_balance(m_alice_bob_start_amount - alice_proposal_fee - alice_cancellation_request_fee, m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - alice_proposal_fee - alice_cancellation_request_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 3 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(m_alice_bob_start_amount - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - bob_release_fee - bob_acceptace_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
|
||||
//
|
||||
// Stage 2 : check normal contract workflow
|
||||
// don't check balances on request and accept as it was checked above
|
||||
//
|
||||
|
||||
uint64_t alice_balance_before_stage_2 = m_alice_bob_start_amount - alice_proposal_fee - alice_cancellation_request_fee;
|
||||
uint64_t bob_balance_before_stage_2 = m_alice_bob_start_amount - bob_release_fee - bob_acceptace_fee;
|
||||
|
||||
alice_bc->expect_balance(alice_balance_before_stage_2 - alice_proposal_fee, m_alice_bob_start_amount - 5 * m_alice_bob_start_chunk_amount);
|
||||
|
||||
LOG_PRINT_GREEN("\n" "stage2: alice_wlt->send_escrow_proposal()", LOG_LEVEL_0);
|
||||
proposal_tx = AUTO_VAL_INIT(proposal_tx);
|
||||
escrow_template_tx = AUTO_VAL_INIT(escrow_template_tx);
|
||||
alice_wlt->send_escrow_proposal(cpd, 0, 0, expiration_time, alice_proposal_fee, bob_release_fee, "", proposal_tx, escrow_template_tx);
|
||||
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
contracts.clear();
|
||||
r = alice_wlt->get_contracts(contracts);
|
||||
CHECK_AND_ASSERT_MES(r && contracts.size() == 2, false, "get_contracts() for Alice failed");
|
||||
// get new contract id
|
||||
if (contract_id != contracts.begin()->first)
|
||||
contract_id = contracts.begin()->first;
|
||||
else
|
||||
contract_id = (++contracts.begin())->first;
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
bob_wlt->refresh();
|
||||
|
||||
bob_bc->expect_balance(bob_balance_before_stage_2 - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount);
|
||||
|
||||
LOG_PRINT_GREEN("\n" "stage2: bob_wlt->accept_proposal()", LOG_LEVEL_0);
|
||||
bob_wlt->accept_proposal(contract_id, bob_acceptace_fee);
|
||||
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
alice_bc->expect_balance(alice_balance_before_stage_2 - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay, m_alice_bob_start_amount - 5 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
alice_balance_before_stage_2 - alice_proposal_fee - cpd.amount_a_pledge - cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 5 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed");
|
||||
|
||||
bob_bc->expect_balance(bob_balance_before_stage_2 - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
bob_balance_before_stage_2 - cpd.amount_b_pledge - bob_release_fee - bob_acceptace_fee, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
//
|
||||
// contract release
|
||||
//
|
||||
|
||||
alice_bc->expect_balance();
|
||||
|
||||
alice_wlt->finish_contract(contract_id, BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_NORMAL);
|
||||
|
||||
CHECK_AND_ASSERT_MES(!alice_bc->called(), false, "balance callback check failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// contract release tx is unconfirmed
|
||||
alice_bc->expect_balance(alice_balance_before_stage_2 - alice_proposal_fee - cpd.amount_to_pay, m_alice_bob_start_amount - 5 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
alice_balance_before_stage_2 - alice_proposal_fee - cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 5 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
cpd.amount_a_pledge, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(bob_balance_before_stage_2 - bob_release_fee - bob_acceptace_fee + cpd.amount_to_pay, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
bob_balance_before_stage_2 - bob_release_fee - bob_acceptace_fee + cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
cpd.amount_b_pledge + cpd.amount_to_pay, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// contract release tx is confirmed
|
||||
alice_bc->expect_balance(alice_balance_before_stage_2 - alice_proposal_fee - cpd.amount_to_pay, m_alice_bob_start_amount - 5 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
alice_balance_before_stage_2 - alice_proposal_fee - cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 5 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(alice_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
bob_bc->expect_balance(bob_balance_before_stage_2 - bob_release_fee - bob_acceptace_fee + cpd.amount_to_pay, m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount);
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
bob_balance_before_stage_2 - bob_release_fee - bob_acceptace_fee + cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
0, // awaited in
|
||||
0 // awaited out
|
||||
), false, "");
|
||||
CHECK_AND_ASSERT_MES(bob_bc->check(), false, "balance callback check failed, see above");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,3 +158,13 @@ struct escrow_acceptance_and_balance : public wallet_test
|
|||
mutable uint64_t m_bob_fee_accept;
|
||||
mutable bc_services::contract_private_details m_cpd;
|
||||
};
|
||||
|
||||
struct escrow_balance : public wallet_test
|
||||
{
|
||||
escrow_balance();
|
||||
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);
|
||||
|
||||
mutable uint64_t m_alice_bob_start_amount;
|
||||
mutable uint64_t m_alice_bob_start_chunk_amount;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,3 +43,47 @@ protected:
|
|||
mutable test_generator generator;
|
||||
std::shared_ptr<tools::i_core_proxy> m_core_proxy;
|
||||
};
|
||||
|
||||
// wallet callback helper to check balance in wallet callbacks
|
||||
// see escrow_balance test for usage example
|
||||
struct wallet_callback_balance_checker : public tools::i_wallet2_callback
|
||||
{
|
||||
wallet_callback_balance_checker(const std::string& label) : m_label(label), m_result(true), m_called(false), m_balance(UINT64_MAX), m_unlocked_balance(UINT64_MAX), m_total_mined(UINT64_MAX) {}
|
||||
|
||||
void expect_balance(uint64_t balance = UINT64_MAX, uint64_t unlocked_balance = UINT64_MAX, uint64_t total_mined = UINT64_MAX)
|
||||
{
|
||||
m_balance = balance;
|
||||
m_unlocked_balance = unlocked_balance;
|
||||
m_total_mined = total_mined;
|
||||
m_called = false;
|
||||
}
|
||||
|
||||
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) override
|
||||
{
|
||||
m_called = true;
|
||||
m_result = false;
|
||||
CHECK_AND_ASSERT_MES(m_balance == UINT64_MAX || balance == m_balance, (void)(0), m_label << " balance is incorrect: " << currency::print_money_brief(balance) << ", expected: " << currency::print_money_brief(m_balance));
|
||||
CHECK_AND_ASSERT_MES(m_unlocked_balance == UINT64_MAX || unlocked_balance == m_unlocked_balance, (void)(0), m_label << " unlocked balance is incorrect: " << currency::print_money_brief(unlocked_balance) << ", expected: " << currency::print_money_brief(m_unlocked_balance));
|
||||
CHECK_AND_ASSERT_MES(m_total_mined == UINT64_MAX || total_mined == m_total_mined, (void)(0), m_label << " total mined is incorrect: " << currency::print_money_brief(total_mined) << ", expected: " << currency::print_money_brief(m_total_mined));
|
||||
m_result = true;
|
||||
}
|
||||
|
||||
bool check()
|
||||
{
|
||||
bool result = m_result;
|
||||
m_result = false; // clear result to avoid errorneous successive calls to check() without calling except_balance()
|
||||
return result;
|
||||
}
|
||||
|
||||
bool called()
|
||||
{
|
||||
return m_called;
|
||||
}
|
||||
|
||||
bool m_result;
|
||||
bool m_called;
|
||||
std::string m_label;
|
||||
uint64_t m_balance;
|
||||
uint64_t m_unlocked_balance;
|
||||
uint64_t m_total_mined;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue