Skip to content

Commit 6986270

Browse files
mergify[bot]luchenqunjulienrbrt
authored
fix(simulation): Fix all problems make test-sim-custom-genesis-fast for simulation test. (backport #17911) (#20909)
Co-authored-by: Chenqun Lu <luchenqun@qq.com> Co-authored-by: Julien Robert <julien@rbrt.fr>
1 parent c51f58c commit 6986270

File tree

13 files changed

+79
-27
lines changed

13 files changed

+79
-27
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
6363

6464
### Bug Fixes
6565

66+
* (simulation) [#17911](https://github.com/cosmos/cosmos-sdk/pull/17911) Fix all problems with executing command `make test-sim-custom-genesis-fast` for simulation test.
6667
* (baseapp) [#20346](https://github.com/cosmos/cosmos-sdk/pull/20346) Correctly assign `execModeSimulate` to context for `simulateTx`.
6768
* (baseapp) [#20144](https://github.com/cosmos/cosmos-sdk/pull/20144) Remove txs from mempool when AnteHandler fails in recheck.
6869
* (baseapp) [#20107](https://github.com/cosmos/cosmos-sdk/pull/20107) Avoid header height overwrite block height.

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,9 @@ test-sim-nondeterminism-streaming:
277277

278278
test-sim-custom-genesis-fast:
279279
@echo "Running custom genesis simulation..."
280-
@echo "By default, ${HOME}/.gaiad/config/genesis.json will be used."
281-
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -run TestFullAppSimulation -Genesis=${HOME}/.gaiad/config/genesis.json \
282-
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h
280+
@echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
281+
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
282+
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -SigverifyTx=false -v -timeout 24h
283283

284284
test-sim-import-export: runsim
285285
@echo "Running application import/export simulation. This may take several minutes..."
@@ -291,8 +291,8 @@ test-sim-after-import: runsim
291291

292292
test-sim-custom-genesis-multi-seed: runsim
293293
@echo "Running multi-seed custom genesis simulation..."
294-
@echo "By default, ${HOME}/.gaiad/config/genesis.json will be used."
295-
@cd ${CURRENT_DIR}/simapp && $(BINDIR)/runsim -Genesis=${HOME}/.gaiad/config/genesis.json -SimAppPkg=. -ExitOnFail 400 5 TestFullAppSimulation
294+
@echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
295+
@cd ${CURRENT_DIR}/simapp && $(BINDIR)/runsim -Genesis=${HOME}/.simapp/config/genesis.json -SigverifyTx=false -SimAppPkg=. -ExitOnFail 400 5 TestFullAppSimulation
296296

297297
test-sim-multi-seed-long: runsim
298298
@echo "Running long multi-seed application simulation. This may take awhile!"

baseapp/baseapp.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ type BaseApp struct {
9191
addrPeerFilter sdk.PeerFilter // filter peers by address and port
9292
idPeerFilter sdk.PeerFilter // filter peers by node ID
9393
fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed.
94+
sigverifyTx bool // in the simulation test, since the account does not have a private key, we have to ignore the tx sigverify.
9495

9596
// manages snapshots, i.e. dumps of app state at certain intervals
9697
snapshotManager *snapshots.Manager
@@ -211,6 +212,7 @@ func NewBaseApp(
211212
msgServiceRouter: NewMsgServiceRouter(),
212213
txDecoder: txDecoder,
213214
fauxMerkleMode: false,
215+
sigverifyTx: true,
214216
queryGasLimit: math.MaxUint64,
215217
}
216218

@@ -667,6 +669,8 @@ func (app *BaseApp) getContextForTx(mode execMode, txBytes []byte) sdk.Context {
667669
WithGasMeter(storetypes.NewInfiniteGasMeter())
668670
// WithVoteInfos(app.voteInfos) // TODO: identify if this is needed
669671

672+
ctx = ctx.WithIsSigverifyTx(app.sigverifyTx)
673+
670674
ctx = ctx.WithConsensusParams(app.GetConsensusParams(ctx))
671675

672676
if mode == execModeReCheck {

baseapp/options.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ func (app *BaseApp) SetFauxMerkleMode() {
260260
app.fauxMerkleMode = true
261261
}
262262

263+
// SetNotSigverify during simulation testing, transaction signature verification needs to be ignored.
264+
func (app *BaseApp) SetNotSigverifyTx() {
265+
app.sigverifyTx = false
266+
}
267+
263268
// SetCommitMultiStoreTracer sets the store tracer on the BaseApp's underlying
264269
// CommitMultiStore.
265270
func (app *BaseApp) SetCommitMultiStoreTracer(w io.Writer) {

baseapp/test_helpers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func (app *BaseApp) SimDeliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo,
3535
if err != nil {
3636
return sdk.GasInfo{}, nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err)
3737
}
38+
3839
gasInfo, result, _, err := app.runTx(execModeFinalize, bz)
3940
return gasInfo, result, err
4041
}

simapp/sim_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ func TestFullAppSimulation(t *testing.T) {
7676
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
7777

7878
app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID))
79+
if !simcli.FlagSigverifyTxValue {
80+
app.SetNotSigverifyTx()
81+
}
7982
require.Equal(t, "SimApp", app.Name())
8083

8184
// run randomized simulation
@@ -121,6 +124,9 @@ func TestAppImportExport(t *testing.T) {
121124
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
122125

123126
app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID))
127+
if !simcli.FlagSigverifyTxValue {
128+
app.SetNotSigverifyTx()
129+
}
124130
require.Equal(t, "SimApp", app.Name())
125131

126132
// Run randomized simulation
@@ -240,6 +246,9 @@ func TestAppSimulationAfterImport(t *testing.T) {
240246
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
241247

242248
app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID))
249+
if !simcli.FlagSigverifyTxValue {
250+
app.SetNotSigverifyTx()
251+
}
243252
require.Equal(t, "SimApp", app.Name())
244253

245254
// Run randomized simulation
@@ -362,6 +371,9 @@ func TestAppStateDeterminism(t *testing.T) {
362371

363372
db := dbm.NewMemDB()
364373
app := NewSimApp(logger, db, nil, true, appOptions, interBlockCacheOpt(), baseapp.SetChainID(SimAppChainID))
374+
if !simcli.FlagSigverifyTxValue {
375+
app.SetNotSigverifyTx()
376+
}
365377

366378
fmt.Printf(
367379
"running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",

testutil/sims/state_helpers.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
package sims
22

33
import (
4+
"bufio"
45
"encoding/json"
56
"fmt"
67
"io"
78
"math/rand"
89
"os"
10+
"path/filepath"
911
"time"
1012

1113
"github.com/cosmos/gogoproto/proto"
1214

1315
"cosmossdk.io/math"
1416

1517
"github.com/cosmos/cosmos-sdk/codec"
18+
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
1619
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
1720
sdk "github.com/cosmos/cosmos-sdk/types"
1821
"github.com/cosmos/cosmos-sdk/types/module"
@@ -250,19 +253,23 @@ func AppStateRandomizedFn(
250253
// AppStateFromGenesisFileFn util function to generate the genesis AppState
251254
// from a genesis.json file.
252255
func AppStateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile string) (genutiltypes.AppGenesis, []simtypes.Account, error) {
253-
bytes, err := os.ReadFile(genesisFile)
256+
file, err := os.Open(filepath.Clean(genesisFile))
254257
if err != nil {
255258
panic(err)
256259
}
257260

258-
var genesis genutiltypes.AppGenesis
259-
if err = json.Unmarshal(bytes, &genesis); err != nil {
260-
return genesis, nil, err
261+
genesis, err := genutiltypes.AppGenesisFromReader(bufio.NewReader(file))
262+
if err != nil {
263+
return *genesis, nil, err
264+
}
265+
266+
if err := file.Close(); err != nil {
267+
return *genesis, nil, err
261268
}
262269

263270
var appState map[string]json.RawMessage
264271
if err = json.Unmarshal(genesis.AppState, &appState); err != nil {
265-
return genesis, nil, err
272+
return *genesis, nil, err
266273
}
267274

268275
var authGenesis authtypes.GenesisState
@@ -284,13 +291,13 @@ func AppStateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile str
284291

285292
a, ok := acc.GetCachedValue().(sdk.AccountI)
286293
if !ok {
287-
return genesis, nil, fmt.Errorf("expected account")
294+
return *genesis, nil, fmt.Errorf("expected account")
288295
}
289296

290297
// create simulator accounts
291-
simAcc := simtypes.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: a.GetAddress()}
298+
simAcc := simtypes.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: a.GetAddress(), ConsKey: ed25519.GenPrivKeyFromSecret(privkeySeed)}
292299
newAccs[i] = simAcc
293300
}
294301

295-
return genesis, newAccs, nil
302+
return *genesis, newAccs, nil
296303
}

types/context.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type Context struct {
5454
blockGasMeter storetypes.GasMeter
5555
checkTx bool
5656
recheckTx bool // if recheckTx == true, then checkTx must also be true
57+
sigverifyTx bool // when run simulation, because the private key corresponding to the account in the genesis.json randomly generated, we must skip the sigverify.
5758
execMode ExecMode
5859
minGasPrice DecCoins
5960
consParams cmtproto.ConsensusParams
@@ -82,6 +83,7 @@ func (c Context) GasMeter() storetypes.GasMeter { return c.gasMe
8283
func (c Context) BlockGasMeter() storetypes.GasMeter { return c.blockGasMeter }
8384
func (c Context) IsCheckTx() bool { return c.checkTx }
8485
func (c Context) IsReCheckTx() bool { return c.recheckTx }
86+
func (c Context) IsSigverifyTx() bool { return c.sigverifyTx }
8587
func (c Context) ExecMode() ExecMode { return c.execMode }
8688
func (c Context) MinGasPrices() DecCoins { return c.minGasPrice }
8789
func (c Context) EventManager() EventManagerI { return c.eventManager }
@@ -131,6 +133,7 @@ func NewContext(ms storetypes.MultiStore, header cmtproto.Header, isCheckTx bool
131133
header: header,
132134
chainID: header.ChainID,
133135
checkTx: isCheckTx,
136+
sigverifyTx: true,
134137
logger: logger,
135138
gasMeter: storetypes.NewInfiniteGasMeter(),
136139
minGasPrice: DecCoins{},
@@ -260,6 +263,12 @@ func (c Context) WithIsReCheckTx(isRecheckTx bool) Context {
260263
return c
261264
}
262265

266+
// WithIsSigverifyTx called with true will sigverify in auth module
267+
func (c Context) WithIsSigverifyTx(isSigverifyTx bool) Context {
268+
c.sigverifyTx = isSigverifyTx
269+
return c
270+
}
271+
263272
// WithExecMode returns a Context with an updated ExecMode.
264273
func (c Context) WithExecMode(m ExecMode) Context {
265274
c.execMode = m

x/auth/ante/sigverify.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b
9090
pk = simSecp256k1Pubkey
9191
}
9292
// Only make check if simulate=false
93-
if !simulate && !bytes.Equal(pk.Address(), signers[i]) {
93+
if !simulate && !bytes.Equal(pk.Address(), signers[i]) && ctx.IsSigverifyTx() {
9494
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidPubKey,
9595
"pubKey does not match signer address %s with signer index: %d", signerStrs[i], i)
9696
}
@@ -302,7 +302,7 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
302302
}
303303

304304
// no need to verify signatures on recheck tx
305-
if !simulate && !ctx.IsReCheckTx() {
305+
if !simulate && !ctx.IsReCheckTx() && ctx.IsSigverifyTx() {
306306
anyPk, _ := codectypes.NewAnyWithValue(pubKey)
307307

308308
signerData := txsigning.SignerData{

x/auth/ante/sigverify_test.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,23 +190,26 @@ func TestSigVerification(t *testing.T) {
190190
accSeqs []uint64
191191
invalidSigs bool // used for testing sigverify on RecheckTx
192192
recheck bool
193+
sigverify bool
193194
shouldErr bool
194195
}
195196
validSigs := false
196197
testCases := []testCase{
197-
{"no signers", []cryptotypes.PrivKey{}, []uint64{}, []uint64{}, validSigs, false, true},
198-
{"not enough signers", []cryptotypes.PrivKey{priv1, priv2}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber()}, []uint64{0, 0}, validSigs, false, true},
199-
{"wrong order signers", []cryptotypes.PrivKey{priv3, priv2, priv1}, []uint64{accs[2].GetAccountNumber(), accs[1].GetAccountNumber(), accs[0].GetAccountNumber()}, []uint64{0, 0, 0}, validSigs, false, true},
200-
{"wrong accnums", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{7, 8, 9}, []uint64{0, 0, 0}, validSigs, false, true},
201-
{"wrong sequences", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber(), accs[2].GetAccountNumber()}, []uint64{3, 4, 5}, validSigs, false, true},
202-
{"valid tx", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber(), accs[2].GetAccountNumber()}, []uint64{0, 0, 0}, validSigs, false, false},
203-
{"no err on recheck", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 0, 0}, []uint64{0, 0, 0}, !validSigs, true, false},
198+
{"no signers", []cryptotypes.PrivKey{}, []uint64{}, []uint64{}, validSigs, false, true, true},
199+
{"not enough signers", []cryptotypes.PrivKey{priv1, priv2}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber()}, []uint64{0, 0}, validSigs, false, true, true},
200+
{"wrong order signers", []cryptotypes.PrivKey{priv3, priv2, priv1}, []uint64{accs[2].GetAccountNumber(), accs[1].GetAccountNumber(), accs[0].GetAccountNumber()}, []uint64{0, 0, 0}, validSigs, false, true, true},
201+
{"wrong accnums", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{7, 8, 9}, []uint64{0, 0, 0}, validSigs, false, true, true},
202+
{"wrong sequences", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber(), accs[2].GetAccountNumber()}, []uint64{3, 4, 5}, validSigs, false, true, true},
203+
{"valid tx", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber(), accs[2].GetAccountNumber()}, []uint64{0, 0, 0}, validSigs, false, true, false},
204+
{"sigverify tx with wrong order signers", []cryptotypes.PrivKey{priv3, priv2, priv1}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber(), accs[2].GetAccountNumber()}, []uint64{0, 0, 0}, validSigs, false, true, true},
205+
{"skip sigverify tx with wrong order signers", []cryptotypes.PrivKey{priv3, priv2, priv1}, []uint64{accs[0].GetAccountNumber(), accs[1].GetAccountNumber(), accs[2].GetAccountNumber()}, []uint64{0, 0, 0}, validSigs, false, false, false},
206+
{"no err on recheck", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 0, 0}, []uint64{0, 0, 0}, !validSigs, true, true, false},
204207
}
205208

206209
for i, tc := range testCases {
207210
for _, signMode := range enabledSignModes {
208211
t.Run(fmt.Sprintf("%s with %s", tc.name, signMode), func(t *testing.T) {
209-
suite.ctx = suite.ctx.WithIsReCheckTx(tc.recheck)
212+
suite.ctx = suite.ctx.WithIsReCheckTx(tc.recheck).WithIsSigverifyTx(tc.sigverify)
210213
suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test
211214

212215
require.NoError(t, suite.txBuilder.SetMsgs(msgs...))

0 commit comments

Comments
 (0)