Skip to content
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: Implement rollback buffer #149

Merged
merged 1 commit into from
Feb 17, 2022
Merged

feat: Implement rollback buffer #149

merged 1 commit into from
Feb 17, 2022

Conversation

scarmuega
Copy link
Member

@scarmuega scarmuega commented Feb 16, 2022

This PR introduces a rollback buffer to mitigate the impact of chain rollbacks in downstream stages of the data-processing pipeline.

Problem

Handling rollbacks in a persistent storage requires clearing the orphaned data before adding new records. The complexity of this process may vary by concrete storage engine, but it always has an associated impact on performance. In some scenarios, it might even be prohibitive to process events without a reasonable level of confidence about the immutability of the record.

Rollbacks occur frequently under normal conditions, but the chances of a block becoming orphaned diminishes as the depth of the block increases. Some Oura use-cases may benefit from this property, some pipelines might prefer lesser rollback events, even if it means waiting for a certain number of confirmations.

Solution

This PR implements a "rollback buffer" that will hold blocks in memory until they reach a certain depth. Only blocks above a min depth threshold will be sent down the pipeline. If a rollback occurs and the intersection is within the scope of the buffer, the rollback operation will occur within memory, totally transparent to the subsequent stages of the pipeline.

If a rollback occurs and the intersection is outside of the scope of the buffer, Oura will fallback to the original behaviour and publish a RollbackEvent so that the "sink" stages may handle the rollback procedure manually.

There's an obvious trade-off to this approach: latency. A pipeline will not process any events until the buffer fills up. Once the initial wait is over, the throughput of the whole pipeline should be equivalent to having no buffer at all (due to Oura's "pipelining" nature). If a rollback occurs, an extra delay will be required to fill the buffer again.

Notice that even if the throughput isn't affected, the latency (measured as the delta between the timestamp at which the event reaches the "sink" stage and the original timestamp of the block) will always be affected by a fixed value proportional to the size of the buffer.

The buffer logic is implemented in pallas-miniprotocols library. It works by keeping a VecDeque data structure of chain "points", where roll-forward operations accumulate at the end of the deque and retrieving confirmed points means popping from the front of the deque.

The min depth is a configurable setting available when running in daemon mode. Higher min_depth values will lower the chances of experiencing a rollback event, at the cost of adding more latency. An node-to-node source stage config would look like this:

[source]
type = "N2N"
address = ["Tcp", "relays-new.cardano-mainnet.iohk.io:3001"]
magic = "mainnet"
min_depth = 6

Node-to-client sources provide an equivalent setting.

@scarmuega scarmuega requested a review from rvcas February 16, 2022 23:21
@scarmuega scarmuega added the enhancement New feature or request label Feb 16, 2022
@scarmuega scarmuega self-assigned this Feb 16, 2022
@scarmuega scarmuega added this to the v1.2 milestone Feb 16, 2022
@scarmuega scarmuega linked an issue Feb 16, 2022 that may be closed by this pull request
@rinor
Copy link
Collaborator

rinor commented Feb 17, 2022

I assume that min_depth = 0 will disable the rollback buffer.

@scarmuega
Copy link
Member Author

scarmuega commented Feb 17, 2022

@rinor correct, min_depth=0 yields the same output as having no buffer, which is the default value.

@scarmuega
Copy link
Member Author

rollback buffer structure was defined in txpipe/pallas#49

@scarmuega scarmuega marked this pull request as ready for review February 17, 2022 13:00
@scarmuega scarmuega merged commit db2fb01 into main Feb 17, 2022
@scarmuega scarmuega deleted the feat/buffer branch February 17, 2022 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

feat: Handle forks and rollbacks
3 participants