diff --git a/x/wasm/keeper/msg_dispatcher.go b/x/wasm/keeper/msg_dispatcher.go index edbfe162..51bb37cc 100644 --- a/x/wasm/keeper/msg_dispatcher.go +++ b/x/wasm/keeper/msg_dispatcher.go @@ -1,6 +1,8 @@ package keeper import ( + "fmt" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -131,8 +133,10 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk }, } } else { + // Issue #759 - we don't return error string for worries of non-determinism + moduleLogger(ctx).Info("Redacting submessage error", "cause", err) result = wasmvmtypes.SubcallResult{ - Err: err.Error(), + Err: redactError(err), } } @@ -155,6 +159,15 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk return rsp, nil } +func redactError(err error) string { + // FIXME: do we want to hardcode some constant string mappings here as well? + // Or better document them? (SDK error string may change on a patch release to fix wording) + // sdk/11 is out of gas + // sdk/5 is insufficient funds (on bank send) + codespace, code, _ := sdkerrors.ABCIInfo(err, false) + return fmt.Sprintf("codespace: %s, code: %d", codespace, code) +} + func filterEvents(events []sdk.Event) []sdk.Event { // pre-allocate space for efficiency res := make([]sdk.Event, 0, len(events)) diff --git a/x/wasm/keeper/msg_dispatcher_test.go b/x/wasm/keeper/msg_dispatcher_test.go index b1a806a6..b53eac72 100644 --- a/x/wasm/keeper/msg_dispatcher_test.go +++ b/x/wasm/keeper/msg_dispatcher_test.go @@ -5,6 +5,8 @@ import ( "fmt" "testing" + "github.com/tendermint/tendermint/libs/log" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" @@ -347,7 +349,7 @@ func TestDispatchSubmessages(t *testing.T) { em := sdk.NewEventManager() ctx := sdk.Context{}.WithMultiStore(&mockStore). WithGasMeter(sdk.NewGasMeter(100)). - WithEventManager(em) + WithEventManager(em).WithLogger(log.TestingLogger()) d := NewMessageDispatcher(spec.msgHandler, spec.replyer) gotData, gotErr := d.DispatchSubmessages(ctx, RandomAccountAddress(t), "any_port", spec.msgs) if spec.expErr { diff --git a/x/wasm/keeper/submsg_test.go b/x/wasm/keeper/submsg_test.go index 2fdb17eb..29c3ad8e 100644 --- a/x/wasm/keeper/submsg_test.go +++ b/x/wasm/keeper/submsg_test.go @@ -254,7 +254,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { msg: invalidBankSend, subMsgError: true, // uses less gas than the send tokens (cost of bank transfer) - resultAssertions: []assertion{assertGasUsed(76000, 79000), assertErrorString("insufficient funds")}, + resultAssertions: []assertion{assertGasUsed(76000, 79000), assertErrorString("codespace: sdk, code: 5")}, }, "out of gas panic with no gas limit": { submsgID: 7, @@ -275,7 +275,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { subMsgError: true, gasLimit: &subGasLimit, // uses same gas as call without limit (note we do not charge the 40k on reply) - resultAssertions: []assertion{assertGasUsed(79000, 79040), assertErrorString("insufficient funds")}, + resultAssertions: []assertion{assertGasUsed(77800, 77900), assertErrorString("codespace: sdk, code: 5")}, }, "out of gas caught with gas limit": { submsgID: 17, @@ -283,7 +283,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) { subMsgError: true, gasLimit: &subGasLimit, // uses all the subGasLimit, plus the 52k or so for the main contract - resultAssertions: []assertion{assertGasUsed(subGasLimit+73000, subGasLimit+80000), assertErrorString("out of gas")}, + resultAssertions: []assertion{assertGasUsed(subGasLimit+73000, subGasLimit+74000), assertErrorString("codespace: sdk, code: 11")}, }, "instantiate contract gets address in data and events": { submsgID: 21,