From 0dd695c126367e09f212a5e86f5c07c627fbebad Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 11 Jun 2021 12:27:27 +0200 Subject: [PATCH 1/2] Cleanup keeper result types --- x/wasm/keeper/contract_keeper.go | 8 ++--- x/wasm/keeper/keeper.go | 27 +++++---------- x/wasm/keeper/keeper_test.go | 8 ++--- x/wasm/keeper/msg_dispatcher.go | 8 ++--- x/wasm/keeper/msg_dispatcher_test.go | 50 +++++++++++++++++++--------- x/wasm/keeper/msg_server.go | 9 +++-- x/wasm/keeper/proposal_handler.go | 10 +----- x/wasm/keeper/test_common.go | 8 +++-- x/wasm/types/exported_keepers.go | 4 +-- 9 files changed, 65 insertions(+), 67 deletions(-) diff --git a/x/wasm/keeper/contract_keeper.go b/x/wasm/keeper/contract_keeper.go index ad4670a94f3..05a87b934d9 100644 --- a/x/wasm/keeper/contract_keeper.go +++ b/x/wasm/keeper/contract_keeper.go @@ -11,11 +11,11 @@ var _ types.ContractOpsKeeper = PermissionedKeeper{} type decoratedKeeper interface { create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, source string, builder string, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, 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) (*sdk.Result, 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 pinCode(ctx sdk.Context, codeID uint64) error unpinCode(ctx sdk.Context, codeID uint64) error - execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) + execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) ([]byte, error) setContractInfoExtension(ctx sdk.Context, contract sdk.AccAddress, extra types.ContractInfoExtension) error } @@ -44,11 +44,11 @@ func (p PermissionedKeeper) Instantiate(ctx sdk.Context, codeID uint64, creator, return p.nested.instantiate(ctx, codeID, creator, admin, initMsg, label, deposit, p.authZPolicy) } -func (p PermissionedKeeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) { +func (p PermissionedKeeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) ([]byte, error) { return p.nested.execute(ctx, contractAddress, caller, msg, coins) } -func (p PermissionedKeeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) (*sdk.Result, error) { +func (p PermissionedKeeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) ([]byte, error) { return p.nested.migrate(ctx, contractAddress, caller, newCodeID, msg, p.authZPolicy) } diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 6ebe8877187..a5a6f3d2225 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -316,7 +316,7 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A } // Execute executes the contract instance -func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) { +func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "execute") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { @@ -355,13 +355,10 @@ func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } - - return &sdk.Result{ - Data: data, - }, nil + return data, nil } -func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) (*sdk.Result, error) { +func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "migrate") if !k.IsPinnedCode(ctx, newCodeID) { ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: migrate") @@ -427,16 +424,13 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } - - return &sdk.Result{ - Data: data, - }, nil + return data, nil } // Sudo allows priviledged access to a contract. This can never be called by governance or external tx, but only by // another native Go module directly. Thus, the keeper doesn't place any access controls on it, that is the // responsibility or the app developer (who passes the wasm.Keeper in app.go) -func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) (*sdk.Result, error) { +func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "sudo") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { @@ -467,15 +461,12 @@ func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } - - return &sdk.Result{ - Data: data, - }, nil + return data, nil } // reply is only called from keeper internal functions (dispatchSubmessages) after processing the submessage // it -func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { +func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) if err != nil { return nil, err @@ -509,9 +500,7 @@ func (k Keeper) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply was if err != nil { return nil, sdkerrors.Wrap(err, "dispatch") } - return &sdk.Result{ - Data: data, - }, nil + return data, nil } // addToContractCodeSecondaryIndex adds element to the index for contracts-by-codeid queries diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index a3dd7d143ed..e0c951d0a69 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -1009,10 +1009,9 @@ func TestMigrateWithDispatchedMessage(t *testing.T) { migMsgBz := BurnerExampleInitMsg{Payout: myPayoutAddr}.GetBytes(t) ctx = ctx.WithEventManager(sdk.NewEventManager()).WithBlockHeight(ctx.BlockHeight() + 1) - res, err := keeper.Migrate(ctx, contractAddr, fred, burnerContractID, migMsgBz) + data, err := keeper.Migrate(ctx, contractAddr, fred, burnerContractID, migMsgBz) require.NoError(t, err) - assert.Equal(t, "burnt 1 keys", string(res.Data)) - assert.Equal(t, "", res.Log) + assert.Equal(t, "burnt 1 keys", string(data)) type dict map[string]interface{} expEvents := []dict{ { @@ -1184,9 +1183,8 @@ func TestSudo(t *testing.T) { sudoMsg, err := json.Marshal(msg) require.NoError(t, err) - res, err := keepers.WasmKeeper.Sudo(ctx, addr, sudoMsg) + _, err = keepers.WasmKeeper.Sudo(ctx, addr, sudoMsg) require.NoError(t, err) - require.NotNil(t, res) // ensure community now exists and got paid comAcct = accKeeper.GetAccount(ctx, community) diff --git a/x/wasm/keeper/msg_dispatcher.go b/x/wasm/keeper/msg_dispatcher.go index 78e2b947141..a81a57014e9 100644 --- a/x/wasm/keeper/msg_dispatcher.go +++ b/x/wasm/keeper/msg_dispatcher.go @@ -16,7 +16,7 @@ type Messenger interface { // replyer is a subset of keeper that can handle replies to submessages type replyer interface { - reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) + reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) } // MessageDispatcher coordinates message sending and submessage reply/ state commits @@ -140,12 +140,12 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk // we can ignore any result returned as there is nothing to do with the data // and the events are already in the ctx.EventManager() - rData, err := d.keeper.reply(ctx, contractAddr, reply) + rspData, err := d.keeper.reply(ctx, contractAddr, reply) switch { case err != nil: return nil, sdkerrors.Wrap(err, "reply") - case rData.Data != nil: - rsp = rData.Data + case rspData != nil: + rsp = rspData } } return rsp, nil diff --git a/x/wasm/keeper/msg_dispatcher_test.go b/x/wasm/keeper/msg_dispatcher_test.go index 36b389d8cee..e58c49338b5 100644 --- a/x/wasm/keeper/msg_dispatcher_test.go +++ b/x/wasm/keeper/msg_dispatcher_test.go @@ -50,8 +50,8 @@ func TestDispatchSubmessages(t *testing.T) { ReplyOn: wasmvmtypes.ReplySuccess, }}, replyer: &mockReplyer{ - replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { - return &sdk.Result{Data: []byte("myReplyData")}, nil + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { + return []byte("myReplyData"), nil }, }, msgHandler: &wasmtesting.MockMessageHandler{ @@ -67,8 +67,8 @@ func TestDispatchSubmessages(t *testing.T) { ReplyOn: wasmvmtypes.ReplyError, }}, replyer: &mockReplyer{ - replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { - return &sdk.Result{Data: []byte("myReplyData")}, nil + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { + return []byte("myReplyData"), nil }, }, msgHandler: &wasmtesting.MockMessageHandler{ @@ -84,8 +84,8 @@ func TestDispatchSubmessages(t *testing.T) { ReplyOn: wasmvmtypes.ReplySuccess, }}, replyer: &mockReplyer{ - replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { - return &sdk.Result{Data: []byte("myReplyData")}, nil + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { + return []byte("myReplyData"), nil }, }, msgHandler: &wasmtesting.MockMessageHandler{ @@ -106,7 +106,7 @@ func TestDispatchSubmessages(t *testing.T) { ReplyOn: wasmvmtypes.ReplySuccess, }}, replyer: &mockReplyer{ - replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { return nil, errors.New("reply failed") }, }, @@ -124,8 +124,8 @@ func TestDispatchSubmessages(t *testing.T) { ReplyOn: wasmvmtypes.ReplyError, }}, replyer: &mockReplyer{ - replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { - return &sdk.Result{Data: []byte("myReplyData")}, nil + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { + return []byte("myReplyData"), nil }, }, msgHandler: &wasmtesting.MockMessageHandler{ @@ -154,8 +154,8 @@ func TestDispatchSubmessages(t *testing.T) { "multiple msg - last reply": { msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyError}, {ID: 2, ReplyOn: wasmvmtypes.ReplyError}}, replyer: &mockReplyer{ - replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { - return &sdk.Result{Data: []byte(fmt.Sprintf("myReplyData:%d", reply.ID))}, nil + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { + return []byte(fmt.Sprintf("myReplyData:%d", reply.ID)), nil }, }, msgHandler: &wasmtesting.MockMessageHandler{ @@ -169,11 +169,11 @@ func TestDispatchSubmessages(t *testing.T) { "multiple msg - last reply with non nil": { msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyError}, {ID: 2, ReplyOn: wasmvmtypes.ReplyError}}, replyer: &mockReplyer{ - replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { if reply.ID == 2 { - return &sdk.Result{}, nil + return nil, nil } - return &sdk.Result{Data: []byte("myReplyData:1")}, nil + return []byte("myReplyData:1"), nil }, }, msgHandler: &wasmtesting.MockMessageHandler{ @@ -184,6 +184,24 @@ func TestDispatchSubmessages(t *testing.T) { expData: []byte("myReplyData:1"), expCommits: []bool{false, false}, }, + "multiple msg - last reply can be empty to overwrite": { + msgs: []wasmvmtypes.SubMsg{{ID: 1, ReplyOn: wasmvmtypes.ReplyError}, {ID: 2, ReplyOn: wasmvmtypes.ReplyError}}, + replyer: &mockReplyer{ + replyFn: func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { + if reply.ID == 2 { + return []byte{}, nil + } + return []byte("myReplyData:1"), nil + }, + }, + msgHandler: &wasmtesting.MockMessageHandler{ + DispatchMsgFn: func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) { + return nil, nil, errors.New("my error") + }, + }, + expData: []byte{}, + expCommits: []bool{false, false}, + }, "empty replyOn rejected": { msgs: []wasmvmtypes.SubMsg{{}}, replyer: noReplyCalled, @@ -225,10 +243,10 @@ func TestDispatchSubmessages(t *testing.T) { } type mockReplyer struct { - replyFn func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) + replyFn func(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) } -func (m mockReplyer) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) (*sdk.Result, error) { +func (m mockReplyer) reply(ctx sdk.Context, contractAddress sdk.AccAddress, reply wasmvmtypes.Reply) ([]byte, error) { if m.replyFn == nil { panic("not expected to be called") } diff --git a/x/wasm/keeper/msg_server.go b/x/wasm/keeper/msg_server.go index 67ed3ee0c82..93e80043f2c 100644 --- a/x/wasm/keeper/msg_server.go +++ b/x/wasm/keeper/msg_server.go @@ -85,7 +85,7 @@ func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteC return nil, sdkerrors.Wrap(err, "contract") } - res, err := m.keeper.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds) + data, err := m.keeper.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds) if err != nil { return nil, err } @@ -98,9 +98,8 @@ func (m msgServer) ExecuteContract(goCtx context.Context, msg *types.MsgExecuteC )) return &types.MsgExecuteContractResponse{ - Data: res.Data, + Data: data, }, nil - } func (m msgServer) MigrateContract(goCtx context.Context, msg *types.MsgMigrateContract) (*types.MsgMigrateContractResponse, error) { @@ -114,7 +113,7 @@ func (m msgServer) MigrateContract(goCtx context.Context, msg *types.MsgMigrateC return nil, sdkerrors.Wrap(err, "contract") } - res, err := m.keeper.Migrate(ctx, contractAddr, senderAddr, msg.CodeID, msg.MigrateMsg) + data, err := m.keeper.Migrate(ctx, contractAddr, senderAddr, msg.CodeID, msg.MigrateMsg) if err != nil { return nil, err } @@ -127,7 +126,7 @@ func (m msgServer) MigrateContract(goCtx context.Context, msg *types.MsgMigrateC )) return &types.MsgMigrateContractResponse{ - Data: res.Data, + Data: data, }, nil } diff --git a/x/wasm/keeper/proposal_handler.go b/x/wasm/keeper/proposal_handler.go index 32b7eb28d78..77c29e9ba70 100644 --- a/x/wasm/keeper/proposal_handler.go +++ b/x/wasm/keeper/proposal_handler.go @@ -112,7 +112,7 @@ func handleMigrateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.M if err != nil { return sdkerrors.Wrap(err, "run as address") } - res, err := k.Migrate(ctx, contractAddr, runAsAddr, p.CodeID, p.MigrateMsg) + _, err = k.Migrate(ctx, contractAddr, runAsAddr, p.CodeID, p.MigrateMsg) if err != nil { return err } @@ -123,14 +123,6 @@ func handleMigrateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.M sdk.NewAttribute(types.AttributeKeyContract, p.Contract), ) ctx.EventManager().EmitEvent(ourEvent) - - for _, e := range res.Events { - attr := make([]sdk.Attribute, len(e.Attributes)) - for i, a := range e.Attributes { - attr[i] = sdk.NewAttribute(string(a.Key), string(a.Value)) - } - ctx.EventManager().EmitEvent(sdk.NewEvent(e.Type, attr...)) - } return nil } diff --git a/x/wasm/keeper/test_common.go b/x/wasm/keeper/test_common.go index be766d952be..cf1eedae10c 100644 --- a/x/wasm/keeper/test_common.go +++ b/x/wasm/keeper/test_common.go @@ -406,13 +406,15 @@ func handleExecute(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgExe if err != nil { return nil, sdkerrors.Wrap(err, "admin") } - res, err := k.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds) + data, err := k.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds) if err != nil { return nil, err } - res.Events = ctx.EventManager().Events().ToABCIEvents() - return res, nil + return &sdk.Result{ + Data: data, + Events: ctx.EventManager().Events().ToABCIEvents(), + }, nil } func RandomAccountAddress(_ TestingT) sdk.AccAddress { diff --git a/x/wasm/types/exported_keepers.go b/x/wasm/types/exported_keepers.go index 201653130ed..15e09367975 100644 --- a/x/wasm/types/exported_keepers.go +++ b/x/wasm/types/exported_keepers.go @@ -32,10 +32,10 @@ type ContractOpsKeeper interface { Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins) (sdk.AccAddress, []byte, error) // Execute executes the contract instance - Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) + Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) ([]byte, error) // Migrate allows to upgrade a contract to a new code with data migration. - Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) (*sdk.Result, error) + Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) ([]byte, error) // UpdateContractAdmin sets the admin value on the ContractInfo. It must be a valid address (use ClearContractAdmin to remove it) UpdateContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newAdmin sdk.AccAddress) error From 44e7669611c5410004b1efa03556defc28b456b9 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 14 Jun 2021 08:28:46 +0200 Subject: [PATCH 2/2] Empty submsg result does not overwrite --- x/wasm/keeper/msg_dispatcher.go | 2 +- x/wasm/keeper/msg_dispatcher_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/wasm/keeper/msg_dispatcher.go b/x/wasm/keeper/msg_dispatcher.go index a81a57014e9..0e3db65ca81 100644 --- a/x/wasm/keeper/msg_dispatcher.go +++ b/x/wasm/keeper/msg_dispatcher.go @@ -144,7 +144,7 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk switch { case err != nil: return nil, sdkerrors.Wrap(err, "reply") - case rspData != nil: + case len(rspData) != 0: rsp = rspData } } diff --git a/x/wasm/keeper/msg_dispatcher_test.go b/x/wasm/keeper/msg_dispatcher_test.go index e58c49338b5..f152b4f2216 100644 --- a/x/wasm/keeper/msg_dispatcher_test.go +++ b/x/wasm/keeper/msg_dispatcher_test.go @@ -199,7 +199,7 @@ func TestDispatchSubmessages(t *testing.T) { return nil, nil, errors.New("my error") }, }, - expData: []byte{}, + expData: []byte("myReplyData:1"), expCommits: []bool{false, false}, }, "empty replyOn rejected": {