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

Snowbridge free consensus updates #5201

Merged
merged 23 commits into from
Sep 2, 2024

Conversation

claravanstaden
Copy link
Contributor

Allow free Snowbridge consensus updates, if the header interval is larger than the configured value (set to 32, so once a epoch).

This PR also moves the Rococo Snowbridge pallet config into its own module.

Original PR: Snowfork#159

* free finalized updates

* update comment

* fix check

* fixes

* tests

* fixes

* fmt

* finishing touches

* comments

* adds missing impl

* adds test

* fixes

* fix
@claravanstaden claravanstaden marked this pull request as ready for review August 1, 2024 13:41
@paritytech-review-bot paritytech-review-bot bot requested a review from a team August 1, 2024 13:42
@claravanstaden
Copy link
Contributor Author

@yrong @vgeddes Please review. :)

Copy link
Contributor

@yrong yrong left a comment

Choose a reason for hiding this comment

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

+1

return Pays::No;
}

// If free headers are allowed and the latest finalized header is larger than the
Copy link
Contributor

Choose a reason for hiding this comment

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

This part of the comment, "If free headers are allowed". I don't see it reflected in the code. Should it be another condition apart from the inequality?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, in an older implementation it was optional. Comment updated here: ab8739c#diff-adbbba03e39a047dd71745d3ed0eaf33b4e982ac58d64f273f1574816ff44940R664

bridges/snowbridge/pallets/ethereum-client/src/lib.rs Outdated Show resolved Hide resolved
new_tester().execute_with(|| {
// Not free, smaller than the allowed free header interval
assert_eq!(
EthereumBeaconClient::check_refundable(&finalized_update.clone(), 8190),
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be clearer if you use finalized_update.finalized_header.slot + some_offset

Copy link
Contributor Author

Choose a reason for hiding this comment

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

type RuntimeEvent = RuntimeEvent;
type ForkVersions = ChainForkVersions;
// Free consensus update every epoch. Works out to be 225 updates per day.
type FreeHeadersInterval = ConstU32<32>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess the epoch will not change often, but probably better to use a constant like EPOCH_LENGTH

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 9 to 10
Allow free consensus updates to the Snowbridge Ethereum client if the headers are more than a certain
number of headers apart.
Copy link
Contributor

Choose a reason for hiding this comment

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

How does this impact the devs? Is it cheaper to run relayers now?
Does this affect the user somehow? E.g. cheaper to use the bridge?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@serban300 serban300 added the T15-bridges This PR/Issue is related to bridges. label Aug 21, 2024
Comment on lines +473 to +483
let pays_fee = Self::check_refundable(update, latest_finalized_state.slot);
let actual_weight = match update.next_sync_committee_update {
None => T::WeightInfo::submit(),
Some(_) => T::WeightInfo::submit_with_sync_committee(),
};

if update.finalized_header.slot > latest_finalized_state.slot {
Self::store_finalized_header(update.finalized_header, update.block_roots_root)?;
}

Ok(())
Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee })
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you double-check and confirm that this doesn't allow free spamming for this call with using the same "valid" update (with update.next_sync_committee_update.is_some() == true) over and over for free, potentially DoS-ing BH blocks?

It looks like there is a compute_period verification for updating sync committee, that would not allow the DoS I described above, but I got a bit lost in the details and would like you to confirm.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@acatangiu that's a valid point, thanks! There is a specific test for that (duplicate_sync_committee_updates_are_not_free): https://github.com/paritytech/polkadot-sdk/pull/5201/files#diff-ea6025b3cac6719f750d1f0065ba30d70a16d386a5ce374e4a6b79299f48a3eeR684

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, didn't yet look at tests 🙈

Copy link
Contributor

Choose a reason for hiding this comment

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

The test tries to submit the exact same proof twice, which will fail the second time because the attested header in the proof is no longer newer than the stored one on-chain.

But what about the following scenario:

  • Relayer submits valid update for slot N in period P with sync committee S provided in Some(next_sync_committee_update)
  • Relayer then provides update for slot N+1 in period P with sync committee S provided in Some(next_sync_committee_update)?

Basically try to "farm" the Some(next_sync_committee_update) tx fee freebie, to spam update one slot at a time.

Copy link
Contributor

Choose a reason for hiding this comment

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

The above is a valid issue, and is being fixed in Snowfork#172

@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: test-linux-stable 1/3
Logs: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/7125017

Copy link
Contributor

@acatangiu acatangiu left a comment

Choose a reason for hiding this comment

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

Approving this like so, Clara to follow-up with requested test in another PR.

@bkchr
Copy link
Member

bkchr commented Sep 2, 2024

@claravanstaden please merge master to make this mergable.

@ggwpez ggwpez disabled auto-merge September 2, 2024 17:20
@claravanstaden
Copy link
Contributor Author

@claravanstaden please merge master to make this mergable.

On it!

# Conflicts:
#	cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
@bkchr bkchr added this pull request to the merge queue Sep 2, 2024
Merged via the queue into paritytech:master with commit c8015b2 Sep 2, 2024
183 of 185 checks passed
@claravanstaden claravanstaden deleted the free-consensus-updates branch September 3, 2024 06:27
acatangiu pushed a commit to acatangiu/polkadot-sdk that referenced this pull request Sep 3, 2024
Allow free Snowbridge consensus updates, if the header interval is
larger than the configured value (set to 32, so once a epoch).

This PR also moves the Rococo Snowbridge pallet config into its own
module.

Original PR: Snowfork#159

---------

Co-authored-by: Francisco Aguirre <[email protected]>
acatangiu added a commit that referenced this pull request Sep 3, 2024
Allow free Snowbridge consensus updates, if the header interval is
larger than the configured value (set to 32, so once a epoch).

This PR also moves the Rococo Snowbridge pallet config into its own
module.

Original PR: Snowfork#159

----------

Original `pr_5201.prdoc` is present but moved to release dir, ergo
`R0-Silent` for this backport PR.

---------

Co-authored-by: Clara van Staden <[email protected]>
Co-authored-by: Francisco Aguirre <[email protected]>
x3c41a pushed a commit that referenced this pull request Sep 4, 2024
Allow free Snowbridge consensus updates, if the header interval is
larger than the configured value (set to 32, so once a epoch).

This PR also moves the Rococo Snowbridge pallet config into its own
module.

Original PR: Snowfork#159

---------

Co-authored-by: Francisco Aguirre <[email protected]>
@acatangiu acatangiu self-assigned this Sep 4, 2024
github-merge-queue bot pushed a commit that referenced this pull request Sep 24, 2024
# Description

A fix for a border condition introduced with new feature
#5201. A malicious
relayer could spam the Ethereum client with sync committee updates that
have already been imported for the period. This PR adds a storage item
to track the last imported sync committee period, so that subsequent
irrelevant updates are not free.

Original PR: Snowfork#172

## Integration

Downstream projects are not affected. Relayers will not be able to spam
the Ethereum client with irrelevant sync committee updates for free.

## Review Notes

Adds a storage item to track the last free sync committee update period,
so that duplicate imports are not free.

---------

Co-authored-by: Adrian Catangiu <[email protected]>
github-actions bot pushed a commit that referenced this pull request Sep 24, 2024
# Description

A fix for a border condition introduced with new feature
#5201. A malicious
relayer could spam the Ethereum client with sync committee updates that
have already been imported for the period. This PR adds a storage item
to track the last imported sync committee period, so that subsequent
irrelevant updates are not free.

Original PR: Snowfork#172

## Integration

Downstream projects are not affected. Relayers will not be able to spam
the Ethereum client with irrelevant sync committee updates for free.

## Review Notes

Adds a storage item to track the last free sync committee update period,
so that duplicate imports are not free.

---------

Co-authored-by: Adrian Catangiu <[email protected]>
(cherry picked from commit 1790e42)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T15-bridges This PR/Issue is related to bridges.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

8 participants