-
Notifications
You must be signed in to change notification settings - Fork 14
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
feat: remove swap and retry batch on price impact #5285
Conversation
7035c1b
to
5612077
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.
Looks good - I want to take another look on Monday but I don't expect any major comments.
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 was wrong - I have some comments :)
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5285 +/- ##
=====================================
- Coverage 70% 70% -0%
=====================================
Files 487 487
Lines 87463 87489 +26
Branches 87463 87489 +26
=====================================
- Hits 61509 61450 -59
- Misses 22672 22755 +83
- Partials 3282 3284 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
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.
Looking good now. I'll give it another pass and try to get it merged tomorrow.
Self::deposit_event(Event::<T>::BatchSwapFailed { | ||
asset, | ||
direction, | ||
amount, | ||
}); |
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.
It might we worth adjusting how we communicate this: the swaps have not longer actually failed, they might be retried. Maybe we don't need this event at all any more?
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 also thought about deleting this. I think this was only used for alterts, but because now these failures no longer block other swaps, this is really no different from "low liquidity" (for which we already have other alerts, I think).
// Abort if we couldn't find a swap to remove; otherwise, remove the | ||
// swap and try again with the remaining swaps: |
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 comment is not quite accurate any more / a bit confusing.
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.
Combined with the expression above and updated the comment.
failed_swaps.extend(violating_swaps); | ||
swaps_to_execute = non_violating_swaps; | ||
}, | ||
Err(BatchExecutionError::DispatchError { error }) => return Err(error), |
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 the only error condition in this loop, and it can only happen if we exceed the the transaction depth limit, right? So am I right in thinking that this function (execute_batch) doesn't need to be transactional (since it can never really error, and never needs to roll back)?
ie. instead of passing this error back up the chain, we could just log it at this level.
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.
Right, I changed this to never return BatchExecutionOutcomes directly now.
pub fn add_liquidity(asset: Asset, amount: AssetAmount) { | ||
let liquidity = Liquidity::get() |
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 was thinking there might be a simpler way to simulate this. We don't need to add amounts etc, we could just configure the mock to behave as if there is no liquidity in a certain pool (ie. instead of a liquidity amount we just have a bool).
This would avoid having to calculate/reason about how much input is required at current prices to make the test fail etc.
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 almost ended up making this change, but then ran into the price_impact_removes_one_swap
test where we actually want low liquidity, but enough for one swap to test the retrying works (and even the swaps from the failing pool/side can be retired). Because retrying is done entirely within a single call to on_finalize there is no way for us to change liquidity between iteration as we remove swaps, so we need a bit more control in the mock's liquidity than to just say "all swaps in the pool should fail".
Also, I thought it was nice that we could check the resulting liquidity in presence of rollbacks (e.g. in storage_state_rolls_back_on_fok_violation
), which I thought was the whole point of marking Liquidity
as storage
.
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 thought we wanted to remove the BatchSwapFailed event?
Maybe. Though it also sounded like we wanted to at least replace it with another way to tell that a swap failed due to low liquidity (for example, by adding a field to |
Ok I'll open an issue to follow this up. (PRO-1692) |
…-sdk-1.15.2 * origin/main: (31 commits) feat: liveness electoral system (#5278) chore: bump asset-balances to match release (#5305) refactor: Strongly-typed identifiers for SwapId/SwapRequestId (#5294) fix: only install solana if `run-job` is true 🐛 (#5304) Chore/debug 3 nodes (#5302) feat: remove swap and retry batch on price impact (#5285) refactor: Collect settings extrinsic in threshold signer pallet into a single extrinsic (#5299) feat: add solana monitoring data (#5277) fix: Redemption amount printed not consistent in rounding (#5296) refactor: use chainflip api for DCA test (#5289) fix: add audit exception for RUSTSEC-2024-0375 (#5303) fix: filter out stale bitcoin utxos (#5291) PRO-1594: Add healthcheck endpoints to broker and lp apis (#5282) Tests elections pallet (#5190) PRO-1620: Ensure that default port is used if none is given in configuration (#5281) test: egress success tests (#5288) feat: localnet scripts to create and recreate easier (#5284) Denote broadcast timeout in target chain blocks. (#5270) fix: force version bump endpoint (#5280) refactor: user friendly bouncer new swap cmd (#5273) ... # Conflicts: # .zepter.yaml # Cargo.lock # api/bin/chainflip-cli/Cargo.toml # api/bin/chainflip-lp-api/src/main.rs # engine/Cargo.toml # state-chain/custom-rpc/Cargo.toml # state-chain/custom-rpc/src/lib.rs # state-chain/pallets/cf-swapping/src/lib.rs # state-chain/runtime/src/monitoring_apis.rs # utilities/Cargo.toml
* feat: remove swap and retry batch on price impact * fix: storage rolls back on FoK violation * feat: use storage for liquidity mock * refactor: split_off_highest_impact_swap * chore: remove unnecessary tests * test: rework failed_swaps_are_rolled_back integration test * refactor: use add_liquidity in setup_pool_and_accounts * refactor: execute_batch never to return Error * chore: update comment * test: check full state of liquidity pools
* feat: remove swap and retry batch on price impact * fix: storage rolls back on FoK violation * feat: use storage for liquidity mock * refactor: split_off_highest_impact_swap * chore: remove unnecessary tests * test: rework failed_swaps_are_rolled_back integration test * refactor: use add_liquidity in setup_pool_and_accounts * refactor: execute_batch never to return Error * chore: update comment * test: check full state of liquidity pools
* feat: remove swap and retry batch on price impact * fix: storage rolls back on FoK violation * feat: use storage for liquidity mock * refactor: split_off_highest_impact_swap * chore: remove unnecessary tests * test: rework failed_swaps_are_rolled_back integration test * refactor: use add_liquidity in setup_pool_and_accounts * refactor: execute_batch never to return Error * chore: update comment * test: check full state of liquidity pools
Pull Request
Closes: PRO-1440, PRO-1632
Checklist
Please conduct a thorough self-review before opening the PR.
Summary
Moved the retry loop from
on_finalize
(where we only retried on FoK failures) toexecute_batch
(where now we retry on both price impact and FoK failures). In order to determine which swap to remove in case of "price impact" we compareswap_amount
(which may be input amount, or may be the result of the first leg) and remove the largest; for this I added swap_states toSwapLegFailed
.One thing to note is that now
BatchSwapFailed
may be emitted more than once per block due to retrying. I think it makes sense: each error would refer to a different batch, potentially to different pools even, but it also might not be ideal if the same error is repeated many times with consequent errors not providing much additional information.