Skip to content

Conversation

@mattfoley8
Copy link
Contributor

This PR removes any jailed stake from our GlobalActiveStakeAmountNanos value. If a validator is jailed, we do not want to consider their stake in the total active stake across validators used in determining if we have a 2/3rd consensus on votes. This PR makes the following changes:

  1. Renames GlobalStakeAmountNanos to GlobalActiveStakeAmountNanos. Note the addition of the keyword Active. This value describes the total active stake across validators, excluding any jailed validators' stake.
  2. When a user stakes with a validator, we only add the additional stake to the GlobalActiveStakeAmountNanos if the validator isn't jailed.
  3. When a user unstakes from a validator, we only subtract the decreased stake from the GlobalActiveStakeAmountNanos if the validator isn't jailed.
  4. When a validator is jailed, we subtract their TotalStakeAmountNanos from the GlobalActiveStakeAmountNanos.
  5. When a validator unjails himself, we add back their TotalStakeAmountNanos to the GlobalActiveStakeAmountNanos.
  6. When a validator unregisters, we only subtract their now unstaked TotalStakeAmountNanos from the GlobalActiveStakeAmountNanos it they weren't jailed.

@mattfoley8 mattfoley8 self-assigned this May 19, 2023
@mattfoley8 mattfoley8 requested a review from a team as a code owner May 19, 2023 14:29
// Restore the PrevGlobalStakeAmountNanos.
bav._setGlobalStakeAmountNanos(operationData.PrevGlobalStakeAmountNanos)
// Restore the PrevGlobalActiveStakeAmountNanos if the PrevValidatorEntry was active.
if prevValidatorEntry.Status() == ValidatorStatusActive {
Copy link
Member

Choose a reason for hiding this comment

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

we could just check if PrevGlobalActiveStakeAmountNanos is non-nil. I generally prefer that as opposed to relying on a different field. The prevs generally means "revert to this state when disconnecting".

// Restore the PrevGlobalStakeAmountNanos.
bav._setGlobalStakeAmountNanos(operationData.PrevGlobalStakeAmountNanos)
// Restore the PrevGlobalActiveStakeAmountNanos if the PrevValidatorEntry was active.
if prevValidatorEntry.Status() == ValidatorStatusActive {
Copy link
Member

Choose a reason for hiding this comment

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

same as above.

Comment on lines 1880 to 1881
if prevGlobalActiveStakeAmountNanos, err := VariableDecodeUint256(rr); err == nil {
op.PrevGlobalActiveStakeAmountNanos = prevGlobalActiveStakeAmountNanos
Copy link
Member

Choose a reason for hiding this comment

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

we could just write if op.PrevGlobalActiveStakeAmountNanos, err := VariableDecodeUint256(rr); err != nil here instead.

// Set the CurrentValidatorEntry.
bav._setValidatorEntryMappings(currentValidatorEntry)

// Increase the GlobalActiveStakeAmountNanos.
Copy link
Member

Choose a reason for hiding this comment

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

IsValidUnjailValidatorMetadata ensures that the validator is indeed jailed, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's correct. See link here. It also validates that sufficient epochs have elapsed for the validator to be unjailed.

return 0, 0, nil, errors.Wrapf(err, "_connectStake: error adding StakeAmountNanos to GlobalStakeAmountNanos: ")
// Increase the GlobalActiveStakeAmountNanos if the validator is active.
var prevGlobalActiveStakeAmountNanos *uint256.Int
if currentValidatorEntry.Status() == ValidatorStatusActive {
Copy link
Member

Choose a reason for hiding this comment

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

I'm sure you've thougth about this, but do we want to make it so that you can't stake to a jailed validator? You would just add an else if block here to error if the status is jailed.

If you did this, I'd also add an else for "Unknown validator status" error.

Copy link
Member

Choose a reason for hiding this comment

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

I thought about it more, and I think what you're doing here is more elegant. If we were to disallow staking to jailed validators, we'd break symmetry with Unstake, which I think adds complexity.

} else {
return errors.Wrapf(err, "UtxoOperation.Decode: Problem reading PrevGlobalStakeAmountNanos: ")
// PrevGlobalActiveStakeAmountNanos
if op.PrevGlobalActiveStakeAmountNanos, err = VariableDecodeUint256(rr); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: No need to fix this here, but I tend to prefer breaking assignments out of if statements like the following. I know it's not "Go-like" but I find it easier to read and less error-prone:

		// PrevGlobalActiveStakeAmountNanos
        op.PrevGlobalActiveStakeAmountNanos, err = VariableDecodeUint256(rr)
		if err != nil {
			return errors.Wrapf(err, "UtxoOperation.Decode: Problem reading PrevGlobalActiveStakeAmountNanos: ")
		}

// Restore the PrevGlobalActiveStakeAmountNanos.
prevGlobalActiveStakeAmountNanos := operationData.PrevGlobalActiveStakeAmountNanos
if prevGlobalActiveStakeAmountNanos == nil {
return errors.New("_disconnectUnjailValidator: PrevGlobalActiveStakeAmountNanos is nil")
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Whenever something should never happen, like I think is the case here, I like to add "This should never happen" or "sanity-check failed" to indicate that in the logs for whoever ends up having to debug it.

Copy link
Member

Choose a reason for hiding this comment

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

Let's add this^


// Global stake across all validators
GlobalStakeAmountNanos *uint256.Int
// Global active stake across all validators
Copy link
Member

Choose a reason for hiding this comment

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

can we expound upon this comment? Something like The global active stake is the sum of all DESO staked to validators who are not jailed.

// Restore the PrevGlobalActiveStakeAmountNanos.
prevGlobalActiveStakeAmountNanos := operationData.PrevGlobalActiveStakeAmountNanos
if prevGlobalActiveStakeAmountNanos == nil {
return errors.New("_disconnectUnjailValidator: PrevGlobalActiveStakeAmountNanos is nil")
Copy link
Member

Choose a reason for hiding this comment

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

Let's add this^

@mattfoley8 mattfoley8 merged commit ae9032c into feature/pos-txn-types May 22, 2023
@mattfoley8 mattfoley8 deleted the mf/remove-jailed-stake-from-global-active-stake branch May 22, 2023 17:02
mattfoley8 added a commit that referenced this pull request May 22, 2023
* Diamondhands/pos txn types review (#530)

* POS fixes and comments from diamondhands

* Mf/pos txn types review (#531)

* Add comments.

* Addres review comments.

* Add first batch of sanity check utils.

* Add second batch of txn sanity checks.

* Rename encode uint256 funcs in comments.

* Nuke RegisteredAtBlockHeight.

* Address review feedback.

* Fix a few more typos.

* Update some comments

---------

Co-authored-by: diamondhands <diamondhands@bitcloutdev.com>

---------

Co-authored-by: Matt Foley <100429827+mattfoley8@users.noreply.github.com>

* Exclude zero-stake validators from TopValidatorsByStake. (#535)

* Mf/remove jailed stake from global active stake (#533)

* Remove jailed stake from global active stake.

* Write to the UtxoView if no errors in jailing.

* Add additional sanity checks.

* PR review feedback.

* Remove FIXME comment.

---------

Co-authored-by: diamondhands0 <81935176+diamondhands0@users.noreply.github.com>
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.

4 participants