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
co-authored by Thane Thomson William Banfield
parent 03bdcad31e
commit 0bc5399249
13 changed files with 508 additions and 126 deletions
+6
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":
+5
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
+19 -18
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.
+7 -1
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
+3
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,
+13 -3
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)
}
})
}