Make contract addresses predictable
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user