-
Notifications
You must be signed in to change notification settings - Fork 20.8k
eth/filters, core/filtermaps: safe chain view update #31590
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
Conversation
fd0eae9
to
6c7951a
Compare
888367a
to
844e795
Compare
My general feeling is that the chain view management was Whenever a potential reorg occurs, the current implementation Instead, the new chain view is updated asynchronously, and This approach may introduce a number of issues while offering Ideally, it should be implemented that: once reorg occurs, immediately |
844e795
to
e7f92a9
Compare
8cf5ffa
to
9bd1f9a
Compare
Blocking |
9bd1f9a
to
c5939b3
Compare
c5939b3
to
d096756
Compare
eth/filters: discard cached matching result if the error occurs
s.filter.rangeLogsTestHook <- rangeLogsTestEvent{rangeLogsTestSynced, s.syncRange.ValidBlocks} | ||
} | ||
// discard everything that might be invalid | ||
trimRange := s.syncRange.ValidBlocks.Intersection(s.chainView.SharedRange(s.syncRange.IndexedView)) |
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.
Can I just confirm that
s.syncRange.ValidBlocks
is always consistent with the result returned by s.filter.indexedLogs
right?
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.
hmm, probably not.
e.g., the indexed view was A->B
, then A->B->C->D
; then it's changed to A->B'->C'->D'
;
The match backend was initialized with at A->B
; the s.syncRange.ValidBlocks
returned is A
(B was removed due to indexed view reorg). s.syncRange.ValidBlocks
is aligned with the indexed view.
However, the indexed view might be forked with the current block chain (e.g. chain is rewound to A'->B''->C''->D'') and this view hasn't be propagated into the indexer yet.
In this case, the s.syncRange.ValidBlocks
will be trimmed by the intersection of indexed view and chain view.
This subset should be totally trusted and canonical.
@zsfelfoldi is it correct?
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.
Yes, it's correct. The block number range in syncRange.ValidBlocks
always refers to syncRange.IndexedView
which is usually the same as the local reference view s.chainView
but has this small delay because of async indexing so in case they are different the guaranteed correct range is trimmed further so that s.matchRange
and s.matches
always stay consistent with s.chainView
.
The indexer's event handler will check for new heads before the new matcher sync iteration so in the next sync the two views will hopefully match and the results of the next search iteration will all be considered safe and the search can be successfully finished (unless of course there is a next reorg happening very quickly).
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’ve tried my best to review this PR, and it looks good to me.
However, my understanding of this package isn’t very comprehensive, so I can’t guarantee that the new filtermap implementation is completely issue free.
But the flaky test appears to be resolved, which is a good sign.
This PR changes the chain view update mechanism of the log filter. Previously the head updates were all wired through the indexer, even in unindexed mode. This was both a bit weird and also unsafe as the indexer's chain view was updates asynchronously with some delay, making some log related tests flaky. Also, the reorg safety of the indexed search was integrated with unindexed search in a weird way, relying on `syncRange.ValidBlocks` in the unindexed case too, with a special condition added to only consider the head of the valid range but not the tail in the unindexed case. In this PR the current chain view is directly accessible through the filter backend and unindexed search is also chain view based, making it inherently safe. The matcher sync mechanism is now only used for indexed search as originally intended, removing a few ugly special conditions. The PR is currently based on top of ethereum#31642 Together they fix ethereum#31518 and replace ethereum#31542 --------- Co-authored-by: Gary Rong <[email protected]>
This PR changes the chain view update mechanism of the log filter. Previously the head updates were all wired through the indexer, even in unindexed mode. This was both a bit weird and also unsafe as the indexer's chain view was updates asynchronously with some delay, making some log related tests flaky. Also, the reorg safety of the indexed search was integrated with unindexed search in a weird way, relying on `syncRange.ValidBlocks` in the unindexed case too, with a special condition added to only consider the head of the valid range but not the tail in the unindexed case. In this PR the current chain view is directly accessible through the filter backend and unindexed search is also chain view based, making it inherently safe. The matcher sync mechanism is now only used for indexed search as originally intended, removing a few ugly special conditions. The PR is currently based on top of ethereum#31642 Together they fix ethereum#31518 and replace ethereum#31542 --------- Co-authored-by: Gary Rong <[email protected]>
This PR changes the chain view update mechanism of the log filter. Previously the head updates were all wired through the indexer, even in unindexed mode. This was both a bit weird and also unsafe as the indexer's chain view was updates asynchronously with some delay, making some log related tests flaky. Also, the reorg safety of the indexed search was integrated with unindexed search in a weird way, relying on
syncRange.ValidBlocks
in the unindexed case too, with a special condition added to only consider the head of the valid range but not the tail in the unindexed case.In this PR the current chain view is directly accessible through the filter backend and unindexed search is also chain view based, making it inherently safe. The matcher sync mechanism is now only used for indexed search as originally intended, removing a few ugly special conditions.
The PR is currently based on top of #31642
Together they fix #31518 and replace #31542