imp, ci: address pending issues from EVM simulation (#1063)
* add note fix note * add TestAppStateFn TestRandomAccounts * marshal int slice to json * add paramschange for enableCreate and enableCall * AppStateFn -> StateFn * add TestDecodeStore * update github actions to run evm simulation * add TestParamChanges * add TestRandomizedGenState * use go install for runsim * resolve conflict * use random gasCap to estimate gas * use estimateGas to calculate max transferableAmount * update godoc * TestAppStateFn -> TestStateFn * Update x/evm/simulation/genesis.go * comment Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <federico.kunze94@gmail.com>
This commit is contained in:
parent
c25669c761
commit
4ea9b6dc6d
80
.github/workflows/test.yml
vendored
80
.github/workflows/test.yml
vendored
@ -118,3 +118,83 @@ jobs:
|
||||
run: |
|
||||
make test-integration
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-sim-nondeterminism:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.17
|
||||
check-latest: true
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- name: Test x/evm simulation nondeterminism
|
||||
run: |
|
||||
make test-sim-nondeterminism
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-sim-random-genesis-fast:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.17
|
||||
check-latest: true
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- name: Test x/evm simulation with random genesis
|
||||
run: |
|
||||
make test-sim-random-genesis-fast
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-sim-import-export:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.17
|
||||
check-latest: true
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- name: Test x/evm simulation import and export
|
||||
run: |
|
||||
make test-sim-import-export
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-sim-after-import:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.17
|
||||
check-latest: true
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- name: Test x/evm simulation after import
|
||||
run: |
|
||||
make test-sim-after-import
|
||||
if: env.GIT_DIFF
|
@ -47,6 +47,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* Move `rpc/ethereum/backend` -> `rpc/backend`
|
||||
* Move `rpc/ethereum/namespaces` -> `rpc/namespaces/ethereum`
|
||||
|
||||
### Improvements
|
||||
|
||||
* (ci, evm) [tharsis#1063](https://github.com/tharsis/ethermint/pull/1063) Run simulations on CI.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (rpc) [tharsis#1059](https://github.com/tharsis/ethermint/pull/1059) Remove unnecessary event filtering logic on the `eth_baseFee` JSON-RPC endpoint.
|
||||
|
4
Makefile
4
Makefile
@ -201,7 +201,7 @@ RUNSIM = $(TOOLS_DESTDIR)/runsim
|
||||
runsim: $(RUNSIM)
|
||||
$(RUNSIM):
|
||||
@echo "Installing runsim..."
|
||||
@(cd /tmp && ${GO_MOD} go get github.com/cosmos/tools/cmd/runsim@master)
|
||||
@(cd /tmp && ${GO_MOD} go install github.com/cosmos/tools/cmd/runsim@master)
|
||||
|
||||
statik: $(STATIK)
|
||||
$(STATIK):
|
||||
@ -343,7 +343,7 @@ test-sim-nondeterminism:
|
||||
-NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h
|
||||
|
||||
test-sim-random-genesis-fast:
|
||||
@echo "Running custom genesis simulation..."
|
||||
@echo "Running random genesis simulation..."
|
||||
@go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation \
|
||||
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h
|
||||
|
||||
|
@ -108,7 +108,7 @@ func RandomAccounts(r *rand.Rand, n int) []simtypes.Account {
|
||||
|
||||
prv := secp256k1.GenPrivKeyFromSecret(privkeySeed)
|
||||
ethPrv := ðsecp256k1.PrivKey{}
|
||||
_ = ethPrv.UnmarshalAmino(prv.Bytes())
|
||||
_ = ethPrv.UnmarshalAmino(prv.Bytes()) // UnmarshalAmino simply copies the bytes and assigns them to ethPrv.Key
|
||||
accs[i].PrivKey = ethPrv
|
||||
accs[i].PubKey = accs[i].PrivKey.PubKey()
|
||||
accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address())
|
||||
|
@ -1,7 +1,9 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -11,7 +13,10 @@ import (
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
|
||||
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
|
||||
ethermint "github.com/tharsis/ethermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
@ -53,3 +58,54 @@ func TestRandomGenesisAccounts(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStateFn(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
if skip {
|
||||
t.Skip("skipping AppStateFn testing")
|
||||
}
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
config.ChainID = SimAppChainID
|
||||
config.Commit = true
|
||||
|
||||
defer func() {
|
||||
db.Close()
|
||||
require.NoError(t, os.RemoveAll(dir))
|
||||
}()
|
||||
|
||||
app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||
require.Equal(t, appName, app.Name())
|
||||
|
||||
appStateFn := StateFn(app.AppCodec(), app.SimulationManager())
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
accounts := RandomAccounts(r, rand.Intn(maxTestingAccounts))
|
||||
appState, _, _, _ := appStateFn(r, accounts, config)
|
||||
|
||||
rawState := make(map[string]json.RawMessage)
|
||||
err = json.Unmarshal(appState, &rawState)
|
||||
require.NoError(t, err)
|
||||
|
||||
stakingStateBz, ok := rawState[stakingtypes.ModuleName]
|
||||
require.True(t, ok)
|
||||
|
||||
stakingState := new(stakingtypes.GenesisState)
|
||||
app.AppCodec().MustUnmarshalJSON(stakingStateBz, stakingState)
|
||||
bondDenom := stakingState.Params.BondDenom
|
||||
|
||||
evmStateBz, ok := rawState[evmtypes.ModuleName]
|
||||
require.True(t, ok)
|
||||
|
||||
evmState := new(evmtypes.GenesisState)
|
||||
app.AppCodec().MustUnmarshalJSON(evmStateBz, evmState)
|
||||
require.Equal(t, bondDenom, evmState.Params.EvmDenom)
|
||||
}
|
||||
|
||||
func TestRandomAccounts(t *testing.T) {
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
accounts := RandomAccounts(r, rand.Intn(maxTestingAccounts))
|
||||
for _, acc := range accounts {
|
||||
_, ok := acc.PrivKey.(*ethsecp256k1.PrivKey)
|
||||
require.True(t, ok)
|
||||
}
|
||||
}
|
||||
|
@ -10,18 +10,18 @@ import (
|
||||
)
|
||||
|
||||
// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's
|
||||
// Value to the corresponding evm type.
|
||||
// value to the corresponding EVM type.
|
||||
func NewDecodeStore() func(kvA, kvB kv.Pair) string {
|
||||
return func(kvA, kvB kv.Pair) string {
|
||||
switch {
|
||||
case bytes.Equal(kvA.Key[:1], types.KeyPrefixStorage):
|
||||
storageHashA := common.BytesToHash(kvA.Value).Hex()
|
||||
storageHashB := common.BytesToHash(kvB.Value).Hex()
|
||||
storageA := common.BytesToHash(kvA.Value).Hex()
|
||||
storageB := common.BytesToHash(kvB.Value).Hex()
|
||||
|
||||
return fmt.Sprintf("%v\n%v", storageHashA, storageHashB)
|
||||
return fmt.Sprintf("%v\n%v", storageA, storageB)
|
||||
case bytes.Equal(kvA.Key[:1], types.KeyPrefixCode):
|
||||
codeHashA := common.BytesToHash(kvA.Value).Hex()
|
||||
codeHashB := common.BytesToHash(kvB.Value).Hex()
|
||||
codeHashA := common.Bytes2Hex(kvA.Value)
|
||||
codeHashB := common.Bytes2Hex(kvB.Value)
|
||||
|
||||
return fmt.Sprintf("%v\n%v", codeHashA, codeHashB)
|
||||
default:
|
||||
|
47
x/evm/simulation/decoder_test.go
Normal file
47
x/evm/simulation/decoder_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
// TestDecodeStore tests that evm simulation decoder decodes the key value pairs as expected.
|
||||
func TestDecodeStore(t *testing.T) {
|
||||
dec := NewDecodeStore()
|
||||
|
||||
hash := common.BytesToHash([]byte("hash"))
|
||||
code := common.Bytes2Hex([]byte{1, 2, 3})
|
||||
|
||||
kvPairs := kv.Pairs{
|
||||
Pairs: []kv.Pair{
|
||||
{Key: types.KeyPrefixCode, Value: common.FromHex(code)},
|
||||
{Key: types.KeyPrefixStorage, Value: hash.Bytes()},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"Code", fmt.Sprintf("%v\n%v", code, code)},
|
||||
{"Storage", fmt.Sprintf("%v\n%v", hash, hash)},
|
||||
{"other", ""},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
i, tt := i, tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -10,18 +10,44 @@ import (
|
||||
"github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
// GenExtraEIPs randomly generates specific extra eips or not.
|
||||
func genExtraEIPs(r *rand.Rand) []int64 {
|
||||
const (
|
||||
extraEIPsKey = "extra_eips"
|
||||
)
|
||||
|
||||
// GenExtraEIPs defines a set of extra EIPs with 50% probability
|
||||
func GenExtraEIPs(r *rand.Rand) []int64 {
|
||||
var extraEIPs []int64
|
||||
if r.Uint32()%2 == 0 {
|
||||
// 50% chance of having extra EIPs
|
||||
if r.Intn(2) == 0 {
|
||||
extraEIPs = []int64{1344, 1884, 2200, 2929, 3198, 3529}
|
||||
}
|
||||
return extraEIPs
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for nft
|
||||
// GenEnableCreate enables the EnableCreate param with 80% probability
|
||||
func GenEnableCreate(r *rand.Rand) bool {
|
||||
// 80% chance of enabling create contract
|
||||
enableCreate := r.Intn(100) < 80
|
||||
return enableCreate
|
||||
}
|
||||
|
||||
// GenEnableCall enables the EnableCall param with 80% probability
|
||||
func GenEnableCall(r *rand.Rand) bool {
|
||||
// 80% chance of enabling evm account transfer and calling contract
|
||||
enableCall := r.Intn(100) < 80
|
||||
return enableCall
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for the EVM module
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
extraEIPs := genExtraEIPs(simState.Rand)
|
||||
// evm params
|
||||
var extraEIPs []int64
|
||||
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, extraEIPsKey, &extraEIPs, simState.Rand,
|
||||
func(r *rand.Rand) { extraEIPs = GenExtraEIPs(r) },
|
||||
)
|
||||
|
||||
params := types.NewParams(types.DefaultEVMDenom, true, true, types.DefaultChainConfig(), extraEIPs...)
|
||||
evmGenesis := types.NewGenesisState(params, []types.GenesisAccount{})
|
||||
|
||||
|
50
x/evm/simulation/genesis_test.go
Normal file
50
x/evm/simulation/genesis_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/tharsis/ethermint/x/evm/simulation"
|
||||
"github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
// TestRandomizedGenState tests the normal scenario of applying RandomizedGenState.
|
||||
// Abonormal scenarios are not tested here.
|
||||
func TestRandomizedGenState(t *testing.T) {
|
||||
registry := codectypes.NewInterfaceRegistry()
|
||||
types.RegisterInterfaces(registry)
|
||||
cdc := codec.NewProtoCodec(registry)
|
||||
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
simState := module.SimulationState{
|
||||
AppParams: make(simtypes.AppParams),
|
||||
Cdc: cdc,
|
||||
Rand: r,
|
||||
NumBonded: 3,
|
||||
Accounts: simtypes.RandomAccounts(r, 3),
|
||||
InitialStake: 1000,
|
||||
GenState: make(map[string]json.RawMessage),
|
||||
}
|
||||
|
||||
simulation.RandomizedGenState(&simState)
|
||||
|
||||
var evmGenesis types.GenesisState
|
||||
simState.Cdc.MustUnmarshalJSON(simState.GenState[types.ModuleName], &evmGenesis)
|
||||
|
||||
require.Equal(t, true, evmGenesis.Params.GetEnableCreate())
|
||||
require.Equal(t, true, evmGenesis.Params.GetEnableCall())
|
||||
require.Equal(t, types.DefaultEVMDenom, evmGenesis.Params.GetEvmDenom())
|
||||
require.Equal(t, simulation.GenExtraEIPs(r), evmGenesis.Params.GetExtraEIPs())
|
||||
require.Equal(t, types.DefaultChainConfig(), evmGenesis.Params.GetChainConfig())
|
||||
|
||||
require.Equal(t, len(evmGenesis.Accounts), 0)
|
||||
}
|
@ -25,7 +25,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/tharsis/ethermint/encoding"
|
||||
"github.com/tharsis/ethermint/server/config"
|
||||
"github.com/tharsis/ethermint/tests"
|
||||
"github.com/tharsis/ethermint/x/evm/keeper"
|
||||
"github.com/tharsis/ethermint/x/evm/types"
|
||||
@ -203,10 +202,12 @@ func SimulateEthTx(
|
||||
|
||||
// CreateRandomValidEthTx create the ethereum tx with valid random values
|
||||
func CreateRandomValidEthTx(ctx *simulateContext, from, to *common.Address, amount *big.Int, data *hexutil.Bytes) (ethTx *types.MsgEthereumTx, err error) {
|
||||
estimateGas, err := EstimateGas(ctx, from, to, data)
|
||||
gasCap := ctx.rand.Uint64()
|
||||
estimateGas, err := EstimateGas(ctx, from, to, data, gasCap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// we suppose that gasLimit should be larger than estimateGas to ensure tx validity
|
||||
gasLimit := estimateGas + uint64(ctx.rand.Intn(int(sdktx.MaxGasWanted-estimateGas)))
|
||||
ethChainID := ctx.keeper.ChainID()
|
||||
chainConfig := ctx.keeper.GetParams(ctx.context).ChainConfig.EthereumConfig(ethChainID)
|
||||
@ -216,7 +217,7 @@ func CreateRandomValidEthTx(ctx *simulateContext, from, to *common.Address, amou
|
||||
nonce := ctx.keeper.GetNonce(ctx.context, *from)
|
||||
|
||||
if amount == nil {
|
||||
amount, err = RandomTransferableAmount(ctx, *from, gasLimit, gasFeeCap)
|
||||
amount, err = RandomTransferableAmount(ctx, *from, estimateGas, gasFeeCap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -228,7 +229,7 @@ func CreateRandomValidEthTx(ctx *simulateContext, from, to *common.Address, amou
|
||||
}
|
||||
|
||||
// EstimateGas estimates the gas used by quering the keeper.
|
||||
func EstimateGas(ctx *simulateContext, from, to *common.Address, data *hexutil.Bytes) (gas uint64, err error) {
|
||||
func EstimateGas(ctx *simulateContext, from, to *common.Address, data *hexutil.Bytes, gasCap uint64) (gas uint64, err error) {
|
||||
args, err := json.Marshal(&types.TransactionArgs{To: to, From: from, Data: data})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -236,7 +237,7 @@ func EstimateGas(ctx *simulateContext, from, to *common.Address, data *hexutil.B
|
||||
|
||||
res, err := ctx.keeper.EstimateGas(sdk.WrapSDKContext(ctx.context), &types.EthCallRequest{
|
||||
Args: args,
|
||||
GasCap: config.DefaultGasCap,
|
||||
GasCap: gasCap,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -246,9 +247,9 @@ func EstimateGas(ctx *simulateContext, from, to *common.Address, data *hexutil.B
|
||||
|
||||
// RandomTransferableAmount generates a random valid transferable amount.
|
||||
// Transferable amount is between the range [0, spendable), spendable = balance - gasFeeCap * GasLimit.
|
||||
func RandomTransferableAmount(ctx *simulateContext, address common.Address, gasLimit uint64, gasFeeCap *big.Int) (amount *big.Int, err error) {
|
||||
func RandomTransferableAmount(ctx *simulateContext, address common.Address, estimateGas uint64, gasFeeCap *big.Int) (amount *big.Int, err error) {
|
||||
balance := ctx.keeper.GetBalance(ctx.context, address)
|
||||
feeLimit := new(big.Int).Mul(gasFeeCap, big.NewInt(int64(gasLimit)))
|
||||
feeLimit := new(big.Int).Mul(gasFeeCap, big.NewInt(int64(estimateGas)))
|
||||
if (feeLimit.Cmp(balance)) > 0 {
|
||||
return nil, ErrNoEnoughBalance
|
||||
}
|
||||
|
@ -6,22 +6,35 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
amino "github.com/cosmos/cosmos-sdk/codec"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
const (
|
||||
keyExtraEIPs = "ExtraEIPs"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation.
|
||||
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyExtraEIPs,
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyExtraEIPs),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", genExtraEIPs(r))
|
||||
extraEIPs := GenExtraEIPs(r)
|
||||
amino := amino.NewLegacyAmino()
|
||||
bz, err := amino.MarshalJSON(extraEIPs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(bz)
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyEnableCreate),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%v", GenEnableCreate(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyEnableCall),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%v", GenEnableCall(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
|
44
x/evm/simulation/params_test.go
Normal file
44
x/evm/simulation/params_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package simulation_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tharsis/ethermint/x/evm/simulation"
|
||||
)
|
||||
|
||||
// TestParamChanges tests the paramChanges are generated as expected.
|
||||
func TestParamChanges(t *testing.T) {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
extraEIPs := simulation.GenExtraEIPs(r)
|
||||
bz, err := json.Marshal(extraEIPs)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := []struct {
|
||||
composedKey string
|
||||
key string
|
||||
simValue string
|
||||
subspace string
|
||||
}{
|
||||
{"evm/EnableExtraEIPs", "EnableExtraEIPs", string(bz), "evm"},
|
||||
{"evm/EnableCreate", "EnableCreate", fmt.Sprintf("%v", simulation.GenEnableCreate(r)), "evm"},
|
||||
{"evm/EnableCall", "EnableCall", fmt.Sprintf("%v", simulation.GenEnableCall(r)), "evm"},
|
||||
}
|
||||
|
||||
paramChanges := simulation.ParamChanges(r)
|
||||
|
||||
require.Len(t, paramChanges, 3)
|
||||
|
||||
for i, p := range paramChanges {
|
||||
require.Equal(t, expected[i].composedKey, p.ComposedKey())
|
||||
require.Equal(t, expected[i].key, p.Key())
|
||||
require.Equal(t, expected[i].simValue, p.SimValue()(r))
|
||||
require.Equal(t, expected[i].subspace, p.Subspace())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user