New mode of head-polling using client-side state management only - #225
New mode of head-polling using client-side state management only#225peterbroadhurst wants to merge 9 commits into
Conversation
peterbroadhurst
commented
Aug 31, 2026
Signed-off-by: Peter Broadhurst <peter.broadhurst@kaleido.io>
b06d585 to
8ac9518
Compare
Signed-off-by: Peter Broadhurst <peter.broadhurst@kaleido.io>
Signed-off-by: Peter Broadhurst <peter.broadhurst@kaleido.io>
| } | ||
| // HWM is the configured fromBlock | ||
| l.hwmBlock = int64(firstBlock) //nolint:gosec // convert to int64 to match the type of hwmBlock, we should change the type of hwmBlock to uint64 | ||
| l.hwmBlock = blockNumberToInt64(firstBlock) |
There was a problem hiding this comment.
Given this was getting proliferated, I've condensed to a single place and a single behavior if we ever ended up with the (invalid) case of a block in the >maxint64 range.
| var exiting bool | ||
| if es.c.eventFilterPollingMode == FilterPollingModeClient { | ||
| exiting = es.leadGroupSteadyStateGetLogs() | ||
| } else { | ||
| exiting = es.leadGroupSteadyState() | ||
| } |
There was a problem hiding this comment.
Deliberately a hard split here, to protect the existing code path from churn.
Signed-off-by: Peter Broadhurst <peter.broadhurst@kaleido.io>
… client-side-filtering
…connect into client-side-filtering
Signed-off-by: Peter Broadhurst <peter.broadhurst@kaleido.io>
Signed-off-by: Peter Broadhurst <peter.broadhurst@kaleido.io>
| // Catchup only polls blocks that are outside the re-org unstable window at the head of | ||
| // the chain (checkpointBlockGap behind the head). | ||
| // The steady-state loops own delivery of the unstable window. | ||
| // We stop on the first page where the end lands between catchupThreshold+checkpointBlockGap | ||
| // (say 550) and the checkpointBlockGap (say 50) before the head to do the switch. | ||
| pollableHead := blockNumberToInt64(chainHeadBlock) - es.c.checkpointBlockGap | ||
| if pollableHead < 0 { | ||
| pollableHead = 0 | ||
| } | ||
| headGap := pollableHead - fromBlock |
There was a problem hiding this comment.
This might seem decoupled from the primary feature, but this precision on the right change-over point from catchup to steady-state is more important for client-side filtering (particularly in light mode).
In client-side filtering we just maintain a block number, and page forwards from there. Things behind the earliest block we consume from are completely ignored. So the steady state looks a lot like the catchup mode, but we are extra vigilant to re-detect things in the in the checkpointBlockGap (the unstable part).
So it's really important there's no case where this catchup never goes beyond that checkpointBlockGap, and before there was an edge case where the last page could land in that unstable window.
Note the window only existed in the leadGroupCatchup path.
The listenerCatchupLoop that is used when a new listener is added that's behind the lead group already had the strong protection against joining the lead group in the checkpointBlockGap.
Signed-off-by: Peter Broadhurst <peter.broadhurst@kaleido.io>