From 82a2bd70764c79f6d576f0a68795d16cd6767ef6 Mon Sep 17 00:00:00 2001 From: William Banfield Date: Tue, 30 Nov 2021 15:15:56 -0500 Subject: [PATCH] add validation and testing for genesis doc --- types/genesis_test.go | 16 +++-- types/params.go | 19 +++++- types/params_test.go | 147 ++++++++++++++++++++++++++---------------- 3 files changed, 122 insertions(+), 60 deletions(-) diff --git a/types/genesis_test.go b/types/genesis_test.go index 422c2125f..c0e031e35 100644 --- a/types/genesis_test.go +++ b/types/genesis_test.go @@ -52,25 +52,31 @@ func TestGenesisBad(t *testing.T) { for _, testCase := range testCases { _, err := GenesisDocFromJSON(testCase) + t.Logf("err %s", err) assert.Error(t, err, "expected error for empty genDoc json") } } -func TestGenesisGood(t *testing.T) { +func TestBasicGenesisDoc(t *testing.T) { // test a good one by raw json genDocBytes := []byte( `{ "genesis_time": "0001-01-01T00:00:00Z", "chain_id": "test-chain-QDKdJr", "initial_height": "1000", - "consensus_params": null, "validators": [{ "pub_key":{"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="}, "power":"10", "name":"" }], "app_hash":"", - "app_state":{"account_owner": "Bob"} + "app_state":{"account_owner": "Bob"}, + "consensus_params": { + "timing": {"precision": "1", "message_delay": "10"}, + "validator": {"pub_key_types":["ed25519"]}, + "block": {"max_bytes": "100"}, + "evidence": {"max_age_num_blocks": "100", "max_age_duration": "10"} + } }`, ) _, err := GenesisDocFromJSON(genDocBytes) @@ -97,12 +103,12 @@ func TestGenesisGood(t *testing.T) { genDocBytes, err = tmjson.Marshal(genDoc) assert.NoError(t, err, "error marshaling genDoc") genDoc, err = GenesisDocFromJSON(genDocBytes) - assert.NoError(t, err, "expected no error for valid genDoc json") + require.NoError(t, err, "expected no error for valid genDoc json") // test with invalid consensus params genDoc.ConsensusParams.Block.MaxBytes = 0 genDocBytes, err = tmjson.Marshal(genDoc) - assert.NoError(t, err, "error marshaling genDoc") + require.NoError(t, err, "error marshaling genDoc") _, err = GenesisDocFromJSON(genDocBytes) assert.Error(t, err, "expected error for genDoc json with block size of 0") diff --git a/types/params.go b/types/params.go index 1a2b60ab0..3c3f00b57 100644 --- a/types/params.go +++ b/types/params.go @@ -90,6 +90,7 @@ func DefaultConsensusParams() *ConsensusParams { Evidence: DefaultEvidenceParams(), Validator: DefaultValidatorParams(), Version: DefaultVersionParams(), + Timing: DefaultTimingParams(), } } @@ -165,7 +166,7 @@ func (params ConsensusParams) ValidateConsensusParams() error { } if params.Evidence.MaxAgeDuration <= 0 { - return fmt.Errorf("evidence.MaxAgeDuration must be grater than 0 if provided, Got %v", + return fmt.Errorf("evidence.MaxAgeDuration must be greater than 0 if provided, Got %v", params.Evidence.MaxAgeDuration) } @@ -179,6 +180,16 @@ func (params ConsensusParams) ValidateConsensusParams() error { params.Evidence.MaxBytes) } + if params.Timing.MessageDelay <= 0 { + return fmt.Errorf("timing.MessageDelay must be greater than 0. Got: %d", + params.Timing.MessageDelay) + } + + if params.Timing.Precision <= 0 { + return fmt.Errorf("timing.Precision must be greater than 0. Got: %d", + params.Timing.Precision) + } + if len(params.Validator.PubKeyTypes) == 0 { return errors.New("len(Validator.PubKeyTypes) must be greater than 0") } @@ -222,6 +233,8 @@ func (params ConsensusParams) HashConsensusParams() []byte { func (params *ConsensusParams) Equals(params2 *ConsensusParams) bool { return params.Block == params2.Block && params.Evidence == params2.Evidence && + params.Version == params2.Version && + params.Timing == params2.Timing && tmstrings.StringSliceEqual(params.Validator.PubKeyTypes, params2.Validator.PubKeyTypes) } @@ -252,6 +265,10 @@ func (params ConsensusParams) UpdateConsensusParams(params2 *tmproto.ConsensusPa if params2.Version != nil { res.Version.AppVersion = params2.Version.AppVersion } + if params2.Timing != nil { + res.Timing.Precision = params2.Timing.Precision + res.Timing.MessageDelay = params2.Timing.MessageDelay + } return res } diff --git a/types/params_test.go b/types/params_test.go index 8b69a81fc..b391746b5 100644 --- a/types/params_test.go +++ b/types/params_test.go @@ -23,23 +23,26 @@ 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}, - 7: {makeParams(1024*1024*1024, 0, -1, 0, valEd25519), false}, + {makeParams(makeParamsArgs{blockBytes: 1, evidenceAge: 2, precision: 1, messageDelay: 1}), true}, + {makeParams(makeParamsArgs{blockBytes: 0, evidenceAge: 2, precision: 1, messageDelay: 1}), false}, + {makeParams(makeParamsArgs{blockBytes: 47 * 1024 * 1024, evidenceAge: 2, precision: 1, messageDelay: 1}), true}, + {makeParams(makeParamsArgs{blockBytes: 10, evidenceAge: 2, precision: 1, messageDelay: 1}), true}, + {makeParams(makeParamsArgs{blockBytes: 100 * 1024 * 1024, evidenceAge: 2, precision: 1, messageDelay: 1}), true}, + {makeParams(makeParamsArgs{blockBytes: 101 * 1024 * 1024, evidenceAge: 2, precision: 1, messageDelay: 1}), false}, + {makeParams(makeParamsArgs{blockBytes: 1024 * 1024 * 1024, evidenceAge: 2, precision: 1, messageDelay: 1}), false}, + {makeParams(makeParamsArgs{blockBytes: 1024 * 1024 * 1024, evidenceAge: 2, precision: 1, messageDelay: 1}), false}, // test evidence params - 8: {makeParams(1, 0, 0, 0, valEd25519), false}, - 9: {makeParams(1, 0, 2, 2, valEd25519), false}, - 10: {makeParams(1000, 0, 2, 1, valEd25519), true}, - 11: {makeParams(1, 0, -1, 0, valEd25519), false}, + {makeParams(makeParamsArgs{blockBytes: 1, evidenceAge: 0, maxEvidenceBytes: 0, precision: 1, messageDelay: 1}), false}, + {makeParams(makeParamsArgs{blockBytes: 1, evidenceAge: 2, maxEvidenceBytes: 2, precision: 1, messageDelay: 1}), false}, + {makeParams(makeParamsArgs{blockBytes: 1000, evidenceAge: 2, maxEvidenceBytes: 1, precision: 1, messageDelay: 1}), true}, + {makeParams(makeParamsArgs{blockBytes: 1, evidenceAge: -1, maxEvidenceBytes: 0, precision: 1, messageDelay: 1}), false}, // test no pubkey type provided - 12: {makeParams(1, 0, 2, 0, []string{}), false}, + {makeParams(makeParamsArgs{evidenceAge: 2, pubkeyTypes: []string{}, precision: 1, messageDelay: 1}), false}, // test invalid pubkey type provided - 13: {makeParams(1, 0, 2, 0, []string{"potatoes make good pubkeys"}), false}, + {makeParams(makeParamsArgs{evidenceAge: 2, pubkeyTypes: []string{"potatoes make good pubkeys"}, precision: 1, messageDelay: 1}), false}, + // test invalid pubkey type provided + {makeParams(makeParamsArgs{evidenceAge: 2, precision: 1, messageDelay: -1}), false}, + {makeParams(makeParamsArgs{evidenceAge: 2, precision: -1, messageDelay: 1}), false}, } for i, tc := range testCases { if tc.valid { @@ -50,38 +53,51 @@ func TestConsensusParamsValidation(t *testing.T) { } } -func makeParams( - blockBytes, blockGas int64, - evidenceAge int64, - maxEvidenceBytes int64, - pubkeyTypes []string, -) ConsensusParams { +type makeParamsArgs struct { + blockBytes int64 + blockGas int64 + evidenceAge int64 + maxEvidenceBytes int64 + pubkeyTypes []string + precision time.Duration + messageDelay time.Duration +} + +func makeParams(args makeParamsArgs) ConsensusParams { + if args.pubkeyTypes == nil { + args.pubkeyTypes = valEd25519 + } return ConsensusParams{ Block: BlockParams{ - MaxBytes: blockBytes, - MaxGas: blockGas, + MaxBytes: args.blockBytes, + MaxGas: args.blockGas, }, Evidence: EvidenceParams{ - MaxAgeNumBlocks: evidenceAge, - MaxAgeDuration: time.Duration(evidenceAge), - MaxBytes: maxEvidenceBytes, + MaxAgeNumBlocks: args.evidenceAge, + MaxAgeDuration: time.Duration(args.evidenceAge), + MaxBytes: args.maxEvidenceBytes, }, Validator: ValidatorParams{ - PubKeyTypes: pubkeyTypes, + PubKeyTypes: args.pubkeyTypes, + }, + Timing: TimingParams{ + Precision: args.precision, + MessageDelay: args.messageDelay, }, } + } 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(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)) @@ -101,20 +117,31 @@ func TestConsensusParamsHash(t *testing.T) { func TestConsensusParamsUpdate(t *testing.T) { testCases := []struct { - params ConsensusParams + intialParams ConsensusParams updates *tmproto.ConsensusParams updatedParams ConsensusParams }{ // empty updates { - makeParams(1, 2, 3, 0, valEd25519), - &tmproto.ConsensusParams{}, - makeParams(1, 2, 3, 0, valEd25519), + intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}), + updates: &tmproto.ConsensusParams{}, + updatedParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}), + }, + { + // update timing params + intialParams: makeParams(makeParamsArgs{evidenceAge: 3, precision: time.Second, messageDelay: 3 * time.Second}), + updates: &tmproto.ConsensusParams{ + Timing: &tmproto.TimingParams{ + Precision: time.Second * 2, + MessageDelay: time.Second * 4, + }, + }, + updatedParams: makeParams(makeParamsArgs{evidenceAge: 3, precision: 2 * time.Second, messageDelay: 4 * time.Second}), }, // fine updates { - makeParams(1, 2, 3, 0, valEd25519), - &tmproto.ConsensusParams{ + intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}), + updates: &tmproto.ConsensusParams{ Block: &tmproto.BlockParams{ MaxBytes: 100, MaxGas: 200, @@ -128,11 +155,15 @@ func TestConsensusParamsUpdate(t *testing.T) { PubKeyTypes: valSecp256k1, }, }, - makeParams(100, 200, 300, 50, valSecp256k1), + updatedParams: makeParams(makeParamsArgs{ + blockBytes: 100, blockGas: 200, + evidenceAge: 300, + maxEvidenceBytes: 50, + pubkeyTypes: valSecp256k1}), }, { - makeParams(1, 2, 3, 0, valEd25519), - &tmproto.ConsensusParams{ + intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}), + updates: &tmproto.ConsensusParams{ Block: &tmproto.BlockParams{ MaxBytes: 100, MaxGas: 200, @@ -145,17 +176,23 @@ func TestConsensusParamsUpdate(t *testing.T) { Validator: &tmproto.ValidatorParams{ PubKeyTypes: valSr25519, }, - }, makeParams(100, 200, 300, 50, valSr25519), + }, + updatedParams: makeParams(makeParamsArgs{ + blockBytes: 100, + blockGas: 200, + evidenceAge: 300, + maxEvidenceBytes: 50, + pubkeyTypes: valSr25519}), }, } for _, tc := range testCases { - assert.Equal(t, tc.updatedParams, tc.params.UpdateConsensusParams(tc.updates)) + assert.Equal(t, tc.updatedParams, tc.intialParams.UpdateConsensusParams(tc.updates)) } } func TestConsensusParamsUpdate_AppVersion(t *testing.T) { - params := makeParams(1, 2, 3, 0, valEd25519) + params := makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}) assert.EqualValues(t, 0, params.Version.AppVersion) @@ -167,14 +204,16 @@ func TestConsensusParamsUpdate_AppVersion(t *testing.T) { 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(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 {