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

staking: rework the unbonding delay mechanism #3738

Closed
erwanor opened this issue Feb 5, 2024 · 3 comments · Fixed by #3923
Closed

staking: rework the unbonding delay mechanism #3738

erwanor opened this issue Feb 5, 2024 · 3 comments · Fixed by #3923
Assignees
Labels
A-staking Area: Design and implementation of staking and delegation _P-high High priority

Comments

@erwanor
Copy link
Member

erwanor commented Feb 5, 2024

Is your feature request related to a problem? Please describe.
Delegation pools follow an unbonding schedule determined by the chain to provide a window of opportunity for the consensus layer to propagate evidence of misbehavior (e.g., validator equivocation) back to the application so that it can be punished by the staking component ("byzantine slashing").

Currently, the unbonding schedule is defined in terms of epochs (StakingParameters::unbonding_epochs) that must elapse before an undelegation can be claimed or for a pool to become Unbonded.

However, since changes in the active validator set trigger epoch changes, it is possible for a consortium of active-set validators to expedite the unbonding period (in terms of the wall clock) by forcing early epoch changes.

Potential solution.

  1. Make the unbonding schedule a number of blocks:
    • Penalty calculations work the same as before but we do an extra lookup to fetch the end block's epoch index
  2. Add a minimum wall clock duration (X blocks must have elapsed AND Y hours)
  3. Add a synchrony check to the chain to neutralize $f+1$ BFT time manipulation (penumbra: add a synchrony check to BFT time #3668)

** Other solutions you have considered **

  1. Increase the unbonding_duration chain parameter
  2. Rely completely on time-based duration (cons: a combination of logical and wall clock is more robust)
@erwanor erwanor added the A-staking Area: Design and implementation of staking and delegation label Feb 5, 2024
@erwanor erwanor self-assigned this Feb 5, 2024
@hdevalence hdevalence added the _P-high High priority label Feb 9, 2024
@hdevalence
Copy link
Member

  1. seems like the best avenue. The tokens are parameterized by an unbonding end epoch. so either we need to change the token semantics or add a new lookup from "original unbonding end epoch" => "not-before block height". it seems simlper to change the token semantics. if we did this in an upgrade we would be fine because the numbers would get bigger (any outstanding tokens would become unbondable post-upgrade, seems fine while we're on testnet).

we'll want to rely completely on block count to prevent time manipulation.

@aubrika aubrika added this to the Sprint 0 milestone Feb 13, 2024
@erwanor
Copy link
Member Author

erwanor commented Feb 14, 2024

The intuition behind "block height is harder to manipulate than BFT time" is that in one case, a $f+1$ cabal is enough (without a synchrony check) to accelerate the chain's wall clock because this is a large enough node quorum to censor honest proposers. Whereas the same attack would not work for accelerating block height (triggering new rounds incurs additional delay, self-defeating). Instead, in order to accelerate the clock, malicious proposers will have to set their precommit timeout to the lower bound of application execution, and the "acceleration factor" (vs. a 100% honest chain) is linear in their share of control of the network (because they will get selected for proposing with probability $f/N$).

(right?)

@aubrika
Copy link
Contributor

aubrika commented Mar 4, 2024

Moved to backlog for PTO reasons

cratelyn pushed a commit that referenced this issue Mar 12, 2024
Close #3738, this PR makes the unbonding mechanism based on block delay
rather than epochs. In practice, this means that a user will wait X
blocks for a validator pool to unbond (rather than Y epochs).

To achieve this, this PR:
- defines `StakeParamater::unbonding_delay` measured in blocks
- parameterize unbonding tokens based on a `start_height`
- deprecate `start_epoch_index` fields in delegate/claim actions
- strip `epoch_index` from validator `RateData`s
- generalize the unbonding token denom format: 
`2.013718unbonding_start_at_1540_penumbravalid1` (vs. `_epoch_XXX`)

Important point about the mechanism: we bind tokens to the starting
height of the epoch that they belong to. This let us avoid binding
transactions to specific block heights.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-staking Area: Design and implementation of staking and delegation _P-high High priority
Projects
Archived in project
Status: Next
Development

Successfully merging a pull request may close this issue.

3 participants