Vote extensions: add proto fields for enabling extensions (#9865)

* [cherry-picked] abci++: add proto fields for enabling vote extensions (#8587)

This pull requests adds the protocol buffer field for the `ABCI.VoteExtensionsEnableHeight` parameter. This proto field is threaded throughout all of the relevant places where consensus params are used and referenced.

This PR also adds validation of the consensus param updates. Previous consensus param changes didn't depend on _previous_ versions of the params, so this change adds a method for validating against the old params as well.

closes: #8453

* Re-sync some things with original patch

* fixes

* Remove 'Skip' from TestApp_VoteExtensions

* Fix all unit tests

* Appease linter

* Update types/params.go

Co-authored-by: Thane Thomson <connect@thanethomson.com>

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: Thane Thomson <connect@thanethomson.com>
This commit is contained in:
Sergio Mena
2022-12-13 12:05:15 +01:00
committed by GitHub
parent 03bdcad31e
commit 0bc5399249
13 changed files with 508 additions and 126 deletions

View File

@@ -18,7 +18,7 @@ message NoBlockResponse {
// BlockResponse returns block to the requested
message BlockResponse {
tendermint.types.Block block = 1;
tendermint.types.Block block = 1;
tendermint.types.ExtendedCommit ext_commit = 2;
}

View File

@@ -34,6 +34,7 @@ type ConsensusParams struct {
Evidence *EvidenceParams `protobuf:"bytes,2,opt,name=evidence,proto3" json:"evidence,omitempty"`
Validator *ValidatorParams `protobuf:"bytes,3,opt,name=validator,proto3" json:"validator,omitempty"`
Version *VersionParams `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
Abci *ABCIParams `protobuf:"bytes,5,opt,name=abci,proto3" json:"abci,omitempty"`
}
func (m *ConsensusParams) Reset() { *m = ConsensusParams{} }
@@ -97,6 +98,13 @@ func (m *ConsensusParams) GetVersion() *VersionParams {
return nil
}
func (m *ConsensusParams) GetAbci() *ABCIParams {
if m != nil {
return m.Abci
}
return nil
}
// BlockParams contains limits on the block size.
type BlockParams struct {
// Max block size, in bytes.
@@ -373,6 +381,60 @@ func (m *HashedParams) GetBlockMaxGas() int64 {
return 0
}
// ABCIParams configure functionality specific to the Application Blockchain Interface.
type ABCIParams struct {
// vote_extensions_enable_height configures the first height during which
// vote extensions will be enabled. During this specified height, and for all
// subsequent heights, precommit messages that do not contain valid extension data
// will be considered invalid. Prior to this height, vote extensions will not
// be used or accepted by validators on the network.
//
// Once enabled, vote extensions will be created by the application in ExtendVote,
// passed to the application for validation in VerifyVoteExtension and given
// to the application to use when proposing a block during PrepareProposal.
VoteExtensionsEnableHeight int64 `protobuf:"varint,1,opt,name=vote_extensions_enable_height,json=voteExtensionsEnableHeight,proto3" json:"vote_extensions_enable_height,omitempty"`
}
func (m *ABCIParams) Reset() { *m = ABCIParams{} }
func (m *ABCIParams) String() string { return proto.CompactTextString(m) }
func (*ABCIParams) ProtoMessage() {}
func (*ABCIParams) Descriptor() ([]byte, []int) {
return fileDescriptor_e12598271a686f57, []int{6}
}
func (m *ABCIParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ABCIParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ABCIParams.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *ABCIParams) XXX_Merge(src proto.Message) {
xxx_messageInfo_ABCIParams.Merge(m, src)
}
func (m *ABCIParams) XXX_Size() int {
return m.Size()
}
func (m *ABCIParams) XXX_DiscardUnknown() {
xxx_messageInfo_ABCIParams.DiscardUnknown(m)
}
var xxx_messageInfo_ABCIParams proto.InternalMessageInfo
func (m *ABCIParams) GetVoteExtensionsEnableHeight() int64 {
if m != nil {
return m.VoteExtensionsEnableHeight
}
return 0
}
func init() {
proto.RegisterType((*ConsensusParams)(nil), "tendermint.types.ConsensusParams")
proto.RegisterType((*BlockParams)(nil), "tendermint.types.BlockParams")
@@ -380,45 +442,49 @@ func init() {
proto.RegisterType((*ValidatorParams)(nil), "tendermint.types.ValidatorParams")
proto.RegisterType((*VersionParams)(nil), "tendermint.types.VersionParams")
proto.RegisterType((*HashedParams)(nil), "tendermint.types.HashedParams")
proto.RegisterType((*ABCIParams)(nil), "tendermint.types.ABCIParams")
}
func init() { proto.RegisterFile("tendermint/types/params.proto", fileDescriptor_e12598271a686f57) }
var fileDescriptor_e12598271a686f57 = []byte{
// 513 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0x4f, 0x6f, 0xd3, 0x30,
0x18, 0xc6, 0xeb, 0xa5, 0x6c, 0xed, 0x5b, 0xba, 0x56, 0x16, 0x12, 0x61, 0x68, 0x49, 0xc9, 0x01,
0x4d, 0x9a, 0x94, 0x48, 0xec, 0x80, 0x40, 0x48, 0x13, 0x05, 0x34, 0xfe, 0x68, 0x08, 0x45, 0xc0,
0x61, 0x97, 0xc8, 0x69, 0x4c, 0x16, 0xad, 0x8e, 0xa3, 0x38, 0xa9, 0xda, 0x1b, 0x1f, 0x81, 0x23,
0xc7, 0x1d, 0xe1, 0x1b, 0xf0, 0x11, 0x76, 0xdc, 0x91, 0x13, 0xa0, 0xf6, 0xc2, 0xc7, 0x40, 0x71,
0x62, 0xd2, 0x76, 0xbb, 0x39, 0x7e, 0x7e, 0x8f, 0x9d, 0xe7, 0xb1, 0x5e, 0xd8, 0xcd, 0x68, 0x1c,
0xd0, 0x94, 0x45, 0x71, 0xe6, 0x64, 0xb3, 0x84, 0x0a, 0x27, 0x21, 0x29, 0x61, 0xc2, 0x4e, 0x52,
0x9e, 0x71, 0xdc, 0xaf, 0x65, 0x5b, 0xca, 0x3b, 0xb7, 0x42, 0x1e, 0x72, 0x29, 0x3a, 0xc5, 0xaa,
0xe4, 0x76, 0x8c, 0x90, 0xf3, 0x70, 0x4c, 0x1d, 0xf9, 0xe5, 0xe7, 0x9f, 0x9c, 0x20, 0x4f, 0x49,
0x16, 0xf1, 0xb8, 0xd4, 0xad, 0xcf, 0x1b, 0xd0, 0x7b, 0xc6, 0x63, 0x41, 0x63, 0x91, 0x8b, 0x77,
0xf2, 0x06, 0x7c, 0x00, 0x37, 0xfc, 0x31, 0x1f, 0x9d, 0xe9, 0x68, 0x80, 0xf6, 0x3a, 0x0f, 0x76,
0xed, 0xf5, 0xbb, 0xec, 0x61, 0x21, 0x97, 0xb4, 0x5b, 0xb2, 0xf8, 0x09, 0xb4, 0xe8, 0x24, 0x0a,
0x68, 0x3c, 0xa2, 0xfa, 0x86, 0xf4, 0x0d, 0xae, 0xfa, 0x5e, 0x54, 0x44, 0x65, 0xfd, 0xef, 0xc0,
0x87, 0xd0, 0x9e, 0x90, 0x71, 0x14, 0x90, 0x8c, 0xa7, 0xba, 0x26, 0xed, 0xf7, 0xae, 0xda, 0x3f,
0x2a, 0xa4, 0xf2, 0xd7, 0x1e, 0xfc, 0x08, 0xb6, 0x26, 0x34, 0x15, 0x11, 0x8f, 0xf5, 0xa6, 0xb4,
0x9b, 0xd7, 0xd8, 0x4b, 0xa0, 0x32, 0x2b, 0xde, 0x7a, 0x05, 0x9d, 0xa5, 0x3c, 0xf8, 0x2e, 0xb4,
0x19, 0x99, 0x7a, 0xfe, 0x2c, 0xa3, 0x42, 0x36, 0xa0, 0xb9, 0x2d, 0x46, 0xa6, 0xc3, 0xe2, 0x1b,
0xdf, 0x86, 0xad, 0x42, 0x0c, 0x89, 0x90, 0x21, 0x35, 0x77, 0x93, 0x91, 0xe9, 0x11, 0x11, 0xaf,
0x9b, 0x2d, 0xad, 0xdf, 0xb4, 0xbe, 0x23, 0xd8, 0x5e, 0xcd, 0x88, 0xf7, 0x01, 0x17, 0x0e, 0x12,
0x52, 0x2f, 0xce, 0x99, 0x27, 0xcb, 0x52, 0xe7, 0xf6, 0x18, 0x99, 0x3e, 0x0d, 0xe9, 0xdb, 0x9c,
0xc9, 0x1f, 0x10, 0xf8, 0x18, 0xfa, 0x0a, 0x56, 0xef, 0x54, 0x95, 0x79, 0xc7, 0x2e, 0x1f, 0xd2,
0x56, 0x0f, 0x69, 0x3f, 0xaf, 0x80, 0x61, 0xeb, 0xe2, 0x97, 0xd9, 0xf8, 0xfa, 0xdb, 0x44, 0xee,
0x76, 0x79, 0x9e, 0x52, 0x56, 0xa3, 0x68, 0xab, 0x51, 0xac, 0x43, 0xe8, 0xad, 0xf5, 0x89, 0x2d,
0xe8, 0x26, 0xb9, 0xef, 0x9d, 0xd1, 0x99, 0x27, 0x1b, 0xd3, 0xd1, 0x40, 0xdb, 0x6b, 0xbb, 0x9d,
0x24, 0xf7, 0xdf, 0xd0, 0xd9, 0xfb, 0x62, 0xeb, 0x71, 0xeb, 0xc7, 0xb9, 0x89, 0xfe, 0x9e, 0x9b,
0xc8, 0xda, 0x87, 0xee, 0x4a, 0xa3, 0xb8, 0x0f, 0x1a, 0x49, 0x12, 0x99, 0xad, 0xe9, 0x16, 0xcb,
0x25, 0xf8, 0x04, 0x6e, 0xbe, 0x24, 0xe2, 0x94, 0x06, 0x15, 0x7b, 0x1f, 0x7a, 0xb2, 0x0a, 0x6f,
0xbd, 0xeb, 0xae, 0xdc, 0x3e, 0x56, 0x85, 0x5b, 0xd0, 0xad, 0xb9, 0xba, 0xf6, 0x8e, 0xa2, 0x8e,
0x88, 0x18, 0x7e, 0xf8, 0x36, 0x37, 0xd0, 0xc5, 0xdc, 0x40, 0x97, 0x73, 0x03, 0xfd, 0x99, 0x1b,
0xe8, 0xcb, 0xc2, 0x68, 0x5c, 0x2e, 0x8c, 0xc6, 0xcf, 0x85, 0xd1, 0x38, 0x79, 0x18, 0x46, 0xd9,
0x69, 0xee, 0xdb, 0x23, 0xce, 0x9c, 0xe5, 0x99, 0xaa, 0x97, 0xe5, 0xd0, 0xac, 0xcf, 0x9b, 0xbf,
0x29, 0xf7, 0x0f, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x48, 0xd2, 0x61, 0x14, 0x8a, 0x03, 0x00,
0x00,
// 573 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0x3f, 0x6f, 0xd3, 0x4e,
0x18, 0xc7, 0x73, 0x75, 0xda, 0xa6, 0x4f, 0x7e, 0x69, 0xa2, 0xd3, 0x4f, 0xc2, 0x14, 0xe2, 0x04,
0x0f, 0xa8, 0x52, 0x25, 0x1b, 0xd1, 0x01, 0x81, 0x90, 0xaa, 0xa4, 0x44, 0x6d, 0x41, 0x05, 0x64,
0x01, 0x43, 0x17, 0xeb, 0x9c, 0x1c, 0x8e, 0xd5, 0xd8, 0x67, 0xf9, 0xce, 0x51, 0xf2, 0x2e, 0x18,
0x19, 0x3b, 0xc2, 0xca, 0xc4, 0x4b, 0xe8, 0xd8, 0x91, 0x09, 0x50, 0xb2, 0xf0, 0x32, 0x90, 0xcf,
0x76, 0x9d, 0x3f, 0x6c, 0x77, 0xf7, 0x7c, 0x3e, 0xf7, 0xe7, 0xfb, 0xe8, 0xa0, 0x29, 0x68, 0x30,
0xa0, 0x91, 0xef, 0x05, 0xc2, 0x14, 0xd3, 0x90, 0x72, 0x33, 0x24, 0x11, 0xf1, 0xb9, 0x11, 0x46,
0x4c, 0x30, 0xdc, 0x28, 0xca, 0x86, 0x2c, 0xef, 0xfd, 0xef, 0x32, 0x97, 0xc9, 0xa2, 0x99, 0x8c,
0x52, 0x6e, 0x4f, 0x73, 0x19, 0x73, 0x47, 0xd4, 0x94, 0x33, 0x27, 0xfe, 0x68, 0x0e, 0xe2, 0x88,
0x08, 0x8f, 0x05, 0x69, 0x5d, 0xff, 0xb6, 0x01, 0xf5, 0x63, 0x16, 0x70, 0x1a, 0xf0, 0x98, 0xbf,
0x95, 0x27, 0xe0, 0x43, 0xd8, 0x74, 0x46, 0xac, 0x7f, 0xa9, 0xa2, 0x36, 0xda, 0xaf, 0x3e, 0x6e,
0x1a, 0xab, 0x67, 0x19, 0xdd, 0xa4, 0x9c, 0xd2, 0x56, 0xca, 0xe2, 0xe7, 0x50, 0xa1, 0x63, 0x6f,
0x40, 0x83, 0x3e, 0x55, 0x37, 0xa4, 0xd7, 0x5e, 0xf7, 0x7a, 0x19, 0x91, 0xa9, 0xb7, 0x06, 0x3e,
0x82, 0x9d, 0x31, 0x19, 0x79, 0x03, 0x22, 0x58, 0xa4, 0x2a, 0x52, 0x7f, 0xb0, 0xae, 0x7f, 0xc8,
0x91, 0xcc, 0x2f, 0x1c, 0xfc, 0x14, 0xb6, 0xc7, 0x34, 0xe2, 0x1e, 0x0b, 0xd4, 0xb2, 0xd4, 0x5b,
0xff, 0xd0, 0x53, 0x20, 0x93, 0x73, 0x1e, 0x3f, 0x82, 0x32, 0x71, 0xfa, 0x9e, 0xba, 0x29, 0xbd,
0xfb, 0xeb, 0x5e, 0xa7, 0x7b, 0x7c, 0x96, 0x49, 0x92, 0xd4, 0xcf, 0xa0, 0xba, 0x90, 0x00, 0xbe,
0x07, 0x3b, 0x3e, 0x99, 0xd8, 0xce, 0x54, 0x50, 0x2e, 0x33, 0x53, 0xac, 0x8a, 0x4f, 0x26, 0xdd,
0x64, 0x8e, 0xef, 0xc0, 0x76, 0x52, 0x74, 0x09, 0x97, 0xb1, 0x28, 0xd6, 0x96, 0x4f, 0x26, 0x27,
0x84, 0xbf, 0x2c, 0x57, 0x94, 0x46, 0x59, 0xff, 0x8a, 0x60, 0x77, 0x39, 0x15, 0x7c, 0x00, 0x38,
0x31, 0x88, 0x4b, 0xed, 0x20, 0xf6, 0x6d, 0x19, 0x6f, 0xbe, 0x6f, 0xdd, 0x27, 0x93, 0x8e, 0x4b,
0x5f, 0xc7, 0xbe, 0xbc, 0x00, 0xc7, 0xe7, 0xd0, 0xc8, 0xe1, 0xbc, 0xb3, 0x59, 0xfc, 0x77, 0x8d,
0xb4, 0xf5, 0x46, 0xde, 0x7a, 0xe3, 0x45, 0x06, 0x74, 0x2b, 0xd7, 0x3f, 0x5b, 0xa5, 0xcf, 0xbf,
0x5a, 0xc8, 0xda, 0x4d, 0xf7, 0xcb, 0x2b, 0xcb, 0x4f, 0x51, 0x96, 0x9f, 0xa2, 0x1f, 0x41, 0x7d,
0xa5, 0x03, 0x58, 0x87, 0x5a, 0x18, 0x3b, 0xf6, 0x25, 0x9d, 0xda, 0x32, 0x2b, 0x15, 0xb5, 0x95,
0xfd, 0x1d, 0xab, 0x1a, 0xc6, 0xce, 0x2b, 0x3a, 0x7d, 0x97, 0x2c, 0x3d, 0xab, 0x7c, 0xbf, 0x6a,
0xa1, 0x3f, 0x57, 0x2d, 0xa4, 0x1f, 0x40, 0x6d, 0xa9, 0x07, 0xb8, 0x01, 0x0a, 0x09, 0x43, 0xf9,
0xb6, 0xb2, 0x95, 0x0c, 0x17, 0xe0, 0x0b, 0xf8, 0xef, 0x94, 0xf0, 0x21, 0x1d, 0x64, 0xec, 0x43,
0xa8, 0xcb, 0x28, 0xec, 0xd5, 0xac, 0x6b, 0x72, 0xf9, 0x3c, 0x0f, 0x5c, 0x87, 0x5a, 0xc1, 0x15,
0xb1, 0x57, 0x73, 0xea, 0x84, 0x70, 0xfd, 0x0d, 0x40, 0xd1, 0x54, 0xdc, 0x81, 0xe6, 0x98, 0x09,
0x6a, 0xd3, 0x89, 0xa0, 0x41, 0x72, 0x3b, 0x6e, 0xd3, 0x80, 0x38, 0x23, 0x6a, 0x0f, 0xa9, 0xe7,
0x0e, 0x45, 0x76, 0xce, 0x5e, 0x02, 0xf5, 0x6e, 0x99, 0x9e, 0x44, 0x4e, 0x25, 0xd1, 0x7d, 0xff,
0x65, 0xa6, 0xa1, 0xeb, 0x99, 0x86, 0x6e, 0x66, 0x1a, 0xfa, 0x3d, 0xd3, 0xd0, 0xa7, 0xb9, 0x56,
0xba, 0x99, 0x6b, 0xa5, 0x1f, 0x73, 0xad, 0x74, 0xf1, 0xc4, 0xf5, 0xc4, 0x30, 0x76, 0x8c, 0x3e,
0xf3, 0xcd, 0xc5, 0x6f, 0x5d, 0x0c, 0xd3, 0x7f, 0xbb, 0xfa, 0xe5, 0x9d, 0x2d, 0xb9, 0x7e, 0xf8,
0x37, 0x00, 0x00, 0xff, 0xff, 0x97, 0xf3, 0x81, 0x30, 0x0d, 0x04, 0x00, 0x00,
}
func (this *ConsensusParams) Equal(that interface{}) bool {
@@ -452,6 +518,9 @@ func (this *ConsensusParams) Equal(that interface{}) bool {
if !this.Version.Equal(that1.Version) {
return false
}
if !this.Abci.Equal(that1.Abci) {
return false
}
return true
}
func (this *BlockParams) Equal(that interface{}) bool {
@@ -591,6 +660,30 @@ func (this *HashedParams) Equal(that interface{}) bool {
}
return true
}
func (this *ABCIParams) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
that1, ok := that.(*ABCIParams)
if !ok {
that2, ok := that.(ABCIParams)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
return this == nil
} else if this == nil {
return false
}
if this.VoteExtensionsEnableHeight != that1.VoteExtensionsEnableHeight {
return false
}
return true
}
func (m *ConsensusParams) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -611,6 +704,18 @@ func (m *ConsensusParams) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.Abci != nil {
{
size, err := m.Abci.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintParams(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x2a
}
if m.Version != nil {
{
size, err := m.Version.MarshalToSizedBuffer(dAtA[:i])
@@ -720,12 +825,12 @@ func (m *EvidenceParams) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x18
}
n5, err5 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.MaxAgeDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.MaxAgeDuration):])
if err5 != nil {
return 0, err5
n6, err6 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.MaxAgeDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.MaxAgeDuration):])
if err6 != nil {
return 0, err6
}
i -= n5
i = encodeVarintParams(dAtA, i, uint64(n5))
i -= n6
i = encodeVarintParams(dAtA, i, uint64(n6))
i--
dAtA[i] = 0x12
if m.MaxAgeNumBlocks != 0 {
@@ -829,6 +934,34 @@ func (m *HashedParams) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *ABCIParams) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ABCIParams) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ABCIParams) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.VoteExtensionsEnableHeight != 0 {
i = encodeVarintParams(dAtA, i, uint64(m.VoteExtensionsEnableHeight))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintParams(dAtA []byte, offset int, v uint64) int {
offset -= sovParams(v)
base := offset
@@ -954,6 +1087,10 @@ func (m *ConsensusParams) Size() (n int) {
l = m.Version.Size()
n += 1 + l + sovParams(uint64(l))
}
if m.Abci != nil {
l = m.Abci.Size()
n += 1 + l + sovParams(uint64(l))
}
return n
}
@@ -1031,6 +1168,18 @@ func (m *HashedParams) Size() (n int) {
return n
}
func (m *ABCIParams) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.VoteExtensionsEnableHeight != 0 {
n += 1 + sovParams(uint64(m.VoteExtensionsEnableHeight))
}
return n
}
func sovParams(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -1210,6 +1359,42 @@ func (m *ConsensusParams) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Abci", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthParams
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthParams
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Abci == nil {
m.Abci = &ABCIParams{}
}
if err := m.Abci.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipParams(dAtA[iNdEx:])
@@ -1679,6 +1864,75 @@ func (m *HashedParams) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ABCIParams) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ABCIParams: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ABCIParams: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteExtensionsEnableHeight", wireType)
}
m.VoteExtensionsEnableHeight = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.VoteExtensionsEnableHeight |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipParams(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthParams
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipParams(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@@ -15,6 +15,7 @@ message ConsensusParams {
EvidenceParams evidence = 2;
ValidatorParams validator = 3;
VersionParams version = 4;
ABCIParams abci = 5;
}
// BlockParams contains limits on the block size.
@@ -75,3 +76,17 @@ message HashedParams {
int64 block_max_bytes = 1;
int64 block_max_gas = 2;
}
// ABCIParams configure functionality specific to the Application Blockchain Interface.
message ABCIParams {
// vote_extensions_enable_height configures the first height during which
// vote extensions will be enabled. During this specified height, and for all
// subsequent heights, precommit messages that do not contain valid extension data
// will be considered invalid. Prior to this height, vote extensions will not
// be used or accepted by validators on the network.
//
// Once enabled, vote extensions will be created by the application in ExtendVote,
// passed to the application for validation in VerifyVoteExtension and given
// to the application to use when proposing a block during PrepareProposal.
int64 vote_extensions_enable_height = 1;
}

View File

@@ -532,7 +532,7 @@ func updateState(
if len(validatorUpdates) > 0 {
err := nValSet.UpdateWithChangeSet(validatorUpdates)
if err != nil {
return state, fmt.Errorf("error changing validator set: %v", err)
return state, fmt.Errorf("changing validator set: %w", err)
}
// Change results from this height but only applies to the next next height.
lastHeightValsChanged = header.Height + 1 + 1
@@ -545,11 +545,16 @@ func updateState(
nextParams := state.ConsensusParams
lastHeightParamsChanged := state.LastHeightConsensusParamsChanged
if abciResponse.ConsensusParamUpdates != nil {
// NOTE: must not mutate s.ConsensusParams
// NOTE: must not mutate state.ConsensusParams
nextParams = state.ConsensusParams.Update(abciResponse.ConsensusParamUpdates)
err := nextParams.ValidateBasic()
if err != nil {
return state, fmt.Errorf("error updating consensus params: %v", err)
return state, fmt.Errorf("updating consensus params: %w", err)
}
err = state.ConsensusParams.ValidateUpdate(abciResponse.ConsensusParamUpdates, header.Height)
if err != nil {
return state, fmt.Errorf("updating consensus params: %w", err)
}
state.Version.Consensus.App = nextParams.Version.App

View File

@@ -1,12 +1,10 @@
package state
import (
"encoding/binary"
"errors"
"fmt"
"github.com/cosmos/gogoproto/proto"
"github.com/google/orderedcode"
dbm "github.com/tendermint/tm-db"
abci "github.com/tendermint/tendermint/abci/types"
@@ -39,18 +37,6 @@ func calcABCIResponsesKey(height int64) []byte {
return []byte(fmt.Sprintf("abciResponsesKey:%v", height))
}
var tmpABCIKey []byte
func init() {
var err error
// temporary extra key before consensus param protos are regenerated
// TODO(wbanfield) remove in next PR
tmpABCIKey, err = orderedcode.Append(nil, int64(10000))
if err != nil {
panic(err)
}
}
//----------------------
var lastABCIResponseKey = []byte("lastABCIResponseKey")
@@ -176,13 +162,6 @@ func (store dbStore) loadState(key []byte) (state State, err error) {
if err != nil {
return state, err
}
buf, err = store.db.Get(tmpABCIKey)
if err != nil {
return state, err
}
h, _ := binary.Varint(buf)
sm.ConsensusParams.ABCI.VoteExtensionsEnableHeight = h
return *sm, nil
}
@@ -217,11 +196,6 @@ func (store dbStore) save(state State, key []byte) error {
if err != nil {
return err
}
bz := make([]byte, 5)
binary.PutVarint(bz, state.ConsensusParams.ABCI.VoteExtensionsEnableHeight)
if err := store.db.SetSync(tmpABCIKey, bz); err != nil {
return err
}
return nil
}

View File

@@ -47,6 +47,8 @@ var (
"kill": 0.1,
"restart": 0.1,
}
voteExtensionEnableHeightOffset = uniformChoice{int64(0), int64(10), int64(100)}
voteExtensionEnabled = uniformChoice{true, false}
)
// Generate generates random testnets using the given RNG.
@@ -86,6 +88,10 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er
manifest.CheckTxDelay = 20 * time.Millisecond
}
if voteExtensionEnabled.Choose(r).(bool) {
manifest.VoteExtensionsEnableHeight = manifest.InitialHeight + voteExtensionEnableHeightOffset.Choose(r).(int64)
}
var numSeeds, numValidators, numFulls, numLightClients int
switch opt["topology"].(string) {
case "single":

View File

@@ -56,6 +56,11 @@ type Manifest struct {
// testnet via the RPC endpoint of a random node. Default is 0
Evidence int `toml:"evidence"`
// VoteExtensionsEnableHeight configures the first height during which
// the chain will use and require vote extension data to be present
// in precommit messages.
VoteExtensionsEnableHeight int64 `toml:"vote_extensions_enable_height"`
// ABCIProtocol specifies the protocol used to communicate with the ABCI
// application: "unix", "tcp", "grpc", or "builtin". Defaults to builtin.
// builtin will build a complete Tendermint node into the application and

View File

@@ -56,24 +56,25 @@ const (
// Testnet represents a single testnet.
type Testnet struct {
Name string
File string
Dir string
IP *net.IPNet
InitialHeight int64
InitialState map[string]string
Validators map[*Node]int64
ValidatorUpdates map[int64]map[*Node]int64
Nodes []*Node
KeyType string
Evidence int
LoadTxSizeBytes int
LoadTxBatchSize int
LoadTxConnections int
ABCIProtocol string
PrepareProposalDelay time.Duration
ProcessProposalDelay time.Duration
CheckTxDelay time.Duration
Name string
File string
Dir string
IP *net.IPNet
InitialHeight int64
InitialState map[string]string
Validators map[*Node]int64
ValidatorUpdates map[int64]map[*Node]int64
Nodes []*Node
KeyType string
Evidence int
LoadTxSizeBytes int
LoadTxBatchSize int
LoadTxConnections int
ABCIProtocol string
PrepareProposalDelay time.Duration
ProcessProposalDelay time.Duration
CheckTxDelay time.Duration
VoteExtensionsEnableHeight int64
}
// Node represents a Tendermint node in a testnet.

View File

@@ -94,9 +94,15 @@ func InjectEvidence(ctx context.Context, r *rand.Rand, testnet *e2e.Testnet, amo
ctx, privVals, evidenceHeight, valSet, testnet.Name, blockRes.Block.Time,
)
} else {
ev, err = generateDuplicateVoteEvidence(
var dve *types.DuplicateVoteEvidence
dve, err = generateDuplicateVoteEvidence(
ctx, privVals, evidenceHeight, valSet, testnet.Name, blockRes.Block.Time,
)
if dve.VoteA.Height < testnet.VoteExtensionsEnableHeight {
dve.VoteA.StripExtension()
dve.VoteB.StripExtension()
}
ev = dve
}
if err != nil {
return err

View File

@@ -131,6 +131,9 @@ func MakeGenesis(testnet *e2e.Testnet) (types.GenesisDoc, error) {
}
// set the app version to 1
genesis.ConsensusParams.Version.App = 1
genesis.ConsensusParams.Evidence.MaxAgeNumBlocks = e2e.EvidenceAgeHeight
genesis.ConsensusParams.Evidence.MaxAgeDuration = e2e.EvidenceAgeTime
genesis.ConsensusParams.ABCI.VoteExtensionsEnableHeight = testnet.VoteExtensionsEnableHeight
for validator, power := range testnet.Validators {
genesis.Validators = append(genesis.Validators, types.GenesisValidator{
Name: validator.Name,

View File

@@ -2,6 +2,7 @@ package e2e_test
import (
"bytes"
"errors"
"fmt"
"math/rand"
"strconv"
@@ -107,16 +108,25 @@ func TestApp_Tx(t *testing.T) {
func TestApp_VoteExtensions(t *testing.T) {
testNode(t, func(t *testing.T, node e2e.Node) {
t.Skip()
client, err := node.Client()
require.NoError(t, err)
info, err := client.ABCIInfo(ctx)
require.NoError(t, err)
// This special value should have been created by way of vote extensions
resp, err := client.ABCIQuery(ctx, "", []byte("extensionSum"))
require.NoError(t, err)
extSum, err := strconv.Atoi(string(resp.Response.Value))
require.NoError(t, err)
require.GreaterOrEqual(t, extSum, 0)
// if extensions are not enabled on the network, we should not expect
// the app to have any extension value set.
if node.Testnet.VoteExtensionsEnableHeight == 0 ||
info.Response.LastBlockHeight < node.Testnet.VoteExtensionsEnableHeight+1 {
target := &strconv.NumError{}
require.True(t, errors.As(err, &target))
} else {
require.NoError(t, err)
require.GreaterOrEqual(t, extSum, 0)
}
})
}

View File

@@ -174,6 +174,10 @@ func (params ConsensusParams) ValidateBasic() error {
params.Evidence.MaxBytes)
}
if params.ABCI.VoteExtensionsEnableHeight < 0 {
return fmt.Errorf("ABCI.VoteExtensionsEnableHeight cannot be negative. Got: %d", params.ABCI.VoteExtensionsEnableHeight)
}
if len(params.Validator.PubKeyTypes) == 0 {
return errors.New("len(Validator.PubKeyTypes) must be greater than 0")
}
@@ -190,6 +194,30 @@ func (params ConsensusParams) ValidateBasic() error {
return nil
}
func (params ConsensusParams) ValidateUpdate(updated *tmproto.ConsensusParams, h int64) error {
if updated.Abci == nil {
return nil
}
if params.ABCI.VoteExtensionsEnableHeight == updated.Abci.VoteExtensionsEnableHeight {
return nil
}
if params.ABCI.VoteExtensionsEnableHeight != 0 && updated.Abci.VoteExtensionsEnableHeight == 0 {
return errors.New("vote extensions cannot be disabled once enabled")
}
if updated.Abci.VoteExtensionsEnableHeight <= h {
return fmt.Errorf("VoteExtensionsEnableHeight cannot be updated to a past height, "+
"initial height: %d, current height %d",
params.ABCI.VoteExtensionsEnableHeight, h)
}
if params.ABCI.VoteExtensionsEnableHeight <= h {
return fmt.Errorf("VoteExtensionsEnableHeight cannot be modified once"+
"the initial height has occurred, "+
"initial height: %d, current height %d",
params.ABCI.VoteExtensionsEnableHeight, h)
}
return nil
}
// Hash returns a hash of a subset of the parameters to store in the block header.
// Only the Block.MaxBytes and Block.MaxGas are included in the hash.
// This allows the ConsensusParams to evolve more without breaking the block
@@ -241,6 +269,9 @@ func (params ConsensusParams) Update(params2 *tmproto.ConsensusParams) Consensus
if params2.Version != nil {
res.Version.App = params2.Version.App
}
if params2.Abci != nil {
res.ABCI.VoteExtensionsEnableHeight = params2.Abci.GetVoteExtensionsEnableHeight()
}
return res
}
@@ -261,11 +292,14 @@ func (params *ConsensusParams) ToProto() tmproto.ConsensusParams {
Version: &tmproto.VersionParams{
App: params.Version.App,
},
Abci: &tmproto.ABCIParams{
VoteExtensionsEnableHeight: params.ABCI.VoteExtensionsEnableHeight,
},
}
}
func ConsensusParamsFromProto(pbParams tmproto.ConsensusParams) ConsensusParams {
return ConsensusParams{
c := ConsensusParams{
Block: BlockParams{
MaxBytes: pbParams.Block.MaxBytes,
MaxGas: pbParams.Block.MaxGas,
@@ -282,4 +316,8 @@ func ConsensusParamsFromProto(pbParams tmproto.ConsensusParams) ConsensusParams
App: pbParams.Version.App,
},
}
if pbParams.Abci != nil {
c.ABCI.VoteExtensionsEnableHeight = pbParams.Abci.GetVoteExtensionsEnableHeight()
}
return c
}

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
@@ -22,22 +23,22 @@ func TestConsensusParamsValidation(t *testing.T) {
valid bool
}{
// test block params
0: {makeParams(1, 0, 2, 0, valEd25519), true},
1: {makeParams(0, 0, 2, 0, valEd25519), false},
2: {makeParams(47*1024*1024, 0, 2, 0, valEd25519), true},
3: {makeParams(10, 0, 2, 0, valEd25519), true},
4: {makeParams(100*1024*1024, 0, 2, 0, valEd25519), true},
5: {makeParams(101*1024*1024, 0, 2, 0, valEd25519), false},
6: {makeParams(1024*1024*1024, 0, 2, 0, valEd25519), false},
0: {makeParams(1, 0, 2, 0, valEd25519, 0), true},
1: {makeParams(0, 0, 2, 0, valEd25519, 0), false},
2: {makeParams(47*1024*1024, 0, 2, 0, valEd25519, 0), true},
3: {makeParams(10, 0, 2, 0, valEd25519, 0), true},
4: {makeParams(100*1024*1024, 0, 2, 0, valEd25519, 0), true},
5: {makeParams(101*1024*1024, 0, 2, 0, valEd25519, 0), false},
6: {makeParams(1024*1024*1024, 0, 2, 0, valEd25519, 0), false},
// test evidence params
7: {makeParams(1, 0, 0, 0, valEd25519), false},
8: {makeParams(1, 0, 2, 2, valEd25519), false},
9: {makeParams(1000, 0, 2, 1, valEd25519), true},
10: {makeParams(1, 0, -1, 0, valEd25519), false},
7: {makeParams(1, 0, 0, 0, valEd25519, 0), false},
8: {makeParams(1, 0, 2, 2, valEd25519, 0), false},
9: {makeParams(1000, 0, 2, 1, valEd25519, 0), true},
10: {makeParams(1, 0, -1, 0, valEd25519, 0), false},
// test no pubkey type provided
11: {makeParams(1, 0, 2, 0, []string{}), false},
11: {makeParams(1, 0, 2, 0, []string{}, 0), false},
// test invalid pubkey type provided
12: {makeParams(1, 0, 2, 0, []string{"potatoes make good pubkeys"}), false},
12: {makeParams(1, 0, 2, 0, []string{"potatoes make good pubkeys"}, 0), false},
}
for i, tc := range testCases {
if tc.valid {
@@ -53,6 +54,7 @@ func makeParams(
evidenceAge int64,
maxEvidenceBytes int64,
pubkeyTypes []string,
abciExtensionHeight int64,
) ConsensusParams {
return ConsensusParams{
Block: BlockParams{
@@ -67,19 +69,22 @@ func makeParams(
Validator: ValidatorParams{
PubKeyTypes: pubkeyTypes,
},
ABCI: ABCIParams{
VoteExtensionsEnableHeight: abciExtensionHeight,
},
}
}
func TestConsensusParamsHash(t *testing.T) {
params := []ConsensusParams{
makeParams(4, 2, 3, 1, valEd25519),
makeParams(1, 4, 3, 1, valEd25519),
makeParams(1, 2, 4, 1, valEd25519),
makeParams(2, 5, 7, 1, valEd25519),
makeParams(1, 7, 6, 1, valEd25519),
makeParams(9, 5, 4, 1, valEd25519),
makeParams(7, 8, 9, 1, valEd25519),
makeParams(4, 6, 5, 1, valEd25519),
makeParams(4, 2, 3, 1, valEd25519, 0),
makeParams(1, 4, 3, 1, valEd25519, 0),
makeParams(1, 2, 4, 1, valEd25519, 0),
makeParams(2, 5, 7, 1, valEd25519, 0),
makeParams(1, 7, 6, 1, valEd25519, 0),
makeParams(9, 5, 4, 1, valEd25519, 0),
makeParams(7, 8, 9, 1, valEd25519, 0),
makeParams(4, 6, 5, 1, valEd25519, 0),
}
hashes := make([][]byte, len(params))
@@ -105,13 +110,13 @@ func TestConsensusParamsUpdate(t *testing.T) {
}{
// empty updates
{
makeParams(1, 2, 3, 0, valEd25519),
makeParams(1, 2, 3, 0, valEd25519, 0),
&tmproto.ConsensusParams{},
makeParams(1, 2, 3, 0, valEd25519),
makeParams(1, 2, 3, 0, valEd25519, 0),
},
// fine updates
{
makeParams(1, 2, 3, 0, valEd25519),
makeParams(1, 2, 3, 0, valEd25519, 0),
&tmproto.ConsensusParams{
Block: &tmproto.BlockParams{
MaxBytes: 100,
@@ -126,7 +131,7 @@ func TestConsensusParamsUpdate(t *testing.T) {
PubKeyTypes: valSecp256k1,
},
},
makeParams(100, 200, 300, 50, valSecp256k1),
makeParams(100, 200, 300, 50, valSecp256k1, 0),
},
}
@@ -136,7 +141,7 @@ func TestConsensusParamsUpdate(t *testing.T) {
}
func TestConsensusParamsUpdate_AppVersion(t *testing.T) {
params := makeParams(1, 2, 3, 0, valEd25519)
params := makeParams(1, 2, 3, 0, valEd25519, 0)
assert.EqualValues(t, 0, params.Version.App)
@@ -146,16 +151,76 @@ func TestConsensusParamsUpdate_AppVersion(t *testing.T) {
assert.EqualValues(t, 1, updated.Version.App)
}
func TestConsensusParamsUpdate_VoteExtensionsEnableHeight(t *testing.T) {
t.Run("set to height but initial height already run", func(*testing.T) {
initialParams := makeParams(1, 0, 2, 0, valEd25519, 1)
update := &tmproto.ConsensusParams{
Abci: &tmproto.ABCIParams{
VoteExtensionsEnableHeight: 10,
},
}
require.Error(t, initialParams.ValidateUpdate(update, 1))
require.Error(t, initialParams.ValidateUpdate(update, 5))
})
t.Run("reset to 0", func(t *testing.T) {
initialParams := makeParams(1, 0, 2, 0, valEd25519, 1)
update := &tmproto.ConsensusParams{
Abci: &tmproto.ABCIParams{
VoteExtensionsEnableHeight: 0,
},
}
require.Error(t, initialParams.ValidateUpdate(update, 1))
})
t.Run("set to height before current height run", func(*testing.T) {
initialParams := makeParams(1, 0, 2, 0, valEd25519, 100)
update := &tmproto.ConsensusParams{
Abci: &tmproto.ABCIParams{
VoteExtensionsEnableHeight: 10,
},
}
require.Error(t, initialParams.ValidateUpdate(update, 11))
require.Error(t, initialParams.ValidateUpdate(update, 99))
})
t.Run("set to height after current height run", func(*testing.T) {
initialParams := makeParams(1, 0, 2, 0, valEd25519, 300)
update := &tmproto.ConsensusParams{
Abci: &tmproto.ABCIParams{
VoteExtensionsEnableHeight: 99,
},
}
require.NoError(t, initialParams.ValidateUpdate(update, 11))
require.NoError(t, initialParams.ValidateUpdate(update, 98))
})
t.Run("no error when unchanged", func(*testing.T) {
initialParams := makeParams(1, 0, 2, 0, valEd25519, 100)
update := &tmproto.ConsensusParams{
Abci: &tmproto.ABCIParams{
VoteExtensionsEnableHeight: 100,
},
}
require.NoError(t, initialParams.ValidateUpdate(update, 500))
})
t.Run("updated from 0 to 0", func(t *testing.T) {
initialParams := makeParams(1, 0, 2, 0, valEd25519, 0)
update := &tmproto.ConsensusParams{
Abci: &tmproto.ABCIParams{
VoteExtensionsEnableHeight: 0,
},
}
require.NoError(t, initialParams.ValidateUpdate(update, 100))
})
}
func TestProto(t *testing.T) {
params := []ConsensusParams{
makeParams(4, 2, 3, 1, valEd25519),
makeParams(1, 4, 3, 1, valEd25519),
makeParams(1, 2, 4, 1, valEd25519),
makeParams(2, 5, 7, 1, valEd25519),
makeParams(1, 7, 6, 1, valEd25519),
makeParams(9, 5, 4, 1, valEd25519),
makeParams(7, 8, 9, 1, valEd25519),
makeParams(4, 6, 5, 1, valEd25519),
makeParams(4, 2, 3, 1, valEd25519, 1),
makeParams(1, 4, 3, 1, valEd25519, 1),
makeParams(1, 2, 4, 1, valEd25519, 1),
makeParams(2, 5, 7, 1, valEd25519, 1),
makeParams(1, 7, 6, 1, valEd25519, 1),
makeParams(9, 5, 4, 1, valEd25519, 1),
makeParams(7, 8, 9, 1, valEd25519, 1),
makeParams(4, 6, 5, 1, valEd25519, 1),
}
for i := range params {