Skip to content

Commit 2426a7c

Browse files
perf(params): validate ConsensusParams once per change set (CON-312)
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 1f1542e commit 2426a7c

2 files changed

Lines changed: 31 additions & 8 deletions

File tree

sei-cosmos/x/params/types/proposal/proposal.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ func ValidateChanges(changes []ParamChange) error {
8989
return ErrEmptyChanges
9090
}
9191

92+
hasBaseapp := false
9293
for _, pc := range changes {
9394
if len(pc.Subspace) == 0 {
9495
return ErrEmptySubspace
@@ -99,14 +100,19 @@ func ValidateChanges(changes []ParamChange) error {
99100
if len(pc.Value) == 0 {
100101
return ErrEmptyValue
101102
}
102-
// We need to verify ConsensusParams since they are only validated once the proposal passes.
103-
// If any of them are invalid at time of passing, this will cause a chain halt since validation is done during
104-
// ApplyBlock: https://github.com/sei-protocol/sei-tendermint/blob/d426f1fe475eb0c406296770ff5e9f8869b3887e/internal/state/execution.go#L320
105-
// Therefore, we validate when we get a param-change msg for ConsensusParams
106103
if pc.Subspace == "baseapp" {
107-
if err := verifyConsensusParamsUsingDefault(changes); err != nil {
108-
return err
109-
}
104+
hasBaseapp = true
105+
}
106+
}
107+
108+
// Verify ConsensusParams once for the whole change set. Calling this inside
109+
// the loop above is O(N^2) for N baseapp entries (each call re-scans and
110+
// unmarshals all changes). ConsensusParams are otherwise only validated
111+
// once the proposal passes; invalid values cause a chain halt in ApplyBlock:
112+
// https://github.com/sei-protocol/sei-tendermint/blob/d426f1fe475eb0c406296770ff5e9f8869b3887e/internal/state/execution.go#L320
113+
if hasBaseapp {
114+
if err := verifyConsensusParamsUsingDefault(changes); err != nil {
115+
return err
110116
}
111117
}
112118

sei-cosmos/x/params/types/proposal/proposal_test.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package proposal
22

33
import (
44
"fmt"
5-
"github.com/sei-protocol/sei-chain/sei-tendermint/types"
65
"testing"
76

7+
"github.com/sei-protocol/sei-chain/sei-tendermint/types"
88
"github.com/stretchr/testify/require"
99
)
1010

@@ -38,3 +38,20 @@ func TestConsensusParameterChangeProposal(t *testing.T) {
3838
pcp = NewParameterChangeProposal("test title", "test description", []ParamChange{pc1}, true)
3939
require.Error(t, pcp.ValidateBasic())
4040
}
41+
42+
func BenchmarkValidateChangesBaseapp(b *testing.B) {
43+
value := fmt.Sprintf("{\"max_bytes\":\"%d\"}", types.MaxBlockSizeBytes)
44+
for _, n := range []int{10, 100, 1000} {
45+
changes := make([]ParamChange, n)
46+
for i := 0; i < n; i++ {
47+
changes[i] = NewParamChange("baseapp", "BlockParams", value)
48+
}
49+
b.Run(fmt.Sprintf("n=%d", n), func(b *testing.B) {
50+
for i := 0; i < b.N; i++ {
51+
if err := ValidateChanges(changes); err != nil {
52+
b.Fatal(err)
53+
}
54+
}
55+
})
56+
}
57+
}

0 commit comments

Comments
 (0)