Skip to content

Conversation

@ma2bd
Copy link
Contributor

@ma2bd ma2bd commented Nov 16, 2025

Motivation

Allow users to display their pending orders without following the entire CLOB appchain

Proposal

  • Add a new type of message and a field of user chains
  • Replace Cancel orders by Modify with new quantity equal to 0
  • Simplify ModifyQuantity to avoid code duplication

Test Plan

CI

Release Plan

  • These changes should be backported to the latest testnet branch

@ma2bd ma2bd changed the title Track pending orders on user chains [matching engine] Track pending orders on user chains Nov 16, 2025
@ma2bd ma2bd force-pushed the clob_ack_messages branch 2 times, most recently from 1a9da86 to 8d5207e Compare November 18, 2025 01:10
@ma2bd ma2bd marked this pull request as ready for review November 18, 2025 01:21
@ma2bd ma2bd requested review from MathieuDutSik and afck November 18, 2025 01:21
@ma2bd ma2bd force-pushed the clob_ack_messages branch from 5523e98 to a731c23 Compare November 18, 2025 01:29
Copy link
Contributor

@MathieuDutSik MathieuDutSik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This design of keeping track of the order structure inside of the Matching Engine is not the standard way that this is done.

What exchanges are publishing are the list of operations. See for example Nasdaq: Computer-To-Computer-Interface.
Then it is the job of the receivers of the information to keep track of he orders and maybe have a nice MapView<AccountOwner, BTreeMap<OrderId, ....>>.

If we follow this design, then what we would do is instead emit events corresponding to the transactions. Then another contract would keep track of those events and of the relevant balances, pending orders, and so on if he so wishes. We have all the functionalities in Linera for that.

Copy link
Contributor

@afck afck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MathieuDutSik: I think what you're suggesting would create a lot more overhead: Each user would have to read all events, rather than get notified about only the messages that concern their own orders.

let cancel_quantity = state_order
.quantity
.try_sub(new_quantity)
.expect("Attempt to increase quantity");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like we should support that, too.

Instead of distinguishing between deleting, reducing and adding an order, why not just have a single operation that sets the quantity for a given price? (Just a thought; not something for this PR!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's what we do in this PR!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we? I can see that it's being unified with canceling an order, but not with creating an order?

let removal_message = Message::OrderUpdated {
owner: filled_owner,
order_id: filled_order_id,
new_quantity: Amount::ZERO,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about partially filled orders?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 253 below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean orders that were already in the book? Apparently we do not support this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think insert_and_uncross_market does partially fill orders. E.g. if there's a single bid in the book with an amount of 10, and I make an ask with an amount of 5 and the same price, my ask will be filled, and the bid will be reduced by 5 but remain in the book.

In that case we should probably send a message to the bidder as well, to notify them that their order was partially filled, i.e. modified?


// Test Cancel order (should always succeed)
let cancel_order = Order::Cancel { owner, order_id: 1 };
// Test order cancellation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I still think this whole test is not really carrying its weight: It just tests different methods that all delegate to the same, simple, precision check, regardless of the order type.)

Comment on lines 98 to +99
/// The map giving for each account owner the set of order_id
/// owned by that owner.
/// owned by that owner (used on the matching engine chain).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The map giving for each account owner the set of order_id
/// owned by that owner.
/// owned by that owner (used on the matching engine chain).
/// The map giving for each account owner the set of order IDs
/// owned by that owner.

@MathieuDutSik
Copy link
Contributor

@MathieuDutSik: I think what you're suggesting would create a lot more overhead: Each user would have to read all events, rather than get notified about only the messages that concern their own orders.

Well,
It depends on what we want to achieve:

  • Typically, when doing transactions, there aren't really that many transactions. The 1M achievement is just that, an achievement that has little relation to real usage. There are about 60K visa card transactions per second. So, the 1M is a little irrelevant. What is more important for payment is the latency.
  • So publishing all the transactions and reading them does not strike me as a bad idea.
  • The inconvenience of accessing pending_orders is that we have to parse the view and the BTreeMap. But yes, the managing of the orders is done by the contract.

@afck
Copy link
Contributor

afck commented Nov 18, 2025

Sure, I'm not against also publishing all transactions in an event stream. I agree that could be useful, and I didn't mean to suggest that the overhead for the network would be large.

I just mean that for an individual user making an order it makes sense to me that there should be a low-overhead way to know their order status. This implementation provides that using a message. Subscribing to and filtering the event stream would be a lot more work for the client.

@ma2bd
Copy link
Contributor Author

ma2bd commented Nov 18, 2025

This design of keeping track of the order structure inside of the Matching Engine is not the standard way that this is done.

I don't understand this comment

  1. We're only modifying the state of the application in user chains (acting as a client)
  2. We're not tracking new information

ma2bd and others added 5 commits November 18, 2025 10:02
Co-authored-by: Andreas Fackler <[email protected]>
Signed-off-by: Mathieu Baudet <[email protected]>
Co-authored-by: Andreas Fackler <[email protected]>
Signed-off-by: Mathieu Baudet <[email protected]>
Co-authored-by: Andreas Fackler <[email protected]>
Signed-off-by: Mathieu Baudet <[email protected]>
Co-authored-by: Andreas Fackler <[email protected]>
Signed-off-by: Mathieu Baudet <[email protected]>
Co-authored-by: Andreas Fackler <[email protected]>
Signed-off-by: Mathieu Baudet <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants