Use hourly liquidation events when constructing DLCs #2378
Conversation
45ea3eb
to
24077e4
Compare
24077e4
to
eef1ae8
Compare
b02e9e7
to
91100f8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might have missed it: what's the expectation of how the contract is liquidated? Is the monitoring
taking care of it?
xtra-libp2p-rollover/src/maker.rs
Outdated
let oracle_pk = self.oracle_pk; | ||
let n_payouts = self.n_payouts; | ||
async move { | ||
let Rates { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we will need to add a ttl
or similar to the rates.
This is needed in case the automation died/is not functioning. Otherwise we might be rolling over with outdated rates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose you're implying that because we removed the intermediate confirmation step on the maker for rolling over, we don't check that the automaker
is up before rolling over. And if it is up we understand that the offer must be up-to-date.
I would argue that the current state of affairs of assuming that the offer is up-to-date simply because the automaker
is up is not much safer than not checking anything at all. Nevertheless, I do think we should introduce a safety mechanism. But I would recommend doing in a separate PR, since this one is quite big already and the situation is not significantly worse with this work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose you're implying that because we removed the intermediate confirmation step on the maker for rolling over, we don't check that the automaker is up before rolling over. And if it is up we understand that the offer must be up-to-date.
yes, this was what I thought :)
I think a follow-up PR is fine given the size of this PR. Can you make sure to create a ticket for that once this is merged please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: #2531.
91100f8
to
5cb86ff
Compare
Yes, I think so. My understanding is that before this PR we monitored all of With these changes we have added more attestations to monitor. But the process that occurs after finding an attestation that decrypts a CET is the same: ensure that the CFD is closed with the given CET. |
5cb86ff
to
187cb6f
Compare
I've addressed your comments, @bonomat. Thanks for your review! I've force-pushed, but you can use the I'm only mentioning it because I only recently discovered this. It makes force-pushing a lot safer for reviewers. |
This makes sense. Do you think it would be worth adding a different monitoring agent which monitors the price movement instead? Particularly for collaboratively liquidation this could be useful. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work and very clean commits. It's a shame that we can't use it yet because setup_contract::new
is not used. Do you want to merge this PR anyway or hold back until it is actually being used?
In case it's not clear, we can use dynamic liquidation, but only after the first rollover. I think we're okay to merge it, since it should be tested regularly ASAP, and it's useful by itself. Also the longer we wait the more tricky rebases we'll have to do 😁 |
Thanks for the clarification. I think we should get this tested soon and see what implication this has in regards to storage size and performance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great work, thanks for structuring the code into commits.
I think the scope of this PR exploded a bit.
I feel the decision to remove the rollover confirmation could have done separately to keep this contained. There are so many changes that it becomes hard to evaluate if the complete solution is still sane and no bugs sneaked in. Furthermore, rebasing this work onto the recent rollover changes will not be fun. Maybe it would be worth creating smaller PRs that build on each other next time, so some work can alrady make it into master and we don't have such a big changeset?
I will give this another review after the rebase is done - if you can easily split this work up into multiple PRs that focus on refactor / feature to change accept
/ actual new rollover_v2
that would help, but I am not sure it's worth the effort at this stage.
maker/src/routes.rs
Outdated
|
||
#[rocket::post("/rollover-config", data = "<config>")] | ||
#[instrument(name = "POST /rollover-config", skip(maker), err)] | ||
pub async fn update_rollover_configuration( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the motivation of this change? Because we remove the accept
step we need another way to just stop accepting rollovers? What's the use case for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bonomat maybe you can explain why this feature is needed. I feel we never really turned rollovers off, so I wonder if this feature is actually justified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bonomat I'm merging this as is. But we can remove this feature later if it's deemed unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed this comment. We might indeed not need this feature.
maker/src/cfd.rs
Outdated
@@ -589,6 +589,10 @@ impl<O, T, W> Actor<O, T, W> { | |||
} | |||
} | |||
|
|||
// TODO: Because of this we need to have two rollover actor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could actually refactor the old protocol to remove this step as well.
For me the decision if we want to handle accept
in a different way is independent of the liquidation feature and could be in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: think about why this TODO is still here AND attempt to split this PR into:
- One that removes the accept/reject automation step.
- One that extracts the new crate and introduces the liquidation feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As promised:
- Replace rollover confirmation step with configurable flag #2533 removes the maker's rollover confirmation step.
- This PR introduces hourly liquidation events.
fn new(announcements: Vec<olivia::Announcement>) -> Result<Self> { | ||
let announcements = announcements | ||
.into_iter() | ||
.sorted_by(|a, b| a.id.cmp(&b.id)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to sort using the complete BitMexPriceEventId
or should we rather sort by the timestamp
within BitMexPriceEventId
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great comment!
Currently we have derived PartialOrd
on BitMexPriceEventId
and the timestamp
field happens to be the first field, so we are effectively sorting by timestamp. Unless the timestamps are equal, in which case we would compare the digits
. But those are always 20
, given that we always construct them using BitMexPriceEventId::with_20_digits
.
But this is a bad approach, since someone could nonchalantly flip the order of the fields and assume that everything is fine. So I will add a patch fixing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See 46e0890.
I don't fully see what you have in mind. By monitoring But I suppose if we add the feature of collaborative liquidation we will need to look at a regular price feed (the same one that |
bors r+ |
2378: Use hourly liquidation events when constructing DLCs r=luckysori a=luckysori Fix #2299. The diff is misleadingly massive because when introducing the new feature in 35c4e4e I chose to simply duplicate the rollover actor. The old version is used to stay compatible with old takers. In my opinion, the correct approach would be to release different versions of `xtra_libp2p_rollover` as we introduce breaking changes. But this is blocked by being able to release some of the crates in our workspace (and `maia`): #2393. Co-authored-by: Lucas Soriano del Pino <lucas_soriano@fastmail.com>
44aec6c
to
f93c24b
Compare
Canceled. |
637f05c
to
d212712
Compare
bors r+ I'll add the tests in a separate PR. Let's not block this any longer :D |
Merge conflict. |
The main motivation for this change is to be able to support multiple versions of the rollover protocol at the same time, without incurring in lots of duplicated code or increased code complexity due to branching logic. Additionally, I think this should allow us to test this protocol in isolation. I think it's also worth it in terms of the overall structure of the workspace, and could lead to improved compilation times. In my view, the main downside of this approach is that the API of the rollover protocol is slightly more complicated. We can no longer rely on knowing the actors and components that we interact with, because they remain in `daemon`. Instead we depend on 2 new traits: `model::ExecuteOnCfd` and `rollover::GetAnnouncements`. The upside of making the rollover actors generic via these traits is that we can now test this protocol in isolation, as mentioned above.
This is important because deriving `PartialOrd` normally means that it looks at all the struct's fields _in order_. For this type we want to compare the `timestamp`, but do not care about the `digits`! More importantly, someone could unintentionally change this behaviour by reordering the fields. We also have to ignore the `digits` field for other derived traits, because inconsistencies there could cause trouble[1]. [1]: rust-lang/rust-clippy#1621. Co-authored-by: Daniel Karzel <daniel.karzel@coblox.tech>
The new `itchysats/rollover/2.0.0` protocol adds liquidation events to the DLC. In order to preserve backwards compatibility with takers running `itchysats/rollover/1.0.0` we run another rollover actor in parallel for the maker. This leads to a ton of duplicated code, but this technical debt is temporary and contained in the `xtra-libp2p-rollover` crate. The idea is to release all our crates to `crates.io`, so that we can eventually introduce a single cargo dependency per version of a protocol.
Identified using cargo-udeps.
It was not very intuitive to place the identity public keys and the role in the `xtra_libp2p_rollover::PunishParams` struct. Those values are not specific to the punishment mechanism of the DLC.
This code used to assume that we had a single event per CFD when constructing the corresponding DLC. After introducing liquidation events, that is no longer the case. Caveat: this code is currently not used! When we added patch 99e62ba, we chose to only use the deprecated version of this code (in `setup_contract_deprecated.rs`) for the maker and all possible takers. The idea was to then use `setup_contract::new` after adding the contract setup protocol over the new network layer. Since this hasn't happened at the time of writing this message, we cannot test the changes in this patch yet.
d212712
to
f47bcff
Compare
bors retry |
Already running a review |
After the introduction of the `itchysats/order` protocol we can also prove that the CFD includes liquidation events from the moment it is open (not the case when we first merged #2378). When adding these tests we discovered and fixed a bug which was causing us to only generate _short_ liquidation events.
After the introduction of the `itchysats/order` protocol we can also prove that the CFD includes liquidation events from the moment it is open (not the case when we first merged #2378). When adding these tests we discovered and fixed a bug which was causing us to only generate _short_ liquidation events.
After the introduction of the `itchysats/order` protocol we can also prove that the CFD includes liquidation events from the moment it is open (not the case when we first merged #2378). When adding these tests we discovered and fixed a bug which was causing us to only generate _short_ liquidation events.
2570: Add liquidation actor tests r=luckysori a=luckysori After the introduction of the `itchysats/order` protocol we can also prove that the CFD includes liquidation events from the moment it is open (not the case when we first merged #2378). When adding these tests we discovered and fixed a bug which was causing us to only generate _short_ liquidation events. --- I'm gonna create an issue to add more tests based on the `maker_position`, because that determines the shape of the payout curve, which affects the liquidation intervals. Interestingly, here (maker going short) I only check the _long_ liquidation events, because the short liquidation events are pretty useless and hard to test: we have CETs for one specific price (as opposed to an interval for long liquidation CETs). This is because of the way our payout curve is implemented. Co-authored-by: Lucas Soriano del Pino <lucas_soriano@fastmail.com>
Fix #2299.
The diff is misleadingly massive because when introducing the new feature in 35c4e4e I chose to simply duplicate the rollover actor. The old version is used to stay compatible with old takers. In my opinion, the correct approach would be to release different versions of
xtra_libp2p_rollover
as we introduce breaking changes. But this is blocked by being able to release some of the crates in our workspace (andmaia
): #2393.