improve(BundleDataClient): Support pre-fills#823
Closed
nicholaspai wants to merge 2 commits intomasterfrom
Closed
Conversation
Support use case that will become frequent once deterministic relay hashes go live where a fill precedes a deposit in real world time. This opens up the possibility that even with a [SpokePoolClient.query lag](https://github.com/across-protocol/sdk/blob/40888c405db19f1860f0d3f22e26cc5dc541306f/src/clients/BundleDataClient/utils/PoolRebalanceUtils.ts#L28) applied on all chains, there is a very unlucky situation where a fill is sent at the end of one bundle block range and a deposit is one of the first events in the next bundle block range. Currently, the dataworker would never issue a refund for the fill. There are two ways around this I think and one is very complex to implement while the other is simple but increases relayer repayment latency and puts responsibility of how early to-prefill on the relayer: 1. BundleDataClient will need to "remember" which refunds it has already issued. It can do this easily using the arweave client though this increases dependencies on Arweave. Additionally, it will be quite complex to implement the most efficient data structure. I don't love this approach because of the tradeoffs of the following approach. 2. Increase the buffer that a fill must follow its destination chain HEAD block before the dataworker attempts to repay it. This additional buffer converted to seconds becomes the maximum amount of time that a fill can precede a deposit. I think this can be to something reasonable like 10 minutes assuming that pre-fills are only used by fillers who can guarantee somehow that a deposit lands on-chain when they want it to. Therefore the filler should be able to send a deposit after a fill in under 10 minutes in all cases.
nicholaspai
commented
Jan 10, 2025
| // a filler to send a fill before a deposit in cases where the depositor is delegating transaction submission | ||
| // to the filler and giving them a signed transaction object. | ||
| const getFillBlockWithLag = (fill: V3FillWithBlock): number => { | ||
| const fillBuffer = /* FILL_BUFFER[fill.destinationChainId] ?? */ 0; |
Member
Author
There was a problem hiding this comment.
I imagine to start we'd define a hardcoded value for this fill buffer. Technically it would need to be in the UMIP so it might even have to be a config store variable...
Collaborator
|
@nicholaspai I've been working on the UMIP and I'm wondering if we can get away with an even smaller change for this. So far I think it's feasible to just resolve these old fills via binary search, assuming that we won't be flooded with them. For this we'd also need to ensure that the proposer only ever considers deposits that also occur within its current proposal block range (i.e. so it should not consider deposits that come after). I'm hopeful that it'll work OK but it needs some pressure testing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Support use case that will become frequent once deterministic relay hashes go live where a fill precedes a deposit in real world time.
Update #1:
I'm not even sure there is a problem with refunding pre fills that occur near the end of a bundle (that precede a deposit at the beginning of the following bundle) because bundle end blocks are currently set to lag HEAD on all chains. Additionally, the bundle data client takes into account all deposits, even those right near HEAD, when validating fills. So unless the fill precedes the deposit by more than the bundle end block buffer then there should be no issue.
Problem
This opens up the possibility that even with a SpokePoolClient.query lag applied on all chains, there is a very unlucky situation where a fill is sent at the end of one bundle block range and a deposit is one of the first events in the next bundle block range. Currently, the dataworker would never issue a refund for the fill.
There are two ways around this I think and one is very complex to implement while the other is simple but increases relayer repayment latency and puts responsibility of how early to-prefill on the relayer: