-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
fix(baseapp): Utilizing voting power from VEs in ValidateVoteExtensions #17518
Changes from all commits
fdd0c10
0326838
f5d0bf2
cd4b843
e1adb6a
cb1648c
dc416ce
f1ef63d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,8 +29,7 @@ type ( | |
// extension signatures. Typically, this will be implemented by the x/staking | ||
// module, which has knowledge of the CometBFT public key. | ||
ValidatorStore interface { | ||
TotalBondedTokens(ctx context.Context) (math.Int, error) | ||
BondedTokensAndPubKeyByConsAddr(context.Context, sdk.ConsAddress) (math.Int, cmtprotocrypto.PublicKey, error) | ||
GetPubKeyByConsAddr(context.Context, sdk.ConsAddress) (cmtprotocrypto.PublicKey, error) | ||
} | ||
|
||
// GasTx defines the contract that a transaction with a gas limit must implement. | ||
|
@@ -62,8 +61,16 @@ func ValidateVoteExtensions( | |
return buf.Bytes(), nil | ||
} | ||
|
||
sumVP := math.NewInt(0) | ||
var ( | ||
// Total voting power of all vote extensions. | ||
totalVP int64 | ||
// Total voting power of all validators that submitted valid vote extensions. | ||
sumVP int64 | ||
) | ||
|
||
for _, vote := range extCommit.Votes { | ||
totalVP += vote.Validator.Power | ||
|
||
// Only check + include power if the vote is a commit vote. There must be super-majority, otherwise the | ||
// previous block (the block vote is for) could not have been committed. | ||
if vote.BlockIdFlag != cmtproto.BlockIDFlagCommit { | ||
|
@@ -86,12 +93,12 @@ func ValidateVoteExtensions( | |
} | ||
|
||
valConsAddr := sdk.ConsAddress(vote.Validator.Address) | ||
bondedTokens, cmtPubKeyProto, err := valStore.BondedTokensAndPubKeyByConsAddr(ctx, valConsAddr) | ||
pubKeyProto, err := valStore.GetPubKeyByConsAddr(ctx, valConsAddr) | ||
if err != nil { | ||
return fmt.Errorf("failed to get validator %X info (bonded tokens and public key): %w", valConsAddr, err) | ||
return fmt.Errorf("failed to get validator %X public key: %w", valConsAddr, err) | ||
} | ||
|
||
cmtPubKey, err := cryptoenc.PubKeyFromProto(cmtPubKeyProto) | ||
cmtPubKey, err := cryptoenc.PubKeyFromProto(pubKeyProto) | ||
if err != nil { | ||
return fmt.Errorf("failed to convert validator %X public key: %w", valConsAddr, err) | ||
} | ||
|
@@ -112,19 +119,14 @@ func ValidateVoteExtensions( | |
return fmt.Errorf("failed to verify validator %X vote extension signature", valConsAddr) | ||
} | ||
|
||
sumVP = sumVP.Add(bondedTokens) | ||
sumVP += vote.Validator.Power | ||
} | ||
|
||
// Ensure we have at least 2/3 voting power that submitted valid vote | ||
// extensions. | ||
totalVP, err := valStore.TotalBondedTokens(ctx) | ||
if err != nil { | ||
return fmt.Errorf("failed to get total bonded tokens: %w", err) | ||
} | ||
|
||
percentSubmitted := math.LegacyNewDecFromInt(sumVP).Quo(math.LegacyNewDecFromInt(totalVP)) | ||
if percentSubmitted.LT(VoteExtensionThreshold) { | ||
return fmt.Errorf("insufficient cumulative voting power received to verify vote extensions; got: %s, expected: >=%s", percentSubmitted, VoteExtensionThreshold) | ||
if totalVP > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this should ever be possible, but adding this as a sanity check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. its totalVP a signed integer? lmfao 🤣 I'd flip the logic around, personally. <= 0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol better safe than sorry... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. kek |
||
percentSubmitted := math.LegacyNewDecFromInt(math.NewInt(sumVP)).Quo(math.LegacyNewDecFromInt(math.NewInt(totalVP))) | ||
if percentSubmitted.LT(VoteExtensionThreshold) { | ||
return fmt.Errorf("insufficient cumulative voting power received to verify vote extensions; got: %s, expected: >=%s", percentSubmitted, VoteExtensionThreshold) | ||
} | ||
} | ||
|
||
return nil | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.
this is such a footgun. bondedTokens is actually useless in the
ValidatorStore
interface.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.
yea wasn't sure if updating the staking keeper's
BondedTokensAndPubKeyByConsAddr
would break anything elsewhere. alternatively looks like we could just useValidatorByConsAddr(context.Context, sdk.ConsAddress) (ValidatorI, error)
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.
ValidatorI
has the pubkey we want