mirror of https://github.com/certusone/wasmd.git
Make contract addresses predictable
This commit is contained in:
parent
d9f9f91d13
commit
ccb2fdd0b6
|
@ -71,6 +71,29 @@ func setup(t testing.TB, withGenesis bool, invCheckPeriod uint, opts ...wasm.Opt
|
|||
return app, GenesisState{}
|
||||
}
|
||||
|
||||
// Setup initializes a new WasmApp with DefaultNodeHome for integration tests
|
||||
func Setup(isCheckTx bool, opts ...wasm.Option) *WasmApp {
|
||||
db := dbm.NewMemDB()
|
||||
app := NewWasmApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, MakeEncodingConfig(), wasm.EnableAllProposals, EmptyBaseAppOptions{}, opts)
|
||||
|
||||
if !isCheckTx {
|
||||
genesisState := NewDefaultGenesisState()
|
||||
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
app.InitChain(
|
||||
abci.RequestInitChain{
|
||||
Validators: []abci.ValidatorUpdate{},
|
||||
ConsensusParams: DefaultConsensusParams,
|
||||
AppStateBytes: stateBytes,
|
||||
},
|
||||
)
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
// SetupWithGenesisValSet initializes a new WasmApp with a validator set and genesis accounts
|
||||
// that also act as delegators. For simplicity, each validator is bonded with a delegation
|
||||
// of one consensus engine unit (10^6) in the default token of the WasmApp from first genesis
|
||||
|
|
|
@ -430,6 +430,7 @@ MsgStoreCodeResponse returns store result data.
|
|||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code |
|
||||
| `checksum` | [bytes](#bytes) | | Checksum is the sha256 hash of the stored code |
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ message MsgStoreCode {
|
|||
message MsgStoreCodeResponse {
|
||||
// CodeID is the reference to the stored WASM code
|
||||
uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ];
|
||||
// Checksum is the sha256 hash of the stored code
|
||||
bytes checksum = 2;
|
||||
}
|
||||
|
||||
// MsgInstantiateContract create a new smart contract instance for the given
|
||||
|
|
|
@ -86,7 +86,6 @@ var (
|
|||
ErrQueryFailed = types.ErrQueryFailed
|
||||
ErrInvalidMsg = types.ErrInvalidMsg
|
||||
KeyLastCodeID = types.KeyLastCodeID
|
||||
KeyLastInstanceID = types.KeyLastInstanceID
|
||||
CodeKeyPrefix = types.CodeKeyPrefix
|
||||
ContractKeyPrefix = types.ContractKeyPrefix
|
||||
ContractStorePrefix = types.ContractStorePrefix
|
||||
|
|
|
@ -103,7 +103,7 @@ func GenesisInstantiateContractCmd(defaultNodeHome string, genesisMutator Genesi
|
|||
}
|
||||
|
||||
return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error {
|
||||
// simple sanity check that sender has some balance although it may be consumed by appState previous message already
|
||||
// simple sanity check that sender has some balance, although it may be consumed by appState previous message already
|
||||
switch ok, err := hasAccountBalance(cmd, appState, senderAddr, msg.Funds); {
|
||||
case err != nil:
|
||||
return err
|
||||
|
@ -112,7 +112,7 @@ func GenesisInstantiateContractCmd(defaultNodeHome string, genesisMutator Genesi
|
|||
}
|
||||
|
||||
// does code id exists?
|
||||
codeInfos, err := GetAllCodes(state)
|
||||
codeInfos := GetAllCodes(state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ func GenesisExecuteContractCmd(defaultNodeHome string, genesisMutator GenesisMut
|
|||
}
|
||||
|
||||
return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error {
|
||||
// simple sanity check that sender has some balance although it may be consumed by appState previous message already
|
||||
// simple sanity check that sender has some balance, although it may be consumed by appState previous message already
|
||||
switch ok, err := hasAccountBalance(cmd, appState, senderAddr, msg.Funds); {
|
||||
case err != nil:
|
||||
return err
|
||||
|
@ -211,7 +211,7 @@ func GenesisListCodesCmd(defaultNodeHome string, genReader GenesisReader) *cobra
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
all, err := GetAllCodes(g.WasmModuleState)
|
||||
all := GetAllCodes(g.WasmModuleState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -236,7 +236,10 @@ func GenesisListContractsCmd(defaultNodeHome string, genReader GenesisReader) *c
|
|||
return err
|
||||
}
|
||||
state := g.WasmModuleState
|
||||
all := GetAllContracts(state)
|
||||
all, err := GetAllContracts(state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return printJSONOutput(cmd, all)
|
||||
},
|
||||
}
|
||||
|
@ -245,7 +248,7 @@ func GenesisListContractsCmd(defaultNodeHome string, genReader GenesisReader) *c
|
|||
return cmd
|
||||
}
|
||||
|
||||
// clientCtx marshaller works only with proto or bytes so we marshal the output ourself
|
||||
// clientCtx marshaller works only with proto or bytes, so we marshal the output ourselves
|
||||
func printJSONOutput(cmd *cobra.Command, obj interface{}) error {
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
bz, err := json.MarshalIndent(obj, "", " ")
|
||||
|
@ -260,7 +263,7 @@ type CodeMeta struct {
|
|||
Info types.CodeInfo `json:"info"`
|
||||
}
|
||||
|
||||
func GetAllCodes(state *types.GenesisState) ([]CodeMeta, error) {
|
||||
func GetAllCodes(state *types.GenesisState) []CodeMeta {
|
||||
all := make([]CodeMeta, len(state.Codes))
|
||||
for i, c := range state.Codes {
|
||||
all[i] = CodeMeta{
|
||||
|
@ -277,10 +280,7 @@ func GetAllCodes(state *types.GenesisState) ([]CodeMeta, error) {
|
|||
accessConfig = *msg.InstantiatePermission
|
||||
} else {
|
||||
// default
|
||||
creator, err := sdk.AccAddressFromBech32(msg.Sender)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sender: %s", err)
|
||||
}
|
||||
creator := sdk.MustAccAddressFromBech32(msg.Sender)
|
||||
accessConfig = state.Params.InstantiateDefaultPermission.With(creator)
|
||||
}
|
||||
hash := sha256.Sum256(msg.WASMByteCode)
|
||||
|
@ -295,7 +295,7 @@ func GetAllCodes(state *types.GenesisState) ([]CodeMeta, error) {
|
|||
seq++
|
||||
}
|
||||
}
|
||||
return all, nil
|
||||
return all
|
||||
}
|
||||
|
||||
type ContractMeta struct {
|
||||
|
@ -303,7 +303,18 @@ type ContractMeta struct {
|
|||
Info types.ContractInfo `json:"info"`
|
||||
}
|
||||
|
||||
func GetAllContracts(state *types.GenesisState) []ContractMeta {
|
||||
// returns nil when not found
|
||||
func codeHashByID(state *types.GenesisState, codeID uint64) []byte {
|
||||
codes := GetAllCodes(state)
|
||||
for _, v := range codes {
|
||||
if v.CodeID == codeID {
|
||||
return v.Info.CodeHash
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetAllContracts(state *types.GenesisState) ([]ContractMeta, error) {
|
||||
all := make([]ContractMeta, len(state.Contracts))
|
||||
for i, c := range state.Contracts {
|
||||
all[i] = ContractMeta{
|
||||
|
@ -312,11 +323,18 @@ func GetAllContracts(state *types.GenesisState) []ContractMeta {
|
|||
}
|
||||
}
|
||||
// add inflight
|
||||
seq := contractSeqValue(state)
|
||||
for _, m := range state.GenMsgs {
|
||||
if msg := m.GetInstantiateContract(); msg != nil {
|
||||
senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unsupported address %q: %s", msg.Sender, err))
|
||||
}
|
||||
codeHash := codeHashByID(state, msg.CodeID)
|
||||
if codeHash == nil {
|
||||
return nil, types.ErrNotFound.Wrapf("hash for code-id: %d", msg.CodeID)
|
||||
}
|
||||
all = append(all, ContractMeta{
|
||||
ContractAddress: keeper.BuildContractAddress(msg.CodeID, seq).String(),
|
||||
ContractAddress: keeper.BuildContractAddress(codeHash, senderAddr, msg.Label).String(),
|
||||
Info: types.ContractInfo{
|
||||
CodeID: msg.CodeID,
|
||||
Creator: msg.Sender,
|
||||
|
@ -324,10 +342,9 @@ func GetAllContracts(state *types.GenesisState) []ContractMeta {
|
|||
Label: msg.Label,
|
||||
},
|
||||
})
|
||||
seq++
|
||||
}
|
||||
}
|
||||
return all
|
||||
return all, nil
|
||||
}
|
||||
|
||||
func hasAccountBalance(cmd *cobra.Command, appState map[string]json.RawMessage, sender sdk.AccAddress, coins sdk.Coins) (bool, error) {
|
||||
|
@ -354,13 +371,19 @@ func hasContract(state *types.GenesisState, contractAddr string) bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
seq := contractSeqValue(state)
|
||||
for _, m := range state.GenMsgs {
|
||||
if msg := m.GetInstantiateContract(); msg != nil {
|
||||
if keeper.BuildContractAddress(msg.CodeID, seq).String() == contractAddr {
|
||||
senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unsupported address %q: %s", msg.Sender, err))
|
||||
}
|
||||
hash := codeHashByID(state, msg.CodeID)
|
||||
if hash == nil {
|
||||
panic(fmt.Sprintf("unknown code id: %d", msg.CodeID))
|
||||
}
|
||||
if keeper.BuildContractAddress(hash, senderAddr, msg.Label).String() == contractAddr {
|
||||
return true
|
||||
}
|
||||
seq++
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
@ -453,19 +476,6 @@ func (x DefaultGenesisIO) AlterWasmModuleState(cmd *cobra.Command, callback func
|
|||
return genutil.ExportGenesisFile(g.GenDoc, g.GenesisFile)
|
||||
}
|
||||
|
||||
// contractSeqValue reads the contract sequence from the genesis or
|
||||
// returns default start value used in the keeper
|
||||
func contractSeqValue(state *types.GenesisState) uint64 {
|
||||
var seq uint64 = 1
|
||||
for _, s := range state.Sequences {
|
||||
if bytes.Equal(s.IDKey, types.KeyLastInstanceID) {
|
||||
seq = s.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
return seq
|
||||
}
|
||||
|
||||
// codeSeqValue reads the code sequence from the genesis or
|
||||
// returns default start value used in the keeper
|
||||
func codeSeqValue(state *types.GenesisState) uint64 {
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
|
@ -363,7 +366,8 @@ func TestInstantiateContractCmd(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestExecuteContractCmd(t *testing.T) {
|
||||
const firstContractAddress = "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr"
|
||||
mySenderAddr := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len))
|
||||
myFirstContractAddress := keeper.BuildContractAddress([]byte("myCodeHash"), mySenderAddr, "my").String()
|
||||
minimalWasmGenesis := types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
}
|
||||
|
@ -390,7 +394,7 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: firstContractAddress,
|
||||
ContractAddress: myFirstContractAddress,
|
||||
ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) {
|
||||
info.Created = nil
|
||||
}),
|
||||
|
@ -399,53 +403,34 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
cmd.SetArgs([]string{myFirstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 1,
|
||||
},
|
||||
"all good with contract from genesis store messages without initial sequence": {
|
||||
"all good with contract from genesis store messages": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfoFixture(),
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfoFixture(func(info *types.CodeInfo) {
|
||||
info.CodeHash = []byte("myCodeHash")
|
||||
}),
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: types.MsgInstantiateContractFixture()}},
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: types.MsgInstantiateContractFixture(
|
||||
func(m *types.MsgInstantiateContract) {
|
||||
m.Sender = mySenderAddr.String()
|
||||
m.Label = "my"
|
||||
})}},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 2,
|
||||
},
|
||||
"all good with contract from genesis store messages and contract sequence set": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfoFixture(),
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: types.MsgInstantiateContractFixture()}},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastInstanceID, Value: 100},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
// See TestBuildContractAddress in keeper_test.go
|
||||
cmd.SetArgs([]string{"cosmos1mujpjkwhut9yjw4xueyugc02evfv46y0dtmnz4lh8xxkkdapym9stu5qm8", `{}`})
|
||||
cmd.SetArgs([]string{myFirstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
|
@ -472,7 +457,7 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: firstContractAddress,
|
||||
ContractAddress: myFirstContractAddress,
|
||||
ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) {
|
||||
info.Created = nil
|
||||
}),
|
||||
|
@ -481,7 +466,7 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
cmd.SetArgs([]string{myFirstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t))
|
||||
},
|
||||
|
@ -499,7 +484,7 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: firstContractAddress,
|
||||
ContractAddress: myFirstContractAddress,
|
||||
ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) {
|
||||
info.Created = nil
|
||||
}),
|
||||
|
@ -508,7 +493,7 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
cmd.SetArgs([]string{myFirstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
flagSet.Set("amount", "100stake")
|
||||
|
@ -527,7 +512,7 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: firstContractAddress,
|
||||
ContractAddress: myFirstContractAddress,
|
||||
ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) {
|
||||
info.Created = nil
|
||||
}),
|
||||
|
@ -536,7 +521,7 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
cmd.SetArgs([]string{myFirstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t))
|
||||
flagSet.Set("amount", "10stake")
|
||||
|
@ -565,6 +550,9 @@ func TestExecuteContractCmd(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetAllContracts(t *testing.T) {
|
||||
creatorAddr1 := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len))
|
||||
creatorAddr2 := sdk.AccAddress(bytes.Repeat([]byte{2}, address.Len))
|
||||
|
||||
specs := map[string]struct {
|
||||
src types.GenesisState
|
||||
exp []ContractMeta
|
||||
|
@ -595,68 +583,55 @@ func TestGetAllContracts(t *testing.T) {
|
|||
},
|
||||
"read from message state": {
|
||||
src: types.GenesisState{
|
||||
Codes: []types.Code{{CodeID: 1, CodeInfo: types.CodeInfo{CodeHash: []byte("firstCodeHash")}}},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "first"}}},
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "second"}}},
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Sender: creatorAddr1.String(), Label: "first", CodeID: 1}}},
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Sender: creatorAddr2.String(), Label: "second", CodeID: 1}}},
|
||||
},
|
||||
},
|
||||
exp: []ContractMeta{
|
||||
{
|
||||
ContractAddress: keeper.BuildContractAddress(0, 1).String(),
|
||||
Info: types.ContractInfo{Label: "first"},
|
||||
ContractAddress: keeper.BuildContractAddress([]byte("firstCodeHash"), creatorAddr1, "first").String(),
|
||||
Info: types.ContractInfo{Creator: creatorAddr1.String(), Label: "first", CodeID: 1},
|
||||
},
|
||||
{
|
||||
ContractAddress: keeper.BuildContractAddress(0, 2).String(),
|
||||
Info: types.ContractInfo{Label: "second"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"read from message state with contract sequence": {
|
||||
src: types.GenesisState{
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastInstanceID, Value: 100},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "hundred"}}},
|
||||
},
|
||||
},
|
||||
exp: []ContractMeta{
|
||||
{
|
||||
ContractAddress: keeper.BuildContractAddress(0, 100).String(),
|
||||
Info: types.ContractInfo{Label: "hundred"},
|
||||
ContractAddress: keeper.BuildContractAddress([]byte("firstCodeHash"), creatorAddr2, "second").String(),
|
||||
Info: types.ContractInfo{Creator: creatorAddr2.String(), Label: "second", CodeID: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
"read from contract and message state with contract sequence": {
|
||||
src: types.GenesisState{
|
||||
Codes: []types.Code{
|
||||
{CodeID: 1, CodeInfo: types.CodeInfo{CodeHash: []byte("firstCodeHash")}},
|
||||
{CodeID: 100, CodeInfo: types.CodeInfo{CodeHash: []byte("otherCodeHash")}},
|
||||
},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: "first-contract",
|
||||
ContractInfo: types.ContractInfo{Label: "first"},
|
||||
ContractAddress: keeper.BuildContractAddress([]byte("firstCodeHash"), creatorAddr1, "first").String(),
|
||||
ContractInfo: types.ContractInfo{Label: "first", CodeID: 1},
|
||||
},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastInstanceID, Value: 100},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "hundred"}}},
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Sender: creatorAddr1.String(), Label: "hundred", CodeID: 100}}},
|
||||
},
|
||||
},
|
||||
exp: []ContractMeta{
|
||||
{
|
||||
ContractAddress: "first-contract",
|
||||
Info: types.ContractInfo{Label: "first"},
|
||||
ContractAddress: keeper.BuildContractAddress([]byte("firstCodeHash"), creatorAddr1, "first").String(),
|
||||
Info: types.ContractInfo{Label: "first", CodeID: 1},
|
||||
},
|
||||
{
|
||||
ContractAddress: keeper.BuildContractAddress(0, 100).String(),
|
||||
Info: types.ContractInfo{Label: "hundred"},
|
||||
ContractAddress: keeper.BuildContractAddress([]byte("otherCodeHash"), creatorAddr1, "hundred").String(),
|
||||
Info: types.ContractInfo{Creator: creatorAddr1.String(), Label: "hundred", CodeID: 100},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
got := GetAllContracts(&spec.src)
|
||||
got, err := GetAllContracts(&spec.src)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
|
@ -39,6 +40,7 @@ func GetQueryCmd() *cobra.Command {
|
|||
GetCmdListPinnedCode(),
|
||||
GetCmdLibVersion(),
|
||||
GetCmdQueryParams(),
|
||||
GetCmdBuildAddress(),
|
||||
)
|
||||
return queryCmd
|
||||
}
|
||||
|
@ -63,6 +65,33 @@ func GetCmdLibVersion() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdBuildAddress build a contract address
|
||||
func GetCmdBuildAddress() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "build-address [code-hash] [creator-address] [label]",
|
||||
Short: "build contract address",
|
||||
Aliases: []string{"address"},
|
||||
Args: cobra.ExactArgs(3),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
codeHash, err := hex.DecodeString(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("code-hash: %s", err)
|
||||
}
|
||||
creator, err := sdk.AccAddressFromBech32(args[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("creator: %s", err)
|
||||
}
|
||||
label := args[2]
|
||||
if err := types.ValidateLabel(label); err != nil {
|
||||
return fmt.Errorf("label: %s", err)
|
||||
}
|
||||
cmd.Println(keeper.BuildContractAddress(codeHash, creator, label).String())
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdListCode lists all wasm code uploaded
|
||||
func GetCmdListCode() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
|
@ -117,6 +146,9 @@ func GetCmdListContractByCode() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if codeID == 0 {
|
||||
return errors.New("empty code id")
|
||||
}
|
||||
|
||||
pageReq, err := client.ReadPageRequest(withPageKeyDecoded(cmd.Flags()))
|
||||
if err != nil {
|
||||
|
|
|
@ -13,8 +13,8 @@ func TestInitGenesis(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := data.faucet.NewFundedAccount(data.ctx, deposit.Add(deposit...)...)
|
||||
fred := data.faucet.NewFundedAccount(data.ctx, topUp...)
|
||||
creator := data.faucet.NewFundedRandomAccount(data.ctx, deposit.Add(deposit...)...)
|
||||
fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...)
|
||||
|
||||
h := data.module.Route().Handler()
|
||||
q := data.module.LegacyQuerierHandler(nil)
|
||||
|
|
|
@ -62,6 +62,7 @@ func (chain *TestChain) StoreCode(byteCode []byte) types.MsgStoreCodeResponse {
|
|||
var pInstResp types.MsgStoreCodeResponse
|
||||
require.NoError(chain.t, pInstResp.Unmarshal(protoResult.Data[0].Data))
|
||||
require.NotEmpty(chain.t, pInstResp.CodeID)
|
||||
require.NotEmpty(chain.t, pInstResp.Checksum)
|
||||
return pInstResp
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ var _ types.ContractOpsKeeper = PermissionedKeeper{}
|
|||
|
||||
// decoratedKeeper contains a subset of the wasm keeper that are already or can be guarded by an authorization policy in the future
|
||||
type decoratedKeeper interface {
|
||||
create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, err error)
|
||||
create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, checksum []byte, err error)
|
||||
instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, authZ AuthorizationPolicy) (sdk.AccAddress, []byte, error)
|
||||
migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) ([]byte, error)
|
||||
setContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress, authZ AuthorizationPolicy) error
|
||||
|
@ -39,7 +39,7 @@ func NewDefaultPermissionKeeper(nested decoratedKeeper) *PermissionedKeeper {
|
|||
return NewPermissionedKeeper(nested, DefaultAuthorizationPolicy{})
|
||||
}
|
||||
|
||||
func (p PermissionedKeeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig) (codeID uint64, err error) {
|
||||
func (p PermissionedKeeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig) (codeID uint64, checksum []byte, err error) {
|
||||
return p.nested.create(ctx, creator, wasmCode, instantiateAccess, p.authZPolicy)
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, staki
|
|||
}
|
||||
}
|
||||
|
||||
var maxContractID int
|
||||
for i, contract := range data.Contracts {
|
||||
contractAddr, err := sdk.AccAddressFromBech32(contract.ContractAddress)
|
||||
if err != nil {
|
||||
|
@ -45,7 +44,6 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, staki
|
|||
if err != nil {
|
||||
return nil, sdkerrors.Wrapf(err, "contract number %d", i)
|
||||
}
|
||||
maxContractID = i + 1 // not ideal but max(contractID) is not persisted otherwise
|
||||
}
|
||||
|
||||
for i, seq := range data.Sequences {
|
||||
|
@ -60,10 +58,6 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, staki
|
|||
if seqVal <= maxCodeID {
|
||||
return nil, sdkerrors.Wrapf(types.ErrInvalid, "seq %s with value: %d must be greater than: %d ", string(types.KeyLastCodeID), seqVal, maxCodeID)
|
||||
}
|
||||
seqVal = keeper.PeekAutoIncrementID(ctx, types.KeyLastInstanceID)
|
||||
if seqVal <= uint64(maxContractID) {
|
||||
return nil, sdkerrors.Wrapf(types.ErrInvalid, "seq %s with value: %d must be greater than: %d ", string(types.KeyLastInstanceID), seqVal, maxContractID)
|
||||
}
|
||||
|
||||
if len(data.GenMsgs) == 0 {
|
||||
return nil, nil
|
||||
|
@ -117,7 +111,7 @@ func ExportGenesis(ctx sdk.Context, keeper *Keeper) *types.GenesisState {
|
|||
return false
|
||||
})
|
||||
|
||||
for _, k := range [][]byte{types.KeyLastCodeID, types.KeyLastInstanceID} {
|
||||
for _, k := range [][]byte{types.KeyLastCodeID} {
|
||||
genState.Sequences = append(genState.Sequences, types.Sequence{
|
||||
IDKey: k,
|
||||
Value: keeper.PeekAutoIncrementID(ctx, k),
|
||||
|
|
|
@ -11,6 +11,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -65,7 +69,7 @@ func TestGenesisExportImport(t *testing.T) {
|
|||
|
||||
creatorAddr, err := sdk.AccAddressFromBech32(codeInfo.Creator)
|
||||
require.NoError(t, err)
|
||||
codeID, err := contractKeeper.Create(srcCtx, creatorAddr, wasmCode, &codeInfo.InstantiateConfig)
|
||||
codeID, checksum, err := contractKeeper.Create(srcCtx, creatorAddr, wasmCode, &codeInfo.InstantiateConfig)
|
||||
require.NoError(t, err)
|
||||
if pinned {
|
||||
contractKeeper.PinCode(srcCtx, codeID)
|
||||
|
@ -80,7 +84,7 @@ func TestGenesisExportImport(t *testing.T) {
|
|||
}
|
||||
|
||||
contract.CodeID = codeID
|
||||
contractAddr := wasmKeeper.generateContractAddress(srcCtx, codeID)
|
||||
contractAddr := BuildContractAddress(checksum, creatorAddr, "testing")
|
||||
wasmKeeper.storeContractInfo(srcCtx, contractAddr, &contract)
|
||||
wasmKeeper.appendToContractHistory(srcCtx, contractAddr, history...)
|
||||
wasmKeeper.importContractState(srcCtx, contractAddr, stateModels)
|
||||
|
@ -156,6 +160,16 @@ func TestGenesisInit(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
myCodeInfo := wasmTypes.CodeInfoFixture(wasmTypes.WithSHA256CodeHash(wasmCode))
|
||||
mySenderAddr := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len))
|
||||
myLabel := "testing"
|
||||
myContractInfoFixture := func(mutators ...func(*types.ContractInfo)) types.ContractInfo {
|
||||
return types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) {
|
||||
c.CodeID = 1
|
||||
c.Creator = mySenderAddr.String()
|
||||
c.Label = myLabel
|
||||
}, types.OnlyGenesisFields)
|
||||
}
|
||||
|
||||
specs := map[string]struct {
|
||||
src types.GenesisState
|
||||
stakingMock StakingKeeperMock
|
||||
|
@ -171,7 +185,6 @@ func TestGenesisInit(t *testing.T) {
|
|||
}},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: 2},
|
||||
{IDKey: types.KeyLastInstanceID, Value: 1},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
|
@ -190,7 +203,6 @@ func TestGenesisInit(t *testing.T) {
|
|||
}},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: 10},
|
||||
{IDKey: types.KeyLastInstanceID, Value: 1},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
|
@ -210,7 +222,6 @@ func TestGenesisInit(t *testing.T) {
|
|||
Contracts: nil,
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: 3},
|
||||
{IDKey: types.KeyLastInstanceID, Value: 1},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
|
@ -267,13 +278,12 @@ func TestGenesisInit(t *testing.T) {
|
|||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: BuildContractAddress(1, 1).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
ContractAddress: BuildContractAddress(myCodeInfo.CodeHash, mySenderAddr, myLabel).String(),
|
||||
ContractInfo: myContractInfoFixture(),
|
||||
},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: 2},
|
||||
{IDKey: types.KeyLastInstanceID, Value: 2},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
|
@ -288,16 +298,17 @@ func TestGenesisInit(t *testing.T) {
|
|||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: BuildContractAddress(1, 1).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
ContractAddress: BuildContractAddress(myCodeInfo.CodeHash, mySenderAddr, myLabel).String(),
|
||||
ContractInfo: myContractInfoFixture(),
|
||||
}, {
|
||||
ContractAddress: BuildContractAddress(1, 2).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
ContractAddress: BuildContractAddress(myCodeInfo.CodeHash, mySenderAddr, "other-label").String(),
|
||||
ContractInfo: myContractInfoFixture(func(i *wasmTypes.ContractInfo) {
|
||||
i.Label = "other-label"
|
||||
}),
|
||||
},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: 2},
|
||||
{IDKey: types.KeyLastInstanceID, Value: 3},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
|
@ -307,8 +318,8 @@ func TestGenesisInit(t *testing.T) {
|
|||
src: types.GenesisState{
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: BuildContractAddress(1, 1).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
ContractAddress: BuildContractAddress(myCodeInfo.CodeHash, mySenderAddr, myLabel).String(),
|
||||
ContractInfo: myContractInfoFixture(),
|
||||
},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
|
@ -323,11 +334,11 @@ func TestGenesisInit(t *testing.T) {
|
|||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: BuildContractAddress(1, 1).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
ContractAddress: BuildContractAddress(myCodeInfo.CodeHash, mySenderAddr, myLabel).String(),
|
||||
ContractInfo: myContractInfoFixture(),
|
||||
}, {
|
||||
ContractAddress: BuildContractAddress(1, 1).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
ContractAddress: BuildContractAddress(myCodeInfo.CodeHash, mySenderAddr, myLabel).String(),
|
||||
ContractInfo: myContractInfoFixture(),
|
||||
},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
|
@ -342,8 +353,8 @@ func TestGenesisInit(t *testing.T) {
|
|||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: BuildContractAddress(1, 1).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
ContractAddress: BuildContractAddress(myCodeInfo.CodeHash, mySenderAddr, myLabel).String(),
|
||||
ContractInfo: myContractInfoFixture(),
|
||||
ContractState: []types.Model{
|
||||
{
|
||||
Key: []byte{0x1},
|
||||
|
@ -381,26 +392,6 @@ func TestGenesisInit(t *testing.T) {
|
|||
Params: types.DefaultParams(),
|
||||
},
|
||||
},
|
||||
"prevent contract id seq init value == count contracts": {
|
||||
src: types.GenesisState{
|
||||
Codes: []types.Code{{
|
||||
CodeID: firstCodeID,
|
||||
CodeInfo: myCodeInfo,
|
||||
CodeBytes: wasmCode,
|
||||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: BuildContractAddress(1, 1).String(),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields),
|
||||
},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: 2},
|
||||
{IDKey: types.KeyLastInstanceID, Value: 1},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
},
|
||||
"validator set update called for any genesis messages": {
|
||||
src: wasmTypes.GenesisState{
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
|
@ -559,16 +550,17 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) {
|
|||
}
|
||||
assert.Equal(t, expHistory, keeper.GetContractHistory(ctx, contractAddr))
|
||||
assert.Equal(t, uint64(2), keeper.PeekAutoIncrementID(ctx, types.KeyLastCodeID))
|
||||
assert.Equal(t, uint64(3), keeper.PeekAutoIncrementID(ctx, types.KeyLastInstanceID))
|
||||
}
|
||||
|
||||
func TestSupportedGenMsgTypes(t *testing.T) {
|
||||
wasmCode, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
wasmHash := sha256.Sum256(wasmCode)
|
||||
var (
|
||||
myAddress sdk.AccAddress = bytes.Repeat([]byte{1}, types.ContractAddrLen)
|
||||
verifierAddress sdk.AccAddress = bytes.Repeat([]byte{2}, types.ContractAddrLen)
|
||||
beneficiaryAddress sdk.AccAddress = bytes.Repeat([]byte{3}, types.ContractAddrLen)
|
||||
contractAddr = BuildContractAddress(wasmHash[:], myAddress, "testing")
|
||||
)
|
||||
const denom = "stake"
|
||||
importState := types.GenesisState{
|
||||
|
@ -600,7 +592,7 @@ func TestSupportedGenMsgTypes(t *testing.T) {
|
|||
Sum: &types.GenesisState_GenMsgs_ExecuteContract{
|
||||
ExecuteContract: &types.MsgExecuteContract{
|
||||
Sender: verifierAddress.String(),
|
||||
Contract: BuildContractAddress(1, 1).String(),
|
||||
Contract: contractAddr.String(),
|
||||
Msg: []byte(`{"release":{}}`),
|
||||
},
|
||||
},
|
||||
|
@ -625,7 +617,7 @@ func TestSupportedGenMsgTypes(t *testing.T) {
|
|||
require.NotNil(t, codeInfo)
|
||||
|
||||
// verify contract instantiated
|
||||
cInfo := keeper.GetContractInfo(ctx, BuildContractAddress(1, 1))
|
||||
cInfo := keeper.GetContractInfo(ctx, contractAddr)
|
||||
require.NotNil(t, cInfo)
|
||||
|
||||
// verify contract executed
|
||||
|
@ -668,7 +660,24 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) {
|
|||
wasmConfig := wasmTypes.DefaultWasmConfig()
|
||||
pk := paramskeeper.NewKeeper(encodingConfig.Marshaler, encodingConfig.Amino, keyParams, tkeyParams)
|
||||
|
||||
srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.ModuleName), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, tempDir, wasmConfig, AvailableCapabilities)
|
||||
srcKeeper := NewKeeper(
|
||||
encodingConfig.Marshaler,
|
||||
keyWasm,
|
||||
pk.Subspace(wasmTypes.ModuleName),
|
||||
authkeeper.AccountKeeper{},
|
||||
&bankkeeper.BaseKeeper{},
|
||||
stakingkeeper.Keeper{},
|
||||
distributionkeeper.Keeper{},
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
tempDir,
|
||||
wasmConfig,
|
||||
AvailableCapabilities,
|
||||
)
|
||||
return &srcKeeper, ctx, []sdk.StoreKey{keyWasm, keyParams}
|
||||
}
|
||||
|
||||
|
|
|
@ -327,7 +327,7 @@ func TestBurnCoinMessageHandlerIntegration(t *testing.T) {
|
|||
// picks the message in the default handler chain
|
||||
ctx, keepers := CreateDefaultTestInput(t)
|
||||
// set some supply
|
||||
keepers.Faucet.NewFundedAccount(ctx, sdk.NewCoin("denom", sdk.NewInt(10_000_000)))
|
||||
keepers.Faucet.NewFundedRandomAccount(ctx, sdk.NewCoin("denom", sdk.NewInt(10_000_000)))
|
||||
k := keepers.WasmKeeper
|
||||
|
||||
example := InstantiateHackatomExampleContract(t, ctx, keepers) // with deposit of 100 stake
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/rand"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
@ -41,7 +43,7 @@ func TestBindingPortForIBCContractOnInstantiate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestContractFromPortID(t *testing.T) {
|
||||
contractAddr := BuildContractAddress(1, 100)
|
||||
contractAddr := BuildContractAddress(rand.Bytes(32), RandomAccountAddress(t), "testing")
|
||||
specs := map[string]struct {
|
||||
srcPort string
|
||||
expAddr sdk.AccAddress
|
||||
|
|
|
@ -4,22 +4,25 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
|
||||
wasmvm "github.com/CosmWasm/wasmvm"
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
|
@ -54,6 +57,13 @@ type CoinTransferrer interface {
|
|||
TransferCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
}
|
||||
|
||||
// CoinPruner handles the balances for accounts that are pruned on contract instantiate.
|
||||
// This is an extension point to attach custom logic
|
||||
type CoinPruner interface {
|
||||
// PruneBalances handle balances for given address
|
||||
PruneBalances(ctx sdk.Context, contractAddress sdk.AccAddress) error
|
||||
}
|
||||
|
||||
// WasmVMResponseHandler is an extension point to handles the response data returned by a contract call.
|
||||
type WasmVMResponseHandler interface {
|
||||
// Handle processes the data returned by a contract invocation.
|
||||
|
@ -66,6 +76,25 @@ type WasmVMResponseHandler interface {
|
|||
) ([]byte, error)
|
||||
}
|
||||
|
||||
// list of account types that are accepted for wasm contracts. Chains importing wasmd
|
||||
// can overwrite this list with the WithAcceptedAccountTypesOnContractInstantiation option.
|
||||
var defaultAcceptedAccountTypes = map[reflect.Type]struct{}{
|
||||
reflect.TypeOf(&authtypes.BaseAccount{}): {},
|
||||
}
|
||||
|
||||
// list of account types that are replaced with base accounts. Chains importing wasmd
|
||||
// can overwrite this list with the WithPruneAccountTypesOnContractInstantiation option.
|
||||
//
|
||||
// contains vesting account types that can be created post genesis
|
||||
var defaultPruneAccountTypes = map[reflect.Type]struct{}{
|
||||
reflect.TypeOf(&vestingtypes.DelayedVestingAccount{}): {},
|
||||
reflect.TypeOf(&vestingtypes.ContinuousVestingAccount{}): {},
|
||||
// intentionally not added: genesis account types
|
||||
// reflect.TypeOf(&vestingtypes.BaseVestingAccount{}): {},
|
||||
// reflect.TypeOf(&vestingtypes.PeriodicVestingAccount{}): {},
|
||||
// reflect.TypeOf(&vestingtypes.PermanentLockedAccount{}): {},
|
||||
}
|
||||
|
||||
// Keeper will have a reference to Wasmer with it's own data directory.
|
||||
type Keeper struct {
|
||||
storeKey sdk.StoreKey
|
||||
|
@ -79,10 +108,13 @@ type Keeper struct {
|
|||
wasmVMResponseHandler WasmVMResponseHandler
|
||||
messenger Messenger
|
||||
// queryGasLimit is the max wasmvm gas that can be spent on executing a query with a contract
|
||||
queryGasLimit uint64
|
||||
paramSpace paramtypes.Subspace
|
||||
gasRegister GasRegister
|
||||
maxQueryStackSize uint32
|
||||
queryGasLimit uint64
|
||||
paramSpace paramtypes.Subspace
|
||||
gasRegister GasRegister
|
||||
maxQueryStackSize uint32
|
||||
acceptedAccountTypes map[reflect.Type]struct{}
|
||||
pruneAccountTypes map[reflect.Type]struct{}
|
||||
coinPruner CoinPruner
|
||||
}
|
||||
|
||||
// NewKeeper creates a new contract Keeper instance
|
||||
|
@ -116,18 +148,21 @@ func NewKeeper(
|
|||
}
|
||||
|
||||
keeper := &Keeper{
|
||||
storeKey: storeKey,
|
||||
cdc: cdc,
|
||||
wasmVM: wasmer,
|
||||
accountKeeper: accountKeeper,
|
||||
bank: NewBankCoinTransferrer(bankKeeper),
|
||||
portKeeper: portKeeper,
|
||||
capabilityKeeper: capabilityKeeper,
|
||||
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, bankKeeper, cdc, portSource),
|
||||
queryGasLimit: wasmConfig.SmartQueryGasLimit,
|
||||
paramSpace: paramSpace,
|
||||
gasRegister: NewDefaultWasmGasRegister(),
|
||||
maxQueryStackSize: types.DefaultMaxQueryStackSize,
|
||||
storeKey: storeKey,
|
||||
cdc: cdc,
|
||||
wasmVM: wasmer,
|
||||
accountKeeper: accountKeeper,
|
||||
bank: NewBankCoinTransferrer(bankKeeper),
|
||||
coinPruner: NewCoinBurner(bankKeeper),
|
||||
portKeeper: portKeeper,
|
||||
capabilityKeeper: capabilityKeeper,
|
||||
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, bankKeeper, cdc, portSource),
|
||||
queryGasLimit: wasmConfig.SmartQueryGasLimit,
|
||||
paramSpace: paramSpace,
|
||||
gasRegister: NewDefaultWasmGasRegister(),
|
||||
maxQueryStackSize: types.DefaultMaxQueryStackSize,
|
||||
acceptedAccountTypes: defaultAcceptedAccountTypes,
|
||||
pruneAccountTypes: defaultPruneAccountTypes,
|
||||
}
|
||||
keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, queryRouter, keeper)
|
||||
for _, o := range opts {
|
||||
|
@ -161,13 +196,13 @@ func (k Keeper) SetParams(ctx sdk.Context, ps types.Params) {
|
|||
k.paramSpace.SetParamSet(ctx, &ps)
|
||||
}
|
||||
|
||||
func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, err error) {
|
||||
func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, checksum []byte, err error) {
|
||||
if creator == nil {
|
||||
return 0, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "cannot be nil")
|
||||
return 0, checksum, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "cannot be nil")
|
||||
}
|
||||
|
||||
if !authZ.CanCreateCode(k.getUploadAccessConfig(ctx), creator) {
|
||||
return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code")
|
||||
return 0, checksum, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code")
|
||||
}
|
||||
// figure out proper instantiate access
|
||||
defaultAccessConfig := k.getInstantiateAccessConfig(ctx).With(creator)
|
||||
|
@ -175,25 +210,25 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte,
|
|||
instantiateAccess = &defaultAccessConfig
|
||||
} else if !instantiateAccess.IsSubset(defaultAccessConfig) {
|
||||
// we enforce this must be subset of default upload access
|
||||
return 0, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "instantiate access must be subset of default upload access")
|
||||
return 0, checksum, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "instantiate access must be subset of default upload access")
|
||||
}
|
||||
|
||||
if ioutils.IsGzip(wasmCode) {
|
||||
ctx.GasMeter().ConsumeGas(k.gasRegister.UncompressCosts(len(wasmCode)), "Uncompress gzip bytecode")
|
||||
wasmCode, err = ioutils.Uncompress(wasmCode, uint64(types.MaxWasmSize))
|
||||
if err != nil {
|
||||
return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
|
||||
return 0, checksum, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
ctx.GasMeter().ConsumeGas(k.gasRegister.CompileCosts(len(wasmCode)), "Compiling wasm bytecode")
|
||||
checksum, err := k.wasmVM.Create(wasmCode)
|
||||
checksum, err = k.wasmVM.Create(wasmCode)
|
||||
if err != nil {
|
||||
return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
|
||||
return 0, checksum, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
|
||||
}
|
||||
report, err := k.wasmVM.AnalyzeCode(checksum)
|
||||
if err != nil {
|
||||
return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
|
||||
return 0, checksum, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
|
||||
}
|
||||
codeID = k.autoIncrementID(ctx, types.KeyLastCodeID)
|
||||
k.Logger(ctx).Debug("storing new contract", "capabilities", report.RequiredCapabilities, "code_id", codeID)
|
||||
|
@ -203,13 +238,14 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte,
|
|||
evt := sdk.NewEvent(
|
||||
types.EventTypeStoreCode,
|
||||
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)),
|
||||
sdk.NewAttribute(types.AttributeKeyChecksum, hex.EncodeToString(checksum)),
|
||||
)
|
||||
for _, f := range strings.Split(report.RequiredCapabilities, ",") {
|
||||
evt.AppendAttributes(sdk.NewAttribute(types.AttributeKeyRequiredCapability, strings.TrimSpace(f)))
|
||||
}
|
||||
ctx.EventManager().EmitEvent(evt)
|
||||
|
||||
return codeID, nil
|
||||
return codeID, checksum, nil
|
||||
}
|
||||
|
||||
func (k Keeper) storeCodeInfo(ctx sdk.Context, codeID uint64, codeInfo types.CodeInfo) {
|
||||
|
@ -244,31 +280,15 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn
|
|||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, authZ AuthorizationPolicy) (sdk.AccAddress, []byte, error) {
|
||||
func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins, authPolicy AuthorizationPolicy) (sdk.AccAddress, []byte, error) {
|
||||
defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "instantiate")
|
||||
|
||||
if creator == nil {
|
||||
return nil, nil, types.ErrEmpty.Wrap("creator")
|
||||
}
|
||||
instanceCosts := k.gasRegister.NewContractInstanceCosts(k.IsPinnedCode(ctx, codeID), len(initMsg))
|
||||
ctx.GasMeter().ConsumeGas(instanceCosts, "Loading CosmWasm module: instantiate")
|
||||
|
||||
// create contract address
|
||||
contractAddress := k.generateContractAddress(ctx, codeID)
|
||||
existingAcct := k.accountKeeper.GetAccount(ctx, contractAddress)
|
||||
if existingAcct != nil {
|
||||
return nil, nil, sdkerrors.Wrap(types.ErrAccountExists, existingAcct.GetAddress().String())
|
||||
}
|
||||
|
||||
// deposit initial contract funds
|
||||
if !deposit.IsZero() {
|
||||
if err := k.bank.TransferCoins(ctx, creator, contractAddress, deposit); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
// create an empty account (so we don't have issues later)
|
||||
// TODO: can we remove this?
|
||||
contractAccount := k.accountKeeper.NewAccountWithAddress(ctx, contractAddress)
|
||||
k.accountKeeper.SetAccount(ctx, contractAccount)
|
||||
}
|
||||
|
||||
// get contact info
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(types.GetCodeKey(codeID))
|
||||
|
@ -278,10 +298,53 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A
|
|||
var codeInfo types.CodeInfo
|
||||
k.cdc.MustUnmarshal(bz, &codeInfo)
|
||||
|
||||
if !authZ.CanInstantiateContract(codeInfo.InstantiateConfig, creator) {
|
||||
if !authPolicy.CanInstantiateContract(codeInfo.InstantiateConfig, creator) {
|
||||
return nil, nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not instantiate")
|
||||
}
|
||||
|
||||
contractAddress := BuildContractAddress(codeInfo.CodeHash, creator, label)
|
||||
if k.HasContractInfo(ctx, contractAddress) {
|
||||
return nil, nil, types.ErrDuplicate.Wrap("instance with this code id, sender and label exists: try a different label")
|
||||
}
|
||||
|
||||
// check account
|
||||
// every cosmos module can define custom account types when needed. The cosmos-sdk comes with extension points
|
||||
// to support this and a set of base and vesting account types that we integrated in our default lists.
|
||||
// But not all account types of other modules are known or may make sense for contracts, therefore we kept this
|
||||
// decision logic also very flexible and extendable. We provide new options to overwrite the default settings via WithAcceptedAccountTypesOnContractInstantiation and
|
||||
// WithPruneAccountTypesOnContractInstantiation as constructor arguments
|
||||
existingAcct := k.accountKeeper.GetAccount(ctx, contractAddress)
|
||||
if existingAcct != nil {
|
||||
if existingAcct.GetSequence() != 0 || existingAcct.GetPubKey() != nil {
|
||||
return nil, nil, types.ErrAccountExists.Wrap("address is claimed by external account")
|
||||
}
|
||||
if _, accept := k.acceptedAccountTypes[reflect.TypeOf(existingAcct)]; accept {
|
||||
// keep account and balance as it is
|
||||
k.Logger(ctx).Info("instantiate contract with existing account", "address", contractAddress.String())
|
||||
} else if _, clear := k.pruneAccountTypes[reflect.TypeOf(existingAcct)]; clear {
|
||||
k.Logger(ctx).Info("pruning existing account for contract instantiation", "address", contractAddress.String())
|
||||
// consider an account in the wasmd namespace spam and overwrite it.
|
||||
contractAccount := k.accountKeeper.NewAccountWithAddress(ctx, contractAddress)
|
||||
k.accountKeeper.SetAccount(ctx, contractAccount)
|
||||
// also handle balance to not open cases where these accounts are abused and become liquid
|
||||
if err := k.coinPruner.PruneBalances(ctx, contractAddress); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
} else { // unknown account type
|
||||
return nil, nil, types.ErrAccountExists.Wrapf("refusing to overwrite special account type:: %T", existingAcct)
|
||||
}
|
||||
} else {
|
||||
// create an empty account (so we don't have issues later)
|
||||
contractAccount := k.accountKeeper.NewAccountWithAddress(ctx, contractAddress)
|
||||
k.accountKeeper.SetAccount(ctx, contractAccount)
|
||||
}
|
||||
// deposit initial contract funds
|
||||
if !deposit.IsZero() {
|
||||
if err := k.bank.TransferCoins(ctx, creator, contractAddress, deposit); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// prepare params for contract instantiate call
|
||||
env := types.NewEnv(ctx, contractAddress)
|
||||
info := types.NewInfo(creator, deposit)
|
||||
|
@ -955,18 +1018,19 @@ func (k Keeper) consumeRuntimeGas(ctx sdk.Context, gas uint64) {
|
|||
}
|
||||
}
|
||||
|
||||
// generates a contract address from codeID + instanceID
|
||||
func (k Keeper) generateContractAddress(ctx sdk.Context, codeID uint64) sdk.AccAddress {
|
||||
instanceID := k.autoIncrementID(ctx, types.KeyLastInstanceID)
|
||||
return BuildContractAddress(codeID, instanceID)
|
||||
}
|
||||
|
||||
// BuildContractAddress builds an sdk account address for a contract.
|
||||
func BuildContractAddress(codeID, instanceID uint64) sdk.AccAddress {
|
||||
contractID := make([]byte, 16)
|
||||
binary.BigEndian.PutUint64(contractID[:8], codeID)
|
||||
binary.BigEndian.PutUint64(contractID[8:], instanceID)
|
||||
return address.Module(types.ModuleName, contractID)[:types.ContractAddrLen]
|
||||
// BuildContractAddress generates a contract address for the wasm module with len = types.ContractAddrLen using the
|
||||
// Cosmos SDK address.Module function.
|
||||
// Internally a key is built containing (len(checksum) | checksum | len(sender_address) | sender_address | len(label) | label).
|
||||
// All method parameter values must be valid and not be empty or nil.
|
||||
func BuildContractAddress(checksum []byte, creator sdk.AccAddress, label string) sdk.AccAddress {
|
||||
checksum = address.MustLengthPrefix(checksum)
|
||||
creator = address.MustLengthPrefix(creator)
|
||||
labelBz := address.MustLengthPrefix([]byte(label))
|
||||
key := make([]byte, len(checksum)+len(creator)+len(labelBz))
|
||||
copy(key[0:], checksum)
|
||||
copy(key[len(checksum):], creator)
|
||||
copy(key[len(checksum)+len(creator):], labelBz)
|
||||
return address.Module(types.ModuleName, key)[:types.ContractAddrLen]
|
||||
}
|
||||
|
||||
func (k Keeper) autoIncrementID(ctx sdk.Context, lastIDKey []byte) uint64 {
|
||||
|
@ -1097,6 +1161,34 @@ func (c BankCoinTransferrer) TransferCoins(parentCtx sdk.Context, fromAddr sdk.A
|
|||
return nil
|
||||
}
|
||||
|
||||
var _ CoinPruner = CoinBurner{}
|
||||
|
||||
// CoinBurner default implementation for CoinPruner to burn the coins
|
||||
type CoinBurner struct {
|
||||
bank types.BankKeeper
|
||||
}
|
||||
|
||||
// NewCoinBurner constructor
|
||||
func NewCoinBurner(bank types.BankKeeper) CoinBurner {
|
||||
if bank == nil {
|
||||
panic("bank keeper must not be nil")
|
||||
}
|
||||
return CoinBurner{bank: bank}
|
||||
}
|
||||
|
||||
// PruneBalances burns all coins owned by the account.
|
||||
func (b CoinBurner) PruneBalances(ctx sdk.Context, address sdk.AccAddress) error {
|
||||
if amt := b.bank.GetAllBalances(ctx, address); !amt.IsZero() {
|
||||
if err := b.bank.SendCoinsFromAccountToModule(ctx, address, types.ModuleName, amt); err != nil {
|
||||
return sdkerrors.Wrap(err, "prune account balance")
|
||||
}
|
||||
if err := b.bank.BurnCoins(ctx, types.ModuleName, amt); err != nil {
|
||||
return sdkerrors.Wrap(err, "burn account balance")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type msgDispatcher interface {
|
||||
DispatchSubmessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.SubMsg) ([]byte, error)
|
||||
}
|
||||
|
|
|
@ -2,19 +2,24 @@ package keeper
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
wasmvm "github.com/CosmWasm/wasmvm"
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
stypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
fuzz "github.com/google/gofuzz"
|
||||
|
@ -27,15 +32,7 @@ import (
|
|||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
// When migrated to go 1.16, embed package should be used instead.
|
||||
func init() {
|
||||
b, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
hackatomWasm = b
|
||||
}
|
||||
|
||||
//go:embed testdata/hackatom.wasm
|
||||
var hackatomWasm []byte
|
||||
|
||||
const AvailableCapabilities = "iterator,staking,stargate,cosmwasm_1_1"
|
||||
|
@ -50,10 +47,10 @@ func TestCreateSuccess(t *testing.T) {
|
|||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
em := sdk.NewEventManager()
|
||||
contractID, err := keeper.Create(ctx.WithEventManager(em), creator, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx.WithEventManager(em), creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), contractID)
|
||||
// and verify content
|
||||
|
@ -61,32 +58,33 @@ func TestCreateSuccess(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, hackatomWasm, storedCode)
|
||||
// and events emitted
|
||||
exp := sdk.Events{sdk.NewEvent("store_code", sdk.NewAttribute("code_id", "1"))}
|
||||
codeHash := "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5"
|
||||
exp := sdk.Events{sdk.NewEvent("store_code", sdk.NewAttribute("code_id", "1"), sdk.NewAttribute("code_checksum", codeHash))}
|
||||
assert.Equal(t, exp, em.Events())
|
||||
}
|
||||
|
||||
func TestCreateNilCreatorAddress(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
|
||||
_, err := keepers.ContractKeeper.Create(ctx, nil, hackatomWasm, nil)
|
||||
_, _, err := keepers.ContractKeeper.Create(ctx, nil, hackatomWasm, nil)
|
||||
require.Error(t, err, "nil creator is not allowed")
|
||||
}
|
||||
|
||||
func TestCreateNilWasmCode(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
_, err := keepers.ContractKeeper.Create(ctx, creator, nil, nil)
|
||||
_, _, err := keepers.ContractKeeper.Create(ctx, creator, nil, nil)
|
||||
require.Error(t, err, "nil WASM code is not allowed")
|
||||
}
|
||||
|
||||
func TestCreateInvalidWasmCode(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
_, err := keepers.ContractKeeper.Create(ctx, creator, []byte("potatoes"), nil)
|
||||
_, _, err := keepers.ContractKeeper.Create(ctx, creator, []byte("potatoes"), nil)
|
||||
require.Error(t, err, "potatoes are not valid WASM code")
|
||||
}
|
||||
|
||||
|
@ -127,7 +125,7 @@ func TestCreateStoresInstantiatePermission(t *testing.T) {
|
|||
})
|
||||
fundAccounts(t, ctx, accKeeper, bankKeeper, myAddr, deposit)
|
||||
|
||||
codeID, err := keeper.Create(ctx, myAddr, hackatomWasm, nil)
|
||||
codeID, _, err := keeper.Create(ctx, myAddr, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
codeInfo := keepers.WasmKeeper.GetCodeInfo(ctx, codeID)
|
||||
|
@ -142,8 +140,8 @@ func TestCreateWithParamPermissions(t *testing.T) {
|
|||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
otherAddr := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
otherAddr := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
specs := map[string]struct {
|
||||
srcPermission types.AccessConfig
|
||||
|
@ -172,7 +170,7 @@ func TestCreateWithParamPermissions(t *testing.T) {
|
|||
params := types.DefaultParams()
|
||||
params.CodeUploadAccess = spec.srcPermission
|
||||
keepers.WasmKeeper.SetParams(ctx, params)
|
||||
_, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
_, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.True(t, spec.expError.Is(err), err)
|
||||
if spec.expError != nil {
|
||||
return
|
||||
|
@ -189,8 +187,8 @@ func TestEnforceValidPermissionsOnCreate(t *testing.T) {
|
|||
contractKeeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
other := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
other := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
onlyCreator := types.AccessTypeOnlyAddress.With(creator)
|
||||
onlyOther := types.AccessTypeOnlyAddress.With(other)
|
||||
|
@ -249,7 +247,7 @@ func TestEnforceValidPermissionsOnCreate(t *testing.T) {
|
|||
params := types.DefaultParams()
|
||||
params.InstantiateDefaultPermission = spec.defaultPermssion
|
||||
keeper.SetParams(ctx, params)
|
||||
codeID, err := contractKeeper.Create(ctx, creator, hackatomWasm, spec.requestedPermission)
|
||||
codeID, _, err := contractKeeper.Create(ctx, creator, hackatomWasm, spec.requestedPermission)
|
||||
require.True(t, spec.expError.Is(err), err)
|
||||
if spec.expError == nil {
|
||||
codeInfo := keeper.GetCodeInfo(ctx, codeID)
|
||||
|
@ -264,15 +262,15 @@ func TestCreateDuplicate(t *testing.T) {
|
|||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// create one copy
|
||||
contractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), contractID)
|
||||
|
||||
// create second copy
|
||||
duplicateID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
duplicateID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), duplicateID)
|
||||
|
||||
|
@ -292,18 +290,18 @@ func TestCreateWithSimulation(t *testing.T) {
|
|||
WithGasMeter(stypes.NewInfiniteGasMeter())
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// create this once in simulation mode
|
||||
contractID, err := keepers.ContractKeeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
contractID, _, err := keepers.ContractKeeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), contractID)
|
||||
|
||||
// then try to create it in non-simulation mode (should not fail)
|
||||
ctx, keepers = CreateTestInput(t, false, AvailableCapabilities)
|
||||
ctx = ctx.WithGasMeter(sdk.NewGasMeter(10_000_000))
|
||||
creator = keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
contractID, err = keepers.ContractKeeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
creator = keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
contractID, _, err = keepers.ContractKeeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), contractID)
|
||||
|
@ -344,12 +342,12 @@ func TestCreateWithGzippedPayload(t *testing.T) {
|
|||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
wasmCode, err := os.ReadFile("./testdata/hackatom.wasm.gzip")
|
||||
require.NoError(t, err, "reading gzipped WASM code")
|
||||
|
||||
contractID, err := keeper.Create(ctx, creator, wasmCode, nil)
|
||||
contractID, _, err := keeper.Create(ctx, creator, wasmCode, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), contractID)
|
||||
// and verify content
|
||||
|
@ -363,34 +361,30 @@ func TestCreateWithBrokenGzippedPayload(t *testing.T) {
|
|||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
wasmCode, err := os.ReadFile("./testdata/broken_crc.gzip")
|
||||
require.NoError(t, err, "reading gzipped WASM code")
|
||||
|
||||
gm := sdk.NewInfiniteGasMeter()
|
||||
contractID, err := keeper.Create(ctx.WithGasMeter(gm), creator, wasmCode, nil)
|
||||
codeID, checksum, err := keeper.Create(ctx.WithGasMeter(gm), creator, wasmCode, nil)
|
||||
require.Error(t, err)
|
||||
assert.Empty(t, contractID)
|
||||
assert.Empty(t, codeID)
|
||||
assert.Empty(t, checksum)
|
||||
assert.GreaterOrEqual(t, gm.GasConsumed(), sdk.Gas(121384)) // 809232 * 0.15 (default uncompress costs) = 121384
|
||||
}
|
||||
|
||||
func TestInstantiate(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
|
||||
codeID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
_, _, fred := keyPubAddr()
|
||||
creator := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len))
|
||||
keepers.Faucet.Fund(ctx, creator, deposit...)
|
||||
example := StoreHackatomExampleContract(t, ctx, keepers)
|
||||
|
||||
initMsg := HackatomExampleInitMsg{
|
||||
Verifier: fred,
|
||||
Beneficiary: bob,
|
||||
Verifier: RandomAccountAddress(t),
|
||||
Beneficiary: RandomAccountAddress(t),
|
||||
}
|
||||
initMsgBz, err := json.Marshal(initMsg)
|
||||
require.NoError(t, err)
|
||||
|
@ -399,25 +393,25 @@ func TestInstantiate(t *testing.T) {
|
|||
|
||||
em := sdk.NewEventManager()
|
||||
// create with no balance is also legal
|
||||
gotContractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx.WithEventManager(em), codeID, creator, nil, initMsgBz, "demo contract 1", nil)
|
||||
gotContractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx.WithEventManager(em), example.CodeID, creator, nil, initMsgBz, "demo contract 1", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr", gotContractAddr.String())
|
||||
require.Equal(t, "cosmos1xaq0tcwz9fsqmtxlpzwjn2zr8gw66ljjr079ltfc5pelepcs7sjsk28n5n", gotContractAddr.String())
|
||||
|
||||
gasAfter := ctx.GasMeter().GasConsumed()
|
||||
if types.EnableGasVerification {
|
||||
require.Equal(t, uint64(0x18db5), gasAfter-gasBefore)
|
||||
require.Equal(t, uint64(0x187b8), gasAfter-gasBefore)
|
||||
}
|
||||
|
||||
// ensure it is stored properly
|
||||
info := keepers.WasmKeeper.GetContractInfo(ctx, gotContractAddr)
|
||||
require.NotNil(t, info)
|
||||
assert.Equal(t, creator.String(), info.Creator)
|
||||
assert.Equal(t, codeID, info.CodeID)
|
||||
assert.Equal(t, example.CodeID, info.CodeID)
|
||||
assert.Equal(t, "demo contract 1", info.Label)
|
||||
|
||||
exp := []types.ContractCodeHistoryEntry{{
|
||||
Operation: types.ContractCodeHistoryOperationTypeInit,
|
||||
CodeID: codeID,
|
||||
CodeID: example.CodeID,
|
||||
Updated: types.NewAbsoluteTxPosition(ctx),
|
||||
Msg: initMsgBz,
|
||||
}}
|
||||
|
@ -439,12 +433,9 @@ func TestInstantiateWithDeposit(t *testing.T) {
|
|||
fred = bytes.Repeat([]byte{2}, types.SDKAddrLen)
|
||||
|
||||
deposit = sdk.NewCoins(sdk.NewInt64Coin("denom", 100))
|
||||
initMsg = HackatomExampleInitMsg{Verifier: fred, Beneficiary: bob}
|
||||
initMsg = mustMarshal(t, HackatomExampleInitMsg{Verifier: fred, Beneficiary: bob})
|
||||
)
|
||||
|
||||
initMsgBz, err := json.Marshal(initMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
specs := map[string]struct {
|
||||
srcActor sdk.AccAddress
|
||||
expError bool
|
||||
|
@ -472,11 +463,11 @@ func TestInstantiateWithDeposit(t *testing.T) {
|
|||
if spec.fundAddr {
|
||||
fundAccounts(t, ctx, accKeeper, bankKeeper, spec.srcActor, sdk.NewCoins(sdk.NewInt64Coin("denom", 200)))
|
||||
}
|
||||
contractID, err := keeper.Create(ctx, spec.srcActor, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx, spec.srcActor, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// when
|
||||
addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "my label", deposit)
|
||||
addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsg, "my label", deposit)
|
||||
// then
|
||||
if spec.expError {
|
||||
require.Error(t, err)
|
||||
|
@ -527,6 +518,7 @@ func TestInstantiateWithPermissions(t *testing.T) {
|
|||
srcActor: myAddr,
|
||||
},
|
||||
"onlyAddress with non matching address": {
|
||||
srcActor: myAddr,
|
||||
srcPermission: types.AccessTypeOnlyAddress.With(otherAddr),
|
||||
expError: sdkerrors.ErrUnauthorized,
|
||||
},
|
||||
|
@ -537,7 +529,7 @@ func TestInstantiateWithPermissions(t *testing.T) {
|
|||
accKeeper, bankKeeper, keeper := keepers.AccountKeeper, keepers.BankKeeper, keepers.ContractKeeper
|
||||
fundAccounts(t, ctx, accKeeper, bankKeeper, spec.srcActor, deposit)
|
||||
|
||||
contractID, err := keeper.Create(ctx, myAddr, hackatomWasm, &spec.srcPermission)
|
||||
contractID, _, err := keeper.Create(ctx, myAddr, hackatomWasm, &spec.srcPermission)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = keepers.ContractKeeper.Instantiate(ctx, contractID, spec.srcActor, nil, initMsgBz, "demo contract 1", nil)
|
||||
|
@ -546,11 +538,195 @@ func TestInstantiateWithPermissions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestInstantiateWithUniqueContractAddress(t *testing.T) {
|
||||
parentCtx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
example := InstantiateHackatomExampleContract(t, parentCtx, keepers)
|
||||
otherExample := InstantiateReflectExampleContract(t, parentCtx, keepers)
|
||||
initMsg := mustMarshal(t, HackatomExampleInitMsg{Verifier: example.VerifierAddr, Beneficiary: example.BeneficiaryAddr})
|
||||
|
||||
otherAddress := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(parentCtx, otherAddress, sdk.NewInt64Coin("denom", 100000000))
|
||||
used := make(map[string]struct{})
|
||||
specs := map[string]struct {
|
||||
codeID uint64
|
||||
sender sdk.AccAddress
|
||||
label string
|
||||
initMsg json.RawMessage
|
||||
expErr error
|
||||
}{
|
||||
"reject duplicate which generates the same address": {
|
||||
codeID: example.CodeID,
|
||||
sender: example.CreatorAddr,
|
||||
label: example.Label,
|
||||
initMsg: initMsg,
|
||||
expErr: types.ErrDuplicate,
|
||||
},
|
||||
"different sender": {
|
||||
codeID: example.CodeID,
|
||||
sender: otherAddress,
|
||||
label: example.Label,
|
||||
initMsg: initMsg,
|
||||
},
|
||||
"different code": {
|
||||
codeID: otherExample.CodeID,
|
||||
sender: example.CreatorAddr,
|
||||
label: example.Label,
|
||||
initMsg: []byte(`{}`),
|
||||
},
|
||||
"different label": {
|
||||
codeID: example.CodeID,
|
||||
sender: example.CreatorAddr,
|
||||
label: "other label",
|
||||
initMsg: initMsg,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
ctx, _ := parentCtx.CacheContext()
|
||||
gotAddr, _, gotErr := keepers.ContractKeeper.Instantiate(ctx, spec.codeID, spec.sender, nil, spec.initMsg, spec.label, example.Deposit)
|
||||
if spec.expErr != nil {
|
||||
assert.ErrorIs(t, gotErr, spec.expErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, gotErr)
|
||||
expAddr := BuildContractAddress(keepers.WasmKeeper.GetCodeInfo(ctx, spec.codeID).CodeHash, spec.sender, spec.label)
|
||||
assert.Equal(t, expAddr.String(), gotAddr.String())
|
||||
require.NotContains(t, used, gotAddr.String())
|
||||
used[gotAddr.String()] = struct{}{}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstantiateWithAccounts(t *testing.T) {
|
||||
parentCtx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
example := StoreHackatomExampleContract(t, parentCtx, keepers)
|
||||
require.Equal(t, uint64(1), example.CodeID)
|
||||
initMsg := mustMarshal(t, HackatomExampleInitMsg{Verifier: RandomAccountAddress(t), Beneficiary: RandomAccountAddress(t)})
|
||||
|
||||
senderAddr := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(parentCtx, senderAddr, sdk.NewInt64Coin("denom", 100000000))
|
||||
const myLabel = "testing"
|
||||
contractAddr := BuildContractAddress(example.Checksum, senderAddr, myLabel)
|
||||
|
||||
lastAccountNumber := keepers.AccountKeeper.GetAccount(parentCtx, senderAddr).GetAccountNumber()
|
||||
|
||||
specs := map[string]struct {
|
||||
acceptList Option
|
||||
account authtypes.AccountI
|
||||
initBalance sdk.Coin
|
||||
deposit sdk.Coins
|
||||
expErr error
|
||||
expAccount authtypes.AccountI
|
||||
expBalance sdk.Coins
|
||||
}{
|
||||
"unused BaseAccount exists": {
|
||||
account: authtypes.NewBaseAccount(contractAddr, nil, 0, 0),
|
||||
initBalance: sdk.NewInt64Coin("denom", 100000000),
|
||||
expAccount: authtypes.NewBaseAccount(contractAddr, nil, lastAccountNumber+1, 0), // +1 for next seq
|
||||
expBalance: sdk.NewCoins(sdk.NewInt64Coin("denom", 100000000)),
|
||||
},
|
||||
"BaseAccount with sequence exists": {
|
||||
account: authtypes.NewBaseAccount(contractAddr, nil, 0, 1),
|
||||
expErr: types.ErrAccountExists,
|
||||
},
|
||||
"BaseAccount with pubkey exists": {
|
||||
account: authtypes.NewBaseAccount(contractAddr, &ed25519.PubKey{}, 0, 0),
|
||||
expErr: types.ErrAccountExists,
|
||||
},
|
||||
"no account existed": {
|
||||
expAccount: authtypes.NewBaseAccount(contractAddr, nil, lastAccountNumber+1, 0), // +1 for next seq,
|
||||
expBalance: sdk.NewCoins(),
|
||||
},
|
||||
"no account existed before create with deposit": {
|
||||
expAccount: authtypes.NewBaseAccount(contractAddr, nil, lastAccountNumber+1, 0), // +1 for next seq
|
||||
deposit: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_000))),
|
||||
expBalance: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_000))),
|
||||
},
|
||||
"prune listed DelayedVestingAccount gets overwritten": {
|
||||
account: vestingtypes.NewDelayedVestingAccount(
|
||||
authtypes.NewBaseAccount(contractAddr, nil, 0, 0),
|
||||
sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_000))), time.Now().Add(30*time.Hour).Unix()),
|
||||
initBalance: sdk.NewCoin("denom", sdk.NewInt(1_000)),
|
||||
deposit: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1))),
|
||||
expAccount: authtypes.NewBaseAccount(contractAddr, nil, lastAccountNumber+2, 0), // +1 for next seq, +1 for spec.account created
|
||||
expBalance: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1))),
|
||||
},
|
||||
"prune listed ContinuousVestingAccount gets overwritten": {
|
||||
account: vestingtypes.NewContinuousVestingAccount(
|
||||
authtypes.NewBaseAccount(contractAddr, nil, 0, 0),
|
||||
sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_000))), time.Now().Add(time.Hour).Unix(), time.Now().Add(2*time.Hour).Unix()),
|
||||
initBalance: sdk.NewCoin("denom", sdk.NewInt(1_000)),
|
||||
deposit: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1))),
|
||||
expAccount: authtypes.NewBaseAccount(contractAddr, nil, lastAccountNumber+2, 0), // +1 for next seq, +1 for spec.account created
|
||||
expBalance: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1))),
|
||||
},
|
||||
"prune listed account without balance gets overwritten": {
|
||||
account: vestingtypes.NewContinuousVestingAccount(
|
||||
authtypes.NewBaseAccount(contractAddr, nil, 0, 0),
|
||||
sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(0))), time.Now().Add(time.Hour).Unix(), time.Now().Add(2*time.Hour).Unix()),
|
||||
expAccount: authtypes.NewBaseAccount(contractAddr, nil, lastAccountNumber+2, 0), // +1 for next seq, +1 for spec.account created
|
||||
expBalance: sdk.NewCoins(),
|
||||
},
|
||||
"unknown account type creates error": {
|
||||
account: authtypes.NewModuleAccount(
|
||||
authtypes.NewBaseAccount(contractAddr, nil, 0, 0),
|
||||
"testing",
|
||||
),
|
||||
initBalance: sdk.NewCoin("denom", sdk.NewInt(1_000)),
|
||||
expErr: types.ErrAccountExists,
|
||||
},
|
||||
"with option used to set non default type to accept list": {
|
||||
acceptList: WithAcceptedAccountTypesOnContractInstantiation(&vestingtypes.DelayedVestingAccount{}),
|
||||
account: vestingtypes.NewDelayedVestingAccount(
|
||||
authtypes.NewBaseAccount(contractAddr, nil, 0, 0),
|
||||
sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_000))), time.Now().Add(30*time.Hour).Unix()),
|
||||
initBalance: sdk.NewCoin("denom", sdk.NewInt(1_000)),
|
||||
deposit: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1))),
|
||||
expAccount: vestingtypes.NewDelayedVestingAccount(authtypes.NewBaseAccount(contractAddr, nil, lastAccountNumber+1, 0),
|
||||
sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_000))), time.Now().Add(30*time.Hour).Unix()),
|
||||
expBalance: sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_001))),
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
ctx, _ := parentCtx.CacheContext()
|
||||
if spec.account != nil {
|
||||
keepers.AccountKeeper.SetAccount(ctx, keepers.AccountKeeper.NewAccount(ctx, spec.account))
|
||||
}
|
||||
if !spec.initBalance.IsNil() {
|
||||
keepers.Faucet.Fund(ctx, spec.account.GetAddress(), spec.initBalance)
|
||||
}
|
||||
if spec.acceptList != nil {
|
||||
spec.acceptList.apply(keepers.WasmKeeper)
|
||||
}
|
||||
defer func() {
|
||||
if spec.acceptList != nil { // reset
|
||||
WithAcceptedAccountTypesOnContractInstantiation(&authtypes.BaseAccount{}).apply(keepers.WasmKeeper)
|
||||
}
|
||||
}()
|
||||
// when
|
||||
gotAddr, _, gotErr := keepers.ContractKeeper.Instantiate(ctx, 1, senderAddr, nil, initMsg, myLabel, spec.deposit)
|
||||
if spec.expErr != nil {
|
||||
assert.ErrorIs(t, gotErr, spec.expErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, gotErr)
|
||||
assert.Equal(t, contractAddr, gotAddr)
|
||||
// and
|
||||
gotAcc := keepers.AccountKeeper.GetAccount(ctx, contractAddr)
|
||||
assert.Equal(t, spec.expAccount, gotAcc)
|
||||
// and
|
||||
gotBalance := keepers.BankKeeper.GetAllBalances(ctx, contractAddr)
|
||||
assert.Equal(t, spec.expBalance, gotBalance)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstantiateWithNonExistingCodeID(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
initMsg := HackatomExampleInitMsg{}
|
||||
initMsgBz, err := json.Marshal(initMsg)
|
||||
|
@ -585,13 +761,14 @@ func TestExecute(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(ctx, creator, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedRandomAccount(ctx, topUp...)
|
||||
bob := RandomAccountAddress(t)
|
||||
|
||||
contractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
initMsg := HackatomExampleInitMsg{
|
||||
Verifier: fred,
|
||||
Beneficiary: bob,
|
||||
|
@ -601,7 +778,8 @@ func TestExecute(t *testing.T) {
|
|||
|
||||
addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 3", deposit)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr", addr.String())
|
||||
// cosmos1eycfqpgtcp4gc9g24cvg6useyncxspq8qurv2z7cs0wzcgvmffaquzwe2e build with code-id 1, DeterministicAccountAddress(t, 1) and label `demo contract 3`
|
||||
require.Equal(t, "cosmos1eycfqpgtcp4gc9g24cvg6useyncxspq8qurv2z7cs0wzcgvmffaquzwe2e", addr.String())
|
||||
|
||||
// ensure bob doesn't exist
|
||||
bobAcct := accKeeper.GetAccount(ctx, bob)
|
||||
|
@ -638,7 +816,7 @@ func TestExecute(t *testing.T) {
|
|||
// make sure gas is properly deducted from ctx
|
||||
gasAfter := ctx.GasMeter().GasConsumed()
|
||||
if types.EnableGasVerification {
|
||||
require.Equal(t, uint64(0x17cd2), gasAfter-gasBefore)
|
||||
require.Equal(t, uint64(0x17d87), gasAfter-gasBefore)
|
||||
}
|
||||
// ensure bob now exists and got both payments released
|
||||
bobAcct = accKeeper.GetAccount(ctx, bob)
|
||||
|
@ -725,7 +903,7 @@ func TestExecuteWithDeposit(t *testing.T) {
|
|||
if spec.fundAddr {
|
||||
fundAccounts(t, ctx, accKeeper, bankKeeper, spec.srcActor, sdk.NewCoins(sdk.NewInt64Coin("denom", 200)))
|
||||
}
|
||||
codeID, err := keeper.Create(ctx, spec.srcActor, hackatomWasm, nil)
|
||||
codeID, _, err := keeper.Create(ctx, spec.srcActor, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
initMsg := HackatomExampleInitMsg{Verifier: spec.srcActor, Beneficiary: spec.beneficiary}
|
||||
|
@ -755,7 +933,8 @@ func TestExecuteWithNonExistingAddress(t *testing.T) {
|
|||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(ctx, creator, deposit.Add(deposit...)...)
|
||||
|
||||
// unauthorized - trialCtx so we don't change state
|
||||
nonExistingAddress := RandomAccountAddress(t)
|
||||
|
@ -769,10 +948,11 @@ func TestExecuteWithPanic(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(ctx, creator, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedRandomAccount(ctx, topUp...)
|
||||
|
||||
contractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
|
@ -800,10 +980,11 @@ func TestExecuteWithCpuLoop(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(ctx, creator, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedRandomAccount(ctx, topUp...)
|
||||
|
||||
contractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
|
@ -841,10 +1022,11 @@ func TestExecuteWithStorageLoop(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(ctx, creator, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedRandomAccount(ctx, topUp...)
|
||||
|
||||
contractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
|
@ -877,21 +1059,23 @@ func TestExecuteWithStorageLoop(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMigrate(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
parentCtx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(parentCtx, creator, deposit.Add(deposit...)...)
|
||||
fred := DeterministicAccountAddress(t, 2)
|
||||
keepers.Faucet.Fund(parentCtx, fred, topUp...)
|
||||
|
||||
originalCodeID := StoreHackatomExampleContract(t, ctx, keepers).CodeID
|
||||
newCodeID := StoreHackatomExampleContract(t, ctx, keepers).CodeID
|
||||
ibcCodeID := StoreIBCReflectContract(t, ctx, keepers).CodeID
|
||||
originalCodeID := StoreHackatomExampleContract(t, parentCtx, keepers).CodeID
|
||||
newCodeID := StoreHackatomExampleContract(t, parentCtx, keepers).CodeID
|
||||
ibcCodeID := StoreIBCReflectContract(t, parentCtx, keepers).CodeID
|
||||
require.NotEqual(t, originalCodeID, newCodeID)
|
||||
|
||||
restrictedCodeExample := StoreHackatomExampleContract(t, ctx, keepers)
|
||||
require.NoError(t, keeper.SetAccessConfig(ctx, restrictedCodeExample.CodeID, restrictedCodeExample.CreatorAddr, types.AllowNobody))
|
||||
restrictedCodeExample := StoreHackatomExampleContract(t, parentCtx, keepers)
|
||||
require.NoError(t, keeper.SetAccessConfig(parentCtx, restrictedCodeExample.CodeID, restrictedCodeExample.CreatorAddr, types.AllowNobody))
|
||||
require.NotEqual(t, originalCodeID, restrictedCodeExample.CodeID)
|
||||
|
||||
anyAddr := RandomAccountAddress(t)
|
||||
|
@ -1017,7 +1201,7 @@ func TestMigrate(t *testing.T) {
|
|||
"fail when no IBC callbacks": {
|
||||
admin: fred,
|
||||
caller: fred,
|
||||
initMsg: IBCReflectInitMsg{ReflectCodeID: StoreReflectContract(t, ctx, keepers)}.GetBytes(t),
|
||||
initMsg: IBCReflectInitMsg{ReflectCodeID: StoreReflectContract(t, parentCtx, keepers).CodeID}.GetBytes(t),
|
||||
fromCodeID: ibcCodeID,
|
||||
toCodeID: newCodeID,
|
||||
migrateMsg: migMsgBz,
|
||||
|
@ -1025,10 +1209,13 @@ func TestMigrate(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
blockHeight := parentCtx.BlockHeight()
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
// given a contract instance
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
ctx, _ := parentCtx.WithBlockHeight(blockHeight + 1).CacheContext()
|
||||
blockHeight++
|
||||
|
||||
contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, spec.fromCodeID, creator, spec.admin, spec.initMsg, "demo contract", nil)
|
||||
require.NoError(t, err)
|
||||
if spec.overrideContractAddr != nil {
|
||||
|
@ -1109,15 +1296,16 @@ func TestMigrateWithDispatchedMessage(t *testing.T) {
|
|||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, sdk.NewInt64Coin("denom", 5000))
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(ctx, creator, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedRandomAccount(ctx, sdk.NewInt64Coin("denom", 5000))
|
||||
|
||||
burnerCode, err := os.ReadFile("./testdata/burner.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
originalContractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
originalContractID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
burnerContractID, err := keeper.Create(ctx, creator, burnerCode, nil)
|
||||
burnerContractID, _, err := keeper.Create(ctx, creator, burnerCode, nil)
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, originalContractID, burnerContractID)
|
||||
|
||||
|
@ -1279,9 +1467,10 @@ func TestSudo(t *testing.T) {
|
|||
accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(ctx, creator, deposit.Add(deposit...)...)
|
||||
|
||||
contractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
contractID, _, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
|
@ -1294,7 +1483,7 @@ func TestSudo(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
addr, _, err := keepers.ContractKeeper.Instantiate(ctx, contractID, creator, nil, initMsgBz, "demo contract 3", deposit)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr", addr.String())
|
||||
require.Equal(t, "cosmos1eycfqpgtcp4gc9g24cvg6useyncxspq8qurv2z7cs0wzcgvmffaquzwe2e", addr.String())
|
||||
|
||||
// the community is broke
|
||||
_, _, community := keyPubAddr()
|
||||
|
@ -1358,15 +1547,16 @@ func mustMarshal(t *testing.T, r interface{}) []byte {
|
|||
}
|
||||
|
||||
func TestUpdateContractAdmin(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
parentCtx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(parentCtx, creator, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedRandomAccount(parentCtx, topUp...)
|
||||
|
||||
originalContractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
originalContractID, _, err := keeper.Create(parentCtx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, anyAddr := keyPubAddr()
|
||||
|
@ -1409,6 +1599,7 @@ func TestUpdateContractAdmin(t *testing.T) {
|
|||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
ctx, _ := parentCtx.CacheContext()
|
||||
addr, _, err := keepers.ContractKeeper.Instantiate(ctx, originalContractID, creator, spec.instAdmin, initMsgBz, "demo contract", nil)
|
||||
require.NoError(t, err)
|
||||
if spec.overrideContractAddr != nil {
|
||||
|
@ -1426,15 +1617,16 @@ func TestUpdateContractAdmin(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestClearContractAdmin(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
parentCtx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
keeper := keepers.ContractKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := DeterministicAccountAddress(t, 1)
|
||||
keepers.Faucet.Fund(parentCtx, creator, deposit.Add(deposit...)...)
|
||||
fred := keepers.Faucet.NewFundedRandomAccount(parentCtx, topUp...)
|
||||
|
||||
originalContractID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
|
||||
originalContractID, _, err := keeper.Create(parentCtx, creator, hackatomWasm, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, anyAddr := keyPubAddr()
|
||||
|
@ -1472,6 +1664,7 @@ func TestClearContractAdmin(t *testing.T) {
|
|||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
ctx, _ := parentCtx.CacheContext()
|
||||
addr, _, err := keepers.ContractKeeper.Instantiate(ctx, originalContractID, creator, spec.instAdmin, initMsgBz, "demo contract", nil)
|
||||
require.NoError(t, err)
|
||||
if spec.overrideContractAddr != nil {
|
||||
|
@ -1806,52 +1999,103 @@ func TestQueryIsolation(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBuildContractAddress(t *testing.T) {
|
||||
x, y := sdk.GetConfig().GetBech32AccountAddrPrefix(), sdk.GetConfig().GetBech32AccountPubPrefix()
|
||||
t.Cleanup(func() {
|
||||
sdk.GetConfig().SetBech32PrefixForAccount(x, y)
|
||||
})
|
||||
sdk.GetConfig().SetBech32PrefixForAccount("purple", "purple")
|
||||
|
||||
// test vectors from https://gist.github.com/webmaster128/e4d401d414bd0e7e6f70482f11877fbe
|
||||
specs := map[string]struct {
|
||||
srcCodeID uint64
|
||||
srcInstanceID uint64
|
||||
expectedAddr string
|
||||
checksum []byte
|
||||
label string
|
||||
creator string
|
||||
expAddress string
|
||||
}{
|
||||
"initial contract": {
|
||||
srcCodeID: 1,
|
||||
srcInstanceID: 1,
|
||||
expectedAddr: "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr",
|
||||
"initial account addr example": {
|
||||
checksum: fromHex("13A1FC994CC6D1C81B746EE0C0FF6F90043875E0BF1D9BE6B7D779FC978DC2A5"),
|
||||
label: "instance 1",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py",
|
||||
expAddress: "purple1jukvumwqfxapueg6un6rtmafxktcluzv70xc3edz2m5t3slgw49qrmhc03",
|
||||
},
|
||||
"demo value": {
|
||||
srcCodeID: 1,
|
||||
srcInstanceID: 100,
|
||||
expectedAddr: "cosmos1mujpjkwhut9yjw4xueyugc02evfv46y0dtmnz4lh8xxkkdapym9stu5qm8",
|
||||
"account addr with different label": {
|
||||
checksum: fromHex("13A1FC994CC6D1C81B746EE0C0FF6F90043875E0BF1D9BE6B7D779FC978DC2A5"),
|
||||
label: "instance 2",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py",
|
||||
expAddress: "purple1jpc2w2vu2t6k7u09p6v8e3w28ptnzvvt2snu5rytlj8qya27dq5sjkwm06",
|
||||
},
|
||||
"both below max": {
|
||||
srcCodeID: math.MaxUint32 - 1,
|
||||
srcInstanceID: math.MaxUint32 - 1,
|
||||
"initial contract addr example": {
|
||||
checksum: fromHex("13A1FC994CC6D1C81B746EE0C0FF6F90043875E0BF1D9BE6B7D779FC978DC2A5"),
|
||||
label: "instance 1",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m",
|
||||
expAddress: "purple1wde5zlcveuh79w37w5g244qu9xja3hgfulyfkjvkxvwvjzgd5l3qfraz3c",
|
||||
},
|
||||
"both at max": {
|
||||
srcCodeID: math.MaxUint32,
|
||||
srcInstanceID: math.MaxUint32,
|
||||
"contract addr with different label": {
|
||||
checksum: fromHex("13A1FC994CC6D1C81B746EE0C0FF6F90043875E0BF1D9BE6B7D779FC978DC2A5"),
|
||||
label: "instance 2",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m",
|
||||
expAddress: "purple1vae2kf0r3ehtq5q2jmfkg7wp4ckxwrw8dv4pvazz5nlzzu05lxzq878fa9",
|
||||
},
|
||||
"codeID > max u32": {
|
||||
srcCodeID: math.MaxUint32 + 1,
|
||||
srcInstanceID: 17,
|
||||
expectedAddr: "cosmos1673hrexz4h6s0ft04l96ygq667djzh2nsr335kstjp49x5dk6rpsf5t0le",
|
||||
"account addr with different checksum": {
|
||||
checksum: fromHex("1DA6C16DE2CBAF7AD8CBB66F0925BA33F5C278CB2491762D04658C1480EA229B"),
|
||||
label: "instance 1",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py",
|
||||
expAddress: "purple1gmgvt9levtn52mpfal3gl5tv60f47zez3wgczrh5c9352sfm9crs47zt0k",
|
||||
},
|
||||
"instanceID > max u32": {
|
||||
srcCodeID: 22,
|
||||
srcInstanceID: math.MaxUint32 + 1,
|
||||
expectedAddr: "cosmos10q3pgfvmeyy0veekgtqhxujxkhz0vm9zmalqgc7evrhj68q3l62qrdfg4m",
|
||||
"account addr with different checksum and label": {
|
||||
checksum: fromHex("1DA6C16DE2CBAF7AD8CBB66F0925BA33F5C278CB2491762D04658C1480EA229B"),
|
||||
label: "instance 2",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py",
|
||||
expAddress: "purple13jrcqxknt05rhdxmegjzjel666yay6fj3xvfp6445k7a9q2km4wqa7ss34",
|
||||
},
|
||||
"contract addr with different checksum": {
|
||||
checksum: fromHex("1DA6C16DE2CBAF7AD8CBB66F0925BA33F5C278CB2491762D04658C1480EA229B"),
|
||||
label: "instance 1",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m",
|
||||
expAddress: "purple1lu0lf6wmqeuwtrx93ptzvf4l0dyyz2vz6s8h5y9cj42fvhsmracq49pww9",
|
||||
},
|
||||
"contract addr with different checksum and label": {
|
||||
checksum: fromHex("1DA6C16DE2CBAF7AD8CBB66F0925BA33F5C278CB2491762D04658C1480EA229B"),
|
||||
label: "instance 2",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m",
|
||||
expAddress: "purple1zmerc8a9ml2au29rq3knuu35fktef3akceurckr6pf370n0wku7sw3c9mj",
|
||||
},
|
||||
// regression tests
|
||||
"min label size": {
|
||||
checksum: fromHex("13A1FC994CC6D1C81B746EE0C0FF6F90043875E0BF1D9BE6B7D779FC978DC2A5"),
|
||||
label: "x",
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py",
|
||||
expAddress: "purple16pc8gt824lmp3dh2sxvttj0ykcs02n5p3ldswhv3j7y853gghlfq7mqeh9",
|
||||
},
|
||||
"max label size": {
|
||||
checksum: fromHex("13A1FC994CC6D1C81B746EE0C0FF6F90043875E0BF1D9BE6B7D779FC978DC2A5"),
|
||||
label: strings.Repeat("x", types.MaxLabelSize),
|
||||
creator: "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py",
|
||||
expAddress: "purple1prkdvjmvv4s3tnppfxmlpj259v9cplf3wws4qq9qd7w3s4yqzqeqem4759",
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
gotAddr := BuildContractAddress(spec.srcCodeID, spec.srcInstanceID)
|
||||
require.NotNil(t, gotAddr)
|
||||
assert.Nil(t, sdk.VerifyAddressFormat(gotAddr))
|
||||
if len(spec.expectedAddr) > 0 {
|
||||
require.Equal(t, spec.expectedAddr, gotAddr.String())
|
||||
}
|
||||
creatorAddr, err := sdk.AccAddressFromBech32(spec.creator)
|
||||
require.NoError(t, err)
|
||||
|
||||
// when
|
||||
gotAddr := BuildContractAddress(spec.checksum, creatorAddr, spec.label)
|
||||
|
||||
require.Equal(t, spec.expAddress, gotAddr.String())
|
||||
require.NoError(t, sdk.VerifyAddressFormat(gotAddr))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fromHex(s string) []byte {
|
||||
r, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func TestSetAccessConfig(t *testing.T) {
|
||||
parentCtx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
k := keepers.WasmKeeper
|
||||
|
|
|
@ -21,13 +21,13 @@ func TestLegacyQueryContractState(t *testing.T) {
|
|||
keeper := keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
anyAddr := keepers.Faucet.NewFundedAccount(ctx, sdk.NewInt64Coin("denom", 5000))
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit.Add(deposit...)...)
|
||||
anyAddr := keepers.Faucet.NewFundedRandomAccount(ctx, sdk.NewInt64Coin("denom", 5000))
|
||||
|
||||
wasmCode, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
contractID, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, nil)
|
||||
contractID, _, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
|
@ -159,13 +159,13 @@ func TestLegacyQueryContractListByCodeOrdering(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 500))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit.Add(deposit...)...)
|
||||
anyAddr := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit.Add(deposit...)...)
|
||||
anyAddr := keepers.Faucet.NewFundedRandomAccount(ctx, topUp...)
|
||||
|
||||
wasmCode, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
// Migrator is a struct for handling in-place store migrations.
|
||||
type Migrator struct {
|
||||
keeper *Keeper
|
||||
}
|
||||
|
||||
// NewMigrator returns a new Migrator.
|
||||
func NewMigrator(keeper *Keeper) Migrator {
|
||||
return Migrator{keeper: keeper}
|
||||
}
|
||||
|
||||
var keyLastInstanceID = append(types.SequenceKeyPrefix, []byte("lastContractId")...)
|
||||
|
||||
// Migrate1to2 migrates from version 1 to 2.
|
||||
// Remove the unused sequence for address generation
|
||||
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
|
||||
store := ctx.KVStore(m.keeper.storeKey)
|
||||
store.Delete(keyLastInstanceID)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMigrateV1ToV2(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
store := ctx.KVStore(keepers.WasmKeeper.storeKey)
|
||||
store.Set(keyLastInstanceID, sdk.Uint64ToBigEndian(100))
|
||||
|
||||
// when
|
||||
NewMigrator(keepers.WasmKeeper).Migrate1to2(ctx)
|
||||
|
||||
// then
|
||||
assert.False(t, store.Has(keyLastInstanceID))
|
||||
}
|
|
@ -32,13 +32,14 @@ func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*t
|
|||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
|
||||
))
|
||||
|
||||
codeID, err := m.keeper.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission)
|
||||
codeID, checksum, err := m.keeper.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.MsgStoreCodeResponse{
|
||||
CodeID: codeID,
|
||||
CodeID: codeID,
|
||||
Checksum: checksum,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package keeper_test
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
_ "embed"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/CosmWasm/wasmd/app"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
//go:embed testdata/reflect.wasm
|
||||
var wasmContract []byte
|
||||
|
||||
func TestStoreCode(t *testing.T) {
|
||||
wasmApp := app.Setup(false)
|
||||
ctx := wasmApp.BaseApp.NewContext(false, tmproto.Header{})
|
||||
_, _, sender := testdata.KeyTestPubAddr()
|
||||
msg := types.MsgStoreCodeFixture(func(m *types.MsgStoreCode) {
|
||||
m.WASMByteCode = wasmContract
|
||||
m.Sender = sender.String()
|
||||
})
|
||||
|
||||
// when
|
||||
rsp, err := wasmApp.MsgServiceRouter().Handler(msg)(ctx, msg)
|
||||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
var result types.MsgStoreCodeResponse
|
||||
require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result))
|
||||
assert.Equal(t, uint64(1), result.CodeID)
|
||||
expHash := sha256.Sum256(wasmContract)
|
||||
assert.Equal(t, expHash[:], result.Checksum)
|
||||
// and
|
||||
info := wasmApp.WasmKeeper.GetCodeInfo(ctx, 1)
|
||||
assert.NotNil(t, info)
|
||||
assert.Equal(t, expHash[:], info.CodeHash)
|
||||
assert.Equal(t, sender.String(), info.Creator)
|
||||
assert.Equal(t, types.DefaultParams().InstantiateDefaultPermission.With(sender), info.InstantiateConfig)
|
||||
}
|
|
@ -2,7 +2,9 @@ package keeper
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
|
@ -89,11 +91,25 @@ func WithMessageEncoders(x *MessageEncoders) Option {
|
|||
|
||||
// WithCoinTransferrer is an optional constructor parameter to set a custom coin transferrer
|
||||
func WithCoinTransferrer(x CoinTransferrer) Option {
|
||||
if x == nil {
|
||||
panic("must not be nil")
|
||||
}
|
||||
return optsFn(func(k *Keeper) {
|
||||
k.bank = x
|
||||
})
|
||||
}
|
||||
|
||||
// WithCoinPruner is an optional constructor parameter to set a custom type that handles balances
|
||||
// for accounts pruned on contract instantiate
|
||||
func WithCoinPruner(x CoinPruner) Option {
|
||||
if x == nil {
|
||||
panic("must not be nil")
|
||||
}
|
||||
return optsFn(func(k *Keeper) {
|
||||
k.coinPruner = x
|
||||
})
|
||||
}
|
||||
|
||||
func WithVMCacheMetrics(r prometheus.Registerer) Option {
|
||||
return optsFn(func(k *Keeper) {
|
||||
NewWasmVMMetricsCollector(k.wasmVM).Register(r)
|
||||
|
@ -104,6 +120,9 @@ func WithVMCacheMetrics(r prometheus.Registerer) Option {
|
|||
// When the "gas multiplier" for wasmvm gas conversion is modified inside the new register,
|
||||
// make sure to also use `WithApiCosts` option for non default values
|
||||
func WithGasRegister(x GasRegister) Option {
|
||||
if x == nil {
|
||||
panic("must not be nil")
|
||||
}
|
||||
return optsFn(func(k *Keeper) {
|
||||
k.gasRegister = x
|
||||
})
|
||||
|
@ -123,3 +142,42 @@ func WithMaxQueryStackSize(m uint32) Option {
|
|||
k.maxQueryStackSize = m
|
||||
})
|
||||
}
|
||||
|
||||
// WithAcceptedAccountTypesOnContractInstantiation sets the accepted account types. Account types of this list won't be overwritten or cause a failure
|
||||
// when they exist for an address on contract instantiation.
|
||||
//
|
||||
// Values should be references and contain the `*authtypes.BaseAccount` as default bank account type.
|
||||
func WithAcceptedAccountTypesOnContractInstantiation(accts ...authtypes.AccountI) Option {
|
||||
m := asTypeMap(accts)
|
||||
return optsFn(func(k *Keeper) {
|
||||
k.acceptedAccountTypes = m
|
||||
})
|
||||
}
|
||||
|
||||
// WithPruneAccountTypesOnContractInstantiation sets the account types that should be cleared. Account types of this list
|
||||
// will be overwritten with the BaseAccount type and their balance burned, when they exist for an address on contract
|
||||
// instantiation.
|
||||
//
|
||||
// Values should be references and contain the `*vestingtypes.DelayedVestingAccount`, `*vestingtypes.ContinuousVestingAccount`
|
||||
// as post genesis account types with an open address range.
|
||||
func WithPruneAccountTypesOnContractInstantiation(accts ...authtypes.AccountI) Option {
|
||||
m := asTypeMap(accts)
|
||||
return optsFn(func(k *Keeper) {
|
||||
k.pruneAccountTypes = m
|
||||
})
|
||||
}
|
||||
|
||||
func asTypeMap(accts []authtypes.AccountI) map[reflect.Type]struct{} {
|
||||
m := make(map[reflect.Type]struct{}, len(accts))
|
||||
for _, a := range accts {
|
||||
if a == nil {
|
||||
panic(types.ErrEmpty.Wrap("address"))
|
||||
}
|
||||
at := reflect.TypeOf(a)
|
||||
if _, exists := m[at]; exists {
|
||||
panic(types.ErrDuplicate.Wrapf("%T", a))
|
||||
}
|
||||
m[at] = struct{}{}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
|
@ -81,10 +85,36 @@ func TestConstructorOptions(t *testing.T) {
|
|||
assert.IsType(t, uint32(1), k.maxQueryStackSize)
|
||||
},
|
||||
},
|
||||
"accepted account types": {
|
||||
srcOpt: WithAcceptedAccountTypesOnContractInstantiation(&authtypes.BaseAccount{}, &vestingtypes.ContinuousVestingAccount{}),
|
||||
verify: func(t *testing.T, k Keeper) {
|
||||
exp := map[reflect.Type]struct{}{
|
||||
reflect.TypeOf(&authtypes.BaseAccount{}): {},
|
||||
reflect.TypeOf(&vestingtypes.ContinuousVestingAccount{}): {},
|
||||
}
|
||||
assert.Equal(t, exp, k.acceptedAccountTypes)
|
||||
},
|
||||
},
|
||||
"prune account types": {
|
||||
srcOpt: WithPruneAccountTypesOnContractInstantiation(&authtypes.BaseAccount{}, &vestingtypes.ContinuousVestingAccount{}),
|
||||
verify: func(t *testing.T, k Keeper) {
|
||||
exp := map[reflect.Type]struct{}{
|
||||
reflect.TypeOf(&authtypes.BaseAccount{}): {},
|
||||
reflect.TypeOf(&vestingtypes.ContinuousVestingAccount{}): {},
|
||||
}
|
||||
assert.Equal(t, exp, k.pruneAccountTypes)
|
||||
},
|
||||
},
|
||||
"coin pruner": {
|
||||
srcOpt: WithCoinPruner(CoinBurner{}),
|
||||
verify: func(t *testing.T, k Keeper) {
|
||||
assert.Equal(t, CoinBurner{}, k.coinPruner)
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
k := NewKeeper(nil, nil, paramtypes.NewSubspace(nil, nil, nil, nil, ""), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), AvailableCapabilities, spec.srcOpt)
|
||||
k := NewKeeper(nil, nil, paramtypes.NewSubspace(nil, nil, nil, nil, ""), authkeeper.AccountKeeper{}, &bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), AvailableCapabilities, spec.srcOpt)
|
||||
spec.verify(t, k)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func handleStoreCodeProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types
|
|||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "run as address")
|
||||
}
|
||||
codeID, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission)
|
||||
codeID, _, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package keeper
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
@ -116,9 +117,8 @@ func TestInstantiateProposal(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// then
|
||||
contractAddr, err := sdk.AccAddressFromBech32("cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr")
|
||||
require.NoError(t, err)
|
||||
|
||||
codeHash := keepers.WasmKeeper.GetCodeInfo(ctx, 1).CodeHash
|
||||
contractAddr := BuildContractAddress(codeHash, oneAddress, "testing")
|
||||
cInfo := wasmKeeper.GetContractInfo(ctx, contractAddr)
|
||||
require.NotNil(t, cInfo)
|
||||
assert.Equal(t, uint64(1), cInfo.CodeID)
|
||||
|
@ -188,9 +188,8 @@ func TestInstantiateProposal_NoAdmin(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// then
|
||||
contractAddr, err := sdk.AccAddressFromBech32("cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr")
|
||||
require.NoError(t, err)
|
||||
|
||||
codeHash := keepers.WasmKeeper.GetCodeInfo(ctx, 1).CodeHash
|
||||
contractAddr := BuildContractAddress(codeHash, oneAddress, "testing")
|
||||
cInfo := wasmKeeper.GetContractInfo(ctx, contractAddr)
|
||||
require.NotNil(t, cInfo)
|
||||
assert.Equal(t, uint64(1), cInfo.CodeID)
|
||||
|
@ -229,9 +228,9 @@ func TestMigrateProposal(t *testing.T) {
|
|||
require.NoError(t, wasmKeeper.importCode(ctx, 2, codeInfoFixture, wasmCode))
|
||||
|
||||
var (
|
||||
anyAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, types.ContractAddrLen)
|
||||
otherAddress sdk.AccAddress = bytes.Repeat([]byte{0x2}, types.ContractAddrLen)
|
||||
contractAddr = BuildContractAddress(1, 1)
|
||||
anyAddress = DeterministicAccountAddress(t, 1)
|
||||
otherAddress = DeterministicAccountAddress(t, 2)
|
||||
contractAddr = BuildContractAddress(codeInfoFixture.CodeHash, RandomAccountAddress(t), "")
|
||||
)
|
||||
|
||||
contractInfoFixture := types.ContractInfoFixture(func(c *types.ContractInfo) {
|
||||
|
@ -408,12 +407,13 @@ func TestSudoProposal(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAdminProposals(t *testing.T) {
|
||||
var (
|
||||
otherAddress sdk.AccAddress = bytes.Repeat([]byte{0x2}, types.ContractAddrLen)
|
||||
contractAddr = BuildContractAddress(1, 1)
|
||||
)
|
||||
wasmCode, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
var (
|
||||
otherAddress = DeterministicAccountAddress(t, 2)
|
||||
codeHash = sha256.Sum256(wasmCode)
|
||||
contractAddr = BuildContractAddress(codeHash[:], RandomAccountAddress(t), "")
|
||||
)
|
||||
|
||||
specs := map[string]struct {
|
||||
state types.ContractInfo
|
||||
|
|
|
@ -158,8 +158,9 @@ func TestQuerySmartContractState(t *testing.T) {
|
|||
|
||||
func TestQuerySmartContractPanics(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
|
||||
contractAddr := BuildContractAddress(1, 1)
|
||||
keepers.WasmKeeper.storeCodeInfo(ctx, 1, types.CodeInfo{})
|
||||
creator := RandomAccountAddress(t)
|
||||
contractAddr := BuildContractAddress([]byte("myCodeHash"), creator, "testing")
|
||||
keepers.WasmKeeper.storeCodeInfo(ctx, 1, types.CodeInfo{CodeHash: []byte("myCodeHash")})
|
||||
keepers.WasmKeeper.storeContractInfo(ctx, contractAddr, &types.ContractInfo{
|
||||
CodeID: 1,
|
||||
Created: types.NewAbsoluteTxPosition(ctx),
|
||||
|
@ -262,13 +263,13 @@ func TestQueryContractListByCodeOrdering(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 500))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
anyAddr := keepers.Faucet.NewFundedAccount(ctx, topUp...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
anyAddr := keepers.Faucet.NewFundedRandomAccount(ctx, topUp...)
|
||||
|
||||
wasmCode, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, bob := keyPubAddr()
|
||||
|
|
|
@ -43,18 +43,18 @@ func TestReflectContractSend(t *testing.T) {
|
|||
accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
_, _, bob := keyPubAddr()
|
||||
|
||||
// upload reflect code
|
||||
reflectID, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
reflectID, _, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), reflectID)
|
||||
|
||||
// upload hackatom escrow code
|
||||
escrowCode, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
escrowID, err := keeper.Create(ctx, creator, escrowCode, nil)
|
||||
escrowID, _, err := keeper.Create(ctx, creator, escrowCode, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), escrowID)
|
||||
|
||||
|
@ -122,12 +122,12 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||
accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
bob := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
bob := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
codeID, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
codeID, _, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -213,10 +213,10 @@ func TestMaskReflectCustomQuery(t *testing.T) {
|
|||
keeper := keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// upload code
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -263,10 +263,10 @@ func TestReflectStargateQuery(t *testing.T) {
|
|||
funds := sdk.NewCoins(sdk.NewInt64Coin("denom", 320000))
|
||||
contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000))
|
||||
expectedBalance := funds.Sub(contractStart)
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, funds...)
|
||||
|
||||
// upload code
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -303,7 +303,7 @@ func TestReflectTotalSupplyQuery(t *testing.T) {
|
|||
ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins()))
|
||||
keeper := keepers.WasmKeeper
|
||||
// upload code
|
||||
codeID := StoreReflectContract(t, ctx, keepers)
|
||||
codeID := StoreReflectContract(t, ctx, keepers).CodeID
|
||||
// creator instantiates a contract and gives it tokens
|
||||
creator := RandomAccountAddress(t)
|
||||
contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "testing", nil)
|
||||
|
@ -356,10 +356,10 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||
|
||||
funds := sdk.NewCoins(sdk.NewInt64Coin("denom", 320000))
|
||||
contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, funds...)
|
||||
|
||||
// upload code
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -434,10 +434,10 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||
keeper := keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// upload reflect code
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
reflectID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), reflectID)
|
||||
|
||||
|
@ -504,10 +504,10 @@ func TestWasmRawQueryWithNil(t *testing.T) {
|
|||
keeper := keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// upload reflect code
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
reflectID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), reflectID)
|
||||
|
||||
|
|
|
@ -55,11 +55,10 @@ func TestSnapshotter(t *testing.T) {
|
|||
for i, v := range spec.wasmFiles {
|
||||
wasmCode, err := os.ReadFile(v)
|
||||
require.NoError(t, err)
|
||||
codeID, err := contractKeeper.Create(ctx, genesisAddr, wasmCode, nil)
|
||||
codeID, checksum, err := contractKeeper.Create(ctx, genesisAddr, wasmCode, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(i+1), codeID)
|
||||
hash := sha256.Sum256(wasmCode)
|
||||
srcCodeIDToChecksum[codeID] = hash[:]
|
||||
srcCodeIDToChecksum[codeID] = checksum
|
||||
}
|
||||
// create snapshot
|
||||
srcWasmApp.Commit()
|
||||
|
|
|
@ -103,12 +103,12 @@ func TestInitializeStaking(t *testing.T) {
|
|||
assert.Equal(t, v.GetDelegatorShares(), sdk.NewDec(1234567))
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000), sdk.NewInt64Coin("stake", 500000))
|
||||
creator := k.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := k.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// upload staking derivates code
|
||||
stakingCode, err := os.ReadFile("./testdata/staking.wasm")
|
||||
require.NoError(t, err)
|
||||
stakingID, err := keeper.Create(ctx, creator, stakingCode, nil)
|
||||
stakingID, _, err := keeper.Create(ctx, creator, stakingCode, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), stakingID)
|
||||
|
||||
|
@ -186,12 +186,12 @@ func initializeStaking(t *testing.T) initInfo {
|
|||
assert.Equal(t, v.Status, stakingtypes.Bonded)
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000), sdk.NewInt64Coin("stake", 500000))
|
||||
creator := k.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := k.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// upload staking derivates code
|
||||
stakingCode, err := os.ReadFile("./testdata/staking.wasm")
|
||||
require.NoError(t, err)
|
||||
stakingID, err := k.ContractKeeper.Create(ctx, creator, stakingCode, nil)
|
||||
stakingID, _, err := k.ContractKeeper.Create(ctx, creator, stakingCode, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), stakingID)
|
||||
|
||||
|
@ -239,7 +239,7 @@ func TestBonding(t *testing.T) {
|
|||
// bob has 160k, putting 80k into the contract
|
||||
full := sdk.NewCoins(sdk.NewInt64Coin("stake", 160000))
|
||||
funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 80000))
|
||||
bob := initInfo.faucet.NewFundedAccount(ctx, full...)
|
||||
bob := initInfo.faucet.NewFundedRandomAccount(ctx, full...)
|
||||
|
||||
// check contract state before
|
||||
assertBalance(t, ctx, keeper, contractAddr, bob, "0")
|
||||
|
@ -287,7 +287,7 @@ func TestUnbonding(t *testing.T) {
|
|||
// bob has 160k, putting 80k into the contract
|
||||
full := sdk.NewCoins(sdk.NewInt64Coin("stake", 160000))
|
||||
funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 80000))
|
||||
bob := initInfo.faucet.NewFundedAccount(ctx, full...)
|
||||
bob := initInfo.faucet.NewFundedRandomAccount(ctx, full...)
|
||||
|
||||
bond := StakingHandleMsg{
|
||||
Bond: &struct{}{},
|
||||
|
@ -354,7 +354,7 @@ func TestReinvest(t *testing.T) {
|
|||
// full is 2x funds, 1x goes to the contract, other stays on his wallet
|
||||
full := sdk.NewCoins(sdk.NewInt64Coin("stake", 400000))
|
||||
funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 200000))
|
||||
bob := initInfo.faucet.NewFundedAccount(ctx, full...)
|
||||
bob := initInfo.faucet.NewFundedRandomAccount(ctx, full...)
|
||||
|
||||
// we will stake 200k to a validator with 1M self-bond
|
||||
// this means we should get 1/6 of the rewards
|
||||
|
@ -422,7 +422,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
// full is 2x funds, 1x goes to the contract, other stays on his wallet
|
||||
full := sdk.NewCoins(sdk.NewInt64Coin("stake", 400000))
|
||||
funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 200000))
|
||||
bob := initInfo.faucet.NewFundedAccount(ctx, full...)
|
||||
bob := initInfo.faucet.NewFundedRandomAccount(ctx, full...)
|
||||
|
||||
// we will stake 200k to a validator with 1M self-bond
|
||||
// this means we should get 1/6 of the rewards
|
||||
|
@ -444,10 +444,10 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
|
||||
// STEP 2: Prepare the mask contract
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
creator := initInfo.faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := initInfo.faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
|
||||
// upload mask code
|
||||
maskID, err := initInfo.contractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
maskID, _, err := initInfo.contractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), maskID)
|
||||
|
||||
|
@ -599,7 +599,7 @@ func TestQueryStakingPlugin(t *testing.T) {
|
|||
// full is 2x funds, 1x goes to the contract, other stays on his wallet
|
||||
full := sdk.NewCoins(sdk.NewInt64Coin("stake", 400000))
|
||||
funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 200000))
|
||||
bob := initInfo.faucet.NewFundedAccount(ctx, full...)
|
||||
bob := initInfo.faucet.NewFundedRandomAccount(ctx, full...)
|
||||
|
||||
// we will stake 200k to a validator with 1M self-bond
|
||||
// this means we should get 1/6 of the rewards
|
||||
|
@ -652,7 +652,7 @@ func TestQueryStakingPlugin(t *testing.T) {
|
|||
|
||||
// adds a few validators and returns a list of validators that are registered
|
||||
func addValidator(t *testing.T, ctx sdk.Context, stakingKeeper stakingkeeper.Keeper, faucet *TestFaucet, value sdk.Coin) sdk.ValAddress {
|
||||
owner := faucet.NewFundedAccount(ctx, value)
|
||||
owner := faucet.NewFundedRandomAccount(ctx, value)
|
||||
|
||||
privKey := secp256k1.GenPrivKey()
|
||||
pubKey := privKey.PubKey()
|
||||
|
|
|
@ -26,12 +26,12 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
|
|||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000))
|
||||
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
creatorBalance := deposit.Sub(contractStart)
|
||||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -110,16 +110,16 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||
ctx = ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter())
|
||||
keeper := keepers.WasmKeeper
|
||||
contractStart := sdk.NewCoins(sdk.NewInt64Coin(fundedDenom, int64(fundedAmount)))
|
||||
uploader := keepers.Faucet.NewFundedAccount(ctx, contractStart.Add(contractStart...)...)
|
||||
uploader := keepers.Faucet.NewFundedRandomAccount(ctx, contractStart.Add(contractStart...)...)
|
||||
|
||||
// upload code
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, uploader, testdata.ReflectContractWasm(), nil)
|
||||
reflectID, _, err := keepers.ContractKeeper.Create(ctx, uploader, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// create hackatom contract for testing (for infinite loop)
|
||||
hackatomCode, err := os.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
hackatomID, err := keepers.ContractKeeper.Create(ctx, uploader, hackatomCode, nil)
|
||||
hackatomID, _, err := keepers.ContractKeeper.Create(ctx, uploader, hackatomCode, nil)
|
||||
require.NoError(t, err)
|
||||
_, _, bob := keyPubAddr()
|
||||
_, _, fred := keyPubAddr()
|
||||
|
@ -282,7 +282,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||
}
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, contractStart...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, contractStart...)
|
||||
_, _, empty := keyPubAddr()
|
||||
|
||||
contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, reflectID, creator, nil, []byte("{}"), fmt.Sprintf("contract %s", name), contractStart)
|
||||
|
@ -366,11 +366,11 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
|
|||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000))
|
||||
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// creator instantiates a contract and gives it tokens
|
||||
|
@ -432,11 +432,11 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
|
|||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000))
|
||||
|
||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...)
|
||||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// creator instantiates a contract and gives it tokens
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -8,7 +9,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
@ -91,6 +94,7 @@ var moduleBasics = module.NewBasicManager(
|
|||
upgrade.AppModuleBasic{},
|
||||
evidence.AppModuleBasic{},
|
||||
transfer.AppModuleBasic{},
|
||||
vesting.AppModuleBasic{},
|
||||
)
|
||||
|
||||
func MakeTestCodec(t testing.TB) codec.Codec {
|
||||
|
@ -162,7 +166,7 @@ func (f *TestFaucet) Fund(parentCtx sdk.Context, receiver sdk.AccAddress, amount
|
|||
f.balance = f.balance.Sub(amounts)
|
||||
}
|
||||
|
||||
func (f *TestFaucet) NewFundedAccount(ctx sdk.Context, amounts ...sdk.Coin) sdk.AccAddress {
|
||||
func (f *TestFaucet) NewFundedRandomAccount(ctx sdk.Context, amounts ...sdk.Coin) sdk.AccAddress {
|
||||
_, _, addr := keyPubAddr()
|
||||
f.Fund(ctx, addr, amounts...)
|
||||
return addr
|
||||
|
@ -464,7 +468,7 @@ func handleStoreCode(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgS
|
|||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "sender")
|
||||
}
|
||||
codeID, err := k.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission)
|
||||
codeID, _, err := k.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -523,6 +527,11 @@ func RandomAccountAddress(_ testing.TB) sdk.AccAddress {
|
|||
return addr
|
||||
}
|
||||
|
||||
// DeterministicAccountAddress creates a test address with v repeated to valid address size
|
||||
func DeterministicAccountAddress(_ testing.TB, v byte) sdk.AccAddress {
|
||||
return bytes.Repeat([]byte{v}, address.Len)
|
||||
}
|
||||
|
||||
func RandomBech32AccountAddress(t testing.TB) string {
|
||||
return RandomAccountAddress(t).String()
|
||||
}
|
||||
|
@ -532,6 +541,7 @@ type ExampleContract struct {
|
|||
Creator crypto.PrivKey
|
||||
CreatorAddr sdk.AccAddress
|
||||
CodeID uint64
|
||||
Checksum []byte
|
||||
}
|
||||
|
||||
func StoreHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract {
|
||||
|
@ -546,11 +556,8 @@ func StoreIBCReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers)
|
|||
return StoreExampleContract(t, ctx, keepers, "./testdata/ibc_reflect.wasm")
|
||||
}
|
||||
|
||||
func StoreReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) uint64 {
|
||||
_, _, creatorAddr := keyPubAddr()
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
return codeID
|
||||
func StoreReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract {
|
||||
return StoreExampleContract(t, ctx, keepers, "./testdata/reflect.wasm")
|
||||
}
|
||||
|
||||
func StoreExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers, wasmFile string) ExampleContract {
|
||||
|
@ -561,9 +568,10 @@ func StoreExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers, wa
|
|||
wasmCode, err := os.ReadFile(wasmFile)
|
||||
require.NoError(t, err)
|
||||
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, nil)
|
||||
codeID, _, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, nil)
|
||||
require.NoError(t, err)
|
||||
return ExampleContract{anyAmount, creator, creatorAddr, codeID}
|
||||
hash := keepers.WasmKeeper.GetCodeInfo(ctx, codeID).CodeHash
|
||||
return ExampleContract{anyAmount, creator, creatorAddr, codeID, hash}
|
||||
}
|
||||
|
||||
var wasmIdent = []byte("\x00\x61\x73\x6D")
|
||||
|
@ -602,9 +610,9 @@ func StoreRandomContractWithAccessConfig(
|
|||
fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, creatorAddr, anyAmount)
|
||||
keepers.WasmKeeper.wasmVM = mock
|
||||
wasmCode := append(wasmIdent, rand.Bytes(10)...) //nolint:gocritic
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, cfg)
|
||||
codeID, checksum, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, cfg)
|
||||
require.NoError(t, err)
|
||||
exampleContract := ExampleContract{InitialAmount: anyAmount, Creator: creator, CreatorAddr: creatorAddr, CodeID: codeID}
|
||||
exampleContract := ExampleContract{InitialAmount: anyAmount, Creator: creator, CreatorAddr: creatorAddr, CodeID: codeID, Checksum: checksum}
|
||||
return exampleContract
|
||||
}
|
||||
|
||||
|
@ -615,6 +623,8 @@ type HackatomExampleInstance struct {
|
|||
VerifierAddr sdk.AccAddress
|
||||
Beneficiary crypto.PrivKey
|
||||
BeneficiaryAddr sdk.AccAddress
|
||||
Label string
|
||||
Deposit sdk.Coins
|
||||
}
|
||||
|
||||
// InstantiateHackatomExampleContract load and instantiate the "./testdata/hackatom.wasm" contract
|
||||
|
@ -632,7 +642,8 @@ func InstantiateHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers T
|
|||
initialAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 100))
|
||||
|
||||
adminAddr := contract.CreatorAddr
|
||||
contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, contract.CodeID, contract.CreatorAddr, adminAddr, initMsgBz, "demo contract to query", initialAmount)
|
||||
label := "demo contract to query"
|
||||
contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, contract.CodeID, contract.CreatorAddr, adminAddr, initMsgBz, label, initialAmount)
|
||||
require.NoError(t, err)
|
||||
return HackatomExampleInstance{
|
||||
ExampleContract: contract,
|
||||
|
@ -641,6 +652,31 @@ func InstantiateHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers T
|
|||
VerifierAddr: verifierAddr,
|
||||
Beneficiary: beneficiary,
|
||||
BeneficiaryAddr: beneficiaryAddr,
|
||||
Label: label,
|
||||
Deposit: initialAmount,
|
||||
}
|
||||
}
|
||||
|
||||
type ExampleInstance struct {
|
||||
ExampleContract
|
||||
Contract sdk.AccAddress
|
||||
Label string
|
||||
Deposit sdk.Coins
|
||||
}
|
||||
|
||||
// InstantiateReflectExampleContract load and instantiate the "./testdata/reflect.wasm" contract
|
||||
func InstantiateReflectExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleInstance {
|
||||
example := StoreReflectContract(t, ctx, keepers)
|
||||
initialAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 100))
|
||||
label := "demo contract to query"
|
||||
contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, example.CodeID, example.CreatorAddr, nil, []byte("{}"), label, initialAmount)
|
||||
|
||||
require.NoError(t, err)
|
||||
return ExampleInstance{
|
||||
ExampleContract: example,
|
||||
Contract: contractAddr,
|
||||
Label: label,
|
||||
Deposit: initialAmount,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,7 +700,7 @@ type IBCReflectExampleInstance struct {
|
|||
|
||||
// InstantiateIBCReflectContract load and instantiate the "./testdata/ibc_reflect.wasm" contract
|
||||
func InstantiateIBCReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) IBCReflectExampleInstance {
|
||||
reflectID := StoreReflectContract(t, ctx, keepers)
|
||||
reflectID := StoreReflectContract(t, ctx, keepers).CodeID
|
||||
ibcReflectID := StoreIBCReflectContract(t, ctx, keepers).CodeID
|
||||
|
||||
initMsgBz := IBCReflectInitMsg{
|
||||
|
|
|
@ -111,7 +111,7 @@ type AppModule struct {
|
|||
// module. It should be incremented on each consensus-breaking change
|
||||
// introduced by the module. To avoid wrong/empty versions, the initial version
|
||||
// should be set to 1.
|
||||
func (AppModule) ConsensusVersion() uint64 { return 1 }
|
||||
func (AppModule) ConsensusVersion() uint64 { return 2 }
|
||||
|
||||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(
|
||||
|
@ -134,6 +134,11 @@ func NewAppModule(
|
|||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(keeper.NewDefaultPermissionKeeper(am.keeper)))
|
||||
types.RegisterQueryServer(cfg.QueryServer(), NewQuerier(am.keeper))
|
||||
|
||||
m := keeper.NewMigrator(am.keeper)
|
||||
if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { //nolint:staticcheck
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package wasm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -145,7 +148,8 @@ type state struct {
|
|||
|
||||
func TestHandleInstantiate(t *testing.T) {
|
||||
data := setupTest(t)
|
||||
creator := data.faucet.NewFundedAccount(data.ctx, sdk.NewInt64Coin("denom", 100000))
|
||||
creator := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len))
|
||||
data.faucet.Fund(data.ctx, creator, sdk.NewInt64Coin("denom", 100000))
|
||||
|
||||
h := data.module.Route().Handler()
|
||||
q := data.module.LegacyQuerierHandler(nil)
|
||||
|
@ -179,7 +183,7 @@ func TestHandleInstantiate(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
contractBech32Addr := parseInitResponse(t, res.Data)
|
||||
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr", contractBech32Addr)
|
||||
require.Equal(t, "cosmos1400ax8h2dxe8ch64sus5sczqdhwv28hpjkkaphpa83he4fhz6k4qcm9kul", contractBech32Addr)
|
||||
// this should be standard x/wasm init event, nothing from contract
|
||||
require.Equal(t, 3, len(res.Events), prettyEvents(res.Events))
|
||||
require.Equal(t, "message", res.Events[0].Type)
|
||||
|
@ -206,8 +210,10 @@ func TestHandleExecute(t *testing.T) {
|
|||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
|
||||
creator := data.faucet.NewFundedAccount(data.ctx, deposit.Add(deposit...)...)
|
||||
fred := data.faucet.NewFundedAccount(data.ctx, topUp...)
|
||||
creator := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len))
|
||||
data.faucet.Fund(data.ctx, creator, sdk.NewInt64Coin("denom", 100000*2))
|
||||
|
||||
fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...)
|
||||
|
||||
h := data.module.Route().Handler()
|
||||
q := data.module.LegacyQuerierHandler(nil)
|
||||
|
@ -238,7 +244,7 @@ func TestHandleExecute(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
contractBech32Addr := parseInitResponse(t, res.Data)
|
||||
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr", contractBech32Addr)
|
||||
require.Equal(t, "cosmos1400ax8h2dxe8ch64sus5sczqdhwv28hpjkkaphpa83he4fhz6k4qcm9kul", contractBech32Addr)
|
||||
// this should be standard x/wasm message event, init event, plus a bank send event (2), with no custom contract events
|
||||
require.Equal(t, 6, len(res.Events), prettyEvents(res.Events))
|
||||
require.Equal(t, "message", res.Events[0].Type)
|
||||
|
@ -341,8 +347,9 @@ func TestHandleExecuteEscrow(t *testing.T) {
|
|||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
||||
creator := data.faucet.NewFundedAccount(data.ctx, deposit.Add(deposit...)...)
|
||||
fred := data.faucet.NewFundedAccount(data.ctx, topUp...)
|
||||
creator := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len))
|
||||
data.faucet.Fund(data.ctx, creator, sdk.NewInt64Coin("denom", 100000))
|
||||
fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...)
|
||||
|
||||
h := data.module.Route().Handler()
|
||||
|
||||
|
@ -370,7 +377,7 @@ func TestHandleExecuteEscrow(t *testing.T) {
|
|||
res, err = h(data.ctx, &initCmd)
|
||||
require.NoError(t, err)
|
||||
contractBech32Addr := parseInitResponse(t, res.Data)
|
||||
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr", contractBech32Addr)
|
||||
require.Equal(t, "cosmos1400ax8h2dxe8ch64sus5sczqdhwv28hpjkkaphpa83he4fhz6k4qcm9kul", contractBech32Addr)
|
||||
|
||||
handleMsg := map[string]interface{}{
|
||||
"release": map[string]interface{}{},
|
||||
|
|
|
@ -15,7 +15,6 @@ func RandomizedGenState(simstate *module.SimulationState) {
|
|||
Contracts: nil,
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: simstate.Rand.Uint64()},
|
||||
{IDKey: types.KeyLastInstanceID, Value: simstate.Rand.Uint64()},
|
||||
},
|
||||
GenMsgs: nil,
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ const (
|
|||
|
||||
AttributeKeyContractAddr = "_contract_address"
|
||||
AttributeKeyCodeID = "code_id"
|
||||
AttributeKeyChecksum = "code_checksum"
|
||||
AttributeKeyResultDataHex = "result"
|
||||
AttributeKeyRequiredCapability = "required_capability"
|
||||
)
|
||||
|
|
|
@ -26,7 +26,7 @@ type ViewKeeper interface {
|
|||
// ContractOpsKeeper contains mutable operations on a contract.
|
||||
type ContractOpsKeeper interface {
|
||||
// Create uploads and compiles a WASM contract, returning a short identifier for the contract
|
||||
Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *AccessConfig) (codeID uint64, err error)
|
||||
Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *AccessConfig) (codeID uint64, checksum []byte, err error)
|
||||
|
||||
// Instantiate creates an instance of a WASM contract
|
||||
Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins) (sdk.AccAddress, []byte, error)
|
||||
|
|
|
@ -32,8 +32,7 @@ var (
|
|||
PinnedCodeIndexPrefix = []byte{0x07}
|
||||
TXCounterPrefix = []byte{0x08}
|
||||
|
||||
KeyLastCodeID = append(SequenceKeyPrefix, []byte("lastCodeId")...)
|
||||
KeyLastInstanceID = append(SequenceKeyPrefix, []byte("lastContractId")...)
|
||||
KeyLastCodeID = append(SequenceKeyPrefix, []byte("lastCodeId")...)
|
||||
)
|
||||
|
||||
// GetCodeKey constructs the key for retreiving the ID for the WASM code
|
||||
|
|
|
@ -170,7 +170,7 @@ func (p InstantiateContractProposal) ValidateBasic() error {
|
|||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "code id is required")
|
||||
}
|
||||
|
||||
if err := validateLabel(p.Label); err != nil {
|
||||
if err := ValidateLabel(p.Label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ func (msg MsgInstantiateContract) ValidateBasic() error {
|
|||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "code id is required")
|
||||
}
|
||||
|
||||
if err := validateLabel(msg.Label); err != nil {
|
||||
if err := ValidateLabel(msg.Label); err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "label is required")
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,8 @@ var xxx_messageInfo_MsgStoreCode proto.InternalMessageInfo
|
|||
type MsgStoreCodeResponse struct {
|
||||
// CodeID is the reference to the stored WASM code
|
||||
CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"`
|
||||
// Checksum is the sha256 hash of the stored code
|
||||
Checksum []byte `protobuf:"bytes,2,opt,name=checksum,proto3" json:"checksum,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MsgStoreCodeResponse) Reset() { *m = MsgStoreCodeResponse{} }
|
||||
|
@ -611,55 +613,55 @@ func init() {
|
|||
func init() { proto.RegisterFile("cosmwasm/wasm/v1/tx.proto", fileDescriptor_4f74d82755520264) }
|
||||
|
||||
var fileDescriptor_4f74d82755520264 = []byte{
|
||||
// 759 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0xd3, 0x4a,
|
||||
0x14, 0x8e, 0x1b, 0x27, 0x4d, 0x4e, 0x73, 0x7b, 0x23, 0xdf, 0x36, 0x37, 0xf5, 0xbd, 0x72, 0xa2,
|
||||
0x80, 0x8a, 0x17, 0x60, 0x37, 0x45, 0x62, 0xc3, 0xaa, 0x49, 0x59, 0xb4, 0x92, 0x11, 0x72, 0x55,
|
||||
0x2a, 0xd8, 0x44, 0x13, 0x7b, 0x6a, 0x2c, 0x1a, 0x4f, 0xf0, 0x71, 0x9b, 0xf6, 0x25, 0x10, 0x3b,
|
||||
0xde, 0x81, 0xb7, 0x60, 0xd7, 0x15, 0xea, 0x06, 0x89, 0x55, 0x80, 0xf4, 0x2d, 0x58, 0x21, 0xff,
|
||||
0xa5, 0x6e, 0xea, 0xa4, 0x41, 0x88, 0x4d, 0x32, 0xc7, 0xf3, 0x7d, 0xe7, 0xcc, 0xf9, 0xf4, 0xcd,
|
||||
0x19, 0x58, 0x33, 0x18, 0xf6, 0x06, 0x04, 0x7b, 0x6a, 0xf0, 0x73, 0xd2, 0x54, 0xbd, 0x53, 0xa5,
|
||||
0xef, 0x32, 0x8f, 0x09, 0xe5, 0x78, 0x4b, 0x09, 0x7e, 0x4e, 0x9a, 0xa2, 0xe4, 0x7f, 0x61, 0xa8,
|
||||
0x76, 0x09, 0x52, 0xf5, 0xa4, 0xd9, 0xa5, 0x1e, 0x69, 0xaa, 0x06, 0xb3, 0x9d, 0x90, 0x21, 0xae,
|
||||
0x58, 0xcc, 0x62, 0xc1, 0x52, 0xf5, 0x57, 0xd1, 0xd7, 0xff, 0x6f, 0x96, 0x38, 0xeb, 0x53, 0x0c,
|
||||
0x77, 0x1b, 0x1f, 0x39, 0x28, 0x69, 0x68, 0xed, 0x79, 0xcc, 0xa5, 0x6d, 0x66, 0x52, 0xa1, 0x02,
|
||||
0x79, 0xa4, 0x8e, 0x49, 0xdd, 0x2a, 0x57, 0xe7, 0xe4, 0xa2, 0x1e, 0x45, 0xc2, 0x23, 0x58, 0xf6,
|
||||
0xf9, 0x9d, 0xee, 0x99, 0x47, 0x3b, 0x06, 0x33, 0x69, 0x75, 0xa1, 0xce, 0xc9, 0xa5, 0x56, 0x79,
|
||||
0x34, 0xac, 0x95, 0x0e, 0xb6, 0xf6, 0xb4, 0xd6, 0x99, 0x17, 0x64, 0xd0, 0x4b, 0x3e, 0x2e, 0x8e,
|
||||
0x84, 0x7d, 0xa8, 0xd8, 0x0e, 0x7a, 0xc4, 0xf1, 0x6c, 0xe2, 0xd1, 0x4e, 0x9f, 0xba, 0x3d, 0x1b,
|
||||
0xd1, 0x66, 0x4e, 0x35, 0x57, 0xe7, 0xe4, 0xa5, 0x4d, 0x49, 0x99, 0xec, 0x53, 0xd9, 0x32, 0x0c,
|
||||
0x8a, 0xd8, 0x66, 0xce, 0xa1, 0x6d, 0xe9, 0xab, 0x09, 0xf6, 0xb3, 0x31, 0x79, 0x97, 0x2f, 0x64,
|
||||
0xcb, 0xfc, 0x2e, 0x5f, 0xe0, 0xcb, 0xb9, 0xc6, 0x63, 0x58, 0x49, 0xb6, 0xa0, 0x53, 0xec, 0x33,
|
||||
0x07, 0xa9, 0x70, 0x07, 0x16, 0xfd, 0x83, 0x76, 0x6c, 0x33, 0xe8, 0x85, 0x6f, 0xc1, 0x68, 0x58,
|
||||
0xcb, 0xfb, 0x90, 0x9d, 0x6d, 0x3d, 0xef, 0x6f, 0xed, 0x98, 0x8d, 0xb7, 0x0b, 0x50, 0xd1, 0xd0,
|
||||
0xda, 0xb9, 0xaa, 0xd2, 0x66, 0x8e, 0xe7, 0x12, 0xc3, 0x9b, 0x2a, 0xc5, 0x0a, 0xe4, 0x88, 0xd9,
|
||||
0xb3, 0x9d, 0x40, 0x81, 0xa2, 0x1e, 0x06, 0xc9, 0x6a, 0xd9, 0x69, 0xd5, 0x7c, 0xea, 0x11, 0xe9,
|
||||
0xd2, 0xa3, 0x2a, 0x1f, 0x52, 0x83, 0x40, 0x90, 0x21, 0xdb, 0x43, 0x2b, 0x10, 0xa4, 0xd4, 0xaa,
|
||||
0xfc, 0x18, 0xd6, 0x04, 0x9d, 0x0c, 0xe2, 0x63, 0x68, 0x14, 0x91, 0x58, 0x54, 0xf7, 0x21, 0x02,
|
||||
0x81, 0xdc, 0xe1, 0xb1, 0x63, 0x62, 0x35, 0x5f, 0xcf, 0xca, 0x4b, 0x9b, 0x6b, 0x4a, 0x68, 0x09,
|
||||
0xc5, 0xb7, 0x84, 0x12, 0x59, 0x42, 0x69, 0x33, 0xdb, 0x69, 0x6d, 0x9c, 0x0f, 0x6b, 0x99, 0x0f,
|
||||
0x5f, 0x6b, 0xb2, 0x65, 0x7b, 0xaf, 0x8e, 0xbb, 0x8a, 0xc1, 0x7a, 0x6a, 0xe4, 0x9f, 0xf0, 0xef,
|
||||
0x01, 0x9a, 0xaf, 0x23, 0x2b, 0xf8, 0x04, 0xd4, 0xc3, 0xcc, 0x8d, 0xa7, 0x20, 0xa5, 0xeb, 0x31,
|
||||
0xd6, 0xb5, 0x0a, 0x8b, 0xc4, 0x34, 0x5d, 0x8a, 0x18, 0x09, 0x13, 0x87, 0x82, 0x00, 0xbc, 0x49,
|
||||
0x3c, 0x12, 0x5a, 0x43, 0x0f, 0xd6, 0x8d, 0xcf, 0x1c, 0x08, 0x1a, 0x5a, 0x4f, 0x4e, 0xa9, 0x71,
|
||||
0x3c, 0x87, 0xb8, 0x22, 0x14, 0x8c, 0x08, 0x13, 0xe9, 0x3b, 0x8e, 0x63, 0x9d, 0xb2, 0xbf, 0xa0,
|
||||
0x53, 0xee, 0x8f, 0xe9, 0xb4, 0x01, 0xe2, 0xcd, 0xb6, 0xc6, 0x1a, 0xc5, 0x4a, 0x70, 0x09, 0x25,
|
||||
0xde, 0x87, 0x4a, 0x68, 0xb6, 0xe5, 0x92, 0xdf, 0x54, 0x62, 0x2e, 0xb3, 0x45, 0x72, 0xf1, 0xb7,
|
||||
0xca, 0x15, 0xf5, 0x32, 0x71, 0xb0, 0x99, 0xbd, 0x10, 0x58, 0xd6, 0xd0, 0xda, 0xef, 0x9b, 0xc4,
|
||||
0xa3, 0x5b, 0x81, 0xff, 0xa7, 0xb5, 0xf1, 0x1f, 0x14, 0x1d, 0x3a, 0xe8, 0x24, 0x6f, 0x4c, 0xc1,
|
||||
0xa1, 0x83, 0x90, 0x94, 0xec, 0x31, 0x7b, 0xbd, 0xc7, 0x46, 0x35, 0xb8, 0x98, 0x89, 0x12, 0xf1,
|
||||
0x81, 0x1a, 0x6d, 0xf8, 0x4b, 0x43, 0xab, 0x7d, 0x44, 0x89, 0x3b, 0xbb, 0xf6, 0xac, 0xf4, 0xff,
|
||||
0xc2, 0xea, 0xb5, 0x24, 0x71, 0xf6, 0xcd, 0x4f, 0x3c, 0x64, 0x35, 0xb4, 0x84, 0x3d, 0x28, 0x5e,
|
||||
0x8d, 0xc5, 0x94, 0x31, 0x95, 0x9c, 0x39, 0xe2, 0xfa, 0xec, 0xfd, 0xb1, 0x96, 0x6f, 0xe0, 0x9f,
|
||||
0xb4, 0x51, 0x23, 0xa7, 0xd2, 0x53, 0x90, 0xe2, 0xc6, 0xbc, 0xc8, 0x71, 0x49, 0x0a, 0x7f, 0x4f,
|
||||
0x5e, 0xbe, 0xbb, 0xa9, 0x49, 0x26, 0x50, 0xe2, 0xfd, 0x79, 0x50, 0xc9, 0x32, 0x93, 0xce, 0x4e,
|
||||
0x2f, 0x33, 0x81, 0x9a, 0x52, 0x66, 0x9a, 0x19, 0x5f, 0xc0, 0x52, 0xd2, 0x75, 0xf5, 0x54, 0x72,
|
||||
0x02, 0x21, 0xca, 0xb7, 0x21, 0xc6, 0xa9, 0x9f, 0x03, 0x24, 0x3c, 0x55, 0x4b, 0xe5, 0x5d, 0x01,
|
||||
0xc4, 0x7b, 0xb7, 0x00, 0xe2, 0xbc, 0xad, 0xed, 0xf3, 0xef, 0x52, 0xe6, 0x7c, 0x24, 0x71, 0x17,
|
||||
0x23, 0x89, 0xfb, 0x36, 0x92, 0xb8, 0x77, 0x97, 0x52, 0xe6, 0xe2, 0x52, 0xca, 0x7c, 0xb9, 0x94,
|
||||
0x32, 0x2f, 0xd7, 0x13, 0x83, 0xa7, 0xcd, 0xb0, 0x77, 0x10, 0x3f, 0xd5, 0xa6, 0x7a, 0x1a, 0x3e,
|
||||
0xd9, 0xc1, 0xf0, 0xe9, 0xe6, 0x83, 0x07, 0xfb, 0xe1, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x56,
|
||||
0xd2, 0x4b, 0x17, 0x33, 0x08, 0x00, 0x00,
|
||||
// 766 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcb, 0x6e, 0xd3, 0x40,
|
||||
0x14, 0x8d, 0x1b, 0x27, 0x4d, 0x6e, 0x43, 0x89, 0x4c, 0x1a, 0x52, 0x83, 0x9c, 0x28, 0xa0, 0xe2,
|
||||
0x05, 0xd8, 0x4d, 0x91, 0xd8, 0x37, 0x29, 0x8b, 0x56, 0x32, 0x42, 0xae, 0x4a, 0x05, 0x9b, 0x68,
|
||||
0x62, 0x4f, 0x5d, 0xab, 0xb5, 0x27, 0x78, 0x9c, 0xa6, 0xfd, 0x09, 0xc4, 0x8e, 0x7f, 0xe0, 0x2f,
|
||||
0xd8, 0x75, 0x85, 0xba, 0x41, 0x62, 0x15, 0x20, 0xfd, 0x0b, 0x56, 0xc8, 0xcf, 0xba, 0xa9, 0x93,
|
||||
0x06, 0x21, 0x36, 0xce, 0xdc, 0x99, 0x73, 0x5f, 0x27, 0x67, 0xee, 0xc0, 0xaa, 0x46, 0xa8, 0x35,
|
||||
0x44, 0xd4, 0x92, 0xfd, 0xcf, 0x49, 0x4b, 0x76, 0x4f, 0xa5, 0xbe, 0x43, 0x5c, 0xc2, 0x95, 0xa3,
|
||||
0x23, 0xc9, 0xff, 0x9c, 0xb4, 0x78, 0xc1, 0xdb, 0x21, 0x54, 0xee, 0x21, 0x8a, 0xe5, 0x93, 0x56,
|
||||
0x0f, 0xbb, 0xa8, 0x25, 0x6b, 0xc4, 0xb4, 0x03, 0x0f, 0xbe, 0x62, 0x10, 0x83, 0xf8, 0x4b, 0xd9,
|
||||
0x5b, 0x85, 0xbb, 0x0f, 0x6f, 0xa6, 0x38, 0xeb, 0x63, 0x1a, 0x9c, 0x36, 0xbf, 0x30, 0x50, 0x52,
|
||||
0xa8, 0xb1, 0xeb, 0x12, 0x07, 0x77, 0x88, 0x8e, 0xb9, 0x2a, 0xe4, 0x29, 0xb6, 0x75, 0xec, 0xd4,
|
||||
0x98, 0x06, 0x23, 0x16, 0xd5, 0xd0, 0xe2, 0x5e, 0xc0, 0xb2, 0xe7, 0xdf, 0xed, 0x9d, 0xb9, 0xb8,
|
||||
0xab, 0x11, 0x1d, 0xd7, 0x16, 0x1a, 0x8c, 0x58, 0x6a, 0x97, 0xc7, 0xa3, 0x7a, 0x69, 0x7f, 0x73,
|
||||
0x57, 0x69, 0x9f, 0xb9, 0x7e, 0x04, 0xb5, 0xe4, 0xe1, 0x22, 0x8b, 0xdb, 0x83, 0xaa, 0x69, 0x53,
|
||||
0x17, 0xd9, 0xae, 0x89, 0x5c, 0xdc, 0xed, 0x63, 0xc7, 0x32, 0x29, 0x35, 0x89, 0x5d, 0xcb, 0x35,
|
||||
0x18, 0x71, 0x69, 0x43, 0x90, 0x26, 0xfb, 0x94, 0x36, 0x35, 0x0d, 0x53, 0xda, 0x21, 0xf6, 0x81,
|
||||
0x69, 0xa8, 0x2b, 0x09, 0xef, 0xd7, 0xb1, 0xf3, 0x0e, 0x5b, 0xc8, 0x96, 0xd9, 0x1d, 0xb6, 0xc0,
|
||||
0x96, 0x73, 0xcd, 0x7d, 0xa8, 0x24, 0x5b, 0x50, 0x31, 0xed, 0x13, 0x9b, 0x62, 0xee, 0x11, 0x2c,
|
||||
0x7a, 0x85, 0x76, 0x4d, 0xdd, 0xef, 0x85, 0x6d, 0xc3, 0x78, 0x54, 0xcf, 0x7b, 0x90, 0xed, 0x2d,
|
||||
0x35, 0xef, 0x1d, 0x6d, 0xeb, 0x1c, 0x0f, 0x05, 0xed, 0x10, 0x6b, 0x47, 0x74, 0x60, 0x05, 0x1d,
|
||||
0xa9, 0xb1, 0xdd, 0xfc, 0xb0, 0x00, 0x55, 0x85, 0x1a, 0xdb, 0x57, 0x15, 0x74, 0x88, 0xed, 0x3a,
|
||||
0x48, 0x73, 0xa7, 0xd2, 0x54, 0x81, 0x1c, 0xd2, 0x2d, 0xd3, 0xf6, 0x63, 0x15, 0xd5, 0xc0, 0x48,
|
||||
0x56, 0x92, 0x9d, 0x5a, 0x49, 0x05, 0x72, 0xc7, 0xa8, 0x87, 0x8f, 0x6b, 0x6c, 0xe0, 0xea, 0x1b,
|
||||
0x9c, 0x08, 0x59, 0x8b, 0x1a, 0x3e, 0x59, 0xa5, 0x76, 0xf5, 0xf7, 0xa8, 0xce, 0xa9, 0x68, 0x18,
|
||||
0x95, 0xa1, 0x60, 0x4a, 0x91, 0x81, 0x55, 0x0f, 0xc2, 0x21, 0xc8, 0x1d, 0x0c, 0x6c, 0x9d, 0xd6,
|
||||
0xf2, 0x8d, 0xac, 0xb8, 0xb4, 0xb1, 0x2a, 0x05, 0x72, 0x91, 0x3c, 0xb9, 0x48, 0xa1, 0x5c, 0xa4,
|
||||
0x0e, 0x31, 0xed, 0xf6, 0xfa, 0xf9, 0xa8, 0x9e, 0xf9, 0xfc, 0xa3, 0x2e, 0x1a, 0xa6, 0x7b, 0x38,
|
||||
0xe8, 0x49, 0x1a, 0xb1, 0xe4, 0x50, 0x5b, 0xc1, 0xcf, 0x33, 0xaa, 0x1f, 0x85, 0x32, 0xf1, 0x1c,
|
||||
0xa8, 0x1a, 0x44, 0x6e, 0xbe, 0x02, 0x21, 0x9d, 0x8f, 0x98, 0xf3, 0x1a, 0x2c, 0x22, 0x5d, 0x77,
|
||||
0x30, 0xa5, 0x21, 0x31, 0x91, 0xc9, 0x71, 0xc0, 0xea, 0xc8, 0x45, 0x21, 0xc9, 0xfe, 0xba, 0xf9,
|
||||
0x8d, 0x01, 0x4e, 0xa1, 0xc6, 0xcb, 0x53, 0xac, 0x0d, 0xe6, 0x20, 0xd7, 0xfb, 0xaf, 0x42, 0x4c,
|
||||
0xc8, 0x6f, 0x6c, 0x47, 0x3c, 0x65, 0xff, 0x82, 0xa7, 0xdc, 0x7f, 0xe3, 0x69, 0x1d, 0xf8, 0x9b,
|
||||
0x6d, 0xc5, 0x1c, 0x45, 0x4c, 0x30, 0x09, 0x26, 0x3e, 0x05, 0x4c, 0x28, 0xa6, 0xe1, 0xa0, 0x7f,
|
||||
0x64, 0x62, 0x2e, 0xb1, 0x85, 0x74, 0xb1, 0xb7, 0xd2, 0x15, 0xf6, 0x32, 0x51, 0xd8, 0xcc, 0x5e,
|
||||
0x10, 0x2c, 0x2b, 0xd4, 0xd8, 0xeb, 0xeb, 0xc8, 0xc5, 0x9b, 0xbe, 0xfe, 0xa7, 0xb5, 0xf1, 0x00,
|
||||
0x8a, 0x36, 0x1e, 0x76, 0x93, 0x37, 0xa6, 0x60, 0xe3, 0x61, 0xe0, 0x94, 0xec, 0x31, 0x7b, 0xbd,
|
||||
0xc7, 0x66, 0xcd, 0xbf, 0x98, 0x89, 0x14, 0x51, 0x41, 0xcd, 0x0e, 0xdc, 0x51, 0xa8, 0xd1, 0x39,
|
||||
0xc6, 0xc8, 0x99, 0x9d, 0x7b, 0x56, 0xf8, 0xfb, 0xb0, 0x72, 0x2d, 0x48, 0x14, 0x7d, 0xe3, 0x2b,
|
||||
0x0b, 0x59, 0x85, 0x1a, 0xdc, 0x2e, 0x14, 0xaf, 0x46, 0x66, 0xca, 0x08, 0x4b, 0xce, 0x23, 0x7e,
|
||||
0x6d, 0xf6, 0x79, 0xcc, 0xe5, 0x7b, 0xb8, 0x97, 0x36, 0x6a, 0xc4, 0x54, 0xf7, 0x14, 0x24, 0xbf,
|
||||
0x3e, 0x2f, 0x32, 0x4e, 0x89, 0xe1, 0xee, 0xe4, 0xe5, 0x7b, 0x9c, 0x1a, 0x64, 0x02, 0xc5, 0x3f,
|
||||
0x9d, 0x07, 0x95, 0x4c, 0x33, 0xa9, 0xec, 0xf4, 0x34, 0x13, 0xa8, 0x29, 0x69, 0xa6, 0x89, 0xf1,
|
||||
0x2d, 0x2c, 0x25, 0x55, 0xd7, 0x48, 0x75, 0x4e, 0x20, 0x78, 0xf1, 0x36, 0x44, 0x1c, 0xfa, 0x0d,
|
||||
0x40, 0x42, 0x53, 0xf5, 0x54, 0xbf, 0x2b, 0x00, 0xff, 0xe4, 0x16, 0x40, 0x14, 0xb7, 0xbd, 0x75,
|
||||
0xfe, 0x4b, 0xc8, 0x9c, 0x8f, 0x05, 0xe6, 0x62, 0x2c, 0x30, 0x3f, 0xc7, 0x02, 0xf3, 0xf1, 0x52,
|
||||
0xc8, 0x5c, 0x5c, 0x0a, 0x99, 0xef, 0x97, 0x42, 0xe6, 0xdd, 0x5a, 0x62, 0xf0, 0x74, 0x08, 0xb5,
|
||||
0xf6, 0xa3, 0x67, 0x5c, 0x97, 0x4f, 0x83, 0xe7, 0xdc, 0x1f, 0x3e, 0xbd, 0xbc, 0xff, 0x98, 0x3f,
|
||||
0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xef, 0x6b, 0xa0, 0xa3, 0x4f, 0x08, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -1007,6 +1009,13 @@ func (m *MsgStoreCodeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Checksum) > 0 {
|
||||
i -= len(m.Checksum)
|
||||
copy(dAtA[i:], m.Checksum)
|
||||
i = encodeVarintTx(dAtA, i, uint64(len(m.Checksum)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if m.CodeID != 0 {
|
||||
i = encodeVarintTx(dAtA, i, uint64(m.CodeID))
|
||||
i--
|
||||
|
@ -1458,6 +1467,10 @@ func (m *MsgStoreCodeResponse) Size() (n int) {
|
|||
if m.CodeID != 0 {
|
||||
n += 1 + sovTx(uint64(m.CodeID))
|
||||
}
|
||||
l = len(m.Checksum)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -1854,6 +1867,40 @@ func (m *MsgStoreCodeResponse) Unmarshal(dAtA []byte) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Checksum", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTx
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Checksum = append(m.Checksum[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Checksum == nil {
|
||||
m.Checksum = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipTx(dAtA[iNdEx:])
|
||||
|
|
|
@ -84,6 +84,7 @@ func TestInstantiateContractValidation(t *testing.T) {
|
|||
badAddress := bad.String()
|
||||
// proper address size
|
||||
goodAddress := sdk.AccAddress(make([]byte, 20)).String()
|
||||
sdk.GetConfig().SetAddressVerifier(VerifyAddressLen())
|
||||
|
||||
cases := map[string]struct {
|
||||
msg MsgInstantiateContract
|
||||
|
|
|
@ -88,7 +88,7 @@ func (c *ContractInfo) ValidateBasic() error {
|
|||
return sdkerrors.Wrap(err, "admin")
|
||||
}
|
||||
}
|
||||
if err := validateLabel(c.Label); err != nil {
|
||||
if err := ValidateLabel(c.Label); err != nil {
|
||||
return sdkerrors.Wrap(err, "label")
|
||||
}
|
||||
if c.Extension == nil {
|
||||
|
|
|
@ -22,7 +22,8 @@ func validateWasmCode(s []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateLabel(label string) error {
|
||||
// ValidateLabel ensure label constraints
|
||||
func ValidateLabel(label string) error {
|
||||
if label == "" {
|
||||
return sdkerrors.Wrap(ErrEmpty, "is required")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue