Skip to content

pallet-bounties: allow bounties to never expire#7723

Merged
BigTava merged 27 commits intomasterfrom
tiago-remove-bounties-expiry
Mar 18, 2025
Merged

pallet-bounties: allow bounties to never expire#7723
BigTava merged 27 commits intomasterfrom
tiago-remove-bounties-expiry

Conversation

@BigTava
Copy link
Copy Markdown
Contributor

@BigTava BigTava commented Feb 26, 2025

Description

Fixes polkadot-fellows/runtimes#509

The Bounties expiration and renewal heavily depends on manual interactions through UI. This PR refactors the update_due calculation to use saturating_add, allowing bounties to remain active indefinitely without requiring extend_bounty_expiry and preventing automatic curator slashing for inactivity, which often penalises unnecessarily. Previously, setting BountyUpdatePeriod to a large value, such as BlockNumber::max_value(), could cause an overflow.

Integration

Set BountyUpdatePeriod to BlockNumber::max_value()

Review Notes

Modifies how bounty expiry is handled

🔍 Code Diff Summary
- *update_due = Self::treasury_block_number() + T::BountyUpdatePeriod::get();
+ *update_due = Self::treasury_block_number().saturating_add(T::BountyUpdatePeriod::get());

@BigTava BigTava requested a review from a team as a code owner February 26, 2025 10:41
@BigTava BigTava added the T2-pallets This PR/Issue is related to a particular pallet. label Feb 26, 2025
title: '[pallet-bounties] Make BountyUpdatePeriod optional'
doc:
- audience: Runtime Dev
description: Refactored `BountyUpdatePeriod` to be optional and adjusted expiration handling to default to `BlockNumber::MAX` when `None`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this will be included in the release notes. I would explain what this means. this is more like a description of the implementation, it can be read from the code.

also please add PR description

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. Thanks!

type BountyDepositPayoutDelay: Get<BlockNumberFor<Self, I>>;

/// Bounty duration in blocks.
/// Optional bounty duration in blocks. If `None`, it is considered `BlockNumber::MAX`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it was a poor doc for this parameter, lets give more context. explain behaviour.
".. it is considered BlockNumber::MAX" is description of the implementation. what it means for a user.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. Thanks!

@paritytech-review-bot paritytech-review-bot bot requested a review from a team February 27, 2025 15:48
Comment on lines +8 to +9
If slashing of curators is necessary, it can be handled through OpenGov.
This reduces friction in curator management.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
If slashing of curators is necessary, it can be handled through OpenGov.
This reduces friction in curator management.

this is a bit specific to Polkadot, but the rest looks good

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

type BountyDepositPayoutDelay: Get<BlockNumberFor<Self, I>>;

/// Bounty duration in blocks.
/// Optional bounty duration in blocks.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Optional bounty duration in blocks.
/// The period that starts when a curator is approved, during which they must execute or
/// update the bounty via `extend_bounty_expiry`. If missed, the bounty expires, and the
/// curator may be slashed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for proposing. I think it is too long for the first sentence, given the guide "Strive to make the first sentence succint and short ...". But I will commit

Comment on lines +229 to +230
/// If `None`, bounties stay active indefinitely, removing the need for
/// `extend_bounty_expiry` and restricting curator slashing to OpenGov.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// If `None`, bounties stay active indefinitely, removing the need for
/// `extend_bounty_expiry` and restricting curator slashing to OpenGov.
/// If `None`, bounties stay active indefinitely, removing the need for
/// `extend_bounty_expiry`.

OpenGov part is specific to the runtime e

@paritytech-review-bot paritytech-review-bot bot requested a review from a team February 27, 2025 17:59
Comment on lines +14 to +15
Migrating `BountyUpdatePeriod` from `BlockNumber` to `Option<BlockNumber>` where
if set to (), bounties will no longer expire.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

set to None, () is a unit type. migration is more meant to guide clients who already using this feature and will face the breaking change. here the migration for them is simple, they need to wrap their value into Some(BountyUpdatePeriod) and that would be lead to exact same behaviour

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Awesome feedback!

Comment on lines +834 to +835
T::BountyUpdatePeriod::get()
.unwrap_or(BlockNumberFor::<T, I>::max_value()),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this part repeated few time, you could abstract it into function

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great suggestion.

@github-actions
Copy link
Copy Markdown
Contributor

Review required! Latest push from author must always be reviewed

@github-actions github-actions bot requested a review from muharem February 28, 2025 11:47
@BigTava
Copy link
Copy Markdown
Contributor Author

BigTava commented Feb 28, 2025

@muharem I pushed again to apply your feedback. Who do you recommend for a second reviewer?

@github-actions github-actions bot requested a review from muharem March 17, 2025 12:35

// If `BountyUpdatePeriod` overflows the inactivity timeout the benchmark still executes the slash
let origin = if Pallet::<T>::treasury_block_number() <= inactivity_timeout {
T::RejectOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it should not be Weightless, even if you have not reject origin, the call is still executable by some caller in some cases or by curator

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great catch!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it should be curator when now <= inactivity_timeout, only curator in this case can run unassign_curator call if the bounty is active

@github-actions github-actions bot requested a review from muharem March 17, 2025 15:03
Copy link
Copy Markdown

@AKJUS AKJUS left a comment

Choose a reason for hiding this comment

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

doing the same well...

@paritytech-workflow-stopper
Copy link
Copy Markdown

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/13905994866
Failed job name: test-linux-stable-runtime-benchmarks

@BigTava BigTava requested a review from AKJUS March 17, 2025 18:26
Copy link
Copy Markdown

@AKJUS AKJUS left a comment

Choose a reason for hiding this comment

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

given jasper said pull_request than...

@BigTava BigTava added this pull request to the merge queue Mar 18, 2025
Merged via the queue into master with commit e4f7814 Mar 18, 2025
253 of 260 checks passed
@BigTava BigTava deleted the tiago-remove-bounties-expiry branch March 18, 2025 10:56
ordian added a commit that referenced this pull request Mar 19, 2025
* master: (58 commits)
  Upgrade link-checker cache to v4 (#7874)
  Updating readmes (#7950)
  Cumulus: Remove some old scripts (#7946)
  pallet-bounties: allow bounties to never expire (#7723)
  run frame-omni-bencher overhead command in CI for all runtimes in the runtime matrix (#7459)
  Update README.md for Cumulus (#7930)
  FRAME: Meta Transaction (#6428)
  Follow up for: Use the umbrella crate for the parachain template #5993 (#7464)
  Add an extra_constant to pallet-treasury (#7918)
  Bump the ci_dependencies group across 1 directory with 4 updates (#7855)
  remove compromised action (#7934)
  Fixing token-economics dead link (#5302)
  [pallet-revive] Fix pallet-revive-fixtures build.rs (#7928)
  cumulus: fix pov exporter format (#7923)
  sp-api: Support `mut` in `impl_runtime_apis!` (#7924)
  Remove clones from block seal function (#7917)
  [pallet-revive] precompiles 2->9 (#7810)
  Use non-native token to benchmark xcm on asset hub (#7893)
  [CI] bump timeout wait for build in zombienet workflows. (#7871)
  taplo: split long array line to multiline array (#7905)
  ...
fellowship-merge-bot bot pushed a commit to polkadot-fellows/runtimes that referenced this pull request Jun 18, 2025
Extend bounty update period to 10 years

There have been multiple cases (e.g.,
[referenda/1588](https://polkadot.subsquare.io/referenda/1588)) where
active bounties expired, requiring the community to vote again to
reintroduce the same bounty. This PR increases the update period to 10
years to prevent such issues for newly created bounties.

Note that the community can still cancel any active bounty through a
governance vote.

Once
[polkadot-sdk#7723](paritytech/polkadot-sdk#7723)
is included in an SDK release and adopted in runtime upgrades, we will
be able to configure bounties to never expire.

---------

Co-authored-by: Bastian Köcher <[email protected]>
Co-authored-by: Adrian Catangiu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T2-pallets This PR/Issue is related to a particular pallet.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Remove Bounty Expiry from Bounties Pallet

8 participants