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

Tendermint "power" does not appear to have sufficient magnitude to reflect true power #5791

Closed
njmurarka opened this issue Mar 12, 2020 · 3 comments

Comments

@njmurarka
Copy link
Contributor

njmurarka commented Mar 12, 2020

I have three validators on COSMOS. They each have respectively 125K, 125K, and 175K tokens staked (the last node is in fact 125K self-delegated and 50K from a delegator).

Doing the math and truncating decimal to get whole percentages:

125 + 125 + 175 = 425
125 / 425 = 29%
175 / 425 = 41%

So based on the above math, I expect that if my stake dictates my voting power (and in fact my ensuing block rewards, etc), Tendermint should be instructed to provide powers that are like follows:

29, 29, 41

This is not what I have observed. I see:

1, 1, 1

My only guess (without digging into the code) is that numerical accuracy is being lost when Tendermint (via ACPI) is instructed to update the power of a validator. More specifically, the "smaller" nodes are being given a 1 and the "larger" node is getting a 1.4, which rounds down to 1. So even though the 175K node has 40% more tokens than each of the others, it is still being reported to have the same power.

Without being an expert here, it seems that the issue is that Tendermint is being instructed to designate powers with magnitudes that are way too small. I do not know how this mechanism works exactly, but in this scenario, if those validators were given 29, 29, and 41, all would be happy. Perhaps "1.0, 1.0, and 1.4" are being given via ACPI. Or "1, 1, 1" because Cosmos itself is rounding away the needed information. That "0.4" is pretty important. I understand that for a network with 100 validators, this might not be likely to happen.

This really confuses me, because PoS to me means that more I stake (in tokens):

  • The more I get voting power. What I observer here conflicts with that.
  • The more I earn as rewards. I have no idea if that is being calculated properly now, and concerns me.

I got some great help from @alessio to get started on this, but it appears this is an issue that might be more specific to another person's wheelhouse.

Thanks.

@alessio
Copy link
Contributor

alessio commented Mar 12, 2020

@melekes / @tessr / @erikgrinaker are the go-to persons here :)

@alexanderbez
Copy link
Contributor

alexanderbez commented Mar 12, 2020

Correct, power is designated to Tendermint via the SDK's x/staking module. Specifically, a validator's total power is converted to an int64 value (because this is what Tendermint works with) via the following:

// potential consensus-engine power
func (v Validator) PotentialConsensusPower() int64 {
	return sdk.TokensToConsensusPower(v.Tokens)
}

which calls:

// PowerReduction is the amount of staking tokens required for 1 unit of consensus-engine power
var PowerReduction = NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(6), nil))

// TokensToConsensusPower - convert input tokens to potential consensus-engine power
func TokensToConsensusPower(tokens Int) int64 {
	return (tokens.Quo(PowerReduction)).Int64()
}

This has been described already in detail by @rigelrozanski : #4656 (comment)

If PowerReduction doesn't suite your needs, simply change the value for you chain 👍

@njmurarka
Copy link
Contributor Author

Thanks. I looked at #4656 .

So to summarize, the "power" is the tokens staked / 1M. My case happened to be the case that two of the three validators were 1.25M and one of them was 1.75M. Dividing and then truncating to int,. These correspond to 1 and 1, which is the power in Tendermint.

Is this right?

I suppose this also answers my other question... why 1 and 1 and 1 and not 10 and 10 and 10. 1 seemed arbitrary without an explanation.

So if instead I had validators with 1.25B, 1.25B, and 1.75B tokens, in fact the powers would have been 1250, 1250, and 1750?

Thanks.

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

No branches or pull requests

3 participants