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

tatanka: Add orderbook. #3115

Open
JoeGruffins opened this issue Dec 9, 2024 · 3 comments
Open

tatanka: Add orderbook. #3115

JoeGruffins opened this issue Dec 9, 2024 · 3 comments

Comments

@JoeGruffins
Copy link
Member

WIP

https://github.com/decred/dcrdex/blob/master/tatanka/spec/meshdex.md contains most of the guidelines we have so far and should be read first.

Some more points about orders from matrix:
Lot size is defined per-order based on the user's desired maximum fee exposure, and must be a power of 2.
Rate step is always 1 atom / atom equivalent
All orders are limit orders, so no marketBuyBuffer is required
All orders will have an expiration time shortly into the future, and must be refreshed by the orderer
Probably no epochs

The server does not have anything to do with the orderbook, it is only kept by clients. This issue currently aims to figure out the protocol to use to keep clients synchronized.

@JoeGruffins
Copy link
Member Author

JoeGruffins commented Dec 10, 2024

User requests orderbook per market they are interested in and subscribes to those. They are also expected to participate in sharing all order info on those markets.

Clients can request all order ids or individual orders from other clients. When requesting all orders, it's just the order ids, no info. They may be divided into several sends.

orderbook res

type OrderBook struct {
    Page       uint64      `json:"page"` // from 0
    NPages      uin64       `json:"npages"`
    OrderIDs   []order.ID  `json:"orderids"`
}

On the subscription channel, only individual order changes are broadcast. Orders can be created or updated. updated includes qty changing/cancellation and the timeout being extended. Messages for orders are signed with the private key matching the user's PeerID or ignored. The signature should be passed along with the update and saved with it. Update requests should contain all info so that a listener could eventually know the whole book contents after all timeouts have happened.

Quantity can be moved up or down, no need to add settled amount.
Cancel is inferred by quantity set to zero. There's no difference between canceling an order and declaring everything settled.

order update

type OrderUpdate struct {
    Sig     []byte       `json:"sig"`
    Order   *tanka.Order `json:"order"` // updated status
}

Multiple orders (up to some limit) can also be requested. In that case they would be requested by id and they would get a slice of OrderUpdate from the user.

When a user decides to match an order, they send messages directly to that peer and start negotiation. The maker will update their order if the taker meets their requirements.

Some thoughts:

  • Things we may want to check on order updates: signature, lotSize is divisible by a power of two, expiration is not over some time or in the past
  • We want to check user reputations at some point, maybe for every time expiration is updated? We maybe should save it along with the match. I don't guess we would share it though with the match? The user will want to ask the tatanka servers I guess.
  • Do we want to tell users to prefer older matches on the books? imo it's impossible for us to police and we shouldn't worry about it. It's impossible to police because maybe a user is avoiding another one based on local reputation. I don't think we can prove or disprove some arbitrary reason for choosing an order. But should we match based on oldest with bisonw? Or match randomly just because? I think probably we look at order price/qty first, ofc, then out of those we look at reputation next, then we just go with the oldest order that satisfies our needs. I think we would prefer a newer order over two older orders with different users, as that means less transactions for us. However I could see how that might seem "unfair" and maybe leave some traders with orders that never get filled if they are too small. I guess the answer for that maker is to make the order cheaper, or become a taker.
  • A user will miss some order updates. Maybe they should periodically ask some users for their orders list to see if they are missing some.
  • Expired orders are immediately forgotten. If requests come for an order we don't have, we assume it expired. We do need to save data for candles, but this should be another subscription and issue I think.
  • Only users with interest in a market subscribe to it, and only those users can be asked for orders. Is this good enough, or do all clients need to worry about all markets so that they can distribute data? Probably not?
  • All this means that taker orders are never on the book.
  • If two makers create orders that would match, that is on them to notice and work it out with one becoming the taker. In that case the "taker" would be on the books in a way, but we wouldn't know which was doing which when the trade happens.

@dev-warrior777
Copy link
Contributor

Copying my chat comment:
"latency will be a key issue but I think can assume within 1s most will have heard a broadcast"
Maybe this is a good assumption to work with

@buck54321
Copy link
Member

User requests orderbook per market they are interested in and subscribes to those. They are also expected to participate in sharing all order info on those markets.

How about when the user subscribes to the orderbook (subject), the mesh will send a new_subscriber broadcast to other subscribers, and the other subscribers who have standing orders can message the user.

lotSize is divisible by two

Lot size should be a power of 2, e.g. 2^N for some integer N.

From the user's perspective, lot size is presented as **maximum fee exposure", which is translated to lot size behind the scenes. The variable lot size also means we need to introduce some conception of "visibility", since some orders on the book may not be compatible with the user's current setting. We want to track those orders anyway, so that the user can modify their setting without having to resync the book. This visibility will be a challenge, because say a user has a fee exposure setting that translates to a lot size of 100, while an order on the books has a lot size of 50, but has 2 lots available. We could still match that order, but with the stipulation that we must match both lots.

We want to check user reputations at some point, maybe for every time expiration is updated? We maybe should save it along with the match. I don't guess we would share it though with the match? The user will want to ask the tatanka servers I guess.

Yeah this will be interested to figure out. We should talk about the concept of "funded messages" or "funded broadcasts", where the server validates the funding backing an order, and attaches that validation, in some form, to the message. They could also attach the users current reputation to the message.

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

No branches or pull requests

3 participants