-
Notifications
You must be signed in to change notification settings - Fork 363
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
feat(blobstream): utilizes sdk.Dec type for power difference calculation #2719
feat(blobstream): utilizes sdk.Dec type for power difference calculation #2719
Conversation
x/blobstream/types/validator.go
Outdated
@@ -112,7 +113,8 @@ func EVMAddrLessThan(e common.Address, o common.Address) bool { | |||
// increases by 1% due to inflation, we shouldn't have to generate a new | |||
// validator set, after all the validators retained their relative percentages | |||
// during inflation and normalized Blobstream power shows no difference. | |||
func (ibv InternalBridgeValidators) PowerDiff(c InternalBridgeValidators) float64 { | |||
func (ibv InternalBridgeValidators) PowerDiff( | |||
c InternalBridgeValidators) sdk.Dec { | |||
powers := map[string]int64{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[note to the reviewers] Alternatively, we could perform all calculations using sdk.Dec
from the outset. However, since there are no floating-point calculations involved until later in this function, I thought it might be more efficient to continue using integer operations until that point. Nevertheless, if it is preferable to use sdk.Dec
arithmetic throughout, I can update the initial portion of the function accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think switching to sdk.Dec
would be also future-proof in case we wanted to make any changes not to give to future devs the ability to choose. So, I would go with switching everything to sdk.Dec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your comment!
I'm unsure how this change would effectively enforce any constraints on future developers when the function signature remains unchanged, and only its internals are to be modified to utilize sdk.Dec
. Could you please provide more insight into your perspective?
x/blobstream/types/validator.go
Outdated
powers := map[string]int64{} | ||
// loop over ibv and initialize the map with their powers | ||
for _, bv := range ibv { | ||
powers[bv.EVMAddress.Hex()] = int64(bv.Power) | ||
powers[bv.EVMAddress.Hex()] = int64(bv.Power) // TODO: overflow? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validator powers are of type uint64
, and the current conversion could potentially lead to overflow. Upon reviewing the ValidateBasic
function, it appears that there is no range check performed on the power value. It would be prudent to confirm whether there might be any validators with powers falling within the range of [math.MaxInt64
, math.MaxUint64
]. Such power values could indeed cause an overflow issue in the code line mentioned above. (For example the power value of math.MaxUint64
becomes -1
when converted to int64
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch 👍 But I think if the state machine got to a state where this overflows, then something is seriously messed up with the staking module. In fact, values like those will not be accepted by the staking module, then we normalize those values before this step. I think that we can use a validation at this level as a last line of defense, but reaching it is super unlikely if I understand corerctly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
values like those will not be accepted by the staking module
So, does it mean that there will never be a case in which a validator's power reside in this range [math.MaxInt64, math.MaxUint64]? and it is guaranteed by the staking module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the validator power is using int64
, so no overflow would happen. However, I found something interesting:
https://github.com/celestiaorg/cosmos-sdk/blob/main/x/staking/types/validator.go#L369-L372
// PotentialConsensusPower returns the potential consensus-engine power.
func (v Validator) PotentialConsensusPower(r math.Int) int64 {
return sdk.TokensToConsensusPower(v.Tokens, r)
}
The power is being reduced by a factor of:
// DefaultPowerReduction is the default amount of staking tokens required for 1 unit of consensus-engine power
var DefaultPowerReduction = NewIntFromUint64(1000000)
However, the tokens amount is represented by an int256... So, there might be overflow there when going from tokens to consensus-engine power unless there is the assumption that the staked tokens wouldn't be that much.
cc @evan-forbes any idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry mind pointing out where's the int256 to save me a sec 😅
this is good to keep in the back of our heads, especially for networks such as arabica where the supply and voting power is getting rather insane.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the validator
struct, the delegated tokens are represented using Tokens
which are Int
s which are sdkmath.Int
.
Then, these are used when calculating the validator delegation and power in here after getting the consensus-engine power
which would panic when converting from sdkmath.Int
to int64
if the amount is out of bounds.
Codecov Report
@@ Coverage Diff @@
## main #2719 +/- ##
==========================================
+ Coverage 19.93% 19.95% +0.02%
==========================================
Files 139 139
Lines 16702 16707 +5
==========================================
+ Hits 3329 3334 +5
Misses 13051 13051
Partials 322 322
|
It appears that this PR also resolves issue #2699. I couldn't locate any |
Apparently yes, this is also handling that issue, please do update. Thanks a lot for helping with this 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome stuff 👍
I will approve after we switch all arithmetic operations to using sdk.Dec
.
x/blobstream/types/validator.go
Outdated
@@ -112,7 +113,8 @@ func EVMAddrLessThan(e common.Address, o common.Address) bool { | |||
// increases by 1% due to inflation, we shouldn't have to generate a new | |||
// validator set, after all the validators retained their relative percentages | |||
// during inflation and normalized Blobstream power shows no difference. | |||
func (ibv InternalBridgeValidators) PowerDiff(c InternalBridgeValidators) float64 { | |||
func (ibv InternalBridgeValidators) PowerDiff( | |||
c InternalBridgeValidators) sdk.Dec { | |||
powers := map[string]int64{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think switching to sdk.Dec
would be also future-proof in case we wanted to make any changes not to give to future devs the ability to choose. So, I would go with switching everything to sdk.Dec
imo I think we should do this, but in a different issue/bump. We still need to test this on IRL networks to make sure that we're doing this in a non consensus breaking way or reevaluate and the simpler we can make that process the better |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one quick question to remove another instance of floats right above these, but still not blocking on it
before merging the backported version of this, we should sync from scratch and ideally perform other tests to ensure that this is not consensus breaking. If it is, then we can reevaluate our options from there |
Considering this comment of @evan-forbes, do we still want to refactor the initial section of the |
…in-significantpowerdiff
my understanding was that this would potentially stop an overflow with large stake? correct me if I'm wrong @sweexordious reguardless I think we should merge this or some version of it sooner rather than later as ideally this would be included in the version that is used for mainnet |
…ec-in-significantpowerdiff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome stuff 👍 👍
just apply the comments and will approve
efae962
to
f7d07c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…ion (backport #2719) (#2735) This is an automatic backport of pull request #2719 done by [Mergify](https://mergify.com). Cherry-pick of 6192a5a has failed: ``` On branch mergify/bp/v1.x/pr-2719 Your branch is up to date with 'origin/v1.x'. You are currently cherry-picking commit 6192a5a. (fix conflicts and run "git cherry-pick --continue") (use "git cherry-pick --skip" to skip this patch) (use "git cherry-pick --abort" to cancel the cherry-pick operation) Changes to be committed: modified: x/qgb/abci.go Unmerged paths: (use "git add <file>..." to mark resolution) both modified: x/qgb/types/types_test.go both modified: x/qgb/types/validator.go ``` To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/github/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally --- <details> <summary>Mergify commands and options</summary> <br /> More conditions and actions can be found in the [documentation](https://docs.mergify.com/). You can also trigger Mergify actions by commenting on this pull request: - `@Mergifyio refresh` will re-evaluate the rules - `@Mergifyio rebase` will rebase this PR on its base branch - `@Mergifyio update` will merge the base branch into this PR - `@Mergifyio backport <destination>` will backport this PR on `<destination>` branch Additionally, on Mergify [dashboard](https://dashboard.mergify.com) you can: - look at your merge queues - generate the Mergify configuration with the config editor. Finally, you can contact us on https://mergify.com </details> --------- Co-authored-by: Sanaz Taheri <35961250+staheri14@users.noreply.github.com> Co-authored-by: CHAMI Rachid <chamirachid1@gmail.com>
Closes #2700
Closes #2699