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

chainHead: Ensure reasonable distance between leaf and finalized block #3562

Merged
merged 19 commits into from
Apr 3, 2024

Conversation

lexnv
Copy link
Contributor

@lexnv lexnv commented Mar 4, 2024

This PR ensure that the distance between any leaf and the finalized block is within a reasonable distance.

For a new subscription, the chainHead has to provide all blocks between the leaves of the chain and the finalized block.
When the distance between a leaf and the finalized block is large:

The configuration of the ChainHead is extended with:

  • suspend on lagging distance: When the distance between any leaf and the finalized block is greater than this number, the subscriptions are suspended for a given duration.
    • All active subscriptions are terminated with the Stop event, all blocks are unpinned and data discarded.
    • For incoming subscriptions, until the suspended period expires the subscriptions will immediately receive the Stop event.
    • Defaults to 128 blocks
  • suspended duration: The amount of time for which subscriptions are suspended
    • Defaults to 30 seconds

cc @paritytech/subxt-team

@lexnv lexnv added A1-insubstantial Pull request requires no code review (e.g., a sub-repository hash update). R0-silent Changes should not be mentioned in any release notes I5-enhancement An additional feature request. D1-medium Can be fixed by a coder with good Rust knowledge but little knowledge of the codebase. labels Mar 4, 2024
@lexnv lexnv self-assigned this Mar 4, 2024
///
/// Subscriptions are suspended when the distance between any leaf
/// and the finalized block is too large.
const SUSPENDED_DURATION: Duration = Duration::from_secs(30);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative for this would be to simply recalculate the:

leaves = blockchain.leaves()?;
if leaf - finalized > 128 { return Err(); }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there much of a computation cost for doing the above? Personally I think fewer constants is a good thing, but if it's expensive to compute then having a delay makes sense :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep that makes sense, I was also wondering if the suspended duration is overkill for this.

We might have a slight increase in reading the blockchain leaves numbers if they are placed on the disk, however I think we can live with that, since this is only an edge-case of an edge-case.

Have removed that constant and we should allow subscriptions to resume normal work as soon as the distance is reasonable.

@lexnv lexnv requested review from skunert and davxy March 27, 2024 15:05
Copy link
Contributor

@skunert skunert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic looks good to me!

lexnv added 3 commits April 2, 2024 19:41
Signed-off-by: Alexandru Vasile <[email protected]>
…g-fin' into lexnv/chainhead-edge-case-lagging-fin

Signed-off-by: Alexandru Vasile <[email protected]>
Comment on lines 602 to 605
if self.suspend.is_suspended() {
log::trace!(target: LOG_TARGET, "[id={:?}] Subscription already suspended", sub_id);
return None
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm; is the point of removing this now that we will allow new subscriptions to be added any time, but stop them all regardless whenever generate_events says that the distance is too large? Whereas before we'd not allow new subscriptions to be added for the timeout period.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that makes sense

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The changes def simplify things a fair bit so I'm in favour, and the block distance being too large is def an edge case anyways :)

@lexnv lexnv enabled auto-merge April 3, 2024 11:34
@lexnv lexnv added this pull request to the merge queue Apr 3, 2024
Merged via the queue into master with commit 287b116 Apr 3, 2024
127 of 133 checks passed
@lexnv lexnv deleted the lexnv/chainhead-edge-case-lagging-fin branch April 3, 2024 12:19
Ank4n pushed a commit that referenced this pull request Apr 9, 2024
#3562)

This PR ensure that the distance between any leaf and the finalized
block is within a reasonable distance.

For a new subscription, the chainHead has to provide all blocks between
the leaves of the chain and the finalized block.
 When the distance between a leaf and the finalized block is large:
 - The tree route is costly to compute
 - We could deliver an unbounded number of blocks (potentially millions)
(For more details see
#3445 (comment))

The configuration of the ChainHead is extended with:
- suspend on lagging distance: When the distance between any leaf and
the finalized block is greater than this number, the subscriptions are
suspended for a given duration.
- All active subscriptions are terminated with the `Stop` event, all
blocks are unpinned and data discarded.
- For incoming subscriptions, until the suspended period expires the
subscriptions will immediately receive the `Stop` event.
    - Defaults to 128 blocks
- suspended duration: The amount of time for which subscriptions are
suspended
    - Defaults to 30 seconds
 
 
 cc @paritytech/subxt-team

---------

Signed-off-by: Alexandru Vasile <[email protected]>
Co-authored-by: Sebastian Kunert <[email protected]>
dharjeezy pushed a commit to dharjeezy/polkadot-sdk that referenced this pull request Apr 9, 2024
paritytech#3562)

This PR ensure that the distance between any leaf and the finalized
block is within a reasonable distance.

For a new subscription, the chainHead has to provide all blocks between
the leaves of the chain and the finalized block.
 When the distance between a leaf and the finalized block is large:
 - The tree route is costly to compute
 - We could deliver an unbounded number of blocks (potentially millions)
(For more details see
paritytech#3445 (comment))

The configuration of the ChainHead is extended with:
- suspend on lagging distance: When the distance between any leaf and
the finalized block is greater than this number, the subscriptions are
suspended for a given duration.
- All active subscriptions are terminated with the `Stop` event, all
blocks are unpinned and data discarded.
- For incoming subscriptions, until the suspended period expires the
subscriptions will immediately receive the `Stop` event.
    - Defaults to 128 blocks
- suspended duration: The amount of time for which subscriptions are
suspended
    - Defaults to 30 seconds
 
 
 cc @paritytech/subxt-team

---------

Signed-off-by: Alexandru Vasile <[email protected]>
Co-authored-by: Sebastian Kunert <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A1-insubstantial Pull request requires no code review (e.g., a sub-repository hash update). D1-medium Can be fixed by a coder with good Rust knowledge but little knowledge of the codebase. I5-enhancement An additional feature request. R0-silent Changes should not be mentioned in any release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants