The primary goal was to remove all of the calls to `serde_json::to_string()`
for the data-handling, thus enabling us to do (more or less):
```rust
Order {
row.column,
...
}
```
as well as clean up the SQL for easier reading. This has mostly been
accomplished, with further refinements easily accomplished once the
upstream issues in `sqlx` are addressed. See #314 for issues we are
tracking.
- Handles the Oracle's attestation in the cfd actor, transition according to the knowledge we have about the timelock expiry already.
- Tries to publish the CET if we are in `CetStatus::Ready`, i.e. both the attestation and timelock expiry happened. We try publishing if either event happened, and just print a log in case it's not ready yet.
- Tries to re-publish CET if we are in `PendingCet` upon restart.
- Re-triggers CET monitoring upon startup.
- Extends any state after `ContractSetup` to be able to store the attestation. (see below for ideas to change that)
Things that could be done different:
Currently we are carrying on the attestation through a lot of states - because we cannot just transition the user to `OpenCommitted` because it is a user decision to go for commit, but we have to keep the attestation around once it happened.
To reduce the state complexity, we could store the attestation independent of the state, but associated with the cfd.
This would make things a lot simpler, but we would then always have to go to the database to check if the attestation is already around (which might make other parts more complex).
The problem was that the restriction on the JOIN clause does not properly filter the complete set, but actually results in wrongly joining the CFDs.
This resulted in two CFDs returned, where one was wrongly assembled (the id of the first one, but the data of the second one).
In a cases where the wrong one is the first one in the list of returned CFDs we would run into an error when inserting a new state, because we would try to alter the state of a wrong CFD.
Fixed by joining on the id and filtering for the order.uuid in the where clause.
Note:
I also tested to add the `and orders.uuid = ?` restriction to the first join clause (in addition to the id clause) which might theoretically be more optimized.
That would work as well, but I found it harder to reason about it. As part of the overall where clause one can see the restriction to exactly this value more clearly.
Includes validating that the amount the other party commits to is the expected amount based on calculating the counterparty margin out of the CFD values.
Note: We could also remove the lock amount from the messages and use the calculation on both sides - that would simplify things.
Flattening the Cfd out in the internal mode has caused duplication and confusion.
This refactor puts the Order into the Cfd to make relations clearer.
Note that once we have multiple leverage the leverage and liquidation price will have to move into the Cfd because they depend on the user's choice then.
This should be trivial to do.
The buy margin is calculated from `initial_price`, `quantity` and `leverage`.
The sell margin is calculated from `initial_price` and `quantity` (no leverage trading for the seller at the moment).
Includes several refactors:
- Separate API interface for `Cfd` and `CfdOffer` when mapping `toSseEvent`. This allows internal modelling to be different than the exposed API.
- Remove the profit calculation internally, it is only relevant on the UI feed API level.
- Move code that is specific to taker/maker http API from `model` to the respective `routes` module.
- Some simplification of the calculation model of `Usd` (could be further improved by deriving calculation traits)
- Introduces `OfferOrigin` used to save the offer's origin as `mine` and `others` in the database. This is used to properly derive the CFD position from the offer.