diff --git a/Makefile b/Makefile index 92a472da497f..12fbae141aee 100644 --- a/Makefile +++ b/Makefile @@ -403,7 +403,7 @@ proto-swagger-gen: proto-format: @echo "Formatting Protobuf files" @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ - find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \; ; fi + find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi proto-lint: diff --git a/client/broadcast.go b/client/broadcast.go index 0912de81e818..f3573a5c5182 100644 --- a/client/broadcast.go +++ b/client/broadcast.go @@ -5,8 +5,8 @@ import ( "fmt" "strings" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/mempool" + tmtypes "github.com/tendermint/tendermint/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -46,13 +46,13 @@ func (ctx Context) BroadcastTx(txBytes []byte) (res *sdk.TxResponse, err error) // TODO: Avoid brittle string matching in favor of error matching. This requires // a change to Tendermint's RPCError type to allow retrieval or matching against // a concrete error type. -func CheckTendermintError(err error, txBytes []byte) *sdk.TxResponse { +func CheckTendermintError(err error, tx tmtypes.Tx) *sdk.TxResponse { if err == nil { return nil } errStr := strings.ToLower(err.Error()) - txHash := fmt.Sprintf("%X", tmhash.Sum(txBytes)) + txHash := fmt.Sprintf("%X", tx.Hash()) switch { case strings.Contains(errStr, strings.ToLower(mempool.ErrTxInCache.Error())): diff --git a/docs/package-lock.json b/docs/package-lock.json index 65a162d5d8bb..3d76fb80a920 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -10626,9 +10626,9 @@ } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "requires": { "async-limiter": "~1.0.0" } diff --git a/go.mod b/go.mod index df244e8da014..76672db86d3e 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/otiai10/copy v1.6.0 github.com/pelletier/go-toml v1.8.1 // indirect github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.10.0 + github.com/prometheus/client_golang v1.11.0 github.com/prometheus/common v0.27.0 github.com/rakyll/statik v0.1.7 github.com/regen-network/cosmos-proto v0.3.1 @@ -50,7 +50,6 @@ require ( github.com/tendermint/tendermint v0.34.10 github.com/tendermint/tm-db v0.6.4 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f google.golang.org/grpc v1.38.0 google.golang.org/protobuf v1.26.0 diff --git a/go.sum b/go.sum index d360c4ec3670..39db7f767912 100644 --- a/go.sum +++ b/go.sum @@ -435,8 +435,9 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -597,8 +598,9 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= -github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -615,6 +617,7 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.27.0 h1:kJb5BtkTmonXrV2nfyRRlChGpgqhPCdj2ooGivZ8txo= github.com/prometheus/common v0.27.0/go.mod h1:LdLj/WiR+LL0ThCPrtSZbijrsxInIhizDTiPlJhPPq4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -957,8 +960,8 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/x/distribution/simulation/operations.go b/x/distribution/simulation/operations.go index 677e9cc843fc..f82e921290b4 100644 --- a/x/distribution/simulation/operations.go +++ b/x/distribution/simulation/operations.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp/helpers" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" @@ -93,34 +92,24 @@ func SimulateMsgSetWithdrawAddress(ak types.AccountKeeper, bk types.BankKeeper, account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgSetWithdrawAddress, "unable to generate fees"), nil, err - } - msg := types.NewMsgSetWithdrawAddress(simAccount.Address, simToAccount.Address) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, + } + + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -145,34 +134,24 @@ func SimulateMsgWithdrawDelegatorReward(ak types.AccountKeeper, bk types.BankKee account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgWithdrawDelegatorReward, "unable to generate fees"), nil, err - } - msg := types.NewMsgWithdrawDelegatorReward(simAccount.Address, validator.GetOperator()) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, + } + + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -200,34 +179,24 @@ func SimulateMsgWithdrawValidatorCommission(ak types.AccountKeeper, bk types.Ban account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgWithdrawValidatorCommission, "unable to generate fees"), nil, err - } - msg := types.NewMsgWithdrawValidatorCommission(validator.GetOperator()) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, + } + + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -262,26 +231,19 @@ func SimulateMsgFundCommunityPool(ak types.AccountKeeper, bk types.BankKeeper, k } msg := types.NewMsgFundCommunityPool(fundAmount, funder.Address) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - funder.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + txCtx := simulation.OperationInput{ + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: funder, + AccountKeeper: ak, + ModuleName: types.ModuleName, } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simulation.GenAndDeliverTx(txCtx, fees) } } diff --git a/x/feegrant/periodic_fee.go b/x/feegrant/periodic_fee.go index 63c9e748526f..c6fbc94b6ea9 100644 --- a/x/feegrant/periodic_fee.go +++ b/x/feegrant/periodic_fee.go @@ -49,7 +49,7 @@ func (a *PeriodicAllowance) Accept(ctx sdk.Context, fee sdk.Coins, _ []sdk.Msg) // tryResetPeriod will check if the PeriodReset has been hit. If not, it is a no-op. // If we hit the reset period, it will top up the PeriodCanSpend amount to -// min(PeriodicSpendLimit, a.Basic.SpendLimit) so it is never more than the maximum allowed. +// min(PeriodSpendLimit, Basic.SpendLimit) so it is never more than the maximum allowed. // It will also update the PeriodReset. If we are within one Period, it will update from the // last PeriodReset (eg. if you always do one tx per day, it will always reset the same time) // If we are more then one period out (eg. no activity in a week), reset is one Period from the execution of this method @@ -57,8 +57,9 @@ func (a *PeriodicAllowance) tryResetPeriod(blockTime time.Time) { if blockTime.Before(a.PeriodReset) { return } - // set CanSpend to the lesser of PeriodSpendLimit and the TotalLimit - if _, isNeg := a.Basic.SpendLimit.SafeSub(a.PeriodSpendLimit); isNeg { + + // set PeriodCanSpend to the lesser of Basic.SpendLimit and PeriodSpendLimit + if _, isNeg := a.Basic.SpendLimit.SafeSub(a.PeriodSpendLimit); isNeg && !a.Basic.SpendLimit.Empty() { a.PeriodCanSpend = a.Basic.SpendLimit } else { a.PeriodCanSpend = a.PeriodSpendLimit diff --git a/x/feegrant/periodic_fee_test.go b/x/feegrant/periodic_fee_test.go index a09459cb722e..f09640b5f064 100644 --- a/x/feegrant/periodic_fee_test.go +++ b/x/feegrant/periodic_fee_test.go @@ -31,11 +31,10 @@ func TestPeriodicFeeValidAllow(t *testing.T) { tenMinutes := time.Duration(10) * time.Minute cases := map[string]struct { - allow feegrant.PeriodicAllowance - // all other checks are ignored if valid=false + allow feegrant.PeriodicAllowance fee sdk.Coins blockTime time.Time - valid bool + valid bool // all other checks are ignored if valid=false accept bool remove bool remains sdk.Coins @@ -115,7 +114,7 @@ func TestPeriodicFeeValidAllow(t *testing.T) { remove: false, remainsPeriod: nil, remains: smallAtom, - periodReset: oneHour.Add(10 * time.Minute), // one step from last reset, not now + periodReset: oneHour.Add(tenMinutes), // one step from last reset, not now }, "step limited by global allowance": { allow: feegrant.PeriodicAllowance{ @@ -134,7 +133,20 @@ func TestPeriodicFeeValidAllow(t *testing.T) { remove: false, remainsPeriod: smallAtom.Sub(oneAtom), remains: smallAtom.Sub(oneAtom), - periodReset: oneHour.Add(10 * time.Minute), // one step from last reset, not now + periodReset: oneHour.Add(tenMinutes), // one step from last reset, not now + }, + "period reset no spend limit": { + allow: feegrant.PeriodicAllowance{ + Period: tenMinutes, + PeriodReset: now, + PeriodSpendLimit: atom, + }, + valid: true, + fee: atom, + blockTime: oneHour, + accept: true, + remove: false, + periodReset: oneHour.Add(tenMinutes), // one step from last reset, not now }, "expired": { allow: feegrant.PeriodicAllowance{ diff --git a/x/feegrant/simulation/operations.go b/x/feegrant/simulation/operations.go index 095830215d5d..58095c138454 100644 --- a/x/feegrant/simulation/operations.go +++ b/x/feegrant/simulation/operations.go @@ -5,7 +5,6 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp/helpers" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" @@ -77,12 +76,6 @@ func SimulateMsgGrantAllowance(ak feegrant.AccountKeeper, bk feegrant.BankKeeper account := ak.GetAccount(ctx, granter.Address) spendableCoins := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendableCoins) - if err != nil { - return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, err.Error()), nil, err - } - - spendableCoins = spendableCoins.Sub(fees) if spendableCoins.Empty() { return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, "unable to grant empty coins as SpendLimit"), nil, nil } @@ -96,28 +89,23 @@ func SimulateMsgGrantAllowance(ak feegrant.AccountKeeper, bk feegrant.BankKeeper if err != nil { return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, err.Error()), nil, err } - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - granter.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, "unable to generate mock tx"), nil, err + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: TypeMsgGrantAllowance, + Context: ctx, + SimAccount: granter, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: feegrant.ModuleName, + CoinsSpentInMsg: spendableCoins, } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - - if err != nil { - return simtypes.NoOpMsg(feegrant.ModuleName, sdk.MsgTypeURL(msg), "unable to deliver tx"), nil, err - } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, err + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -157,30 +145,24 @@ func SimulateMsgRevokeAllowance(ak feegrant.AccountKeeper, bk feegrant.BankKeepe account := ak.GetAccount(ctx, granter.Address) spendableCoins := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendableCoins) - if err != nil { - return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgRevokeAllowance, err.Error()), nil, err - } msg := feegrant.NewMsgRevokeAllowance(granterAddr, granteeAddr) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{&msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - granter.PrivKey, - ) - - if err != nil { - return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgRevokeAllowance, err.Error()), nil, err + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: &msg, + MsgType: TypeMsgRevokeAllowance, + Context: ctx, + SimAccount: granter, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: feegrant.ModuleName, + CoinsSpentInMsg: spendableCoins, } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - return simtypes.NewOperationMsg(&msg, true, "", nil), nil, err + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } diff --git a/x/gov/simulation/operations.go b/x/gov/simulation/operations.go index 21ec3f7b298c..214fb9465676 100644 --- a/x/gov/simulation/operations.go +++ b/x/gov/simulation/operations.go @@ -241,26 +241,19 @@ func SimulateMsgDeposit(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Ke } } - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + txCtx := simulation.OperationInput{ + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + ModuleName: types.ModuleName, } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simulation.GenAndDeliverTx(txCtx, fees) } } @@ -298,32 +291,22 @@ func operationSimulateMsgVote(ak types.AccountKeeper, bk types.BankKeeper, k kee account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate fees"), nil, err + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, } - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -361,32 +344,22 @@ func operationSimulateMsgVoteWeighted(ak types.AccountKeeper, bk types.BankKeepe account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate fees"), nil, err - } - - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } diff --git a/x/simulation/expected_keepers.go b/x/simulation/expected_keepers.go new file mode 100644 index 000000000000..c54831b8a401 --- /dev/null +++ b/x/simulation/expected_keepers.go @@ -0,0 +1,16 @@ +package simulation + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// AccountKeeper defines the expected account keeper used for simulations (noalias) +type AccountKeeper interface { + GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI +} + +// BankKeeper defines the expected interface needed to retrieve account balances. +type BankKeeper interface { + SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins +} diff --git a/x/simulation/util.go b/x/simulation/util.go index c600bc2a369a..aa348bfd357f 100644 --- a/x/simulation/util.go +++ b/x/simulation/util.go @@ -5,6 +5,13 @@ import ( "fmt" "math/rand" "testing" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp/helpers" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" ) func getTestingMode(tb testing.TB) (testingMode bool, t *testing.T, b *testing.B) { @@ -53,3 +60,66 @@ func mustMarshalJSONIndent(o interface{}) []byte { return bz } + +// OperationInput is a struct that holds all the needed values to generate a tx and deliver it +type OperationInput struct { + R *rand.Rand + App *baseapp.BaseApp + TxGen client.TxConfig + Cdc *codec.ProtoCodec + Msg sdk.Msg + MsgType string + CoinsSpentInMsg sdk.Coins + Context sdk.Context + SimAccount simtypes.Account + AccountKeeper AccountKeeper + Bankkeeper BankKeeper + ModuleName string +} + +// GenAndDeliverTxWithRandFees generates a transaction with a random fee and delivers it. +func GenAndDeliverTxWithRandFees(txCtx OperationInput) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) + spendable := txCtx.Bankkeeper.SpendableCoins(txCtx.Context, account.GetAddress()) + + var fees sdk.Coins + var err error + + coins, hasNeg := spendable.SafeSub(txCtx.CoinsSpentInMsg) + if hasNeg { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "message doesn't leave room for fees"), nil, err + } + + fees, err = simtypes.RandomFees(txCtx.R, txCtx.Context, coins) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate fees"), nil, err + } + return GenAndDeliverTx(txCtx, fees) +} + +// GenAndDeliverTx generates a transactions and delivers it. +func GenAndDeliverTx(txCtx OperationInput, fees sdk.Coins) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) + tx, err := helpers.GenTx( + txCtx.TxGen, + []sdk.Msg{txCtx.Msg}, + fees, + helpers.DefaultGenTxGas, + txCtx.Context.ChainID(), + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + txCtx.SimAccount.PrivKey, + ) + + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate mock tx"), nil, err + } + + _, _, err = txCtx.App.Deliver(txCtx.TxGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(txCtx.Msg, true, "", txCtx.Cdc), nil, nil + +} diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index 8af20a4c6c5e..ce5ef3dc38ac 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp/helpers" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" @@ -152,27 +151,19 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k k return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to create CreateValidator message"), nil, err } - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + txCtx := simulation.OperationInput{ + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + ModuleName: types.ModuleName, } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simulation.GenAndDeliverTx(txCtx, fees) } } @@ -207,11 +198,6 @@ func SimulateMsgEditValidator(ak types.AccountKeeper, bk types.BankKeeper, k kee account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgEditValidator, "unable to generate fees"), nil, err - } - description := types.NewDescription( simtypes.RandStringOfLength(r, 10), simtypes.RandStringOfLength(r, 10), @@ -222,27 +208,22 @@ func SimulateMsgEditValidator(ak types.AccountKeeper, bk types.BankKeeper, k kee msg := types.NewMsgEditValidator(address, description, &newCommissionRate, nil) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, + } + + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -294,27 +275,19 @@ func SimulateMsgDelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper.K msg := types.NewMsgDelegate(simAccount.Address, val.GetOperator(), bondAmt) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + txCtx := simulation.OperationInput{ + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + ModuleName: types.ModuleName, } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simulation.GenAndDeliverTx(txCtx, fees) } } @@ -378,32 +351,22 @@ func SimulateMsgUndelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper account := ak.GetAccount(ctx, delAddr) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate fees"), nil, err - } - - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, + } + + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -485,36 +448,26 @@ func SimulateMsgBeginRedelegate(ak types.AccountKeeper, bk types.BankKeeper, k k account := ak.GetAccount(ctx, delAddr) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgBeginRedelegate, "unable to generate fees"), nil, err - } - msg := types.NewMsgBeginRedelegate( delAddr, srcAddr, destAddr, sdk.NewCoin(k.BondDenom(ctx), redAmt), ) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: simappparams.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: simAccount, + AccountKeeper: ak, + Bankkeeper: bk, + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, + } + + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } diff --git a/x/staking/simulation/operations_test.go b/x/staking/simulation/operations_test.go index a29321c700b4..da15fdd5e489 100644 --- a/x/staking/simulation/operations_test.go +++ b/x/staking/simulation/operations_test.go @@ -120,10 +120,10 @@ func TestSimulateMsgEditValidator(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "0.280623462081924936", msg.CommissionRate.String()) - require.Equal(t, "rBqDOTtGTO", msg.Description.Moniker) - require.Equal(t, "BSpYuLyYgg", msg.Description.Identity) - require.Equal(t, "wNbeHVIkPZ", msg.Description.Website) - require.Equal(t, "MOXcnQfyze", msg.Description.SecurityContact) + require.Equal(t, "xKGLwQvuyN", msg.Description.Moniker) + require.Equal(t, "SlcxgdXhhu", msg.Description.Identity) + require.Equal(t, "WeLrQKjLxz", msg.Description.Website) + require.Equal(t, "rBqDOTtGTO", msg.Description.SecurityContact) require.Equal(t, types.TypeMsgEditValidator, msg.Type()) require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) require.Len(t, futureOperations, 0)