package types
|
|
|
|
import (
|
|
"bytes"
|
|
"sort"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
|
)
|
|
|
|
var (
|
|
valEd25519 = []string{ABCIPubKeyTypeEd25519}
|
|
valSecp256k1 = []string{ABCIPubKeyTypeSecp256k1}
|
|
valSr25519 = []string{ABCIPubKeyTypeSr25519}
|
|
)
|
|
|
|
func TestConsensusParamsValidation(t *testing.T) {
|
|
testCases := []struct {
|
|
params ConsensusParams
|
|
valid bool
|
|
}{
|
|
// test block params
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 1,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: true,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 0,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 47 * 1024 * 1024,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: true,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 10,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: true,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 100 * 1024 * 1024,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: true,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 101 * 1024 * 1024,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 1024 * 1024 * 1024,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 1024 * 1024 * 1024,
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
// test evidence params
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 1,
|
|
evidenceAge: 0,
|
|
maxEvidenceBytes: 0,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 1,
|
|
evidenceAge: 2,
|
|
maxEvidenceBytes: 2,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 1000,
|
|
evidenceAge: 2,
|
|
maxEvidenceBytes: 1,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: true,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
blockBytes: 1,
|
|
evidenceAge: -1,
|
|
maxEvidenceBytes: 0,
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
// test no pubkey type provided
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
evidenceAge: 2,
|
|
pubkeyTypes: []string{},
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
// test invalid pubkey type provided
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
evidenceAge: 2,
|
|
pubkeyTypes: []string{"potatoes make good pubkeys"},
|
|
precision: 1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
// test invalid pubkey type provided
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
evidenceAge: 2,
|
|
precision: 1,
|
|
messageDelay: -1}),
|
|
valid: false,
|
|
},
|
|
{
|
|
params: makeParams(makeParamsArgs{
|
|
evidenceAge: 2,
|
|
precision: -1,
|
|
messageDelay: 1}),
|
|
valid: false,
|
|
},
|
|
}
|
|
for i, tc := range testCases {
|
|
if tc.valid {
|
|
assert.NoErrorf(t, tc.params.ValidateConsensusParams(), "expected no error for valid params (#%d)", i)
|
|
} else {
|
|
assert.Errorf(t, tc.params.ValidateConsensusParams(), "expected error for non valid params (#%d)", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
type makeParamsArgs struct {
|
|
blockBytes int64
|
|
blockGas int64
|
|
evidenceAge int64
|
|
maxEvidenceBytes int64
|
|
pubkeyTypes []string
|
|
precision time.Duration
|
|
messageDelay time.Duration
|
|
propose time.Duration
|
|
proposeDelta time.Duration
|
|
vote time.Duration
|
|
voteDelta time.Duration
|
|
commit time.Duration
|
|
bypassCommitTimeout bool
|
|
}
|
|
|
|
func makeParams(args makeParamsArgs) ConsensusParams {
|
|
if args.pubkeyTypes == nil {
|
|
args.pubkeyTypes = valEd25519
|
|
}
|
|
return ConsensusParams{
|
|
Block: BlockParams{
|
|
MaxBytes: args.blockBytes,
|
|
MaxGas: args.blockGas,
|
|
},
|
|
Evidence: EvidenceParams{
|
|
MaxAgeNumBlocks: args.evidenceAge,
|
|
MaxAgeDuration: time.Duration(args.evidenceAge),
|
|
MaxBytes: args.maxEvidenceBytes,
|
|
},
|
|
Validator: ValidatorParams{
|
|
PubKeyTypes: args.pubkeyTypes,
|
|
},
|
|
Synchrony: SynchronyParams{
|
|
Precision: args.precision,
|
|
MessageDelay: args.messageDelay,
|
|
},
|
|
Timeout: TimeoutParams{
|
|
Propose: args.propose,
|
|
ProposeDelta: args.proposeDelta,
|
|
Vote: args.vote,
|
|
VoteDelta: args.voteDelta,
|
|
Commit: args.commit,
|
|
BypassCommitTimeout: args.bypassCommitTimeout,
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestConsensusParamsHash(t *testing.T) {
|
|
params := []ConsensusParams{
|
|
makeParams(makeParamsArgs{blockBytes: 4, blockGas: 2, evidenceAge: 3, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 1, blockGas: 4, evidenceAge: 3, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 4, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 2, blockGas: 5, evidenceAge: 7, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 1, blockGas: 7, evidenceAge: 6, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 9, blockGas: 5, evidenceAge: 4, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 7, blockGas: 8, evidenceAge: 9, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 4, blockGas: 6, evidenceAge: 5, maxEvidenceBytes: 1}),
|
|
}
|
|
|
|
hashes := make([][]byte, len(params))
|
|
for i := range params {
|
|
hashes[i] = params[i].HashConsensusParams()
|
|
}
|
|
|
|
// make sure there are no duplicates...
|
|
// sort, then check in order for matches
|
|
sort.Slice(hashes, func(i, j int) bool {
|
|
return bytes.Compare(hashes[i], hashes[j]) < 0
|
|
})
|
|
for i := 0; i < len(hashes)-1; i++ {
|
|
assert.NotEqual(t, hashes[i], hashes[i+1])
|
|
}
|
|
}
|
|
|
|
func TestConsensusParamsUpdate(t *testing.T) {
|
|
testCases := []struct {
|
|
intialParams ConsensusParams
|
|
updates *tmproto.ConsensusParams
|
|
updatedParams ConsensusParams
|
|
}{
|
|
// empty updates
|
|
{
|
|
intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
|
|
updates: &tmproto.ConsensusParams{},
|
|
updatedParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
|
|
},
|
|
{
|
|
// update synchrony params
|
|
intialParams: makeParams(makeParamsArgs{evidenceAge: 3, precision: time.Second, messageDelay: 3 * time.Second}),
|
|
updates: &tmproto.ConsensusParams{
|
|
Synchrony: &tmproto.SynchronyParams{
|
|
Precision: durationPtr(time.Second * 2),
|
|
MessageDelay: durationPtr(time.Second * 4),
|
|
},
|
|
},
|
|
updatedParams: makeParams(makeParamsArgs{evidenceAge: 3, precision: 2 * time.Second, messageDelay: 4 * time.Second}),
|
|
},
|
|
{
|
|
// update timeout params
|
|
intialParams: makeParams(makeParamsArgs{
|
|
propose: 3 * time.Second,
|
|
proposeDelta: 500 * time.Millisecond,
|
|
vote: time.Second,
|
|
voteDelta: 500 * time.Millisecond,
|
|
commit: time.Second,
|
|
bypassCommitTimeout: false,
|
|
}),
|
|
updates: &tmproto.ConsensusParams{
|
|
Timeout: &tmproto.TimeoutParams{
|
|
Propose: durationPtr(2 * time.Second),
|
|
ProposeDelta: durationPtr(400 * time.Millisecond),
|
|
Vote: durationPtr(5 * time.Second),
|
|
VoteDelta: durationPtr(400 * time.Millisecond),
|
|
Commit: durationPtr(time.Minute),
|
|
BypassCommitTimeout: true,
|
|
},
|
|
},
|
|
updatedParams: makeParams(makeParamsArgs{
|
|
propose: 2 * time.Second,
|
|
proposeDelta: 400 * time.Millisecond,
|
|
vote: 5 * time.Second,
|
|
voteDelta: 400 * time.Millisecond,
|
|
commit: time.Minute,
|
|
bypassCommitTimeout: true,
|
|
}),
|
|
},
|
|
// fine updates
|
|
{
|
|
intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
|
|
updates: &tmproto.ConsensusParams{
|
|
Block: &tmproto.BlockParams{
|
|
MaxBytes: 100,
|
|
MaxGas: 200,
|
|
},
|
|
Evidence: &tmproto.EvidenceParams{
|
|
MaxAgeNumBlocks: 300,
|
|
MaxAgeDuration: time.Duration(300),
|
|
MaxBytes: 50,
|
|
},
|
|
Validator: &tmproto.ValidatorParams{
|
|
PubKeyTypes: valSecp256k1,
|
|
},
|
|
},
|
|
updatedParams: makeParams(makeParamsArgs{
|
|
blockBytes: 100, blockGas: 200,
|
|
evidenceAge: 300,
|
|
maxEvidenceBytes: 50,
|
|
pubkeyTypes: valSecp256k1}),
|
|
},
|
|
{
|
|
intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
|
|
updates: &tmproto.ConsensusParams{
|
|
Block: &tmproto.BlockParams{
|
|
MaxBytes: 100,
|
|
MaxGas: 200,
|
|
},
|
|
Evidence: &tmproto.EvidenceParams{
|
|
MaxAgeNumBlocks: 300,
|
|
MaxAgeDuration: time.Duration(300),
|
|
MaxBytes: 50,
|
|
},
|
|
Validator: &tmproto.ValidatorParams{
|
|
PubKeyTypes: valSr25519,
|
|
},
|
|
},
|
|
updatedParams: makeParams(makeParamsArgs{
|
|
blockBytes: 100,
|
|
blockGas: 200,
|
|
evidenceAge: 300,
|
|
maxEvidenceBytes: 50,
|
|
pubkeyTypes: valSr25519}),
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
assert.Equal(t, tc.updatedParams, tc.intialParams.UpdateConsensusParams(tc.updates))
|
|
}
|
|
}
|
|
|
|
func TestConsensusParamsUpdate_AppVersion(t *testing.T) {
|
|
params := makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3})
|
|
|
|
assert.EqualValues(t, 0, params.Version.AppVersion)
|
|
|
|
updated := params.UpdateConsensusParams(
|
|
&tmproto.ConsensusParams{Version: &tmproto.VersionParams{AppVersion: 1}})
|
|
|
|
assert.EqualValues(t, 1, updated.Version.AppVersion)
|
|
}
|
|
|
|
func TestProto(t *testing.T) {
|
|
params := []ConsensusParams{
|
|
makeParams(makeParamsArgs{blockBytes: 4, blockGas: 2, evidenceAge: 3, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 1, blockGas: 4, evidenceAge: 3, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 4, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 2, blockGas: 5, evidenceAge: 7, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 1, blockGas: 7, evidenceAge: 6, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 9, blockGas: 5, evidenceAge: 4, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 7, blockGas: 8, evidenceAge: 9, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{blockBytes: 4, blockGas: 6, evidenceAge: 5, maxEvidenceBytes: 1}),
|
|
makeParams(makeParamsArgs{precision: time.Second, messageDelay: time.Minute}),
|
|
makeParams(makeParamsArgs{precision: time.Nanosecond, messageDelay: time.Millisecond}),
|
|
}
|
|
|
|
for i := range params {
|
|
pbParams := params[i].ToProto()
|
|
|
|
oriParams := ConsensusParamsFromProto(pbParams)
|
|
|
|
assert.Equal(t, params[i], oriParams)
|
|
|
|
}
|
|
}
|
|
|
|
func durationPtr(t time.Duration) *time.Duration {
|
|
return &t
|
|
}
|