Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Limit Order Modification Feature #2743

Merged
merged 31 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
61d85de
Progress #1604: Basic implementation
nathanielhourt Feb 21, 2019
f6bbe4b
Progress #1604: Tests and Fixes
nathanielhourt Feb 22, 2019
5484c9f
Ref #1604: Add matching logic
nathanielhourt Feb 22, 2019
3d24f7c
Progress #1604: Add dust check
nathanielhourt Feb 26, 2019
073ecbe
Progress #1604: Add hardfork guards
nathanielhourt Feb 26, 2019
a34c855
Ref #1604: Another test case
nathanielhourt Feb 26, 2019
fba5bac
Progress #1604: Do not allow sooner expiration
nathanielhourt Feb 27, 2019
8a82d92
Add fee_schedule::exists<op_type>()
nathanielhourt Feb 27, 2019
6180946
Ref #1604: Add missing hardfork guard
nathanielhourt Feb 27, 2019
55dc688
Eliminate variable fee
nathanielhourt Oct 7, 2019
a71cfe4
Merge hardfork branch, fix build and tests
abitmore Apr 29, 2023
a03b4ce
Fix issues about limit_order_update_evaluator
abitmore May 8, 2023
44e6de4
Do not allow inappropriate price manipulation
abitmore May 9, 2023
2387df3
Remove redundant checks for order matching
abitmore May 9, 2023
2b3bcd3
Remove redundant checks for account balance
abitmore May 9, 2023
e8e9d0d
Simplify try-catch wrappers in tests
abitmore May 9, 2023
136007e
Update tests to adapt code changes
abitmore May 10, 2023
cf2fca6
Remove mostly useless try/catch wrappers
abitmore May 10, 2023
9160a7e
Add tests for limit_order_update_operation
abitmore May 10, 2023
c58db0b
Fix potential dereferencing issues in tests
abitmore May 10, 2023
85bef43
Add asset authorization tests for order_update op
abitmore May 10, 2023
afcff0d
Update a comment and an assertion message
abitmore May 10, 2023
dfce7c6
Update default order update fee
abitmore May 11, 2023
8898b5a
Process operation fees
abitmore May 11, 2023
269a16d
Reduce log level of exceptions in order_update_op
abitmore May 11, 2023
032f125
Update a comment
abitmore May 12, 2023
663ecd9
Move deferred fee processing code into a function
abitmore May 12, 2023
d381110
Add tests for order_update fee if paid in CORE
abitmore May 12, 2023
1195df5
Add tests for order_update fee if not paid in CORE
abitmore May 12, 2023
2a34e1b
Update variable names to fix variable shadowing
abitmore May 15, 2023
126987e
Update a comment
abitmore May 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Ref #1604: Add matching logic
Add logic to match an updated limit order if the price is changed to be
higher than the previous top-of-book price.

I believe this completes #1604
  • Loading branch information
nathanielhourt committed Feb 27, 2019
commit 5484c9f9efd103eb0a899ee9e65460f464163e9f
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ namespace graphene { namespace chain {
void_result do_apply(const limit_order_update_operation& o);

const limit_order_object* _order = nullptr;
bool should_match_orders = false;
};

class limit_order_cancel_evaluator : public evaluator<limit_order_cancel_evaluator>
Expand Down
26 changes: 19 additions & 7 deletions libraries/chain/market_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,21 @@ void_result limit_order_update_evaluator::do_evaluate(const limit_order_update_o
// Check this is my order
FC_ASSERT(o.seller == _order->seller, "Cannot update someone else's order");

// Check new price is compatible
if (o.new_price)
FC_ASSERT(o.new_price->base.asset_id == _order->sell_price.base.asset_id &&
o.new_price->quote.asset_id == _order->sell_price.quote.asset_id,
// Check new price is compatible, and determine whether it becomes the best offer on the market
if (o.new_price) {
auto base_id = o.new_price->base.asset_id;
auto quote_id = o.new_price->quote.asset_id;
FC_ASSERT(base_id == _order->sell_price.base.asset_id && quote_id == _order->sell_price.quote.asset_id,
"Cannot update limit order with incompatible price");
const auto& order_index = d.get_index_type<limit_order_index>().indices().get<by_price>();
auto top_of_book = order_index.upper_bound(boost::make_tuple(price::max(base_id, quote_id)));
FC_ASSERT(top_of_book->sell_price.base.asset_id == base_id && top_of_book->sell_price.quote.asset_id == quote_id,
"Paradox: attempting to update an order in a market that has no orders? There's a logic error somewhere.");

// If the new price of our order is greater than the price of the order at the top of the book, we should match orders at the end.
// Otherwise, we can skip matching because there's no way this change could trigger orders to fill.
should_match_orders = (*o.new_price > top_of_book->sell_price);
}

// Check delta asset is compatible
if (o.delta_amount_to_sell) {
Expand All @@ -156,7 +166,7 @@ void_result limit_order_update_evaluator::do_evaluate(const limit_order_update_o
FC_ASSERT(*o.new_expiration >= d.head_block_time(),
"Cannot update limit order with past expiration");

return void_result();
return {};
} FC_CAPTURE_AND_RETHROW((o)) }

void_result limit_order_update_evaluator::do_apply(const limit_order_update_operation& o)
Expand All @@ -182,9 +192,11 @@ void_result limit_order_update_evaluator::do_apply(const limit_order_update_oper
loo.expiration = *o.new_expiration;
});

// TODO: check if order is at front of book and price moved in favor of buyer; if so, trigger matching
// Perform order matching if necessary
if (should_match_orders)
d.apply_order(*_order);

return void_result();
return {};
} FC_CAPTURE_AND_RETHROW((o)) }

void_result limit_order_cancel_evaluator::do_evaluate(const limit_order_cancel_operation& o)
Expand Down
4 changes: 1 addition & 3 deletions libraries/chain/protocol/market.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,4 @@ void bid_collateral_operation::validate()const
FC_ASSERT( debt_covered.amount == 0 || (debt_covered.amount > 0 && additional_collateral.amount > 0) );
} FC_CAPTURE_AND_RETHROW((*this)) }

}

} // graphene::chain
} } // graphene::chain
44 changes: 44 additions & 0 deletions tests/tests/operation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,50 @@ BOOST_AUTO_TEST_CASE(limit_order_update_test)
}
}

BOOST_AUTO_TEST_CASE(limit_order_update_match_test)
{
try {
ACTORS((nathan));
const auto& munee = create_user_issued_asset("MUNEE");

transfer(committee_account, nathan_id, asset(10000));
issue_uia(nathan, munee.amount(1000));

auto expiration = db.head_block_time() + 1000;
limit_order_id_type order_id_1 = create_sell_order(nathan, asset(999), munee.amount(100), expiration)->id;
limit_order_id_type order_id_2 = create_sell_order(nathan, munee.amount(100), asset(1001), expiration)->id;

update_limit_order(order_id_1, price(asset(1001), munee.amount(100)), asset(1));
BOOST_REQUIRE_EQUAL(db.find(order_id_1), nullptr);
BOOST_REQUIRE_EQUAL(db.find(order_id_2)->amount_for_sale().amount.value, 1);
} catch (fc::exception& e) {
edump((e.to_detail_string()));
throw;
}
}

BOOST_AUTO_TEST_CASE(limit_order_update_match_test_2)
{
try {
ACTORS((nathan));
const auto& munee = create_user_issued_asset("MUNEE");

transfer(committee_account, nathan_id, asset(10000));
issue_uia(nathan, munee.amount(1000));

auto expiration = db.head_block_time() + 1000;
limit_order_id_type order_id_1 = create_sell_order(nathan, asset(999), munee.amount(100), expiration)->id;
limit_order_id_type order_id_2 = create_sell_order(nathan, munee.amount(100), asset(1001), expiration)->id;

update_limit_order(order_id_2, price(munee.amount(100), asset(999)));
BOOST_REQUIRE_EQUAL(db.find(order_id_1), nullptr);
BOOST_REQUIRE_EQUAL(db.find(order_id_2), nullptr);
} catch (fc::exception& e) {
edump((e.to_detail_string()));
throw;
}
}

BOOST_AUTO_TEST_CASE( call_order_update_test )
{
try {
Expand Down