Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Extract block announce validation from ChainSync #14675

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

dmitry-markin
Copy link
Contributor

@dmitry-markin dmitry-markin commented Jul 28, 2023

This PR is part of Sync 2.0 preparation work. Resolves paritytech/polkadot-sdk#503.

polkadot companion: paritytech/polkadot#7569
cumulus companion: paritytech/cumulus#2959

@dmitry-markin dmitry-markin added A0-please_review Pull request needs code review. B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders. D3-trivial 🧸 PR contains trivial changes in a runtime directory that do not require an audit labels Jul 28, 2023
@dmitry-markin dmitry-markin requested a review from a team July 28, 2023 11:36
client/network/sync/src/engine.rs Outdated Show resolved Hide resolved
client/network/sync/src/engine.rs Outdated Show resolved Hide resolved
client/network/sync/src/engine.rs Outdated Show resolved Hide resolved
client/network/sync/src/engine.rs Outdated Show resolved Hide resolved
client/network/sync/src/engine.rs Outdated Show resolved Hide resolved
client/network/sync/src/lib.rs Show resolved Hide resolved
@dmitry-markin dmitry-markin marked this pull request as draft July 31, 2023 17:37
@dmitry-markin dmitry-markin changed the title Move block announce validation from ChainSync to SyncingEngine Extract block announce validation from ChainSync Aug 1, 2023
@dmitry-markin dmitry-markin marked this pull request as ready for review August 1, 2023 09:04
@dmitry-markin dmitry-markin requested a review from a team August 1, 2023 13:00
Copy link
Contributor

@melekes melekes left a comment

Choose a reason for hiding this comment

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

👍

client/network/sync/src/lib.rs Outdated Show resolved Hide resolved
client/network/sync/src/block_announce_validator.rs Outdated Show resolved Hide resolved
client/network/sync/src/block_announce_validator.rs Outdated Show resolved Hide resolved
client/network/sync/src/block_announce_validator.rs Outdated Show resolved Hide resolved
/// Wake-up event when new validations are pushed.
event: Event,
/// Listener for wake-up events in [`Stream::poll_next`] implementation.
event_listener: Option<EventListener>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you explain why this is needed? I read your comment and the stream is not getting woken up but why is it necessary to add this machinery to make it wake up?

By the looks of it, a block announcement is pushed if we receive a notification and at the end of SyncingEngine::poll(), the block announcement stream is polled so by my reasoning the newly added announcement should be polled as well (albeit not explicitly but along with any other block announcement) but this is not the case, why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are correct, in our implementation of SyncingEngine::poll() futures unordered are always polled after pushing a block announcement. But I decided to make BlockAnnounceValidator stream future-proof by ensuring the task is woken up even if the block announcements are pushed from somewhere else, and not before polling the stream. We can eliminate this and simplify the implementation, but then we would need to write warnings in the comments stating that the BlockAnnounceValidator stream must be explicitly polled after pushing a block announcement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By the way, looking at it again I think there is an issue with the implementation. In case some futures are already added to self.validations, and we add one more, the task won't be woken up and this new future won't be polled until some other future wakes the task up.

Copy link
Contributor

@altonen altonen Aug 2, 2023

Choose a reason for hiding this comment

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

Would any of this be an issue in the first place of SyncingEngine would use tokio::select! for polling all of its futures simultaneously? That's what we ultimately want and AFAIU it would also give the possibility of pushing a block announcement anywhere in the code and still getting polled.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, in case we use proper .await and select! this can introduce an unneeded latency in block announce validation: the newly added block announcement might not be polled until an already added one resolves. I will look what can be done with this.

Copy link
Contributor

Choose a reason for hiding this comment

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

the newly added block announcement might not be polled until an already added one resolves

I don't understand this. If the block announcements are stored in FuturesUnordered and they're getting polled as a group, I don't understand why some block announcement wouldn't get polled unless another one resolved. Am I overlooking some detail in the implementation?

Copy link
Contributor Author

@dmitry-markin dmitry-markin Aug 2, 2023

Choose a reason for hiding this comment

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

Yes, this is the property of FuturesUnordered:

When new futures are added, poll_next must be called in order to begin receiving wake-ups for new futures.

So, if there are some futures already and the task is waiting, FuturesUnordered::poll_next might not be called until some of them wakes the task up. Only after that the newly added future will be registered in the task.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@altonen Could you take a look again, please? Now the code must be ready for pushing block announcements from a different place and just select!-ing on block_announce_validator.next() in SyncingEngine.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not super happy with this approach either because I feel as though it complicates a relatively simple problem (push a future to FuturesUnordered and poll that container to get next ready future) but I understand that with the current architecture in SyncingEngine it may not be possible. The code itself looks fine but I still think we can improve this polling in the future so could you create an issue for it?

This PR probably has to be migrated to polkadot-sdk since Anton's review has gone stale

@dmitry-markin dmitry-markin marked this pull request as ready for review August 24, 2023 20:22
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review. B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders. D3-trivial 🧸 PR contains trivial changes in a runtime directory that do not require an audit
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move block announce validation/polling to SyncingEngine
3 participants