Allow configuring custom message handlers in wasm

This commit is contained in:
Ethan Frey
2020-05-07 10:20:18 +02:00
parent f727cb4aff
commit 7b7a293835
9 changed files with 60 additions and 30 deletions

View File

@@ -224,7 +224,8 @@ func NewWasmApp(
}
wasmConfig := wasmWrap.Wasm
app.wasmKeeper = wasm.NewKeeper(app.cdc, keys[wasm.StoreKey], app.accountKeeper, app.bankKeeper, wasmRouter, wasmDir, wasmConfig)
// The last argument can contain custom message handlers, if we want to allow any custom messages
app.wasmKeeper = wasm.NewKeeper(app.cdc, keys[wasm.StoreKey], app.accountKeeper, app.bankKeeper, wasmRouter, wasmDir, wasmConfig, nil)
// create evidence keeper with evidence router
evidenceKeeper := evidence.NewKeeper(

View File

@@ -16,6 +16,14 @@ type MessageHandler struct {
encoders MessageEncoders
}
func NewMessageHandler(router sdk.Router, customEncoders MessageEncoders) MessageHandler {
encoders := DefaultEncoders().Merge(customEncoders)
return MessageHandler{
router: router,
encoders: encoders,
}
}
type MessageEncoders struct {
Bank func(sender sdk.AccAddress, msg *wasmTypes.BankMsg) (sdk.Msg, error)
Custom func(sender sdk.AccAddress, msg json.RawMessage) (sdk.Msg, error)
@@ -32,6 +40,22 @@ func DefaultEncoders() MessageEncoders {
}
}
func (e MessageEncoders) Merge(o MessageEncoders) MessageEncoders {
if o.Bank != nil {
e.Bank = o.Bank
}
if o.Custom != nil {
e.Custom = o.Custom
}
if o.Staking != nil {
e.Staking = o.Staking
}
if o.Wasm != nil {
e.Wasm = o.Wasm
}
return e
}
func EncodeBankMsg(sender sdk.AccAddress, msg *wasmTypes.BankMsg) (sdk.Msg, error) {
if msg.Send == nil {
return nil, sdkerrors.Wrap(types.ErrInvalidMsg, "Unknown variant of Bank")

View File

@@ -33,8 +33,6 @@ type Keeper struct {
accountKeeper auth.AccountKeeper
bankKeeper bank.Keeper
router sdk.Router
wasmer wasm.Wasmer
queryMods QueryModules
messenger MessageHandler
@@ -43,20 +41,20 @@ type Keeper struct {
}
// NewKeeper creates a new contract Keeper instance
// If customEncoders is non-nil, we can use this to override some of the message handler, especially custom
func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, accountKeeper auth.AccountKeeper, bankKeeper bank.Keeper,
router sdk.Router, homeDir string, wasmConfig types.WasmConfig) Keeper {
router sdk.Router, homeDir string, wasmConfig types.WasmConfig, customEncoders *MessageEncoders) Keeper {
wasmer, err := wasm.NewWasmer(filepath.Join(homeDir, "wasm"), wasmConfig.CacheSize)
if err != nil {
panic(err)
}
messenger := MessageHandler{
router: router,
encoders: DefaultEncoders(),
}
queryMods := QueryModules{
Bank: bankKeeper,
if customEncoders == nil {
customEncoders = &MessageEncoders{}
}
messenger := NewMessageHandler(router, *customEncoders)
// TODO: make this configurable also
queryMods := DefaultQueryModules(bankKeeper)
return Keeper{
storeKey: storeKey,

View File

@@ -23,7 +23,7 @@ func TestNewKeeper(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
_, _, keeper := CreateTestInput(t, false, tempDir)
_, _, keeper := CreateTestInput(t, false, tempDir, nil)
require.NotNil(t, keeper)
}
@@ -31,7 +31,7 @@ func TestCreate(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
@@ -52,7 +52,7 @@ func TestCreateDuplicate(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
@@ -83,7 +83,7 @@ func TestCreateWithSimulation(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
ctx = ctx.WithBlockHeader(abci.Header{Height: 1}).
WithGasMeter(stypes.NewInfiniteGasMeter())
@@ -99,7 +99,7 @@ func TestCreateWithSimulation(t *testing.T) {
require.Equal(t, uint64(1), contractID)
// then try to create it in non-simulation mode (should not fail)
ctx, accKeeper, keeper = CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper = CreateTestInput(t, false, tempDir, nil)
contractID, err = keeper.Create(ctx, creator, wasmCode, "https://github.com/cosmwasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "confio/cosmwasm-opt:0.7.2")
require.NoError(t, err)
require.Equal(t, uint64(1), contractID)
@@ -139,7 +139,7 @@ func TestCreateWithGzippedPayload(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
@@ -162,7 +162,7 @@ func TestInstantiate(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
@@ -206,7 +206,7 @@ func TestInstantiateWithNonExistingCodeID(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
@@ -227,7 +227,7 @@ func TestExecute(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
@@ -304,7 +304,7 @@ func TestExecuteWithNonExistingAddress(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
@@ -319,7 +319,7 @@ func TestExecuteWithPanic(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
@@ -352,7 +352,7 @@ func TestExecuteWithCpuLoop(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
@@ -395,7 +395,7 @@ func TestExecuteWithStorageLoop(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))

View File

@@ -39,7 +39,7 @@ func TestMaskReflectCustom(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
@@ -170,7 +170,7 @@ func TestMaskReflectContractSend(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)

View File

@@ -19,7 +19,7 @@ func TestQueryContractState(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
@@ -147,7 +147,7 @@ func TestListContractByCodeOrdering(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000000))
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 500))

View File

@@ -21,6 +21,12 @@ type QueryModules struct {
Bank bank.ViewKeeper
}
func DefaultQueryModules(bank bank.ViewKeeper) QueryModules {
return QueryModules{
Bank: bank,
}
}
//type QueryPlugins struct {
// Bank func(msg *wasmTypes.BankQuery) ([]byte, error)
// Custom func(msg json.RawMessage) ([]byte, error)

View File

@@ -39,7 +39,8 @@ func MakeTestCodec() *codec.Codec {
return cdc
}
func CreateTestInput(t *testing.T, isCheckTx bool, tempDir string) (sdk.Context, auth.AccountKeeper, Keeper) {
// encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default)
func CreateTestInput(t *testing.T, isCheckTx bool, tempDir string, encoders *MessageEncoders) (sdk.Context, auth.AccountKeeper, Keeper) {
keyContract := sdk.NewKVStoreKey(types.StoreKey)
keyAcc := sdk.NewKVStoreKey(auth.StoreKey)
keyParams := sdk.NewKVStoreKey(params.StoreKey)
@@ -84,7 +85,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, tempDir string) (sdk.Context,
// Load default wasm config
wasmConfig := wasmTypes.DefaultWasmConfig()
keeper := NewKeeper(cdc, keyContract, accountKeeper, bk, router, tempDir, wasmConfig)
keeper := NewKeeper(cdc, keyContract, accountKeeper, bk, router, tempDir, wasmConfig, encoders)
// add wasm handler so we can loop-back (contracts calling contracts)
router.AddRoute(wasmTypes.RouterKey, TestHandler(keeper))

View File

@@ -34,7 +34,7 @@ func setupTest(t *testing.T) (testData, func()) {
tempDir, err := ioutil.TempDir("", "wasm")
require.NoError(t, err)
ctx, acctKeeper, keeper := CreateTestInput(t, false, tempDir)
ctx, acctKeeper, keeper := CreateTestInput(t, false, tempDir, nil)
data := testData{
module: NewAppModule(keeper),
ctx: ctx,