abci++: Vote extension cleanup (#8402)

* Split vote verification/validation based on vote extensions

Some parts of the code need vote extensions to be verified and
validated (mostly in consensus), and other parts of the code don't
because its possible that, in some cases (as per RFC 017), we won't have
vote extensions.

This explicitly facilitates that split.

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Only sign extensions in precommits, not prevotes

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update privval/file.go

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Apply suggestions from code review

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Temporarily disable extension requirement again for E2E testing

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Reorganize comment for clarity

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Leave vote validation and pre-call nil check up to caller of VoteToProto

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Split complex vote validation test into multiple tests

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Universally enforce no vote extensions on any vote type but precommits

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Make error messages more generic

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Verify with vote extensions when constructing a VoteSet

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Expand comment for clarity

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Add extension check for prevotes prior to signing votes

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Fix supporting test code to only inject extensions into precommits

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Separate vote malleation from signing in vote tests for clarity

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Add extension signature length check and corresponding test

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Perform basic vote validation in CommitToVoteSet

Signed-off-by: Thane Thomson <connect@thanethomson.com>

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
This commit is contained in:
Thane Thomson
2022-04-28 17:54:33 -04:00
committed by tycho garen
co-authored by M. J. Fromberger
parent 4868bb48f5
commit 516ff45392
10 changed files with 278 additions and 100 deletions
+5 -1
View File
@@ -159,7 +159,11 @@ func signVote(
chainID string,
blockID types.BlockID) *types.Vote {
v, err := vs.signVote(ctx, voteType, chainID, blockID, []byte("extension"))
var ext []byte
if voteType == tmproto.PrecommitType {
ext = []byte("extension")
}
v, err := vs.signVote(ctx, voteType, chainID, blockID, ext)
require.NoError(t, err, "failed to sign vote")
vs.lastVote = v
+8 -2
View File
@@ -220,9 +220,13 @@ type VoteMessage struct {
func (*VoteMessage) TypeTag() string { return "tendermint/Vote" }
// ValidateBasic performs basic validation.
// ValidateBasic checks whether the vote within the message is well-formed.
func (m *VoteMessage) ValidateBasic() error {
return m.Vote.ValidateBasic()
// Here we validate votes with vote extensions, since we require vote
// extensions to be sent in precommit messages during consensus. Prevote
// messages should never have vote extensions, and this is also validated
// here.
return m.Vote.ValidateWithExtension()
}
// String returns a string representation.
@@ -534,6 +538,8 @@ func MsgFromProto(msg *tmcons.Message) (Message, error) {
Part: parts,
}
case *tmcons.Message_Vote:
// Vote validation will be handled in the vote message ValidateBasic
// call below.
vote, err := types.VoteFromProto(msg.Vote.Vote)
if err != nil {
return nil, fmt.Errorf("vote msg to proto error: %w", err)
+1
View File
@@ -40,5 +40,6 @@ func MakeVote(
}
v.Signature = vpb.Signature
v.ExtensionSignature = vpb.ExtensionSignature
return v, nil
}