Added data structures for matching and settlement engine messages
Added tests
Updated benchclient to reflect new data structures
Fixed #11
Fixed #7
Fixed #6
DB Refactor
I've split the DB into a set of interfaces:
SettlementEngine
SettlementEngine has two methods. One method checks whether or not a settlement execution could take place if it were executed (think of this as "can we credit this user X of an asset").
The second method actually executes the settlement execution(s).
AuctionEngine
AuctionEngine is the matching engine for auction orders. It has a place method, a cancel method, and a match method. The match method takes an auction ID as input, since orders cannot be matched cross-auction. This matches according to a clearing price based auction matching algorithm.
LimitEngine
LimitEngine is the matching engine for limit orders. It has a place method, a cancel method, and a match method. This matches according to a price-time priority auction matching algorithm.
AuctionOrderbook
AuctionOrderbook gets updated by the auction matching engine, and is viewable by the user. This also has other methods that may be useful, for example methods to get orders by ID, pubkey, or auction.
LimitOrderbook
LimitOrderbook is very similar to AuctionOrderbook except it does not have methods dependent on a specific auction, since limit orderbooks do not have auctions.
PuzzleStore
PuzzleStore is a simple store for storing timelock puzzles, as well as marking specific timelock puzzles to commit to or match.
DepositStore
DepositStore stores the mapping from pubkey to deposit address. This also keeps track of pending deposits. Pending deposits do not have a fixed number of confirmations, and can be set arbitrarily.
Refactor rationale
Much of the design was inspired by this talk about the JX crossing engine by Brian Nigito at Jane Street. The fundamental difference between the design of JX and this design is that all settlement engine and matching engine operations must be atomic. In the Jane Street example, there is no question of whether or not a user has the funds to execute a trade or place an order. In our system, we do consider this, so that is the reason for the atomicity.
The reason for splitting up the database is because the matching algorithm was previously intertwined with a balance table, the settlement layer for the custodial exchange. This is changed now, the logic for order validation ("Can this order be placed") is within the server rather than in the database layer.
Because settlement and matching are now separate and abstracted, we can interchange them according to market or according to coin. This means we can support custodial trading for one coin, and non custodial for another. This also means we can support front-running resistant order matching for one trading pair, but non front-running resistant order matching for another pair.
The user-viewable and functional pieces of the exchange are now separated as well. This means that the matching engine can focus on placing and matching orders, rather than serving read queries from the user.
This also means that the system for handling deposits is entirely optional. Most importantly, atomic swaps as a settlement layer are now possible.
I haven't yet removed old code from cxdbmemory, but I plan on doing so in the future.
Quick description of changes
benchclient
to reflect new data structuresDB Refactor
I've split the DB into a set of interfaces:
SettlementEngine
SettlementEngine has two methods. One method checks whether or not a settlement execution could take place if it were executed (think of this as "can we credit this user X of an asset"). The second method actually executes the settlement execution(s).
AuctionEngine
AuctionEngine is the matching engine for auction orders. It has a place method, a cancel method, and a match method. The match method takes an auction ID as input, since orders cannot be matched cross-auction. This matches according to a clearing price based auction matching algorithm.
LimitEngine
LimitEngine is the matching engine for limit orders. It has a place method, a cancel method, and a match method. This matches according to a price-time priority auction matching algorithm.
AuctionOrderbook
AuctionOrderbook gets updated by the auction matching engine, and is viewable by the user. This also has other methods that may be useful, for example methods to get orders by ID, pubkey, or auction.
LimitOrderbook
LimitOrderbook is very similar to AuctionOrderbook except it does not have methods dependent on a specific auction, since limit orderbooks do not have auctions.
PuzzleStore
PuzzleStore is a simple store for storing timelock puzzles, as well as marking specific timelock puzzles to commit to or match.
DepositStore
DepositStore stores the mapping from pubkey to deposit address. This also keeps track of pending deposits. Pending deposits do not have a fixed number of confirmations, and can be set arbitrarily.
Refactor rationale
Much of the design was inspired by this talk about the JX crossing engine by Brian Nigito at Jane Street. The fundamental difference between the design of JX and this design is that all settlement engine and matching engine operations must be atomic. In the Jane Street example, there is no question of whether or not a user has the funds to execute a trade or place an order. In our system, we do consider this, so that is the reason for the atomicity.
The reason for splitting up the database is because the matching algorithm was previously intertwined with a balance table, the settlement layer for the custodial exchange. This is changed now, the logic for order validation ("Can this order be placed") is within the server rather than in the database layer. Because settlement and matching are now separate and abstracted, we can interchange them according to market or according to coin. This means we can support custodial trading for one coin, and non custodial for another. This also means we can support front-running resistant order matching for one trading pair, but non front-running resistant order matching for another pair.
The user-viewable and functional pieces of the exchange are now separated as well. This means that the matching engine can focus on placing and matching orders, rather than serving read queries from the user.
This also means that the system for handling deposits is entirely optional. Most importantly, atomic swaps as a settlement layer are now possible.
I haven't yet removed old code from
cxdbmemory
, but I plan on doing so in the future.DB interface implementation status