forked from CosmWasm/wasmd
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add tokenfactory in wasm v0.45.0
- Loading branch information
Showing
70 changed files
with
11,803 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package apptesting | ||
|
||
import sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
// AssertEventEmitted asserts that ctx's event manager has emitted the given number of events | ||
// of the given type. | ||
func (s *KeeperTestHelper) AssertEventEmitted(ctx sdk.Context, eventTypeExpected string, numEventsExpected int) { | ||
allEvents := ctx.EventManager().Events() | ||
// filter out other events | ||
actualEvents := make([]sdk.Event, 0) | ||
for _, event := range allEvents { | ||
if event.Type == eventTypeExpected { | ||
actualEvents = append(actualEvents, event) | ||
} | ||
} | ||
s.Equal(numEventsExpected, len(actualEvents)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,298 @@ | ||
package apptesting | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"testing" | ||
"time" | ||
|
||
"cosmossdk.io/math" | ||
dbm "github.com/cometbft/cometbft-db" | ||
abci "github.com/cometbft/cometbft/abci/types" | ||
"github.com/cometbft/cometbft/crypto/ed25519" | ||
"github.com/cometbft/cometbft/libs/log" | ||
tmtypes "github.com/cometbft/cometbft/proto/tendermint/types" | ||
"github.com/cosmos/cosmos-sdk/baseapp" | ||
"github.com/cosmos/cosmos-sdk/client" | ||
cdctypes "github.com/cosmos/cosmos-sdk/codec/types" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" | ||
"github.com/cosmos/cosmos-sdk/store/rootmulti" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/cosmos/cosmos-sdk/types/tx/signing" | ||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" | ||
"github.com/cosmos/cosmos-sdk/x/authz" | ||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" | ||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" | ||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||
"github.com/stretchr/testify/require" | ||
"github.com/stretchr/testify/suite" | ||
|
||
authzcodec "github.com/CosmWasm/wasmd/x/tokenfactory/types/authzcodec" | ||
|
||
"github.com/CosmWasm/wasmd/app" | ||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" | ||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" | ||
) | ||
|
||
type KeeperTestHelper struct { | ||
suite.Suite | ||
|
||
App *app.WasmApp | ||
Ctx sdk.Context | ||
QueryHelper *baseapp.QueryServiceTestHelper | ||
TestAccs []sdk.AccAddress | ||
} | ||
|
||
var ( | ||
SecondaryDenom = "uion" | ||
SecondaryAmount = sdk.NewInt(100000000) | ||
) | ||
|
||
// Setup sets up basic environment for suite (App, Ctx, and test accounts) | ||
func (s *KeeperTestHelper) Setup() { | ||
s.App = app.Setup(s.T()) | ||
s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) | ||
s.QueryHelper = &baseapp.QueryServiceTestHelper{ | ||
GRPCQueryRouter: s.App.GRPCQueryRouter(), | ||
Ctx: s.Ctx, | ||
} | ||
s.TestAccs = CreateRandomAccounts(3) | ||
} | ||
|
||
func (s *KeeperTestHelper) SetupTestForInitGenesis() { | ||
db := dbm.NewMemDB() | ||
s.App = app.NewWasmAppWithCustomOptions(s.T(), true, app.SetupOptions{ | ||
Logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)), | ||
DB: db, | ||
AppOpts: simtestutil.NewAppOptionsWithFlagHome(s.T().TempDir()), | ||
}) | ||
s.Ctx = s.App.BaseApp.NewContext(true, tmtypes.Header{}) | ||
} | ||
|
||
// CreateTestContext creates a test context. | ||
func (s *KeeperTestHelper) CreateTestContext() sdk.Context { | ||
ctx, _ := s.CreateTestContextWithMultiStore() | ||
return ctx | ||
} | ||
|
||
// CreateTestContextWithMultiStore creates a test context and returns it together with multi store. | ||
func (s *KeeperTestHelper) CreateTestContextWithMultiStore() (sdk.Context, sdk.CommitMultiStore) { | ||
db := dbm.NewMemDB() | ||
logger := log.NewNopLogger() | ||
|
||
ms := rootmulti.NewStore(db, logger) | ||
|
||
return sdk.NewContext(ms, tmtypes.Header{}, false, logger), ms | ||
} | ||
|
||
// CreateTestContext creates a test context. | ||
func (s *KeeperTestHelper) Commit() { | ||
oldHeight := s.Ctx.BlockHeight() | ||
oldHeader := s.Ctx.BlockHeader() | ||
s.App.Commit() | ||
newHeader := tmtypes.Header{Height: oldHeight + 1, ChainID: oldHeader.ChainID, Time: oldHeader.Time.Add(time.Second)} | ||
s.App.BeginBlock(abci.RequestBeginBlock{Header: newHeader}) | ||
s.Ctx = s.App.NewContext(false, newHeader) | ||
} | ||
|
||
// FundAcc funds target address with specified amount. | ||
func (s *KeeperTestHelper) FundAcc(acc sdk.AccAddress, amounts sdk.Coins) { | ||
err := app.FundAccount(s.App.BankKeeper, s.Ctx, acc, amounts) | ||
s.Require().NoError(err) | ||
} | ||
|
||
// FundModuleAcc funds target modules with specified amount. | ||
func (s *KeeperTestHelper) FundModuleAcc(moduleName string, amounts sdk.Coins) { | ||
err := app.FundModuleAccount(s.App.BankKeeper, s.Ctx, moduleName, amounts) | ||
s.Require().NoError(err) | ||
} | ||
|
||
func (s *KeeperTestHelper) MintCoins(coins sdk.Coins) { | ||
err := s.App.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins) | ||
s.Require().NoError(err) | ||
} | ||
|
||
// SetupValidator sets up a validator and returns the ValAddress. | ||
func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sdk.ValAddress { | ||
valPub := secp256k1.GenPrivKey().PubKey() | ||
valAddr := sdk.ValAddress(valPub.Address()) | ||
bondDenom := s.App.StakingKeeper.GetParams(s.Ctx).BondDenom | ||
selfBond := sdk.NewCoins(sdk.Coin{Amount: sdk.DefaultPowerReduction, Denom: bondDenom}) | ||
|
||
s.FundAcc(sdk.AccAddress(valAddr), selfBond) | ||
|
||
stakingCoin := sdk.NewCoin(sdk.DefaultBondDenom, selfBond[0].Amount) | ||
ZeroCommission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) | ||
_, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) | ||
s.Require().NoError(err) | ||
|
||
val, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) | ||
s.Require().True(found) | ||
|
||
val = val.UpdateStatus(bondStatus) | ||
s.App.StakingKeeper.SetValidator(s.Ctx, val) | ||
|
||
consAddr, err := val.GetConsAddr() | ||
s.Suite.Require().NoError(err) | ||
|
||
signingInfo := slashingtypes.NewValidatorSigningInfo( | ||
consAddr, | ||
s.Ctx.BlockHeight(), | ||
0, | ||
time.Unix(0, 0), | ||
false, | ||
0, | ||
) | ||
s.App.SlashingKeeper.SetValidatorSigningInfo(s.Ctx, consAddr, signingInfo) | ||
|
||
return valAddr | ||
} | ||
|
||
// BeginNewBlock starts a new block. | ||
func (s *KeeperTestHelper) BeginNewBlock() { | ||
var valAddr []byte | ||
|
||
validators := s.App.StakingKeeper.GetAllValidators(s.Ctx) | ||
if len(validators) >= 1 { | ||
valAddrFancy, err := validators[0].GetConsAddr() | ||
s.Require().NoError(err) | ||
valAddr = valAddrFancy.Bytes() | ||
} else { | ||
valAddrFancy := s.SetupValidator(stakingtypes.Bonded) | ||
validator, _ := s.App.StakingKeeper.GetValidator(s.Ctx, valAddrFancy) | ||
valAddr2, _ := validator.GetConsAddr() | ||
valAddr = valAddr2.Bytes() | ||
} | ||
|
||
s.BeginNewBlockWithProposer(valAddr) | ||
} | ||
|
||
// BeginNewBlockWithProposer begins a new block with a proposer. | ||
func (s *KeeperTestHelper) BeginNewBlockWithProposer(proposer sdk.ValAddress) { | ||
validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, proposer) | ||
s.Assert().True(found) | ||
|
||
valConsAddr, err := validator.GetConsAddr() | ||
s.Require().NoError(err) | ||
|
||
valAddr := valConsAddr.Bytes() | ||
|
||
newBlockTime := s.Ctx.BlockTime().Add(5 * time.Second) | ||
|
||
header := tmtypes.Header{Height: s.Ctx.BlockHeight() + 1, Time: newBlockTime} | ||
newCtx := s.Ctx.WithBlockTime(newBlockTime).WithBlockHeight(s.Ctx.BlockHeight() + 1) | ||
s.Ctx = newCtx | ||
lastCommitInfo := abci.CommitInfo{ | ||
Votes: []abci.VoteInfo{{ | ||
Validator: abci.Validator{Address: valAddr, Power: 1000}, | ||
SignedLastBlock: true, | ||
}}, | ||
} | ||
reqBeginBlock := abci.RequestBeginBlock{Header: header, LastCommitInfo: lastCommitInfo} | ||
|
||
fmt.Println("beginning block ", s.Ctx.BlockHeight()) | ||
s.App.BeginBlocker(s.Ctx, reqBeginBlock) | ||
} | ||
|
||
// EndBlock ends the block. | ||
func (s *KeeperTestHelper) EndBlock() { | ||
reqEndBlock := abci.RequestEndBlock{Height: s.Ctx.BlockHeight()} | ||
s.App.EndBlocker(s.Ctx, reqEndBlock) | ||
} | ||
|
||
// AllocateRewardsToValidator allocates reward tokens to a distribution module then allocates rewards to the validator address. | ||
func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, rewardAmt math.Int) { | ||
validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) | ||
s.Require().True(found) | ||
|
||
// allocate reward tokens to distribution module | ||
coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, rewardAmt)} | ||
err := app.FundModuleAccount(s.App.BankKeeper, s.Ctx, distrtypes.ModuleName, coins) | ||
s.Require().NoError(err) | ||
|
||
// allocate rewards to validator | ||
s.Ctx = s.Ctx.WithBlockHeight(s.Ctx.BlockHeight() + 1) | ||
decTokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(20000)}} | ||
s.App.DistrKeeper.AllocateTokensToValidator(s.Ctx, validator, decTokens) | ||
} | ||
|
||
// BuildTx builds a transaction. | ||
func (s *KeeperTestHelper) BuildTx( | ||
txBuilder client.TxBuilder, | ||
msgs []sdk.Msg, | ||
sigV2 signing.SignatureV2, | ||
memo string, txFee sdk.Coins, | ||
gasLimit uint64, | ||
) authsigning.Tx { | ||
err := txBuilder.SetMsgs(msgs[0]) | ||
s.Require().NoError(err) | ||
|
||
err = txBuilder.SetSignatures(sigV2) | ||
s.Require().NoError(err) | ||
|
||
txBuilder.SetMemo(memo) | ||
txBuilder.SetFeeAmount(txFee) | ||
txBuilder.SetGasLimit(gasLimit) | ||
|
||
return txBuilder.GetTx() | ||
} | ||
|
||
// CreateRandomAccounts is a function return a list of randomly generated AccAddresses | ||
func CreateRandomAccounts(numAccts int) []sdk.AccAddress { | ||
testAddrs := make([]sdk.AccAddress, numAccts) | ||
for i := 0; i < numAccts; i++ { | ||
pk := ed25519.GenPrivKey().PubKey() | ||
testAddrs[i] = sdk.AccAddress(pk.Address()) | ||
} | ||
|
||
return testAddrs | ||
} | ||
|
||
func TestMessageAuthzSerialization(t *testing.T, msg sdk.Msg) { | ||
someDate := time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC) | ||
var expire *time.Time | ||
|
||
const ( | ||
mockGranter string = "cosmos1abc" | ||
mockGrantee string = "cosmos1xyz" | ||
) | ||
|
||
var ( | ||
mockMsgGrant authz.MsgGrant | ||
mockMsgRevoke authz.MsgRevoke | ||
mockMsgExec authz.MsgExec | ||
) | ||
|
||
// Authz: Grant Msg | ||
typeURL := sdk.MsgTypeURL(msg) | ||
grant, err := authz.NewGrant(someDate, authz.NewGenericAuthorization(typeURL), expire) | ||
require.NoError(t, err) | ||
|
||
msgGrant := authz.MsgGrant{Granter: mockGranter, Grantee: mockGrantee, Grant: grant} | ||
msgGrantBytes := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgGrant))) | ||
err = authzcodec.ModuleCdc.UnmarshalJSON(msgGrantBytes, &mockMsgGrant) | ||
require.NoError(t, err) | ||
|
||
// Authz: Revoke Msg | ||
msgRevoke := authz.MsgRevoke{Granter: mockGranter, Grantee: mockGrantee, MsgTypeUrl: typeURL} | ||
msgRevokeByte := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgRevoke))) | ||
err = authzcodec.ModuleCdc.UnmarshalJSON(msgRevokeByte, &mockMsgRevoke) | ||
require.NoError(t, err) | ||
|
||
// Authz: Exec Msg | ||
msgAny, err := cdctypes.NewAnyWithValue(msg) | ||
require.NoError(t, err) | ||
msgExec := authz.MsgExec{Grantee: mockGrantee, Msgs: []*cdctypes.Any{msgAny}} | ||
execMsgByte := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgExec))) | ||
err = authzcodec.ModuleCdc.UnmarshalJSON(execMsgByte, &mockMsgExec) | ||
require.NoError(t, err) | ||
require.Equal(t, msgExec.Msgs[0].Value, mockMsgExec.Msgs[0].Value) | ||
} | ||
|
||
func GenerateTestAddrs() (string, string) { | ||
pk1 := ed25519.GenPrivKey().PubKey() | ||
validAddr := sdk.AccAddress(pk1.Address()).String() | ||
invalidAddr := sdk.AccAddress("invalid").String() | ||
return validAddr, invalidAddr | ||
} |
Oops, something went wrong.