From aa60533269d7ca5e534bedb8a63ac4742d50164c Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Sat, 29 Jul 2017 18:42:25 +0200 Subject: [PATCH 1/8] Added unit test to reproducee the OP in issue #338 --- tests/tests/market_tests.cpp | 125 +++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 tests/tests/market_tests.cpp diff --git a/tests/tests/market_tests.cpp b/tests/tests/market_tests.cpp new file mode 100644 index 0000000000..9f6cc81de0 --- /dev/null +++ b/tests/tests/market_tests.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2017 Peter Conrad, and other contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include +#include +#include + +#include + +#include "../common/database_fixture.hpp" + +using namespace graphene::chain; +using namespace graphene::chain::test; +using namespace graphene::wallet; + +BOOST_FIXTURE_TEST_SUITE(market_tests, database_fixture) + +/*** + * Reproduce bitshares-core issue #338 + */ +BOOST_AUTO_TEST_CASE(issue_338) +{ try { + generate_blocks(HARDFORK_436_TIME); + generate_block(); + + set_expiration( db, trx ); + + ACTORS((buyer)(seller)(borrower)(feedproducer)); + + const auto& bitusd = create_bitasset("USDBIT", feedproducer_id); + const auto& core = asset_id_type()(db); + + int64_t init_balance(1000000); + + transfer(committee_account, buyer_id, asset(init_balance)); + transfer(committee_account, borrower_id, asset(init_balance)); + update_feed_producers( bitusd, {feedproducer.id} ); + + price_feed current_feed; + current_feed.maintenance_collateral_ratio = 1750; + current_feed.maximum_short_squeeze_ratio = 1100; + current_feed.settlement_price = bitusd.amount( 1 ) / core.amount(5); + publish_feed( bitusd, feedproducer, current_feed ); + // start out with 300% collateral, call price is 15/1.75 CORE/USD = 60/7 + const call_order_object& call = *borrow( borrower, bitusd.amount(1000), asset(15000)); + transfer(borrower, seller, bitusd.amount(1000)); + + BOOST_CHECK_EQUAL( 1000, call.debt.value ); + BOOST_CHECK_EQUAL( 15000, call.collateral.value ); + BOOST_CHECK_EQUAL( 1000, get_balance(seller, bitusd) ); + BOOST_CHECK_EQUAL( 0, get_balance(seller, core) ); + + // adjust price feed to get call_order into margin call territory + current_feed.settlement_price = bitusd.amount( 1 ) / core.amount(10); + publish_feed( bitusd, feedproducer, current_feed ); + // settlement price = 1/10, mssp = 1/11 + + // This order slightly below the call price will not be matched + limit_order_id_type sell_low = create_sell_order(seller, bitusd.amount(7), core.amount(59))->id; + // This order above the MSSP will not be matched + limit_order_id_type sell_high = create_sell_order(seller, bitusd.amount(7), core.amount(78))->id; + // This would match but is blocked by sell_low?! + limit_order_id_type sell_med = create_sell_order(seller, bitusd.amount(7), core.amount(60))->id; + + cancel_limit_order( sell_med(db) ); + cancel_limit_order( sell_high(db) ); + cancel_limit_order( sell_low(db) ); + + // current implementation: an incoming limit order will be filled at the + // requested price + BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(60)) ); + BOOST_CHECK_EQUAL( 993, get_balance(seller, bitusd) ); + BOOST_CHECK_EQUAL( 60, get_balance(seller, core) ); + BOOST_CHECK_EQUAL( 993, call.debt.value ); + BOOST_CHECK_EQUAL( 14940, call.collateral.value ); + + auto buy_low = create_sell_order(buyer, asset(90), bitusd.amount(10))->id; + // margin call takes precedence + BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(60)) ); + BOOST_CHECK_EQUAL( 986, get_balance(seller, bitusd) ); + BOOST_CHECK_EQUAL( 120, get_balance(seller, core) ); + BOOST_CHECK_EQUAL( 986, call.debt.value ); + BOOST_CHECK_EQUAL( 14880, call.collateral.value ); + + auto buy_med = create_sell_order(buyer, asset(105), bitusd.amount(10))->id; + // margin call takes precedence + BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(70)) ); + BOOST_CHECK_EQUAL( 979, get_balance(seller, bitusd) ); + BOOST_CHECK_EQUAL( 190, get_balance(seller, core) ); + BOOST_CHECK_EQUAL( 979, call.debt.value ); + BOOST_CHECK_EQUAL( 14810, call.collateral.value ); + + auto buy_high = create_sell_order(buyer, asset(115), bitusd.amount(10))->id; + // margin call still has precedence (!)) + BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(77)) ); + BOOST_CHECK_EQUAL( 972, get_balance(seller, bitusd) ); + BOOST_CHECK_EQUAL( 267, get_balance(seller, core) ); + BOOST_CHECK_EQUAL( 972, call.debt.value ); + BOOST_CHECK_EQUAL( 14733, call.collateral.value ); +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_SUITE_END() From ea0a0832c28a3b7af91a625b48fd8ce145f594c8 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Sat, 29 Jul 2017 20:04:37 +0200 Subject: [PATCH 2/8] Added log message for bad order matching in margin calls --- libraries/chain/db_market.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/chain/db_market.cpp b/libraries/chain/db_market.cpp index 59f777621e..e5a11069f6 100644 --- a/libraries/chain/db_market.cpp +++ b/libraries/chain/db_market.cpp @@ -530,6 +530,8 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan order_pays = usd_to_buy; filled_call = true; + if( filled_limit ) + wlog( "Multiple limit match problem (issue 338) occurred at block #${block}", ("block",head_block_num()) ); } FC_ASSERT( filled_call || filled_limit ); From c7558b8be931b29fb333c8166522e4fa6a2cd757 Mon Sep 17 00:00:00 2001 From: Alexander Morris Date: Fri, 11 Aug 2017 08:44:36 -0400 Subject: [PATCH 3/8] added my rounding tests in "GLOB OP_TESTS" --- tests/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7edc54bd41..b6d1640a11 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,3 +30,7 @@ add_executable( intense_test ${INTENSE_SOURCES} ${COMMON_SOURCES} ) target_link_libraries( intense_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) add_subdirectory( generate_empty_blocks ) + +file(GLOB OP_TESTS "mytests/*.cpp") +add_executable( optest ${OP_TESTS} ${COMMON_SOURCES} ) +target_link_libraries( optest graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc graphene_wallet ${PLATFORM_SPECIFIC_LIBS} ) From f303c7a0d7ad8448d11c2054b2561493c4486d6f Mon Sep 17 00:00:00 2001 From: Alexander Morris Date: Fri, 11 Aug 2017 08:49:33 -0400 Subject: [PATCH 4/8] new set of tests to verify correct rounding functionality --- tests/mytests/optest.cpp | 775 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 775 insertions(+) create mode 100644 tests/mytests/optest.cpp diff --git a/tests/mytests/optest.cpp b/tests/mytests/optest.cpp new file mode 100644 index 0000000000..56255d1d95 --- /dev/null +++ b/tests/mytests/optest.cpp @@ -0,0 +1,775 @@ +/* + * Copyright (c) 2015 Cryptonomex, Inc., and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define BOOST_TEST_MODULE Test Application +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../common/database_fixture.hpp" + +using namespace graphene::chain; +using namespace graphene::chain::test; + +BOOST_FIXTURE_TEST_SUITE( operation_tests, database_fixture ) + +//exec: /home/vm/bitshares-core/tests/optest +//workdir: /home/vm/bitshares-core/tests/ + + +BOOST_AUTO_TEST_CASE( create_uia ) +{ + try { + asset_id_type test_asset_id = db.get_index().get_next_id(); + asset_create_operation creator; + creator.issuer = account_id_type(); + creator.fee = asset(); + creator.symbol = "TEST"; + creator.common_options.max_supply = 100000000; + creator.precision = 2; + creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ + creator.common_options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK; + creator.common_options.flags = charge_market_fee; + creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); + trx.operations.push_back(std::move(creator)); + PUSH_TX( db, trx, ~0 ); + + const asset_object& test_asset = test_asset_id(db); + BOOST_CHECK(test_asset.symbol == "TEST"); + BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2)); + BOOST_CHECK((test_asset.options.flags & white_list) == 0); + BOOST_CHECK(test_asset.options.max_supply == 100000000); + BOOST_CHECK(!test_asset.bitasset_data_id.valid()); + BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100); + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); + + const asset_dynamic_data_object& test_asset_dynamic_data = test_asset.dynamic_asset_data_id(db); + BOOST_CHECK(test_asset_dynamic_data.current_supply == 0); + BOOST_CHECK(test_asset_dynamic_data.accumulated_fees == 0); + BOOST_CHECK(test_asset_dynamic_data.fee_pool == 0); + + auto op = trx.operations.back().get(); + op.symbol = "TESTFAIL"; + REQUIRE_THROW_WITH_VALUE(op, issuer, account_id_type(99999999)); + REQUIRE_THROW_WITH_VALUE(op, common_options.max_supply, -1); + REQUIRE_THROW_WITH_VALUE(op, common_options.max_supply, 0); + REQUIRE_THROW_WITH_VALUE(op, symbol, "A"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "qqq"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "11"); + REQUIRE_THROW_WITH_VALUE(op, symbol, ".AAA"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "AAA."); + REQUIRE_THROW_WITH_VALUE(op, symbol, "AB CD"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price({asset(-100), asset(1)})); + REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price({asset(100),asset(-1)})); + } catch(fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( create_account_test ) +{ + try { + trx.operations.push_back(make_account()); + account_create_operation op = trx.operations.back().get(); + + REQUIRE_THROW_WITH_VALUE(op, registrar, account_id_type(9999999)); + REQUIRE_THROW_WITH_VALUE(op, fee, asset(-1)); + REQUIRE_THROW_WITH_VALUE(op, name, "!"); + REQUIRE_THROW_WITH_VALUE(op, name, "Sam"); + REQUIRE_THROW_WITH_VALUE(op, name, "saM"); + REQUIRE_THROW_WITH_VALUE(op, name, "sAm"); + REQUIRE_THROW_WITH_VALUE(op, name, "6j"); + REQUIRE_THROW_WITH_VALUE(op, name, "j-"); + REQUIRE_THROW_WITH_VALUE(op, name, "-j"); + REQUIRE_THROW_WITH_VALUE(op, name, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + REQUIRE_THROW_WITH_VALUE(op, name, "aaaa."); + REQUIRE_THROW_WITH_VALUE(op, name, ".aaaa"); + REQUIRE_THROW_WITH_VALUE(op, options.voting_account, account_id_type(999999999)); + + auto auth_bak = op.owner; + op.owner.add_authority(account_id_type(9999999999), 10); + trx.operations.back() = op; + op.owner = auth_bak; + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); + op.owner = auth_bak; + + trx.operations.back() = op; + sign( trx, init_account_priv_key ); + trx.validate(); + PUSH_TX( db, trx, ~0 ); + + const account_object& nathan_account = *db.get_index_type().indices().get().find("nathan"); + BOOST_CHECK(nathan_account.id.space() == protocol_ids); + BOOST_CHECK(nathan_account.id.type() == account_object_type); + BOOST_CHECK(nathan_account.name == "nathan"); + + BOOST_REQUIRE(nathan_account.owner.num_auths() == 1); + BOOST_CHECK(nathan_account.owner.key_auths.at(committee_key) == 123); + BOOST_REQUIRE(nathan_account.active.num_auths() == 1); + BOOST_CHECK(nathan_account.active.key_auths.at(committee_key) == 321); + BOOST_CHECK(nathan_account.options.voting_account == GRAPHENE_PROXY_TO_SELF_ACCOUNT); + BOOST_CHECK(nathan_account.options.memo_key == committee_key); + + const account_statistics_object& statistics = nathan_account.statistics(db); + BOOST_CHECK(statistics.id.space() == implementation_ids); + BOOST_CHECK(statistics.id.type() == impl_account_statistics_object_type); + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( issue_uia ) +{ + try { + INVOKE(create_uia); + INVOKE(create_account_test); + + const asset_object& test_asset = *db.get_index_type().indices().get().find("TEST"); + const account_object& nathan_account = *db.get_index_type().indices().get().find("nathan"); + + asset_issue_operation op; + op.issuer = test_asset.issuer; + op.asset_to_issue = test_asset.amount(5000000); + op.issue_to_account = nathan_account.id; + trx.operations.push_back(op); + + REQUIRE_THROW_WITH_VALUE(op, asset_to_issue, asset(200)); + REQUIRE_THROW_WITH_VALUE(op, fee, asset(-1)); + REQUIRE_THROW_WITH_VALUE(op, issue_to_account, account_id_type(999999999)); + + trx.operations.back() = op; + PUSH_TX( db, trx, ~0 ); + + const asset_dynamic_data_object& test_dynamic_data = test_asset.dynamic_asset_data_id(db); + BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 5000000); + BOOST_CHECK(test_dynamic_data.current_supply == 5000000); + BOOST_CHECK(test_dynamic_data.accumulated_fees == 0); + BOOST_CHECK(test_dynamic_data.fee_pool == 0); + + PUSH_TX( db, trx, ~0 ); + + BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 10000000); + BOOST_CHECK(test_dynamic_data.current_supply == 10000000); + BOOST_CHECK(test_dynamic_data.accumulated_fees == 0); + BOOST_CHECK(test_dynamic_data.fee_pool == 0); + } catch(fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + + +BOOST_AUTO_TEST_CASE( taker_sells_1to1 ) +{ try { + return; + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order( seller_account, core_asset.amount(50), test_asset.amount(100) )->id; + limit_order_id_type second_id = create_sell_order( seller_account, core_asset.amount(100), test_asset.amount(100) )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order( buyer_account, test_asset.amount(100), core_asset.amount(100) ); + //print_market( "", "" ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( !unmatched ); + + //APM + //sell_asset nathan 400 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 4 (bts) + //sell_asset nathan 300 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 3 + //sell_asset nathan 300 BTS 600 TEST 100000 false true <-- buyer SELL 300 TEST @ 2 + //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 150 /*200*/ ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 198 /*297*/ ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 2 /*3*/ ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9800 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_sells_small_lot_too_low ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(150), test_asset.amount(100), true )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(11), core_asset.amount(5), false ); + //print_market( "", "" ); + BOOST_CHECK( db.find( first_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( !unmatched ); + + //APM + //sell_asset nathan 150 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 1.50 (bts) + //sell_asset nathan 11 TEST 5 BTS 100000 false true <-- buyer SELL 11 TEST @ 0.454545 + //expected result: 11 TEST filled @1.5 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 11 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 16 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9989 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_buys_small_lot_too_high ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(80), false )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9900 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(15), test_asset.amount(11), true ); + //print_market( "", "" ); + BOOST_CHECK( db.find( first_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( !unmatched ); + + //APM + //sell_asset nathan 100 TEST 80 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.80 (bts) + //sell_asset nathan 15 CORE 11 TEST 100000 false true <-- seller BUY 11 TEST @ 1.363636 + //expected result: 11 TEST filled @0.80 + // buyer is selling TEST buying CORE + // seller is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 11 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 9 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9991 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9900 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_sells_above_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(400), test_asset.amount(100), true )->id; + limit_order_id_type second_id = create_sell_order_with_flag( seller_account, core_asset.amount(300), test_asset.amount(100), true )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9300 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(300), core_asset.amount(600), true ); + //print_market( "", "" ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 400 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 4 (bts) + //sell_asset nathan 300 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 3 + //sell_asset nathan 300 TEST 600 BTS 100000 false true <-- buyer SELL 300 TEST @ 2 + //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 693 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 7 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9300 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + + + +BOOST_AUTO_TEST_CASE( taker_sells_below_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(25), test_asset.amount(100), false )->id; + limit_order_id_type second_id = create_sell_order_with_flag( seller_account, core_asset.amount(50), test_asset.amount(100), false )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9925 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(300), core_asset.amount(50), false ); + //print_market( "", "" ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 25 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 0.25 (bts) + //sell_asset nathan 50 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 0.50 + //sell_asset nathan 300 BTS 150 TEST 100000 false true <-- buyer SELL 300 TEST @0.16667 + //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 75 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9925 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + + +BOOST_AUTO_TEST_CASE( taker_buys_below_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(25), false )->id; + limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(50), false )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(275), test_asset.amount(300), false ); + //print_market( "", "" ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 100 TEST 25 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.25 (bts) + //sell_asset nathan 100 TEST 50 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.50 + //sell_asset nathan 275 BTS 300 TEST 100000 false true <-- seller BUY 275 TEST @0.916667 + //expected result: 100 TEST filled @0.25, 100 TEST filled @0.50, remainder: 100 TEST bid @0.916667 + // buyer is selling TEST buying CORE + // seller is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 75 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9725 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_buys_above_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(400), true )->id; + limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(300), true )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(1500), test_asset.amount(300), true ); + //print_market( "", "" ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 100 TEST 400 BTS 100000 false true <-- seller SELL 100 TEST @ 4 (bts) + //sell_asset nathan 100 TEST 300 BTS 100000 false true <-- seller SELL 100 TEST @ 3 + //sell_asset nathan 1500 BTS 300 TEST 100000 false true <-- buyer BUY 300 TEST @ 5 + //expected result: 100 TEST filled @3, 100 TEST filled @4, remainder: 100 TEST bid @5 + // seller is selling TEST buying CORE + // buyer is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 693 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 7 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 8800 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( create_buy_uia_multiple_match_new ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(100), true )->id; + limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(200), true )->id; + limit_order_id_type third_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(300), true )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + + //print_market( "", "" ); + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(300), test_asset.amount(150), true ); + //print_market( "", "" ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( db.find( second_id ) ); + BOOST_CHECK( db.find( third_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( !unmatched ); + + //APM + //sell_asset nathan 100 TEST 100 BTS 100000 false true <-- buyer SELL 100 TEST @ 1 (bts) + //sell_asset nathan 100 TEST 200 BTS 100000 false true <-- buyer SELL 100 TEST @ 2 (bts) + //sell_asset nathan 100 TEST 300 BTS 100000 false true <-- buyer SELL 100 TEST @ 3 (bts) + //sell_asset nathan 300 BTS 150 TEST 100000 false true <-- seller BUY 150 TEST @ 2 (bts) + //expected result: 100 TEST filled @1, 50 TEST filled @2 + // buyer is selling TEST buying CORE + // seller is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 150 /*200*/ ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 198 /*297*/ ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 2 /*3*/ ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9800 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + + +BOOST_AUTO_TEST_CASE( whalehole_test_1 ) +{ try { + ACTORS((buyer)(seller)(borrower)(borrower2)(feedproducer)); + + int64_t init_balance(1000000); + transfer(committee_account, buyer_id, asset(init_balance)); + + transfer(committee_account, seller_id, asset(init_balance)); + + asset_id_type core_id = db.get_index().get_next_id(); + asset_create_operation creator; + creator.issuer = account_id_type(); //buyer.get_id(); + creator.fee = asset(); + creator.symbol = "CORE"; + creator.common_options.max_supply = 100000000; + creator.precision = 8; + creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ + //creator.common_options.issuer_permissions = charge_market_fee|white_list|override_authority|transfer_restricted|disable_confidential; + //creator.common_options.flags = charge_market_fee|white_list|override_authority|disable_confidential; + creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); + //creator.common_options.whitelist_authorities.insert(buyer); + //creator.common_options.whitelist_authorities.insert(seller); + //creator.common_options.whitelist_authorities = creator.common_options.blacklist_authorities = {account_id_type()}; + trx.operations.push_back(std::move(creator)); + PUSH_TX( db, trx, ~0 ); + trx.clear(); + + const asset_object& core = core_id(db); + + asset_id_type whalehole_id = db.get_index().get_next_id(); + //asset_create_operation creator; + creator.issuer = account_id_type(); //buyer.get_id(); + creator.fee = asset(); + creator.symbol = "WHALEHOLE"; + creator.common_options.max_supply = 100000000; + creator.precision = 0; + creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ + //creator1.common_options.issuer_permissions = charge_market_fee|white_list|override_authority|transfer_restricted|disable_confidential; + //creator1.common_options.flags = charge_market_fee|white_list|override_authority|disable_confidential; + creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); + //creator1.common_options.whitelist_authorities.insert(buyer); + //creator1.common_options.whitelist_authorities.insert(seller); + //creator1.common_options.whitelist_authorities = creator1.common_options.blacklist_authorities = {account_id_type()}; + trx.operations.push_back(std::move(creator)); + PUSH_TX( db, trx, ~0 ); + trx.clear(); + + const asset_object& whalehole = whalehole_id(db); + + asset_id_type mole_id = db.get_index().get_next_id(); + //asset_create_operation creator; + creator.issuer = account_id_type(); //buyer.get_id(); + creator.fee = asset(); + creator.symbol = "MOLE"; + creator.common_options.max_supply = 100000000; + creator.precision = 4; + creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ + //creator1.common_options.issuer_permissions = charge_market_fee|white_list|override_authority|transfer_restricted|disable_confidential; + //creator1.common_options.flags = charge_market_fee|white_list|override_authority|disable_confidential; + creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); + //creator1.common_options.whitelist_authorities.insert(buyer); + //creator1.common_options.whitelist_authorities.insert(seller); + //creator1.common_options.whitelist_authorities = creator1.common_options.blacklist_authorities = {account_id_type()}; + trx.operations.push_back(std::move(creator)); + PUSH_TX( db, trx, ~0 ); + trx.clear(); + + const asset_object& mole = mole_id(db); + + //const auto& bitusd = create_bitasset("USDBIT", feedproducer_id); + //const auto& test = asset_id_type()(db); + + + + asset usd_pays, usd_receives, core_pays, core_receives; + price match_price; + //price ask_core = price(asset(80,whalehole_id), asset(480,core_id)); + //price bid_usd = price(asset(21,core_id), asset(2,whalehole_id)); + + // bid-taker + limit_order_object ask_core = limit_order_object(); + ask_core.seller = seller.get_id(); + ask_core.sell_price = price(asset(80,whalehole_id), asset(480,core_id)); + ask_core.for_sale = 80; + limit_order_object bid_usd = limit_order_object(); + bid_usd.seller = buyer.get_id(); + bid_usd.sell_price = price(asset(21,core_id), asset(2,whalehole_id)); + bid_usd.for_sale = 21; + match_price = ask_core.sell_price; + + // ask-taker + /*limit_order_object bid_usd = limit_order_object(); + bid_usd.seller = seller.get_id(); + bid_usd.sell_price = price(asset(80,whalehole_id), asset(480,core_id)); + bid_usd.for_sale = 80; + limit_order_object ask_core = limit_order_object(); + ask_core.seller = buyer.get_id(); + ask_core.sell_price = price(asset(21,core_id), asset(2,whalehole_id)); + ask_core.for_sale = 21; + match_price = bid_usd.sell_price;*/ + + + auto usd_for_sale = bid_usd.amount_for_sale(); + auto core_for_sale = ask_core.amount_for_sale(); + + double real_match_price = match_price.to_real(); + double real_order_price = bid_usd.sell_price.to_real(); + double real_book_price = ask_core.sell_price.to_real(); + int64_t usd_max_counter_size = round(bid_usd.amount_to_receive().amount.value / real_book_price); + if (usd_max_counter_size < usd_for_sale.amount) usd_for_sale.amount = usd_max_counter_size; + int64_t core_max_counter_size = round(ask_core.amount_to_receive().amount.value * real_book_price); + if (core_max_counter_size < core_for_sale.amount) core_for_sale.amount = core_max_counter_size; + + idump((usd_max_counter_size)); + idump((usd_for_sale)); + + idump((core_max_counter_size)); + idump((core_for_sale)); + + idump((ask_core)); + idump((bid_usd)); + idump((match_price)); + + if( usd_for_sale <= core_for_sale * match_price ) + { + core_receives = usd_for_sale; + usd_receives = usd_for_sale * match_price; + } + else + { + //This line once read: assert( core_for_sale < usd_for_sale * match_price ); + //This assert is not always true -- see trade_amount_equals_zero in operation_tests.cpp + //Although usd_for_sale is greater than core_for_sale * match_price, core_for_sale == usd_for_sale * match_price + //Removing the assert seems to be safe -- apparently no asset is created or destroyed. + usd_receives = core_for_sale; + core_receives = core_for_sale * match_price; + } + core_pays = usd_receives; + usd_pays = core_receives; + + idump((core_receives)); + idump((usd_receives)); + idump((core_pays)); + idump((usd_pays)); + + bool result = false; + + //step 1 is in match(), step 2 is in fill_order() + + double real_taker_price = bid_usd.sell_price.to_real(); + int64_t real_taker_over = round(usd_receives.amount.value * real_taker_price) - usd_pays.amount.value; + bid_usd.for_sale -= usd_pays.amount; + ask_core.for_sale -= core_pays.amount; + if (real_taker_over > 0) bid_usd.for_sale -= real_taker_over; + + idump((bid_usd)); + idump((ask_core)); + + //try { result |= db.fill_order( bid_usd, usd_pays, usd_receives, false ); } catch(...) {} + //try { result |= db.fill_order( ask_core, core_pays, core_receives, true ) << 1; } catch(...) {} + + + issue_uia(buyer, core.amount(10000000)); + issue_uia(buyer, whalehole.amount(10000)); + issue_uia(buyer, mole.amount(10000000)); + issue_uia(seller, core.amount(10000000)); + issue_uia(seller, whalehole.amount(10000)); + issue_uia(seller, mole.amount(10000000)); + + + auto order = create_sell_order( buyer, asset(925,core_id), asset(1,mole_id)); + order = create_sell_order( seller, asset(950,mole_id), asset(1,core_id)); + order = create_sell_order( seller, asset(9393000,mole_id), asset(101,core_id)); + + //auto order = create_sell_order( seller, asset(480,core_id), asset(80,whalehole_id)); + //order = create_sell_order( buyer, asset(4,whalehole_id), asset(20,core_id)); + //order = create_sell_order( buyer, asset(2,whalehole_id), asset(17,core_id)); + order = create_sell_order( seller, asset(80,whalehole_id), asset(480,core_id)); + order = create_sell_order( buyer, asset(20,core_id), asset(4,whalehole_id)); + order = create_sell_order( buyer, asset(17,core_id), asset(2,whalehole_id)); + order = create_sell_order( buyer, asset(21,core_id), asset(2,whalehole_id)); + + order = create_sell_order( seller, asset(2,whalehole_id), asset(20,core_id)); + order = create_sell_order( seller, asset(5,whalehole_id), asset(20,core_id)); + + + ilog("done!"); + + } catch( const fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + + + +// TODO: Write linear VBO tests + +BOOST_AUTO_TEST_SUITE_END() + From 03902b631e56e67da8c4d0c7637fb6827a9cf8c1 Mon Sep 17 00:00:00 2001 From: Alexander Morris Date: Fri, 11 Aug 2017 13:33:20 -0400 Subject: [PATCH 5/8] slight correction in taker_buys_small_lot_too_high test after rounding adjustment --- tests/mytests/optest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/mytests/optest.cpp b/tests/mytests/optest.cpp index 56255d1d95..ede4976389 100644 --- a/tests/mytests/optest.cpp +++ b/tests/mytests/optest.cpp @@ -310,7 +310,7 @@ BOOST_AUTO_TEST_CASE( taker_buys_small_lot_too_high ) //print_market( "", "" ); BOOST_CHECK( db.find( first_id ) ); if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( !unmatched ); + BOOST_CHECK( unmatched ); //APM //sell_asset nathan 100 TEST 80 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.80 (bts) @@ -318,10 +318,10 @@ BOOST_AUTO_TEST_CASE( taker_buys_small_lot_too_high ) //expected result: 11 TEST filled @0.80 // buyer is selling TEST buying CORE // seller is buying TEST selling CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 11 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 9 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 10 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 8 ); BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9991 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9990 ); BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9900 ); } catch ( const fc::exception& e ) From e29d66f177e6bd345b7f1f84b4a9c4c48cf40f92 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Sat, 12 Aug 2017 09:59:38 +0200 Subject: [PATCH 6/8] Refactored Alex's tests into market_tests --- tests/CMakeLists.txt | 4 - tests/mytests/optest.cpp | 775 ----------------------------------- tests/tests/market_tests.cpp | 500 ++++++++++++++++++++++ 3 files changed, 500 insertions(+), 779 deletions(-) delete mode 100644 tests/mytests/optest.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b6d1640a11..7edc54bd41 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,7 +30,3 @@ add_executable( intense_test ${INTENSE_SOURCES} ${COMMON_SOURCES} ) target_link_libraries( intense_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) add_subdirectory( generate_empty_blocks ) - -file(GLOB OP_TESTS "mytests/*.cpp") -add_executable( optest ${OP_TESTS} ${COMMON_SOURCES} ) -target_link_libraries( optest graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc graphene_wallet ${PLATFORM_SPECIFIC_LIBS} ) diff --git a/tests/mytests/optest.cpp b/tests/mytests/optest.cpp deleted file mode 100644 index ede4976389..0000000000 --- a/tests/mytests/optest.cpp +++ /dev/null @@ -1,775 +0,0 @@ -/* - * Copyright (c) 2015 Cryptonomex, Inc., and contributors. - * - * The MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#define BOOST_TEST_MODULE Test Application -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../common/database_fixture.hpp" - -using namespace graphene::chain; -using namespace graphene::chain::test; - -BOOST_FIXTURE_TEST_SUITE( operation_tests, database_fixture ) - -//exec: /home/vm/bitshares-core/tests/optest -//workdir: /home/vm/bitshares-core/tests/ - - -BOOST_AUTO_TEST_CASE( create_uia ) -{ - try { - asset_id_type test_asset_id = db.get_index().get_next_id(); - asset_create_operation creator; - creator.issuer = account_id_type(); - creator.fee = asset(); - creator.symbol = "TEST"; - creator.common_options.max_supply = 100000000; - creator.precision = 2; - creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ - creator.common_options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK; - creator.common_options.flags = charge_market_fee; - creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); - trx.operations.push_back(std::move(creator)); - PUSH_TX( db, trx, ~0 ); - - const asset_object& test_asset = test_asset_id(db); - BOOST_CHECK(test_asset.symbol == "TEST"); - BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2)); - BOOST_CHECK((test_asset.options.flags & white_list) == 0); - BOOST_CHECK(test_asset.options.max_supply == 100000000); - BOOST_CHECK(!test_asset.bitasset_data_id.valid()); - BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100); - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); - - const asset_dynamic_data_object& test_asset_dynamic_data = test_asset.dynamic_asset_data_id(db); - BOOST_CHECK(test_asset_dynamic_data.current_supply == 0); - BOOST_CHECK(test_asset_dynamic_data.accumulated_fees == 0); - BOOST_CHECK(test_asset_dynamic_data.fee_pool == 0); - - auto op = trx.operations.back().get(); - op.symbol = "TESTFAIL"; - REQUIRE_THROW_WITH_VALUE(op, issuer, account_id_type(99999999)); - REQUIRE_THROW_WITH_VALUE(op, common_options.max_supply, -1); - REQUIRE_THROW_WITH_VALUE(op, common_options.max_supply, 0); - REQUIRE_THROW_WITH_VALUE(op, symbol, "A"); - REQUIRE_THROW_WITH_VALUE(op, symbol, "qqq"); - REQUIRE_THROW_WITH_VALUE(op, symbol, "11"); - REQUIRE_THROW_WITH_VALUE(op, symbol, ".AAA"); - REQUIRE_THROW_WITH_VALUE(op, symbol, "AAA."); - REQUIRE_THROW_WITH_VALUE(op, symbol, "AB CD"); - REQUIRE_THROW_WITH_VALUE(op, symbol, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price({asset(-100), asset(1)})); - REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price({asset(100),asset(-1)})); - } catch(fc::exception& e) { - edump((e.to_detail_string())); - throw; - } -} - -BOOST_AUTO_TEST_CASE( create_account_test ) -{ - try { - trx.operations.push_back(make_account()); - account_create_operation op = trx.operations.back().get(); - - REQUIRE_THROW_WITH_VALUE(op, registrar, account_id_type(9999999)); - REQUIRE_THROW_WITH_VALUE(op, fee, asset(-1)); - REQUIRE_THROW_WITH_VALUE(op, name, "!"); - REQUIRE_THROW_WITH_VALUE(op, name, "Sam"); - REQUIRE_THROW_WITH_VALUE(op, name, "saM"); - REQUIRE_THROW_WITH_VALUE(op, name, "sAm"); - REQUIRE_THROW_WITH_VALUE(op, name, "6j"); - REQUIRE_THROW_WITH_VALUE(op, name, "j-"); - REQUIRE_THROW_WITH_VALUE(op, name, "-j"); - REQUIRE_THROW_WITH_VALUE(op, name, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - REQUIRE_THROW_WITH_VALUE(op, name, "aaaa."); - REQUIRE_THROW_WITH_VALUE(op, name, ".aaaa"); - REQUIRE_THROW_WITH_VALUE(op, options.voting_account, account_id_type(999999999)); - - auto auth_bak = op.owner; - op.owner.add_authority(account_id_type(9999999999), 10); - trx.operations.back() = op; - op.owner = auth_bak; - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); - op.owner = auth_bak; - - trx.operations.back() = op; - sign( trx, init_account_priv_key ); - trx.validate(); - PUSH_TX( db, trx, ~0 ); - - const account_object& nathan_account = *db.get_index_type().indices().get().find("nathan"); - BOOST_CHECK(nathan_account.id.space() == protocol_ids); - BOOST_CHECK(nathan_account.id.type() == account_object_type); - BOOST_CHECK(nathan_account.name == "nathan"); - - BOOST_REQUIRE(nathan_account.owner.num_auths() == 1); - BOOST_CHECK(nathan_account.owner.key_auths.at(committee_key) == 123); - BOOST_REQUIRE(nathan_account.active.num_auths() == 1); - BOOST_CHECK(nathan_account.active.key_auths.at(committee_key) == 321); - BOOST_CHECK(nathan_account.options.voting_account == GRAPHENE_PROXY_TO_SELF_ACCOUNT); - BOOST_CHECK(nathan_account.options.memo_key == committee_key); - - const account_statistics_object& statistics = nathan_account.statistics(db); - BOOST_CHECK(statistics.id.space() == implementation_ids); - BOOST_CHECK(statistics.id.type() == impl_account_statistics_object_type); - } catch (fc::exception& e) { - edump((e.to_detail_string())); - throw; - } -} - -BOOST_AUTO_TEST_CASE( issue_uia ) -{ - try { - INVOKE(create_uia); - INVOKE(create_account_test); - - const asset_object& test_asset = *db.get_index_type().indices().get().find("TEST"); - const account_object& nathan_account = *db.get_index_type().indices().get().find("nathan"); - - asset_issue_operation op; - op.issuer = test_asset.issuer; - op.asset_to_issue = test_asset.amount(5000000); - op.issue_to_account = nathan_account.id; - trx.operations.push_back(op); - - REQUIRE_THROW_WITH_VALUE(op, asset_to_issue, asset(200)); - REQUIRE_THROW_WITH_VALUE(op, fee, asset(-1)); - REQUIRE_THROW_WITH_VALUE(op, issue_to_account, account_id_type(999999999)); - - trx.operations.back() = op; - PUSH_TX( db, trx, ~0 ); - - const asset_dynamic_data_object& test_dynamic_data = test_asset.dynamic_asset_data_id(db); - BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 5000000); - BOOST_CHECK(test_dynamic_data.current_supply == 5000000); - BOOST_CHECK(test_dynamic_data.accumulated_fees == 0); - BOOST_CHECK(test_dynamic_data.fee_pool == 0); - - PUSH_TX( db, trx, ~0 ); - - BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 10000000); - BOOST_CHECK(test_dynamic_data.current_supply == 10000000); - BOOST_CHECK(test_dynamic_data.accumulated_fees == 0); - BOOST_CHECK(test_dynamic_data.fee_pool == 0); - } catch(fc::exception& e) { - edump((e.to_detail_string())); - throw; - } -} - - -BOOST_AUTO_TEST_CASE( taker_sells_1to1 ) -{ try { - return; - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order( seller_account, core_asset.amount(50), test_asset.amount(100) )->id; - limit_order_id_type second_id = create_sell_order( seller_account, core_asset.amount(100), test_asset.amount(100) )->id; - - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order( buyer_account, test_asset.amount(100), core_asset.amount(100) ); - //print_market( "", "" ); - BOOST_CHECK( !db.find( first_id ) ); - BOOST_CHECK( !db.find( second_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( !unmatched ); - - //APM - //sell_asset nathan 400 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 4 (bts) - //sell_asset nathan 300 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 3 - //sell_asset nathan 300 BTS 600 TEST 100000 false true <-- buyer SELL 300 TEST @ 2 - //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 - // seller is buying TEST selling CORE - // buyer is selling TEST buying CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 150 /*200*/ ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 198 /*297*/ ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 2 /*3*/ ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9800 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - -BOOST_AUTO_TEST_CASE( taker_sells_small_lot_too_low ) -{ try { - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(150), test_asset.amount(100), true )->id; - - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(11), core_asset.amount(5), false ); - //print_market( "", "" ); - BOOST_CHECK( db.find( first_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( !unmatched ); - - //APM - //sell_asset nathan 150 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 1.50 (bts) - //sell_asset nathan 11 TEST 5 BTS 100000 false true <-- buyer SELL 11 TEST @ 0.454545 - //expected result: 11 TEST filled @1.5 - // seller is buying TEST selling CORE - // buyer is selling TEST buying CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 11 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 16 ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9989 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - -BOOST_AUTO_TEST_CASE( taker_buys_small_lot_too_high ) -{ try { - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(80), false )->id; - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9900 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(15), test_asset.amount(11), true ); - //print_market( "", "" ); - BOOST_CHECK( db.find( first_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( unmatched ); - - //APM - //sell_asset nathan 100 TEST 80 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.80 (bts) - //sell_asset nathan 15 CORE 11 TEST 100000 false true <-- seller BUY 11 TEST @ 1.363636 - //expected result: 11 TEST filled @0.80 - // buyer is selling TEST buying CORE - // seller is buying TEST selling CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 10 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 8 ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9990 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9900 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - -BOOST_AUTO_TEST_CASE( taker_sells_above_1 ) -{ try { - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(400), test_asset.amount(100), true )->id; - limit_order_id_type second_id = create_sell_order_with_flag( seller_account, core_asset.amount(300), test_asset.amount(100), true )->id; - - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9300 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(300), core_asset.amount(600), true ); - //print_market( "", "" ); - BOOST_CHECK( !db.find( first_id ) ); - BOOST_CHECK( !db.find( second_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( unmatched ); - - //APM - //sell_asset nathan 400 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 4 (bts) - //sell_asset nathan 300 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 3 - //sell_asset nathan 300 TEST 600 BTS 100000 false true <-- buyer SELL 300 TEST @ 2 - //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 - // seller is buying TEST selling CORE - // buyer is selling TEST buying CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 693 ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 7 ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9300 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - - - -BOOST_AUTO_TEST_CASE( taker_sells_below_1 ) -{ try { - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(25), test_asset.amount(100), false )->id; - limit_order_id_type second_id = create_sell_order_with_flag( seller_account, core_asset.amount(50), test_asset.amount(100), false )->id; - - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9925 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(300), core_asset.amount(50), false ); - //print_market( "", "" ); - BOOST_CHECK( !db.find( first_id ) ); - BOOST_CHECK( !db.find( second_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( unmatched ); - - //APM - //sell_asset nathan 25 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 0.25 (bts) - //sell_asset nathan 50 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 0.50 - //sell_asset nathan 300 BTS 150 TEST 100000 false true <-- buyer SELL 300 TEST @0.16667 - //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 - // seller is buying TEST selling CORE - // buyer is selling TEST buying CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 75 ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9925 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - - -BOOST_AUTO_TEST_CASE( taker_buys_below_1 ) -{ try { - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(25), false )->id; - limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(50), false )->id; - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(275), test_asset.amount(300), false ); - //print_market( "", "" ); - BOOST_CHECK( !db.find( first_id ) ); - BOOST_CHECK( !db.find( second_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( unmatched ); - - //APM - //sell_asset nathan 100 TEST 25 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.25 (bts) - //sell_asset nathan 100 TEST 50 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.50 - //sell_asset nathan 275 BTS 300 TEST 100000 false true <-- seller BUY 275 TEST @0.916667 - //expected result: 100 TEST filled @0.25, 100 TEST filled @0.50, remainder: 100 TEST bid @0.916667 - // buyer is selling TEST buying CORE - // seller is buying TEST selling CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 75 ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9725 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - -BOOST_AUTO_TEST_CASE( taker_buys_above_1 ) -{ try { - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(400), true )->id; - limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(300), true )->id; - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(1500), test_asset.amount(300), true ); - //print_market( "", "" ); - BOOST_CHECK( !db.find( first_id ) ); - BOOST_CHECK( !db.find( second_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( unmatched ); - - //APM - //sell_asset nathan 100 TEST 400 BTS 100000 false true <-- seller SELL 100 TEST @ 4 (bts) - //sell_asset nathan 100 TEST 300 BTS 100000 false true <-- seller SELL 100 TEST @ 3 - //sell_asset nathan 1500 BTS 300 TEST 100000 false true <-- buyer BUY 300 TEST @ 5 - //expected result: 100 TEST filled @3, 100 TEST filled @4, remainder: 100 TEST bid @5 - // seller is selling TEST buying CORE - // buyer is buying TEST selling CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 693 ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 7 ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 8800 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - -BOOST_AUTO_TEST_CASE( create_buy_uia_multiple_match_new ) -{ try { - INVOKE( issue_uia ); - const asset_object& core_asset = get_asset( "TEST" ); - const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); - const account_object& nathan_account = get_account( "nathan" ); - const account_object& buyer_account = create_account( "buyer" ); - const account_object& seller_account = create_account( "seller" ); - - transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); - transfer( nathan_account, seller_account, core_asset.amount(10000) ); - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); - - limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(100), true )->id; - limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(200), true )->id; - limit_order_id_type third_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(300), true )->id; - - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); - - //print_market( "", "" ); - auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(300), test_asset.amount(150), true ); - //print_market( "", "" ); - BOOST_CHECK( !db.find( first_id ) ); - BOOST_CHECK( db.find( second_id ) ); - BOOST_CHECK( db.find( third_id ) ); - if( unmatched ) wdump((*unmatched)); - BOOST_CHECK( !unmatched ); - - //APM - //sell_asset nathan 100 TEST 100 BTS 100000 false true <-- buyer SELL 100 TEST @ 1 (bts) - //sell_asset nathan 100 TEST 200 BTS 100000 false true <-- buyer SELL 100 TEST @ 2 (bts) - //sell_asset nathan 100 TEST 300 BTS 100000 false true <-- buyer SELL 100 TEST @ 3 (bts) - //sell_asset nathan 300 BTS 150 TEST 100000 false true <-- seller BUY 150 TEST @ 2 (bts) - //expected result: 100 TEST filled @1, 50 TEST filled @2 - // buyer is selling TEST buying CORE - // seller is buying TEST selling CORE - BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 150 /*200*/ ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 198 /*297*/ ); - BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 2 /*3*/ ); - BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9800 ); - BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); - } - catch ( const fc::exception& e ) - { - elog( "${e}", ("e", e.to_detail_string() ) ); - throw; - } -} - - -BOOST_AUTO_TEST_CASE( whalehole_test_1 ) -{ try { - ACTORS((buyer)(seller)(borrower)(borrower2)(feedproducer)); - - int64_t init_balance(1000000); - transfer(committee_account, buyer_id, asset(init_balance)); - - transfer(committee_account, seller_id, asset(init_balance)); - - asset_id_type core_id = db.get_index().get_next_id(); - asset_create_operation creator; - creator.issuer = account_id_type(); //buyer.get_id(); - creator.fee = asset(); - creator.symbol = "CORE"; - creator.common_options.max_supply = 100000000; - creator.precision = 8; - creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ - //creator.common_options.issuer_permissions = charge_market_fee|white_list|override_authority|transfer_restricted|disable_confidential; - //creator.common_options.flags = charge_market_fee|white_list|override_authority|disable_confidential; - creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); - //creator.common_options.whitelist_authorities.insert(buyer); - //creator.common_options.whitelist_authorities.insert(seller); - //creator.common_options.whitelist_authorities = creator.common_options.blacklist_authorities = {account_id_type()}; - trx.operations.push_back(std::move(creator)); - PUSH_TX( db, trx, ~0 ); - trx.clear(); - - const asset_object& core = core_id(db); - - asset_id_type whalehole_id = db.get_index().get_next_id(); - //asset_create_operation creator; - creator.issuer = account_id_type(); //buyer.get_id(); - creator.fee = asset(); - creator.symbol = "WHALEHOLE"; - creator.common_options.max_supply = 100000000; - creator.precision = 0; - creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ - //creator1.common_options.issuer_permissions = charge_market_fee|white_list|override_authority|transfer_restricted|disable_confidential; - //creator1.common_options.flags = charge_market_fee|white_list|override_authority|disable_confidential; - creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); - //creator1.common_options.whitelist_authorities.insert(buyer); - //creator1.common_options.whitelist_authorities.insert(seller); - //creator1.common_options.whitelist_authorities = creator1.common_options.blacklist_authorities = {account_id_type()}; - trx.operations.push_back(std::move(creator)); - PUSH_TX( db, trx, ~0 ); - trx.clear(); - - const asset_object& whalehole = whalehole_id(db); - - asset_id_type mole_id = db.get_index().get_next_id(); - //asset_create_operation creator; - creator.issuer = account_id_type(); //buyer.get_id(); - creator.fee = asset(); - creator.symbol = "MOLE"; - creator.common_options.max_supply = 100000000; - creator.precision = 4; - creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ - //creator1.common_options.issuer_permissions = charge_market_fee|white_list|override_authority|transfer_restricted|disable_confidential; - //creator1.common_options.flags = charge_market_fee|white_list|override_authority|disable_confidential; - creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); - //creator1.common_options.whitelist_authorities.insert(buyer); - //creator1.common_options.whitelist_authorities.insert(seller); - //creator1.common_options.whitelist_authorities = creator1.common_options.blacklist_authorities = {account_id_type()}; - trx.operations.push_back(std::move(creator)); - PUSH_TX( db, trx, ~0 ); - trx.clear(); - - const asset_object& mole = mole_id(db); - - //const auto& bitusd = create_bitasset("USDBIT", feedproducer_id); - //const auto& test = asset_id_type()(db); - - - - asset usd_pays, usd_receives, core_pays, core_receives; - price match_price; - //price ask_core = price(asset(80,whalehole_id), asset(480,core_id)); - //price bid_usd = price(asset(21,core_id), asset(2,whalehole_id)); - - // bid-taker - limit_order_object ask_core = limit_order_object(); - ask_core.seller = seller.get_id(); - ask_core.sell_price = price(asset(80,whalehole_id), asset(480,core_id)); - ask_core.for_sale = 80; - limit_order_object bid_usd = limit_order_object(); - bid_usd.seller = buyer.get_id(); - bid_usd.sell_price = price(asset(21,core_id), asset(2,whalehole_id)); - bid_usd.for_sale = 21; - match_price = ask_core.sell_price; - - // ask-taker - /*limit_order_object bid_usd = limit_order_object(); - bid_usd.seller = seller.get_id(); - bid_usd.sell_price = price(asset(80,whalehole_id), asset(480,core_id)); - bid_usd.for_sale = 80; - limit_order_object ask_core = limit_order_object(); - ask_core.seller = buyer.get_id(); - ask_core.sell_price = price(asset(21,core_id), asset(2,whalehole_id)); - ask_core.for_sale = 21; - match_price = bid_usd.sell_price;*/ - - - auto usd_for_sale = bid_usd.amount_for_sale(); - auto core_for_sale = ask_core.amount_for_sale(); - - double real_match_price = match_price.to_real(); - double real_order_price = bid_usd.sell_price.to_real(); - double real_book_price = ask_core.sell_price.to_real(); - int64_t usd_max_counter_size = round(bid_usd.amount_to_receive().amount.value / real_book_price); - if (usd_max_counter_size < usd_for_sale.amount) usd_for_sale.amount = usd_max_counter_size; - int64_t core_max_counter_size = round(ask_core.amount_to_receive().amount.value * real_book_price); - if (core_max_counter_size < core_for_sale.amount) core_for_sale.amount = core_max_counter_size; - - idump((usd_max_counter_size)); - idump((usd_for_sale)); - - idump((core_max_counter_size)); - idump((core_for_sale)); - - idump((ask_core)); - idump((bid_usd)); - idump((match_price)); - - if( usd_for_sale <= core_for_sale * match_price ) - { - core_receives = usd_for_sale; - usd_receives = usd_for_sale * match_price; - } - else - { - //This line once read: assert( core_for_sale < usd_for_sale * match_price ); - //This assert is not always true -- see trade_amount_equals_zero in operation_tests.cpp - //Although usd_for_sale is greater than core_for_sale * match_price, core_for_sale == usd_for_sale * match_price - //Removing the assert seems to be safe -- apparently no asset is created or destroyed. - usd_receives = core_for_sale; - core_receives = core_for_sale * match_price; - } - core_pays = usd_receives; - usd_pays = core_receives; - - idump((core_receives)); - idump((usd_receives)); - idump((core_pays)); - idump((usd_pays)); - - bool result = false; - - //step 1 is in match(), step 2 is in fill_order() - - double real_taker_price = bid_usd.sell_price.to_real(); - int64_t real_taker_over = round(usd_receives.amount.value * real_taker_price) - usd_pays.amount.value; - bid_usd.for_sale -= usd_pays.amount; - ask_core.for_sale -= core_pays.amount; - if (real_taker_over > 0) bid_usd.for_sale -= real_taker_over; - - idump((bid_usd)); - idump((ask_core)); - - //try { result |= db.fill_order( bid_usd, usd_pays, usd_receives, false ); } catch(...) {} - //try { result |= db.fill_order( ask_core, core_pays, core_receives, true ) << 1; } catch(...) {} - - - issue_uia(buyer, core.amount(10000000)); - issue_uia(buyer, whalehole.amount(10000)); - issue_uia(buyer, mole.amount(10000000)); - issue_uia(seller, core.amount(10000000)); - issue_uia(seller, whalehole.amount(10000)); - issue_uia(seller, mole.amount(10000000)); - - - auto order = create_sell_order( buyer, asset(925,core_id), asset(1,mole_id)); - order = create_sell_order( seller, asset(950,mole_id), asset(1,core_id)); - order = create_sell_order( seller, asset(9393000,mole_id), asset(101,core_id)); - - //auto order = create_sell_order( seller, asset(480,core_id), asset(80,whalehole_id)); - //order = create_sell_order( buyer, asset(4,whalehole_id), asset(20,core_id)); - //order = create_sell_order( buyer, asset(2,whalehole_id), asset(17,core_id)); - order = create_sell_order( seller, asset(80,whalehole_id), asset(480,core_id)); - order = create_sell_order( buyer, asset(20,core_id), asset(4,whalehole_id)); - order = create_sell_order( buyer, asset(17,core_id), asset(2,whalehole_id)); - order = create_sell_order( buyer, asset(21,core_id), asset(2,whalehole_id)); - - order = create_sell_order( seller, asset(2,whalehole_id), asset(20,core_id)); - order = create_sell_order( seller, asset(5,whalehole_id), asset(20,core_id)); - - - ilog("done!"); - - } catch( const fc::exception& e) { - edump((e.to_detail_string())); - throw; - } -} - - - -// TODO: Write linear VBO tests - -BOOST_AUTO_TEST_SUITE_END() - diff --git a/tests/tests/market_tests.cpp b/tests/tests/market_tests.cpp index 9f6cc81de0..c3d451fb8d 100644 --- a/tests/tests/market_tests.cpp +++ b/tests/tests/market_tests.cpp @@ -122,4 +122,504 @@ BOOST_AUTO_TEST_CASE(issue_338) BOOST_CHECK_EQUAL( 14733, call.collateral.value ); } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( create_uia ) +{ + try { + asset_id_type test_asset_id = db.get_index().get_next_id(); + asset_create_operation creator; + creator.issuer = account_id_type(); + creator.fee = asset(); + creator.symbol = "TEST"; + creator.common_options.max_supply = 100000000; + creator.precision = 2; + creator.common_options.market_fee_percent = GRAPHENE_MAX_MARKET_FEE_PERCENT/100; /*1%*/ + creator.common_options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK; + creator.common_options.flags = charge_market_fee; + creator.common_options.core_exchange_rate = price({asset(2),asset(1,asset_id_type(1))}); + trx.operations.push_back(std::move(creator)); + PUSH_TX( db, trx, ~0 ); + + const asset_object& test_asset = test_asset_id(db); + BOOST_CHECK(test_asset.symbol == "TEST"); + BOOST_CHECK(asset(1, test_asset_id) * test_asset.options.core_exchange_rate == asset(2)); + BOOST_CHECK((test_asset.options.flags & white_list) == 0); + BOOST_CHECK(test_asset.options.max_supply == 100000000); + BOOST_CHECK(!test_asset.bitasset_data_id.valid()); + BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100); + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); + + const asset_dynamic_data_object& test_asset_dynamic_data = test_asset.dynamic_asset_data_id(db); + BOOST_CHECK(test_asset_dynamic_data.current_supply == 0); + BOOST_CHECK(test_asset_dynamic_data.accumulated_fees == 0); + BOOST_CHECK(test_asset_dynamic_data.fee_pool == 0); + + auto op = trx.operations.back().get(); + op.symbol = "TESTFAIL"; + REQUIRE_THROW_WITH_VALUE(op, issuer, account_id_type(99999999)); + REQUIRE_THROW_WITH_VALUE(op, common_options.max_supply, -1); + REQUIRE_THROW_WITH_VALUE(op, common_options.max_supply, 0); + REQUIRE_THROW_WITH_VALUE(op, symbol, "A"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "qqq"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "11"); + REQUIRE_THROW_WITH_VALUE(op, symbol, ".AAA"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "AAA."); + REQUIRE_THROW_WITH_VALUE(op, symbol, "AB CD"); + REQUIRE_THROW_WITH_VALUE(op, symbol, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price({asset(-100), asset(1)})); + REQUIRE_THROW_WITH_VALUE(op, common_options.core_exchange_rate, price({asset(100),asset(-1)})); + } catch(fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( create_account_test ) +{ + try { + trx.operations.push_back(make_account()); + account_create_operation op = trx.operations.back().get(); + + REQUIRE_THROW_WITH_VALUE(op, registrar, account_id_type(9999999)); + REQUIRE_THROW_WITH_VALUE(op, fee, asset(-1)); + REQUIRE_THROW_WITH_VALUE(op, name, "!"); + REQUIRE_THROW_WITH_VALUE(op, name, "Sam"); + REQUIRE_THROW_WITH_VALUE(op, name, "saM"); + REQUIRE_THROW_WITH_VALUE(op, name, "sAm"); + REQUIRE_THROW_WITH_VALUE(op, name, "6j"); + REQUIRE_THROW_WITH_VALUE(op, name, "j-"); + REQUIRE_THROW_WITH_VALUE(op, name, "-j"); + REQUIRE_THROW_WITH_VALUE(op, name, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + REQUIRE_THROW_WITH_VALUE(op, name, "aaaa."); + REQUIRE_THROW_WITH_VALUE(op, name, ".aaaa"); + REQUIRE_THROW_WITH_VALUE(op, options.voting_account, account_id_type(999999999)); + + auto auth_bak = op.owner; + op.owner.add_authority(account_id_type(9999999999), 10); + trx.operations.back() = op; + op.owner = auth_bak; + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); + op.owner = auth_bak; + + trx.operations.back() = op; + sign( trx, init_account_priv_key ); + trx.validate(); + PUSH_TX( db, trx, ~0 ); + + const account_object& nathan_account = *db.get_index_type().indices().get().find("nathan"); + BOOST_CHECK(nathan_account.id.space() == protocol_ids); + BOOST_CHECK(nathan_account.id.type() == account_object_type); + BOOST_CHECK(nathan_account.name == "nathan"); + + BOOST_REQUIRE(nathan_account.owner.num_auths() == 1); + BOOST_CHECK(nathan_account.owner.key_auths.at(committee_key) == 123); + BOOST_REQUIRE(nathan_account.active.num_auths() == 1); + BOOST_CHECK(nathan_account.active.key_auths.at(committee_key) == 321); + BOOST_CHECK(nathan_account.options.voting_account == GRAPHENE_PROXY_TO_SELF_ACCOUNT); + BOOST_CHECK(nathan_account.options.memo_key == committee_key); + + const account_statistics_object& statistics = nathan_account.statistics(db); + BOOST_CHECK(statistics.id.space() == implementation_ids); + BOOST_CHECK(statistics.id.type() == impl_account_statistics_object_type); + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( issue_uia ) +{ + try { + INVOKE(create_uia); + INVOKE(create_account_test); + + const asset_object& test_asset = *db.get_index_type().indices().get().find("TEST"); + const account_object& nathan_account = *db.get_index_type().indices().get().find("nathan"); + + asset_issue_operation op; + op.issuer = test_asset.issuer; + op.asset_to_issue = test_asset.amount(5000000); + op.issue_to_account = nathan_account.id; + trx.operations.push_back(op); + + REQUIRE_THROW_WITH_VALUE(op, asset_to_issue, asset(200)); + REQUIRE_THROW_WITH_VALUE(op, fee, asset(-1)); + REQUIRE_THROW_WITH_VALUE(op, issue_to_account, account_id_type(999999999)); + + trx.operations.back() = op; + PUSH_TX( db, trx, ~0 ); + + const asset_dynamic_data_object& test_dynamic_data = test_asset.dynamic_asset_data_id(db); + BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 5000000); + BOOST_CHECK(test_dynamic_data.current_supply == 5000000); + BOOST_CHECK(test_dynamic_data.accumulated_fees == 0); + BOOST_CHECK(test_dynamic_data.fee_pool == 0); + + PUSH_TX( db, trx, ~0 ); + + BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 10000000); + BOOST_CHECK(test_dynamic_data.current_supply == 10000000); + BOOST_CHECK(test_dynamic_data.accumulated_fees == 0); + BOOST_CHECK(test_dynamic_data.fee_pool == 0); + } catch(fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_sells_1to1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order( seller_account, core_asset.amount(50), test_asset.amount(100) )->id; + limit_order_id_type second_id = create_sell_order( seller_account, core_asset.amount(100), test_asset.amount(100) )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); + + auto unmatched = create_sell_order( buyer_account, test_asset.amount(100), core_asset.amount(100) ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( !unmatched ); + + //APM + //sell_asset nathan 400 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 4 (bts) + //sell_asset nathan 300 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 3 + //sell_asset nathan 300 BTS 600 TEST 100000 false true <-- buyer SELL 300 TEST @ 2 + //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 150 /*200*/ ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 198 /*297*/ ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 2 /*3*/ ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9800 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_sells_small_lot_too_low ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(150), test_asset.amount(100), true )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); + + auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(11), core_asset.amount(5), false ); + BOOST_CHECK( db.find( first_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( !unmatched ); + + //APM + //sell_asset nathan 150 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 1.50 (bts) + //sell_asset nathan 11 TEST 5 BTS 100000 false true <-- buyer SELL 11 TEST @ 0.454545 + //expected result: 11 TEST filled @1.5 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 11 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 16 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9850 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9989 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_buys_small_lot_too_high ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(80), false )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9900 ); + + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(15), test_asset.amount(11), true ); + BOOST_CHECK( db.find( first_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 100 TEST 80 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.80 (bts) + //sell_asset nathan 15 CORE 11 TEST 100000 false true <-- seller BUY 11 TEST @ 1.363636 + //expected result: 11 TEST filled @0.80 + // buyer is selling TEST buying CORE + // seller is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 10 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 8 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9990 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9900 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_sells_above_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(400), test_asset.amount(100), true )->id; + limit_order_id_type second_id = create_sell_order_with_flag( seller_account, core_asset.amount(300), test_asset.amount(100), true )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9300 ); + + auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(300), core_asset.amount(600), true ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 400 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 4 (bts) + //sell_asset nathan 300 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 3 + //sell_asset nathan 300 TEST 600 BTS 100000 false true <-- buyer SELL 300 TEST @ 2 + //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 693 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 7 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9300 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_sells_below_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( seller_account, core_asset.amount(25), test_asset.amount(100), false )->id; + limit_order_id_type second_id = create_sell_order_with_flag( seller_account, core_asset.amount(50), test_asset.amount(100), false )->id; + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9925 ); + + auto unmatched = create_sell_order_with_flag( buyer_account, test_asset.amount(300), core_asset.amount(50), false ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 25 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 0.25 (bts) + //sell_asset nathan 50 BTS 100 TEST 100000 false true <-- seller BUY 100 TEST @ 0.50 + //sell_asset nathan 300 BTS 150 TEST 100000 false true <-- buyer SELL 300 TEST @0.16667 + //expected result: 100 TEST filled @0.50, 100 TEST filled @0.25, remainder: 100 TEST offered @0.16667 + // seller is buying TEST selling CORE + // buyer is selling TEST buying CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 75 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9925 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_buys_below_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(25), false )->id; + limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(50), false )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(275), test_asset.amount(300), false ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 100 TEST 25 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.25 (bts) + //sell_asset nathan 100 TEST 50 BTS 100000 false true <-- buyer SELL 100 TEST @ 0.50 + //sell_asset nathan 275 BTS 300 TEST 100000 false true <-- seller BUY 275 TEST @0.916667 + //expected result: 100 TEST filled @0.25, 100 TEST filled @0.50, remainder: 100 TEST bid @0.916667 + // buyer is selling TEST buying CORE + // seller is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 75 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 0 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9725 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( taker_buys_above_1 ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(400), true )->id; + limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(300), true )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(1500), test_asset.amount(300), true ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( !db.find( second_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( unmatched ); + + //APM + //sell_asset nathan 100 TEST 400 BTS 100000 false true <-- seller SELL 100 TEST @ 4 (bts) + //sell_asset nathan 100 TEST 300 BTS 100000 false true <-- seller SELL 100 TEST @ 3 + //sell_asset nathan 1500 BTS 300 TEST 100000 false true <-- buyer BUY 300 TEST @ 5 + //expected result: 100 TEST filled @3, 100 TEST filled @4, remainder: 100 TEST bid @5 + // seller is selling TEST buying CORE + // buyer is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 200 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 693 ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 7 ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 8800 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9800 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} + +BOOST_AUTO_TEST_CASE( create_buy_uia_multiple_match_new ) +{ try { + INVOKE( issue_uia ); + const asset_object& core_asset = get_asset( "TEST" ); + const asset_object& test_asset = get_asset( GRAPHENE_SYMBOL ); + const account_object& nathan_account = get_account( "nathan" ); + const account_object& buyer_account = create_account( "buyer" ); + const account_object& seller_account = create_account( "seller" ); + + transfer( committee_account(db), buyer_account, test_asset.amount( 10000 ) ); + transfer( nathan_account, seller_account, core_asset.amount(10000) ); + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 10000 ); + + limit_order_id_type first_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(100), true )->id; + limit_order_id_type second_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(200), true )->id; + limit_order_id_type third_id = create_sell_order_with_flag( buyer_account, test_asset.amount(100), core_asset.amount(300), true )->id; + + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + + auto unmatched = create_sell_order_with_flag( seller_account, core_asset.amount(300), test_asset.amount(150), true ); + BOOST_CHECK( !db.find( first_id ) ); + BOOST_CHECK( db.find( second_id ) ); + BOOST_CHECK( db.find( third_id ) ); + if( unmatched ) wdump((*unmatched)); + BOOST_CHECK( !unmatched ); + + //APM + //sell_asset nathan 100 TEST 100 BTS 100000 false true <-- buyer SELL 100 TEST @ 1 (bts) + //sell_asset nathan 100 TEST 200 BTS 100000 false true <-- buyer SELL 100 TEST @ 2 (bts) + //sell_asset nathan 100 TEST 300 BTS 100000 false true <-- buyer SELL 100 TEST @ 3 (bts) + //sell_asset nathan 300 BTS 150 TEST 100000 false true <-- seller BUY 150 TEST @ 2 (bts) + //expected result: 100 TEST filled @1, 50 TEST filled @2 + // buyer is selling TEST buying CORE + // seller is buying TEST selling CORE + BOOST_CHECK_EQUAL( get_balance( seller_account, test_asset ), 150 /*200*/ ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, core_asset ), 198 /*297*/ ); + BOOST_CHECK_EQUAL( core_asset.dynamic_asset_data_id(db).accumulated_fees.value , 2 /*3*/ ); + BOOST_CHECK_EQUAL( get_balance( seller_account, core_asset ), 9800 ); + BOOST_CHECK_EQUAL( get_balance( buyer_account, test_asset ), 9700 ); + } + catch ( const fc::exception& e ) + { + elog( "${e}", ("e", e.to_detail_string() ) ); + throw; + } +} BOOST_AUTO_TEST_SUITE_END() From 5ac0bd8eb0553ff02031e89c5ead0de1a18823e4 Mon Sep 17 00:00:00 2001 From: Alexander Morris Date: Fri, 11 Aug 2017 09:54:27 -0400 Subject: [PATCH 7/8] adds create_sell_order_with_flag() --- tests/common/database_fixture.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index ff98c423ab..b8582b450f 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -709,6 +709,26 @@ const limit_order_object* database_fixture::create_sell_order( const account_obj return db.find( processed.operation_results[0].get() ); } +//APM --> (for TESTS, adds above1 flag via expiration field in order to indicate if expected order price is trading above or below 1 +const limit_order_object* database_fixture::create_sell_order_with_flag( const account_object& user, const asset& amount, const asset& recv, bool above1 ) +{ + //wdump((amount)(recv)); + limit_order_create_operation buy_order; + buy_order.seller = user.id; + buy_order.amount_to_sell = amount; + buy_order.min_to_receive = recv; + if (above1) buy_order.expiration = buy_order.expiration.maximum()-1000; else + buy_order.expiration = buy_order.expiration.maximum()-1001; + trx.operations.push_back(buy_order); + for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); + trx.validate(); + auto processed = db.push_transaction(trx, ~0); + trx.operations.clear(); + verify_asset_supplies(db); + //wdump((processed)); + return db.find( processed.operation_results[0].get() ); +} + asset database_fixture::cancel_limit_order( const limit_order_object& order ) { limit_order_cancel_operation cancel_order; From 7b4b91a5c19e0c5029a634b30bb3e495ec151cd5 Mon Sep 17 00:00:00 2001 From: Alexander Morris Date: Fri, 11 Aug 2017 09:56:09 -0400 Subject: [PATCH 8/8] adds reference to create_sell_order_with_flag() --- tests/common/database_fixture.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index ec5e9bd7d7..49e8f7ed98 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -263,6 +263,7 @@ struct database_fixture { void sign( signed_transaction& trx, const fc::ecc::private_key& key ); const limit_order_object* create_sell_order( account_id_type user, const asset& amount, const asset& recv ); const limit_order_object* create_sell_order( const account_object& user, const asset& amount, const asset& recv ); + const limit_order_object* create_sell_order_with_flag( const account_object& user, const asset& amount, const asset& recv, bool above1 ); asset cancel_limit_order( const limit_order_object& order ); void transfer( account_id_type from, account_id_type to, const asset& amount, const asset& fee = asset() ); void transfer( const account_object& from, const account_object& to, const asset& amount, const asset& fee = asset() );