Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

chainHead: Error on duplicate unpin hashes #3313

Merged
merged 11 commits into from
Feb 14, 2024

Conversation

lexnv
Copy link
Contributor

@lexnv lexnv commented Feb 13, 2024

This PR addresses an issue where calling chainHead_unpin with duplicate hashes could lead to unintended side effects.

This backports: paritytech/json-rpc-interface-spec#135

While at it, have added a test to check that the global reference count is decremented only once on unpin.

cc @paritytech/subxt-team

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@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 I2-bug The node fails to follow expected behavior. D0-easy Can be fixed primarily by duplicating and adapting code by an intermediate coder. labels Feb 13, 2024
@lexnv lexnv self-assigned this Feb 13, 2024
@@ -759,10 +759,13 @@ impl<Block: BlockT, BE: Backend<Block>> SubscriptionsInner<Block, BE> {
return Err(SubscriptionManagementError::SubscriptionAbsent)
};

// Keep only unique hashes.
let hashes = hashes.into_iter().collect::<HashSet<_>>();
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should error on duplicated hashes instead?

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 sounds good to me, I'll create a small PR in the spec to clarify this (part of paritytech/json-rpc-interface-spec#133)

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: cargo-clippy
Logs: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/5209970

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv lexnv changed the title chainHead: Deduplicate unpin hashes chainHead: Error on duplicate unpin hashes Feb 14, 2024
Copy link
Contributor

@tadeohepperle tadeohepperle left a comment

Choose a reason for hiding this comment

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

Nice! :)

Copy link
Member

@davxy davxy left a comment

Choose a reason for hiding this comment

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

Just curious. What is the unintended consequence if there are duplicate hashes?

I ask because the only thing you do after the check is to call self.subscriptions.unpin_blocks(). And if this is where the unintended behavior is triggered then maybe you should add the check there (i.e. in the called function) as it may be called somewhere else

lexnv and others added 3 commits February 14, 2024 13:11
Co-authored-by: Davide Galassi <davxy@datawok.net>
subscriptions

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv
Copy link
Contributor Author

lexnv commented Feb 14, 2024

The side-effect before this PR was that duplicate hashes could decrement the global counter of the blocks multiple times:

// Block have been removed from the subscription. Remove them from the global tracking.
for hash in hashes {
self.global_unregister_block(hash);
}

Have moved the duplicate check in the unpin_blocks logic.

With this check enforced, we'll return an error before doing any other work. The downside of moving the check in the unpin_blocks is that we'll perform the check under a lock. However, considering that we don't expect a large number of blocks for the most common use-case; and that this closes the gap on potentially calling the unpin_blocks from other code paths; I'd say it is a reasonable thing to do.

Thanks for the review everyone! 🙏

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv lexnv added this pull request to the merge queue Feb 14, 2024
Merged via the queue into master with commit 7ec692d Feb 14, 2024
126 of 127 checks passed
@lexnv lexnv deleted the lexnv/chain-head-unpin-multiple branch February 14, 2024 15:06
bgallois pushed a commit to duniter/duniter-polkadot-sdk that referenced this pull request Mar 25, 2024
This PR addresses an issue where calling chainHead_unpin with duplicate
hashes could lead to unintended side effects.

This backports:
paritytech/json-rpc-interface-spec#135

While at it, have added a test to check that the global reference count
is decremented only once on unpin.

cc @paritytech/subxt-team

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: Davide Galassi <davxy@datawok.net>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A1-insubstantial Pull request requires no code review (e.g., a sub-repository hash update). D0-easy Can be fixed primarily by duplicating and adapting code by an intermediate coder. I2-bug The node fails to follow expected behavior. R0-silent Changes should not be mentioned in any release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants