Skip to content

Commit

Permalink
Add factory contract scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
alpe committed Sep 14, 2022
1 parent 8fc9855 commit 6369a5f
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions x/wasm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"os"
"strings"
"testing"
"time"

"github.com/cosmos/cosmos-sdk/baseapp"

wasmvm "github.com/CosmWasm/wasmvm"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
Expand Down Expand Up @@ -755,6 +758,82 @@ func TestInstantiateWithContractDataResponse(t *testing.T) {
assert.Equal(t, []byte("my-response-data"), data)
}

func TestInstantiateWithContractFactoryChildQueriesParent(t *testing.T) {
// Scenario:
// given a factory contract stored
// when instantiated, the contract creates a new child contract instance
// and the child contracts queries the factory contract's codeInfo on instantiation
// then the factory contract's codeInfo should be returned to the child contract
//
// see also: https://github.com/CosmWasm/wasmd/issues/896
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
keeper := keepers.WasmKeeper

var instantiationCount int
callbacks := make([]func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error), 2)
wasmerMock := &wasmtesting.MockWasmer{
// dispatch instantiation calls to callbacks
InstantiateFn: func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
require.Greater(t, len(callbacks), instantiationCount, "unexpected call to instantiation")
do := callbacks[instantiationCount]
instantiationCount++
return do(codeID, env, info, initMsg, store, goapi, querier, gasMeter, gasLimit, deserCost)
},
AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn,
CreateFn: wasmtesting.NoOpCreateFn,
}

// overwrite wasmvm in router
router := baseapp.NewMsgServiceRouter()
router.SetInterfaceRegistry(keepers.EncodingConfig.InterfaceRegistry)
types.RegisterMsgServer(router, NewMsgServerImpl(NewDefaultPermissionKeeper(keeper)))
keeper.messenger = NewDefaultMessageHandler(router, nil, nil, nil, keepers.EncodingConfig.Marshaler, nil)
// overwrite wasmvm in response handler
keeper.wasmVMResponseHandler = NewDefaultWasmVMContractResponseHandler(NewMessageDispatcher(keeper.messenger, keeper))

example := StoreRandomContract(t, ctx, keepers, wasmerMock)
// factory contract
callbacks[0] = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
t.Log("called factory")
return &wasmvmtypes.Response{Data: []byte("parent"), Messages: []wasmvmtypes.SubMsg{
{
ID: 1, ReplyOn: wasmvmtypes.ReplyNever,
Msg: wasmvmtypes.CosmosMsg{
Wasm: &wasmvmtypes.WasmMsg{
Instantiate: &wasmvmtypes.InstantiateMsg{CodeID: example.CodeID, Msg: []byte(`{}`), Label: "child"},
},
},
},
}}, 0, nil
}

// child contract
var capturedSenderAddr string
var capturedCodeInfo []byte
callbacks[1] = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
t.Log("called child")
capturedSenderAddr = info.Sender
var err error
capturedCodeInfo, err = querier.Query(wasmvmtypes.QueryRequest{
Wasm: &wasmvmtypes.WasmQuery{
ContractInfo: &wasmvmtypes.ContractInfoQuery{ContractAddr: info.Sender},
},
}, gasLimit)
require.NoError(t, err)
return &wasmvmtypes.Response{Data: []byte("child")}, 0, nil
}

// when
parentAddr, data, err := keepers.ContractKeeper.Instantiate(ctx, example.CodeID, example.CreatorAddr, nil, nil, "test", nil)

// then
require.NoError(t, err)
assert.Equal(t, []byte("parent"), data)
require.Equal(t, parentAddr.String(), capturedSenderAddr)
expCodeInfo := fmt.Sprintf(`{"code_id":%d,"creator":%q,"pinned":false}`, example.CodeID, example.CreatorAddr.String())
assert.JSONEq(t, expCodeInfo, string(capturedCodeInfo))
}

func TestExecute(t *testing.T) {
ctx, keepers := CreateTestInput(t, false, AvailableCapabilities)
accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.ContractKeeper, keepers.BankKeeper
Expand Down

0 comments on commit 6369a5f

Please sign in to comment.