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

Implement a minimal fix for Penalty calculation in UndelegateClaimCircuit #3478

Merged
merged 7 commits into from
Dec 11, 2023

Conversation

cronokirby
Copy link
Contributor

@cronokirby cronokirby commented Dec 6, 2023

Closes #3456.

I lost track of what exactly had changed in #3466, so I instead just implemented this without basing myself off of that PR.

The difference in approach is that this PR makes the Penalty type completely opaque, and modifies no other typed values in the system to use Penalty or U128x128 except the internal representation of the Penalty type.

I think making Penalty opaque is the correct approach, because it makes it impossible for there to ever be any confusion about what the meaning of the u64s you're passing in to Penalty are.

Another difference with the other PR is that the circuit behavior should match the out of circuit behavior exactly now, whereas the other PR is missing a 1 - X operation in the circuit. This bumps up the constraint count to 15714. (We can golf this down with at least two strategies, but we don't really need to, it still fits).

One important thing that should be considered is the fact that this PR modifies the proto-encoding of penalty to now hold the full precision of U128x128 by encoding the 32 bytes that value consists of. I'm not quite sure of the ramifications of this change but it should be considered.

Update (2023-12-06T08:52:27+00:00): I've switched the Penalty to store the a fraction from [0, 1], representing the kept amount, rather than the removed amount. This simplifies compounding and the circuit, and also fixes the weird test failures I tried to debug for a couple hours.

@redshiftzero
Copy link
Member

Per discussion in today's sprint planning meeting, I'll add a commit later today that adds a test of the U128x128Var::round_down_to_amount functionality

AmountVar {
amount: penalty_var.inner.clone(),
}
Ok(Self {
Copy link
Member

Choose a reason for hiding this comment

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

Here in AllocVar as an additional guard we could return an error if mode is not AllocationMode::Input

use penumbra_num::{
fixpoint::{U128x128, U128x128Var},
Amount, AmountVar,
};

/// Tracks slashing penalties applied to a validator in some epoch.
///
/// The penalty is represented as a fixed-point integer in bps^2 (denominator 10^8).
Copy link
Member

Choose a reason for hiding this comment

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

We should replace this description

Copy link
Member

Choose a reason for hiding this comment

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

We can remove all mention of how it is represented internally since the type is opaque

.expect("converting integral U128xU128 into Amount will succeed")
}

/// Apply this `Penalty` to an some fracton.
Copy link
Member

Choose a reason for hiding this comment

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

nit: typos

Copy link
Member

@erwanor erwanor left a comment

Choose a reason for hiding this comment

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

I have read through the PR and this looks correct to me. I saw some minor typos, I do think we could add more comments too: for example, during the review session, we spent some time recalling why round_down_to_amount would work over the upper limbs of the AmountVar, and shared some context about the endianness quirks of the underlying U256 impl. Otherwise, LGTM.

@cronokirby cronokirby force-pushed the min-staking-fix branch 2 times, most recently from 5d529df to 3eaea83 Compare December 8, 2023 02:00
Copy link
Member

@hdevalence hdevalence left a comment

Choose a reason for hiding this comment

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

This LGTM. Let's land this prior to the Testnet 64 release, and do another round of circuit assurance during Testnet 64.

This speeds up trusted param generation, because it was quicker to
enable than to wait 16x longer
Now it is no longer possible to directly construct this type without
going through a specific constructor which flags what a u64 actually
means. Otherwise, surrounding code isn't changed.

This also propagated to the circuit, which comes in at 15714
constraints, which is still under 2^14.
This saves on constraints: back to 14423

This also makes the circuit tests pass know, not sure why they were failing
before.
@cronokirby cronokirby merged commit ca70a30 into main Dec 11, 2023
5 checks passed
@cronokirby cronokirby deleted the min-staking-fix branch December 11, 2023 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

staking: update UndelegateClaimCircuit to use penumbra-num amount and fixpoint arithmetic
4 participants