diff --git a/proto/neutron/contractmanager/failure.proto b/proto/neutron/contractmanager/failure.proto index d18386884..d09c7b055 100644 --- a/proto/neutron/contractmanager/failure.proto +++ b/proto/neutron/contractmanager/failure.proto @@ -15,4 +15,6 @@ message Failure { uint64 id = 2; // Serialized MessageSudoCallback with Packet and Ack(if exists) bytes sudo_payload = 3; + // Redacted error response of the sudo call. Full error is emitted as an event + string error = 4; } diff --git a/proto/neutron/contractmanager/query.proto b/proto/neutron/contractmanager/query.proto index 8ce870c3e..973cd15ef 100644 --- a/proto/neutron/contractmanager/query.proto +++ b/proto/neutron/contractmanager/query.proto @@ -16,13 +16,19 @@ service Query { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/neutron/contractmanager/params"; } - // Queries a Failure by address. + + // Queries a Failure by contract address and failure ID. + rpc AddressFailure(QueryFailuresRequest) returns (QueryFailuresResponse) { + option (google.api.http).get = "/neutron/contractmanager/failures/{address}/{failure_id}"; + } + + // Queries Failures by contract address. rpc AddressFailures(QueryFailuresRequest) returns (QueryFailuresResponse) { option (google.api.http).get = "/neutron/contractmanager/failures/{address}"; } - // Queries a list of Failure items. + // Queries a list of Failures occurred on the network. rpc Failures(QueryFailuresRequest) returns (QueryFailuresResponse) { option (google.api.http).get = "/neutron/contractmanager/failures"; } @@ -39,11 +45,16 @@ message QueryParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } +// QueryFailuresRequest is request type for the Query/Failures RPC method. message QueryFailuresRequest { + // address of the contract which Sudo call failed. string address = 1; - cosmos.base.query.v1beta1.PageRequest pagination = 2; + // ID of the failure for the given contract. + uint64 failure_id = 2; + cosmos.base.query.v1beta1.PageRequest pagination = 3; } +// QueryFailuresResponse is response type for the Query/Failures RPC method. message QueryFailuresResponse { repeated Failure failures = 1 [ (gogoproto.nullable) = false ]; cosmos.base.query.v1beta1.PageResponse pagination = 2; diff --git a/testutil/mocks/contractmanager/types/expected_keepers.go b/testutil/mocks/contractmanager/types/expected_keepers.go index eb767f134..67887c4bc 100644 --- a/testutil/mocks/contractmanager/types/expected_keepers.go +++ b/testutil/mocks/contractmanager/types/expected_keepers.go @@ -7,10 +7,10 @@ package mock_types import ( reflect "reflect" - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - types "github.com/cosmos/cosmos-sdk/types" + types "github.com/CosmWasm/wasmd/x/wasm/types" + types0 "github.com/cosmos/cosmos-sdk/types" gomock "github.com/golang/mock/gomock" - types0 "github.com/neutron-org/neutron/x/contractmanager/types" + types1 "github.com/neutron-org/neutron/x/contractmanager/types" ) // MockWasmKeeper is a mock of WasmKeeper interface. @@ -19,11 +19,6 @@ type MockWasmKeeper struct { recorder *MockWasmKeeperMockRecorder } -func (m *MockWasmKeeper) GetContractInfo(ctx types.Context, contractAddress types.AccAddress) *wasmtypes.ContractInfo { - // TODO implement me - panic("implement me") -} - // MockWasmKeeperMockRecorder is the mock recorder for MockWasmKeeper. type MockWasmKeeperMockRecorder struct { mock *MockWasmKeeper @@ -41,8 +36,22 @@ func (m *MockWasmKeeper) EXPECT() *MockWasmKeeperMockRecorder { return m.recorder } +// GetContractInfo mocks base method. +func (m *MockWasmKeeper) GetContractInfo(ctx types0.Context, contractAddress types0.AccAddress) *types.ContractInfo { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetContractInfo", ctx, contractAddress) + ret0, _ := ret[0].(*types.ContractInfo) + return ret0 +} + +// GetContractInfo indicates an expected call of GetContractInfo. +func (mr *MockWasmKeeperMockRecorder) GetContractInfo(ctx, contractAddress interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContractInfo", reflect.TypeOf((*MockWasmKeeper)(nil).GetContractInfo), ctx, contractAddress) +} + // HasContractInfo mocks base method. -func (m *MockWasmKeeper) HasContractInfo(ctx types.Context, contractAddress types.AccAddress) bool { +func (m *MockWasmKeeper) HasContractInfo(ctx types0.Context, contractAddress types0.AccAddress) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HasContractInfo", ctx, contractAddress) ret0, _ := ret[0].(bool) @@ -56,7 +65,7 @@ func (mr *MockWasmKeeperMockRecorder) HasContractInfo(ctx, contractAddress inter } // Sudo mocks base method. -func (m *MockWasmKeeper) Sudo(ctx types.Context, contractAddress types.AccAddress, msg []byte) ([]byte, error) { +func (m *MockWasmKeeper) Sudo(ctx types0.Context, contractAddress types0.AccAddress, msg []byte) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Sudo", ctx, contractAddress, msg) ret0, _ := ret[0].([]byte) @@ -94,22 +103,24 @@ func (m *MockContractManagerKeeper) EXPECT() *MockContractManagerKeeperMockRecor } // AddContractFailure mocks base method. -func (m *MockContractManagerKeeper) AddContractFailure(ctx types.Context, address string, sudoPayload []byte) { +func (m *MockContractManagerKeeper) AddContractFailure(ctx types0.Context, address string, sudoPayload []byte, errMsg string) types1.Failure { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddContractFailure", ctx, address, sudoPayload) + ret := m.ctrl.Call(m, "AddContractFailure", ctx, address, sudoPayload, errMsg) + ret0, _ := ret[0].(types1.Failure) + return ret0 } // AddContractFailure indicates an expected call of AddContractFailure. -func (mr *MockContractManagerKeeperMockRecorder) AddContractFailure(ctx, address, sudoPayload interface{}) *gomock.Call { +func (mr *MockContractManagerKeeperMockRecorder) AddContractFailure(ctx, address, sudoPayload, errMsg interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddContractFailure", reflect.TypeOf((*MockContractManagerKeeper)(nil).AddContractFailure), ctx, address, sudoPayload) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddContractFailure", reflect.TypeOf((*MockContractManagerKeeper)(nil).AddContractFailure), ctx, address, sudoPayload, errMsg) } // GetParams mocks base method. -func (m *MockContractManagerKeeper) GetParams(ctx types.Context) types0.Params { +func (m *MockContractManagerKeeper) GetParams(ctx types0.Context) types1.Params { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetParams", ctx) - ret0, _ := ret[0].(types0.Params) + ret0, _ := ret[0].(types1.Params) return ret0 } diff --git a/testutil/mocks/interchaintxs/types/expected_keepers.go b/testutil/mocks/interchaintxs/types/expected_keepers.go index de9a6d792..32923a9b6 100644 --- a/testutil/mocks/interchaintxs/types/expected_keepers.go +++ b/testutil/mocks/interchaintxs/types/expected_keepers.go @@ -7,15 +7,15 @@ package mock_types import ( reflect "reflect" - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - types "github.com/cosmos/cosmos-sdk/types" - types0 "github.com/cosmos/cosmos-sdk/x/auth/types" - types1 "github.com/cosmos/cosmos-sdk/x/capability/types" - types2 "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" - types3 "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + types "github.com/CosmWasm/wasmd/x/wasm/types" + types0 "github.com/cosmos/cosmos-sdk/types" + types1 "github.com/cosmos/cosmos-sdk/x/auth/types" + types2 "github.com/cosmos/cosmos-sdk/x/capability/types" + types3 "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + types4 "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" exported "github.com/cosmos/ibc-go/v7/modules/core/exported" gomock "github.com/golang/mock/gomock" - types4 "github.com/neutron-org/neutron/x/feerefunder/types" + types5 "github.com/neutron-org/neutron/x/feerefunder/types" ) // MockAccountKeeper is a mock of AccountKeeper interface. @@ -42,10 +42,10 @@ func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder { } // GetAccount mocks base method. -func (m *MockAccountKeeper) GetAccount(ctx types.Context, addr types.AccAddress) types0.AccountI { +func (m *MockAccountKeeper) GetAccount(ctx types0.Context, addr types0.AccAddress) types1.AccountI { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAccount", ctx, addr) - ret0, _ := ret[0].(types0.AccountI) + ret0, _ := ret[0].(types1.AccountI) return ret0 } @@ -79,7 +79,7 @@ func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder { } // SendCoins mocks base method. -func (m *MockBankKeeper) SendCoins(ctx types.Context, fromAddr, toAddr types.AccAddress, amt types.Coins) error { +func (m *MockBankKeeper) SendCoins(ctx types0.Context, fromAddr, toAddr types0.AccAddress, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendCoins", ctx, fromAddr, toAddr, amt) ret0, _ := ret[0].(error) @@ -93,10 +93,10 @@ func (mr *MockBankKeeperMockRecorder) SendCoins(ctx, fromAddr, toAddr, amt inter } // SpendableCoins mocks base method. -func (m *MockBankKeeper) SpendableCoins(ctx types.Context, addr types.AccAddress) types.Coins { +func (m *MockBankKeeper) SpendableCoins(ctx types0.Context, addr types0.AccAddress) types0.Coins { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SpendableCoins", ctx, addr) - ret0, _ := ret[0].(types.Coins) + ret0, _ := ret[0].(types0.Coins) return ret0 } @@ -112,10 +112,6 @@ type MockWasmKeeper struct { recorder *MockWasmKeeperMockRecorder } -func (m *MockWasmKeeper) GetContractInfo(ctx types.Context, contractAddress types.AccAddress) *wasmtypes.ContractInfo { - return &wasmtypes.ContractInfo{CodeID: 1} -} - // MockWasmKeeperMockRecorder is the mock recorder for MockWasmKeeper. type MockWasmKeeperMockRecorder struct { mock *MockWasmKeeper @@ -133,8 +129,22 @@ func (m *MockWasmKeeper) EXPECT() *MockWasmKeeperMockRecorder { return m.recorder } +// GetContractInfo mocks base method. +func (m *MockWasmKeeper) GetContractInfo(ctx types0.Context, contractAddress types0.AccAddress) *types.ContractInfo { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetContractInfo", ctx, contractAddress) + ret0, _ := ret[0].(*types.ContractInfo) + return ret0 +} + +// GetContractInfo indicates an expected call of GetContractInfo. +func (mr *MockWasmKeeperMockRecorder) GetContractInfo(ctx, contractAddress interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContractInfo", reflect.TypeOf((*MockWasmKeeper)(nil).GetContractInfo), ctx, contractAddress) +} + // HasContractInfo mocks base method. -func (m *MockWasmKeeper) HasContractInfo(ctx types.Context, contractAddress types.AccAddress) bool { +func (m *MockWasmKeeper) HasContractInfo(ctx types0.Context, contractAddress types0.AccAddress) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HasContractInfo", ctx, contractAddress) ret0, _ := ret[0].(bool) @@ -148,7 +158,7 @@ func (mr *MockWasmKeeperMockRecorder) HasContractInfo(ctx, contractAddress inter } // Sudo mocks base method. -func (m *MockWasmKeeper) Sudo(ctx types.Context, contractAddress types.AccAddress, msg []byte) ([]byte, error) { +func (m *MockWasmKeeper) Sudo(ctx types0.Context, contractAddress types0.AccAddress, msg []byte) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Sudo", ctx, contractAddress, msg) ret0, _ := ret[0].([]byte) @@ -186,7 +196,7 @@ func (m *MockICAControllerKeeper) EXPECT() *MockICAControllerKeeperMockRecorder } // GetActiveChannelID mocks base method. -func (m *MockICAControllerKeeper) GetActiveChannelID(ctx types.Context, connectionID, portID string) (string, bool) { +func (m *MockICAControllerKeeper) GetActiveChannelID(ctx types0.Context, connectionID, portID string) (string, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetActiveChannelID", ctx, connectionID, portID) ret0, _ := ret[0].(string) @@ -201,7 +211,7 @@ func (mr *MockICAControllerKeeperMockRecorder) GetActiveChannelID(ctx, connectio } // GetInterchainAccountAddress mocks base method. -func (m *MockICAControllerKeeper) GetInterchainAccountAddress(ctx types.Context, connectionID, portID string) (string, bool) { +func (m *MockICAControllerKeeper) GetInterchainAccountAddress(ctx types0.Context, connectionID, portID string) (string, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetInterchainAccountAddress", ctx, connectionID, portID) ret0, _ := ret[0].(string) @@ -216,7 +226,7 @@ func (mr *MockICAControllerKeeperMockRecorder) GetInterchainAccountAddress(ctx, } // RegisterInterchainAccount mocks base method. -func (m *MockICAControllerKeeper) RegisterInterchainAccount(ctx types.Context, connectionID, owner, version string) error { +func (m *MockICAControllerKeeper) RegisterInterchainAccount(ctx types0.Context, connectionID, owner, version string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RegisterInterchainAccount", ctx, connectionID, owner, version) ret0, _ := ret[0].(error) @@ -230,7 +240,7 @@ func (mr *MockICAControllerKeeperMockRecorder) RegisterInterchainAccount(ctx, co } // SendTx mocks base method. -func (m *MockICAControllerKeeper) SendTx(ctx types.Context, chanCap *types1.Capability, connectionID, portID string, icaPacketData types2.InterchainAccountPacketData, timeoutTimestamp uint64) (uint64, error) { +func (m *MockICAControllerKeeper) SendTx(ctx types0.Context, chanCap *types2.Capability, connectionID, portID string, icaPacketData types3.InterchainAccountPacketData, timeoutTimestamp uint64) (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendTx", ctx, chanCap, connectionID, portID, icaPacketData, timeoutTimestamp) ret0, _ := ret[0].(uint64) @@ -268,7 +278,7 @@ func (m *MockFeeRefunderKeeper) EXPECT() *MockFeeRefunderKeeperMockRecorder { } // DistributeAcknowledgementFee mocks base method. -func (m *MockFeeRefunderKeeper) DistributeAcknowledgementFee(ctx types.Context, receiver types.AccAddress, packetID types4.PacketID) { +func (m *MockFeeRefunderKeeper) DistributeAcknowledgementFee(ctx types0.Context, receiver types0.AccAddress, packetID types5.PacketID) { m.ctrl.T.Helper() m.ctrl.Call(m, "DistributeAcknowledgementFee", ctx, receiver, packetID) } @@ -280,7 +290,7 @@ func (mr *MockFeeRefunderKeeperMockRecorder) DistributeAcknowledgementFee(ctx, r } // DistributeTimeoutFee mocks base method. -func (m *MockFeeRefunderKeeper) DistributeTimeoutFee(ctx types.Context, receiver types.AccAddress, packetID types4.PacketID) { +func (m *MockFeeRefunderKeeper) DistributeTimeoutFee(ctx types0.Context, receiver types0.AccAddress, packetID types5.PacketID) { m.ctrl.T.Helper() m.ctrl.Call(m, "DistributeTimeoutFee", ctx, receiver, packetID) } @@ -292,7 +302,7 @@ func (mr *MockFeeRefunderKeeperMockRecorder) DistributeTimeoutFee(ctx, receiver, } // LockFees mocks base method. -func (m *MockFeeRefunderKeeper) LockFees(ctx types.Context, payer types.AccAddress, packetID types4.PacketID, fee types4.Fee) error { +func (m *MockFeeRefunderKeeper) LockFees(ctx types0.Context, payer types0.AccAddress, packetID types5.PacketID, fee types5.Fee) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LockFees", ctx, payer, packetID, fee) ret0, _ := ret[0].(error) @@ -329,10 +339,10 @@ func (m *MockChannelKeeper) EXPECT() *MockChannelKeeperMockRecorder { } // GetChannel mocks base method. -func (m *MockChannelKeeper) GetChannel(ctx types.Context, srcPort, srcChan string) (types3.Channel, bool) { +func (m *MockChannelKeeper) GetChannel(ctx types0.Context, srcPort, srcChan string) (types4.Channel, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetChannel", ctx, srcPort, srcChan) - ret0, _ := ret[0].(types3.Channel) + ret0, _ := ret[0].(types4.Channel) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -344,7 +354,7 @@ func (mr *MockChannelKeeperMockRecorder) GetChannel(ctx, srcPort, srcChan interf } // GetConnection mocks base method. -func (m *MockChannelKeeper) GetConnection(ctx types.Context, connectionID string) (exported.ConnectionI, error) { +func (m *MockChannelKeeper) GetConnection(ctx types0.Context, connectionID string) (exported.ConnectionI, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetConnection", ctx, connectionID) ret0, _ := ret[0].(exported.ConnectionI) @@ -359,7 +369,7 @@ func (mr *MockChannelKeeperMockRecorder) GetConnection(ctx, connectionID interfa } // GetNextSequenceSend mocks base method. -func (m *MockChannelKeeper) GetNextSequenceSend(ctx types.Context, portID, channelID string) (uint64, bool) { +func (m *MockChannelKeeper) GetNextSequenceSend(ctx types0.Context, portID, channelID string) (uint64, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetNextSequenceSend", ctx, portID, channelID) ret0, _ := ret[0].(uint64) diff --git a/wasmbinding/test/custom_message_test.go b/wasmbinding/test/custom_message_test.go index a79dd73db..373aa67b7 100644 --- a/wasmbinding/test/custom_message_test.go +++ b/wasmbinding/test/custom_message_test.go @@ -637,7 +637,7 @@ func (suite *CustomMessengerTestSuite) TestResubmitFailureAck() { payload, err := keeper2.PrepareSudoCallbackMessage(packet, &ack) require.NoError(suite.T(), err) failureID := suite.messenger.ContractmanagerKeeper.GetNextFailureIDKey(suite.ctx, suite.contractAddress.String()) - suite.messenger.ContractmanagerKeeper.AddContractFailure(suite.ctx, suite.contractAddress.String(), payload) + suite.messenger.ContractmanagerKeeper.AddContractFailure(suite.ctx, suite.contractAddress.String(), payload, "test error") // Craft message msg, err := json.Marshal(bindings.NeutronMsg{ @@ -669,7 +669,7 @@ func (suite *CustomMessengerTestSuite) TestResubmitFailureTimeout() { payload, err := keeper2.PrepareSudoCallbackMessage(packet, nil) require.NoError(suite.T(), err) failureID := suite.messenger.ContractmanagerKeeper.GetNextFailureIDKey(suite.ctx, suite.contractAddress.String()) - suite.messenger.ContractmanagerKeeper.AddContractFailure(suite.ctx, suite.contractAddress.String(), payload) + suite.messenger.ContractmanagerKeeper.AddContractFailure(suite.ctx, suite.contractAddress.String(), payload, "test error") // Craft message msg, err := json.Marshal(bindings.NeutronMsg{ @@ -704,7 +704,7 @@ func (suite *CustomMessengerTestSuite) TestResubmitFailureFromDifferentContract( failureID := suite.messenger.ContractmanagerKeeper.GetNextFailureIDKey(suite.ctx, testutil.TestOwnerAddress) payload, err := keeper2.PrepareSudoCallbackMessage(packet, &ack) require.NoError(suite.T(), err) - suite.messenger.ContractmanagerKeeper.AddContractFailure(suite.ctx, testutil.TestOwnerAddress, payload) + suite.messenger.ContractmanagerKeeper.AddContractFailure(suite.ctx, testutil.TestOwnerAddress, payload, "test error") // Craft message msg, err := json.Marshal(bindings.NeutronMsg{ diff --git a/x/contractmanager/client/cli/query.go b/x/contractmanager/client/cli/query.go index a60ce28a2..9562d9550 100644 --- a/x/contractmanager/client/cli/query.go +++ b/x/contractmanager/client/cli/query.go @@ -24,6 +24,7 @@ func GetQueryCmd(_ string) *cobra.Command { cmd.AddCommand(CmdQueryParams()) cmd.AddCommand(CmdFailures()) + cmd.AddCommand(CmdFailureDetails()) // this line is used by starport scaffolding # 1 return cmd diff --git a/x/contractmanager/client/cli/query_failure.go b/x/contractmanager/client/cli/query_failure.go index 0a819dc79..9544e3ebc 100644 --- a/x/contractmanager/client/cli/query_failure.go +++ b/x/contractmanager/client/cli/query_failure.go @@ -1,13 +1,16 @@ package cli import ( - "context" + "fmt" + "strconv" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth/tx" + contractmanagertypes "github.com/neutron-org/neutron/x/contractmanager/types" "github.com/spf13/cobra" - - "github.com/neutron-org/neutron/x/contractmanager/types" ) func CmdFailures() *cobra.Command { @@ -23,19 +26,19 @@ func CmdFailures() *cobra.Command { return err } - queryClient := types.NewQueryClient(clientCtx) + queryClient := contractmanagertypes.NewQueryClient(clientCtx) address := "" if len(args) > 0 { address = args[0] } - params := &types.QueryFailuresRequest{ + params := &contractmanagertypes.QueryFailuresRequest{ Address: address, Pagination: pageReq, } - res, err := queryClient.Failures(context.Background(), params) + res, err := queryClient.Failures(cmd.Context(), params) if err != nil { return err } @@ -49,3 +52,60 @@ func CmdFailures() *cobra.Command { return cmd } + +// CmdFailureDetails returns the command handler for the failure's detailed error querying. +func CmdFailureDetails() *cobra.Command { + cmd := &cobra.Command{ + Use: "failure-details [address] [failure-id]", + Short: "Query the detailed error related to a contract's sudo call failure", + Long: "Query the detailed error related to a contract's sudo call failure based on contract's address and failure ID", + Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query failure-details neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0 0", version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + address := args[0] + failureID, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return fmt.Errorf("invalid failure ID %s: expected a uint64: %v", args[1], err) + } + + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := contractmanagertypes.NewQueryClient(clientCtx) + if _, err = queryClient.AddressFailure( + cmd.Context(), + &contractmanagertypes.QueryFailuresRequest{Address: address, FailureId: failureID}, + ); err != nil { + return err + } + + searchEvents := []string{ + fmt.Sprintf("%s.%s='%s'", wasmtypes.EventTypeSudo, wasmtypes.AttributeKeyContractAddr, address), + fmt.Sprintf("%s.%s='%d'", wasmtypes.EventTypeSudo, contractmanagertypes.AttributeKeySudoFailureID, failureID), + } + result, err := tx.QueryTxsByEvents(clientCtx, searchEvents, 1, 1, "") // only a single tx for a pair address+failure_id is expected + if err != nil { + return err + } + + for _, tx := range result.Txs { + for _, event := range tx.Events { + if event.Type == wasmtypes.EventTypeSudo { + for _, attr := range event.Attributes { + if attr.Key == contractmanagertypes.AttributeKeySudoError { + return clientCtx.PrintString(attr.Value) + } + } + } + } + } + return fmt.Errorf("detailed failure error message not found in node events") + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/contractmanager/genesis.go b/x/contractmanager/genesis.go index fd5751c6b..785cadda6 100644 --- a/x/contractmanager/genesis.go +++ b/x/contractmanager/genesis.go @@ -11,7 +11,7 @@ import ( func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { // Set all the failure for _, elem := range genState.FailuresList { - k.AddContractFailure(ctx, elem.Address, elem.SudoPayload) + k.AddContractFailure(ctx, elem.Address, elem.SudoPayload, elem.Error) } // this line is used by starport scaffolding # genesis/module/init err := k.SetParams(ctx, genState.Params) diff --git a/x/contractmanager/ibc_middleware.go b/x/contractmanager/ibc_middleware.go index 1b3370f86..47bb73cdc 100644 --- a/x/contractmanager/ibc_middleware.go +++ b/x/contractmanager/ibc_middleware.go @@ -3,10 +3,10 @@ package contractmanager import ( "fmt" - "cosmossdk.io/errors" - + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/cometbft/cometbft/libs/log" sdk "github.com/cosmos/cosmos-sdk/types" + contractmanagerkeeper "github.com/neutron-org/neutron/x/contractmanager/keeper" contractmanagertypes "github.com/neutron-org/neutron/x/contractmanager/types" ) @@ -34,9 +34,21 @@ func (k SudoLimitWrapper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, // maybe later we'll retrieve actual errors from events resp, err = k.WasmKeeper.Sudo(cacheCtx, contractAddress, msg) }() - if err != nil { - // the contract either returned an error or panicked with `out of gas` - k.contractManager.AddContractFailure(ctx, contractAddress.String(), msg) + if err != nil { // the contract either returned an error or panicked with `out of gas` + failure := k.contractManager.AddContractFailure( + ctx, + contractAddress.String(), + msg, + contractmanagerkeeper.RedactError(err).Error(), + ) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + wasmtypes.EventTypeSudo, + sdk.NewAttribute(wasmtypes.AttributeKeyContractAddr, contractAddress.String()), + sdk.NewAttribute(contractmanagertypes.AttributeKeySudoFailureID, fmt.Sprintf("%d", failure.Id)), + sdk.NewAttribute(contractmanagertypes.AttributeKeySudoError, err.Error()), + ), + }) } else { writeFn() } @@ -60,7 +72,7 @@ func outOfGasRecovery( if !ok || !gasMeter.IsOutOfGas() { panic(r) } - *err = errors.Wrapf(errors.ErrPanic, "%v", r) + *err = contractmanagertypes.ErrSudoOutOfGas } } diff --git a/x/contractmanager/ibc_middleware_test.go b/x/contractmanager/ibc_middleware_test.go index 991d93af7..f56fbd95c 100644 --- a/x/contractmanager/ibc_middleware_test.go +++ b/x/contractmanager/ibc_middleware_test.go @@ -1,13 +1,14 @@ package contractmanager_test import ( - "fmt" "testing" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" test_keeper "github.com/neutron-org/neutron/testutil/interchaintxs/keeper" mock_types "github.com/neutron-org/neutron/testutil/mocks/contractmanager/types" + contractmanagerkeeper "github.com/neutron-org/neutron/x/contractmanager/keeper" "github.com/neutron-org/neutron/x/contractmanager/types" "github.com/stretchr/testify/require" ) @@ -49,11 +50,11 @@ func TestSudo(t *testing.T) { // error during Sudo ctx = infCtx.WithGasMeter(sdk.NewGasMeter(1_000_000_000_000)) cmKeeper.EXPECT().GetParams(ctx).Return(types.Params{SudoCallGasLimit: 10000}) - cmKeeper.EXPECT().AddContractFailure(ctx, contractAddress.String(), msg) + cmKeeper.EXPECT().AddContractFailure(ctx, contractAddress.String(), msg, contractmanagerkeeper.RedactError(wasmtypes.ErrExecuteFailed).Error()) wmKeeper.EXPECT().Sudo(gomock.AssignableToTypeOf(ctx), contractAddress, msg).Do(func(cachedCtx sdk.Context, senderAddress sdk.AccAddress, msg []byte) { st := cachedCtx.KVStore(storeKey) st.Set(ShouldNotBeWrittenKey, ShouldNotBeWritten) - }).Return(nil, fmt.Errorf("sudo error")) + }).Return(nil, wasmtypes.ErrExecuteFailed) _, err = middleware.Sudo(ctx, contractAddress, msg) require.Error(t, err) require.Nil(t, st.Get(ShouldNotBeWrittenKey)) @@ -61,13 +62,13 @@ func TestSudo(t *testing.T) { // ou of gas during Sudo ctx = infCtx.WithGasMeter(sdk.NewGasMeter(1_000_000_000_000)) cmKeeper.EXPECT().GetParams(ctx).Return(types.Params{SudoCallGasLimit: 10000}) - cmKeeper.EXPECT().AddContractFailure(ctx, contractAddress.String(), msg) + cmKeeper.EXPECT().AddContractFailure(ctx, contractAddress.String(), msg, contractmanagerkeeper.RedactError(types.ErrSudoOutOfGas).Error()) wmKeeper.EXPECT().Sudo(gomock.AssignableToTypeOf(ctx), contractAddress, msg).Do(func(cachedCtx sdk.Context, senderAddress sdk.AccAddress, msg []byte) { st := cachedCtx.KVStore(storeKey) st.Set(ShouldNotBeWrittenKey, ShouldNotBeWritten) cachedCtx.GasMeter().ConsumeGas(10001, "heavy calculations") }) _, err = middleware.Sudo(ctx, contractAddress, msg) - require.ErrorContains(t, err, "{heavy calculations}: panic") + require.ErrorContains(t, err, types.ErrSudoOutOfGas.Error()) require.Nil(t, st.Get(ShouldNotBeWrittenKey)) } diff --git a/x/contractmanager/keeper/failure.go b/x/contractmanager/keeper/failure.go index 02e653655..2be5209f9 100644 --- a/x/contractmanager/keeper/failure.go +++ b/x/contractmanager/keeper/failure.go @@ -1,18 +1,30 @@ package keeper import ( - "cosmossdk.io/errors" + "fmt" + + errorsmod "cosmossdk.io/errors" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/neutron-org/neutron/x/contractmanager/types" ) -// AddContractFailure adds a specific failure to the store using address as the key -func (k Keeper) AddContractFailure(ctx sdk.Context, address string, sudoPayload []byte) { +// AddContractFailure adds a specific failure to the store. The provided address is used to determine +// the failure ID and they both are used to create a storage key for the failure. +// +// WARNING: The errMsg string parameter is expected to be deterministic. It means that the errMsg +// must be OS/library version agnostic and carry a concrete defined error message. One of the good +// ways to do so is to redact error using the RedactError func as it is done in SudoLimitWrapper +// Sudo method: +// https://github.com/neutron-org/neutron/blob/eb8b5ae50907439ff9af0527a42ef0cb448a78b5/x/contractmanager/ibc_middleware.go#L42. +// Another good way could be passing here some constant value. +func (k Keeper) AddContractFailure(ctx sdk.Context, address string, sudoPayload []byte, errMsg string) types.Failure { failure := types.Failure{ Address: address, SudoPayload: sudoPayload, + Error: errMsg, } nextFailureID := k.GetNextFailureIDKey(ctx, failure.GetAddress()) failure.Id = nextFailureID @@ -20,6 +32,7 @@ func (k Keeper) AddContractFailure(ctx sdk.Context, address string, sudoPayload store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&failure) store.Set(types.GetFailureKey(failure.GetAddress(), nextFailureID), bz) + return failure } func (k Keeper) GetNextFailureIDKey(ctx sdk.Context, address string) uint64 { @@ -58,7 +71,7 @@ func (k Keeper) GetFailure(ctx sdk.Context, contractAddr sdk.AccAddress, id uint bz := store.Get(key) if bz == nil { - return nil, errors.Wrapf(sdkerrors.ErrKeyNotFound, "no failure found for contractAddress = %s and failureId = %d", contractAddr.String(), id) + return nil, errorsmod.Wrapf(sdkerrors.ErrKeyNotFound, "no failure found for contractAddress = %s and failureId = %d", contractAddr.String(), id) } var res types.Failure k.cdc.MustUnmarshal(bz, &res) @@ -69,11 +82,11 @@ func (k Keeper) GetFailure(ctx sdk.Context, contractAddr sdk.AccAddress, id uint // ResubmitFailure tries to call sudo handler for contract with same parameters as initially. func (k Keeper) ResubmitFailure(ctx sdk.Context, contractAddr sdk.AccAddress, failure *types.Failure) error { if failure.SudoPayload == nil { - return errors.Wrapf(types.IncorrectFailureToResubmit, "cannot resubmit failure without sudo payload; failureId = %d", failure.Id) + return errorsmod.Wrapf(types.ErrIncorrectFailureToResubmit, "cannot resubmit failure without sudo payload; failureId = %d", failure.Id) } if _, err := k.wasmKeeper.Sudo(ctx, contractAddr, failure.SudoPayload); err != nil { - return errors.Wrapf(types.FailedToResubmitFailure, "cannot resubmit failure; failureId = %d; err = %s", failure.Id, err) + return errorsmod.Wrapf(types.ErrFailedToResubmitFailure, "cannot resubmit failure; failureId = %d; err = %s", failure.Id, err) } // Cleanup failure since we resubmitted it successfully @@ -87,3 +100,23 @@ func (k Keeper) removeFailure(ctx sdk.Context, contractAddr sdk.AccAddress, id u failureKey := types.GetFailureKey(contractAddr.String(), id) store.Delete(failureKey) } + +// RedactError removes non-determenistic details from the error returning just codespace and core +// of the error. Returns full error for system errors. +// +// Copy+paste from https://github.com/neutron-org/wasmd/blob/5b59886e41ed55a7a4a9ae196e34b0852285503d/x/wasm/keeper/msg_dispatcher.go#L175-L190 +func RedactError(err error) error { + // Do not redact system errors + // SystemErrors must be created in x/wasm and we can ensure determinism + if wasmvmtypes.ToSystemError(err) != nil { + return err + } + + // 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) + // (we can theoretically redact less in the future, but this is a first step to safety) + codespace, code, _ := errorsmod.ABCIInfo(err, false) + return fmt.Errorf("codespace: %s, code: %d", codespace, code) +} diff --git a/x/contractmanager/keeper/failure_test.go b/x/contractmanager/keeper/failure_test.go index b76ef3013..d0871d3e8 100644 --- a/x/contractmanager/keeper/failure_test.go +++ b/x/contractmanager/keeper/failure_test.go @@ -48,7 +48,8 @@ func createNFailure(k *keeper.Keeper, ctx sdk.Context, addresses, failures int) panic(err) } items[i][c].SudoPayload = sudo - k.AddContractFailure(ctx, items[i][c].Address, sudo) + items[i][c].Error = "test error" + k.AddContractFailure(ctx, items[i][c].Address, sudo, "test error") } } return items @@ -87,11 +88,12 @@ func TestAddGetFailure(t *testing.T) { k, ctx := keepertest.ContractManagerKeeper(t, nil) failureID := k.GetNextFailureIDKey(ctx, contractAddress.String()) sudoPayload := []byte("payload") - k.AddContractFailure(ctx, contractAddress.String(), sudoPayload) + k.AddContractFailure(ctx, contractAddress.String(), sudoPayload, "test error") failure, err := k.GetFailure(ctx, contractAddress, failureID) require.NoError(t, err) require.Equal(t, failureID, failure.Id) require.Equal(t, sudoPayload, failure.SudoPayload) + require.Equal(t, "test error", failure.Error) // non-existent id _, err = k.GetFailure(ctx, contractAddress, failureID+1) @@ -123,7 +125,7 @@ func TestResubmitFailure(t *testing.T) { failureID := k.GetNextFailureIDKey(ctx, contractAddr.String()) payload, err := keeper.PrepareSudoCallbackMessage(packet, &ack) require.NoError(t, err) - k.AddContractFailure(ctx, contractAddr.String(), payload) + k.AddContractFailure(ctx, contractAddr.String(), payload, "test error") // success response xSuc := types.MessageSudoCallback{Response: &types.ResponseSudoPayload{ @@ -159,7 +161,7 @@ func TestResubmitFailure(t *testing.T) { failureID2 := k.GetNextFailureIDKey(ctx, contractAddr.String()) payload, err = keeper.PrepareSudoCallbackMessage(packet, &ack) require.NoError(t, err) - k.AddContractFailure(ctx, contractAddr.String(), payload) + k.AddContractFailure(ctx, contractAddr.String(), payload, "test error") wk.EXPECT().Sudo(ctx, contractAddr, msgSuc).Return(nil, fmt.Errorf("failed to sudo")) @@ -177,7 +179,7 @@ func TestResubmitFailure(t *testing.T) { failureID3 := k.GetNextFailureIDKey(ctx, contractAddr.String()) payload, err = keeper.PrepareSudoCallbackMessage(packet, &ackError) require.NoError(t, err) - k.AddContractFailure(ctx, contractAddr.String(), payload) + k.AddContractFailure(ctx, contractAddr.String(), payload, "test error") wk.EXPECT().Sudo(gomock.AssignableToTypeOf(ctx), contractAddr, msgErr).Return([]byte{}, nil) @@ -193,7 +195,7 @@ func TestResubmitFailure(t *testing.T) { failureID4 := k.GetNextFailureIDKey(ctx, contractAddr.String()) payload, err = keeper.PrepareSudoCallbackMessage(packet, &ackError) require.NoError(t, err) - k.AddContractFailure(ctx, contractAddr.String(), payload) + k.AddContractFailure(ctx, contractAddr.String(), payload, "test error") wk.EXPECT().Sudo(gomock.AssignableToTypeOf(ctx), contractAddr, msgErr).Return(nil, fmt.Errorf("failed to sudo")) @@ -211,7 +213,7 @@ func TestResubmitFailure(t *testing.T) { failureID5 := k.GetNextFailureIDKey(ctx, contractAddr.String()) payload, err = keeper.PrepareSudoCallbackMessage(packet, nil) require.NoError(t, err) - k.AddContractFailure(ctx, contractAddr.String(), payload) + k.AddContractFailure(ctx, contractAddr.String(), payload, "test error") wk.EXPECT().Sudo(gomock.AssignableToTypeOf(ctx), contractAddr, msgTimeout).Return([]byte{}, nil) @@ -227,7 +229,7 @@ func TestResubmitFailure(t *testing.T) { failureID6 := k.GetNextFailureIDKey(ctx, contractAddr.String()) payload, err = keeper.PrepareSudoCallbackMessage(packet, nil) require.NoError(t, err) - k.AddContractFailure(ctx, contractAddr.String(), payload) + k.AddContractFailure(ctx, contractAddr.String(), payload, "test error") wk.EXPECT().Sudo(gomock.AssignableToTypeOf(ctx), contractAddr, msgTimeout).Return(nil, fmt.Errorf("failed to sudo")) diff --git a/x/contractmanager/keeper/grpc_query_failure.go b/x/contractmanager/keeper/grpc_query_failure.go index 87df124fb..188829a71 100644 --- a/x/contractmanager/keeper/grpc_query_failure.go +++ b/x/contractmanager/keeper/grpc_query_failure.go @@ -6,10 +6,9 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" + "github.com/neutron-org/neutron/x/contractmanager/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - - "github.com/neutron-org/neutron/x/contractmanager/types" ) const FailuresQueryMaxLimit uint64 = query.DefaultLimit @@ -58,3 +57,21 @@ func (k Keeper) AddressFailures(c context.Context, req *types.QueryFailuresReque return &types.QueryFailuresResponse{Failures: failures, Pagination: pageRes}, nil } + +func (k Keeper) AddressFailure(c context.Context, req *types.QueryFailuresRequest) (*types.QueryFailuresResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "request field must not be empty") + } + + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid address: %v", err) + } + + resp, err := k.GetFailure(sdk.UnwrapSDKContext(c), addr, req.GetFailureId()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + return &types.QueryFailuresResponse{Failures: []types.Failure{*resp}}, nil +} diff --git a/x/contractmanager/types/errors.go b/x/contractmanager/types/errors.go index 612d6742f..ba32da1fe 100644 --- a/x/contractmanager/types/errors.go +++ b/x/contractmanager/types/errors.go @@ -6,7 +6,7 @@ import ( // x/contractmanager module sentinel errors var ( - IncorrectAckType = errors.Register(ModuleName, 1100, "incorrect acknowledgement type") - IncorrectFailureToResubmit = errors.Register(ModuleName, 1101, "incorrect failure to resubmit") - FailedToResubmitFailure = errors.Register(ModuleName, 1102, "failed to resubmit acknowledgement") + ErrIncorrectFailureToResubmit = errors.Register(ModuleName, 1101, "incorrect failure to resubmit") + ErrFailedToResubmitFailure = errors.Register(ModuleName, 1102, "failed to resubmit failure") + ErrSudoOutOfGas = errors.Register(ModuleName, 1103, "sudo handling went beyond the gas limit allowed by the module") ) diff --git a/x/contractmanager/types/events.go b/x/contractmanager/types/events.go new file mode 100644 index 000000000..36ccef858 --- /dev/null +++ b/x/contractmanager/types/events.go @@ -0,0 +1,10 @@ +package types + +// Contractmanager events +const ( + // AttributeKeySudoError indicates an attribute containing detailed Sudo call error. + AttributeKeySudoError = "error" + // AttributeKeySudoFailureID indicates attribute containing ID of the failure related to an + // error Sudo call. + AttributeKeySudoFailureID = "failure_id" +) diff --git a/x/contractmanager/types/expected_keepers.go b/x/contractmanager/types/expected_keepers.go index f30e346b8..34931862c 100644 --- a/x/contractmanager/types/expected_keepers.go +++ b/x/contractmanager/types/expected_keepers.go @@ -13,6 +13,6 @@ type WasmKeeper interface { } type ContractManagerKeeper interface { - AddContractFailure(ctx sdk.Context, address string, sudoPayload []byte) + AddContractFailure(ctx sdk.Context, address string, sudoPayload []byte, errMsg string) Failure GetParams(ctx sdk.Context) (params Params) } diff --git a/x/contractmanager/types/failure.pb.go b/x/contractmanager/types/failure.pb.go index 063afa74f..c06816160 100644 --- a/x/contractmanager/types/failure.pb.go +++ b/x/contractmanager/types/failure.pb.go @@ -33,6 +33,8 @@ type Failure struct { Id uint64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` // Serialized MessageSudoCallback with Packet and Ack(if exists) SudoPayload []byte `protobuf:"bytes,3,opt,name=sudo_payload,json=sudoPayload,proto3" json:"sudo_payload,omitempty"` + // Redacted error response of the sudo call. Full error is emitted as an event + Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` } func (m *Failure) Reset() { *m = Failure{} } @@ -89,6 +91,13 @@ func (m *Failure) GetSudoPayload() []byte { return nil } +func (m *Failure) GetError() string { + if m != nil { + return m.Error + } + return "" +} + func init() { proto.RegisterType((*Failure)(nil), "neutron.contractmanager.Failure") } @@ -98,22 +107,23 @@ func init() { } var fileDescriptor_fba0c26e85dad46e = []byte{ - // 230 bytes of a gzipped FileDescriptorProto + // 245 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xcd, 0x4b, 0x2d, 0x2d, 0x29, 0xca, 0xcf, 0xd3, 0x4f, 0xce, 0xcf, 0x2b, 0x29, 0x4a, 0x4c, 0x2e, 0xc9, 0x4d, 0xcc, 0x4b, 0x4c, 0x4f, 0x2d, 0xd2, 0x4f, 0x4b, 0xcc, 0xcc, 0x29, 0x2d, 0x4a, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x87, 0x2a, 0xd3, 0x43, 0x53, 0x26, 0xa5, 0x98, 0x99, 0x94, 0xac, 0x9f, 0x9c, 0x5f, 0x94, 0xaa, 0x9f, 0x9c, 0x91, 0x98, 0x97, 0x97, 0x9a, 0xa3, 0x5f, 0x66, 0x08, 0x63, 0x42, - 0xf4, 0x2a, 0x85, 0x71, 0xb1, 0xbb, 0x41, 0x0c, 0x13, 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x49, 0x29, + 0xf4, 0x2a, 0xe5, 0x70, 0xb1, 0xbb, 0x41, 0x0c, 0x13, 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x96, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x71, 0x85, 0xf8, 0xb8, 0x98, 0x32, 0x53, 0x24, 0x98, 0x14, 0x18, 0x35, 0x58, 0x82, 0x98, 0x32, 0x53, 0x84, 0x14, 0xb9, 0x78, 0x8a, 0x4b, 0x53, 0xf2, 0xe3, 0x0b, 0x12, 0x2b, 0x73, 0xf2, 0x13, 0x53, 0x24, 0x98, 0x15, 0x18, - 0x35, 0x78, 0x82, 0xb8, 0x41, 0x62, 0x01, 0x10, 0x21, 0xa7, 0x80, 0x13, 0x8f, 0xe4, 0x18, 0x2f, - 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, - 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4b, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, - 0xd5, 0x87, 0x3a, 0x5c, 0x37, 0xbf, 0x28, 0x1d, 0xc6, 0xd6, 0xaf, 0xc0, 0xf0, 0x6d, 0x49, 0x65, - 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0xc1, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc1, 0xf7, - 0xe5, 0xa7, 0x15, 0x01, 0x00, 0x00, + 0x35, 0x78, 0x82, 0xb8, 0x41, 0x62, 0x01, 0x10, 0x21, 0x21, 0x11, 0x2e, 0xd6, 0xd4, 0xa2, 0xa2, + 0xfc, 0x22, 0x09, 0x16, 0xb0, 0x51, 0x10, 0x8e, 0x53, 0xc0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, + 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, + 0x1e, 0xcb, 0x31, 0x44, 0x99, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, + 0x43, 0xbd, 0xa3, 0x9b, 0x5f, 0x94, 0x0e, 0x63, 0xeb, 0x57, 0x60, 0x84, 0x41, 0x49, 0x65, 0x41, + 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x1b, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x20, 0x77, + 0x4c, 0x2b, 0x01, 0x00, 0x00, } func (m *Failure) Marshal() (dAtA []byte, err error) { @@ -136,6 +146,13 @@ func (m *Failure) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintFailure(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x22 + } if len(m.SudoPayload) > 0 { i -= len(m.SudoPayload) copy(dAtA[i:], m.SudoPayload) @@ -186,6 +203,10 @@ func (m *Failure) Size() (n int) { if l > 0 { n += 1 + l + sovFailure(uint64(l)) } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovFailure(uint64(l)) + } return n } @@ -309,6 +330,38 @@ func (m *Failure) Unmarshal(dAtA []byte) error { m.SudoPayload = []byte{} } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFailure + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthFailure + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthFailure + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipFailure(dAtA[iNdEx:]) diff --git a/x/contractmanager/types/query.pb.go b/x/contractmanager/types/query.pb.go index a4eea203d..b4d8f4adc 100644 --- a/x/contractmanager/types/query.pb.go +++ b/x/contractmanager/types/query.pb.go @@ -113,9 +113,13 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } +// QueryFailuresRequest is request type for the Query/Failures RPC method. type QueryFailuresRequest struct { - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + // address of the contract which Sudo call failed. + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // ID of the failure for the given contract. + FailureId uint64 `protobuf:"varint,2,opt,name=failure_id,json=failureId,proto3" json:"failure_id,omitempty"` + Pagination *query.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryFailuresRequest) Reset() { *m = QueryFailuresRequest{} } @@ -158,6 +162,13 @@ func (m *QueryFailuresRequest) GetAddress() string { return "" } +func (m *QueryFailuresRequest) GetFailureId() uint64 { + if m != nil { + return m.FailureId + } + return 0 +} + func (m *QueryFailuresRequest) GetPagination() *query.PageRequest { if m != nil { return m.Pagination @@ -165,6 +176,7 @@ func (m *QueryFailuresRequest) GetPagination() *query.PageRequest { return nil } +// QueryFailuresResponse is response type for the Query/Failures RPC method. type QueryFailuresResponse struct { Failures []Failure `protobuf:"bytes,1,rep,name=failures,proto3" json:"failures"` Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` @@ -229,37 +241,40 @@ func init() { } var fileDescriptor_f9524a427f219917 = []byte{ - // 475 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x93, 0x31, 0x6f, 0xd4, 0x30, - 0x1c, 0xc5, 0xe3, 0x16, 0x8e, 0xe2, 0x0e, 0x48, 0xe6, 0x10, 0xa7, 0x08, 0xe5, 0xda, 0x14, 0x68, - 0xa1, 0x9c, 0xad, 0x5e, 0x25, 0x36, 0x06, 0x6e, 0x28, 0xeb, 0x11, 0x31, 0xb1, 0x39, 0xa9, 0x31, - 0x91, 0x1a, 0x3b, 0xb5, 0x1d, 0xd4, 0x0a, 0xb1, 0x30, 0x33, 0x20, 0xc1, 0x47, 0x80, 0xef, 0xd2, - 0xb1, 0x12, 0x42, 0x62, 0x42, 0xe8, 0x8e, 0x0f, 0x82, 0x62, 0x3b, 0xa5, 0x5c, 0x49, 0xaf, 0x53, - 0xb7, 0xbb, 0xe4, 0xfd, 0xdf, 0xfb, 0xf9, 0xfd, 0x1d, 0xb8, 0x26, 0x58, 0x65, 0x94, 0x14, 0x24, - 0x93, 0xc2, 0x28, 0x9a, 0x99, 0x82, 0x0a, 0xca, 0x99, 0x22, 0xfb, 0x15, 0x53, 0x87, 0xb8, 0x54, - 0xd2, 0x48, 0x74, 0xdb, 0x8b, 0xf0, 0x8c, 0x28, 0xec, 0x72, 0xc9, 0xa5, 0xd5, 0x90, 0xfa, 0x97, - 0x93, 0x87, 0x77, 0xb8, 0x94, 0x7c, 0x8f, 0x11, 0x5a, 0xe6, 0x84, 0x0a, 0x21, 0x0d, 0x35, 0xb9, - 0x14, 0xda, 0xbf, 0x7d, 0x98, 0x49, 0x5d, 0x48, 0x4d, 0x52, 0xaa, 0x99, 0x4b, 0x21, 0x6f, 0xb6, - 0x52, 0x66, 0xe8, 0x16, 0x29, 0x29, 0xcf, 0x85, 0x15, 0x7b, 0xed, 0xdd, 0x36, 0xba, 0x92, 0x2a, - 0x5a, 0x34, 0x8e, 0xf7, 0xda, 0x54, 0xaf, 0x68, 0xbe, 0x57, 0x29, 0xe6, 0x64, 0x71, 0x17, 0xa2, - 0xe7, 0x75, 0xdc, 0xd8, 0xce, 0x26, 0x6c, 0xbf, 0x62, 0xda, 0xc4, 0x2f, 0xe0, 0xcd, 0x7f, 0x9e, - 0xea, 0x52, 0x0a, 0xcd, 0xd0, 0x13, 0xd8, 0x71, 0x19, 0x3d, 0xb0, 0x02, 0x36, 0x96, 0x87, 0x7d, - 0xdc, 0xd2, 0x01, 0x76, 0x83, 0xa3, 0x2b, 0x47, 0x3f, 0xfb, 0x41, 0xe2, 0x87, 0xe2, 0x03, 0xd8, - 0xb5, 0xae, 0x3b, 0x8e, 0xa0, 0x49, 0x43, 0x3d, 0x78, 0x8d, 0xee, 0xee, 0x2a, 0xa6, 0x9d, 0xef, - 0xf5, 0xa4, 0xf9, 0x8b, 0x76, 0x20, 0xfc, 0x7b, 0xfc, 0xde, 0x82, 0x0d, 0xbd, 0x8f, 0x5d, 0x57, - 0xb8, 0xee, 0x0a, 0xbb, 0x8d, 0xf8, 0xae, 0xf0, 0x98, 0x72, 0xe6, 0x5d, 0x93, 0x53, 0x93, 0xf1, - 0x17, 0x00, 0x6f, 0xcd, 0x44, 0xfb, 0x23, 0x8d, 0xe0, 0x92, 0x2f, 0xa4, 0x0e, 0x5f, 0xdc, 0x58, - 0x1e, 0xae, 0xb4, 0x1e, 0xca, 0x0f, 0xfb, 0x53, 0x9d, 0xcc, 0xa1, 0x67, 0xff, 0xa1, 0x5c, 0x9f, - 0x4b, 0xe9, 0x00, 0x4e, 0x63, 0x0e, 0xbf, 0x2f, 0xc2, 0xab, 0x16, 0x13, 0x7d, 0x00, 0xb0, 0xe3, - 0x3a, 0x44, 0x9b, 0xad, 0x3c, 0x67, 0x17, 0x17, 0x3e, 0xba, 0x98, 0xd8, 0x65, 0xc7, 0xeb, 0xef, - 0xbf, 0xfd, 0xfe, 0xb4, 0xb0, 0x8a, 0xfa, 0xe4, 0xfc, 0x2b, 0x85, 0xbe, 0x02, 0x78, 0xe3, 0xa9, - 0xdb, 0x49, 0xd3, 0x20, 0x1a, 0x9c, 0x1f, 0x35, 0xb3, 0xe4, 0x10, 0x5f, 0x54, 0xee, 0xd9, 0xb6, - 0x2d, 0xdb, 0x00, 0x6d, 0x92, 0x39, 0x17, 0x59, 0x93, 0xb7, 0xfe, 0xba, 0xbc, 0x43, 0x9f, 0x01, - 0x5c, 0xba, 0x2c, 0xc0, 0x07, 0x16, 0x70, 0x0d, 0xad, 0xce, 0x05, 0x1c, 0x8d, 0x8f, 0x26, 0x11, - 0x38, 0x9e, 0x44, 0xe0, 0xd7, 0x24, 0x02, 0x1f, 0xa7, 0x51, 0x70, 0x3c, 0x8d, 0x82, 0x1f, 0xd3, - 0x28, 0x78, 0xf9, 0x98, 0xe7, 0xe6, 0x75, 0x95, 0xe2, 0x4c, 0x16, 0x8d, 0xcd, 0x40, 0x2a, 0x7e, - 0x62, 0x79, 0x70, 0xc6, 0xd4, 0x1c, 0x96, 0x4c, 0xa7, 0x1d, 0xfb, 0xf5, 0x6e, 0xff, 0x09, 0x00, - 0x00, 0xff, 0xff, 0x05, 0x7b, 0x9c, 0xb2, 0xaa, 0x04, 0x00, 0x00, + // 527 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0xc1, 0x6a, 0x13, 0x41, + 0x18, 0xc7, 0x33, 0x69, 0x1b, 0xdb, 0x29, 0x28, 0x8c, 0x11, 0x43, 0xd0, 0x4d, 0xba, 0x55, 0x1b, + 0xad, 0x99, 0xa1, 0x29, 0x88, 0x08, 0x82, 0xe6, 0x50, 0xf1, 0x16, 0x17, 0x4f, 0x5e, 0x64, 0x92, + 0x8c, 0xe3, 0x42, 0x33, 0xb3, 0x9d, 0x99, 0x15, 0x4b, 0xe9, 0xc5, 0x9b, 0xe0, 0x41, 0x50, 0xf0, + 0x05, 0xf4, 0x01, 0x7c, 0x8b, 0x1e, 0x0b, 0x5e, 0x3c, 0x89, 0x24, 0x3e, 0x88, 0x64, 0x66, 0xd2, + 0x36, 0x29, 0xdb, 0xc4, 0x83, 0xbd, 0xed, 0xce, 0xfe, 0xbf, 0xef, 0xff, 0x9b, 0xff, 0xf7, 0xb1, + 0x70, 0x55, 0xb0, 0xd4, 0x28, 0x29, 0x48, 0x47, 0x0a, 0xa3, 0x68, 0xc7, 0xf4, 0xa8, 0xa0, 0x9c, + 0x29, 0xb2, 0x93, 0x32, 0xb5, 0x8b, 0x13, 0x25, 0x8d, 0x44, 0x57, 0xbd, 0x08, 0x4f, 0x88, 0xca, + 0x45, 0x2e, 0xb9, 0xb4, 0x1a, 0x32, 0x7c, 0x72, 0xf2, 0xf2, 0x35, 0x2e, 0x25, 0xdf, 0x66, 0x84, + 0x26, 0x31, 0xa1, 0x42, 0x48, 0x43, 0x4d, 0x2c, 0x85, 0xf6, 0x5f, 0xef, 0x74, 0xa4, 0xee, 0x49, + 0x4d, 0xda, 0x54, 0x33, 0xe7, 0x42, 0xde, 0x6c, 0xb4, 0x99, 0xa1, 0x1b, 0x24, 0xa1, 0x3c, 0x16, + 0x56, 0xec, 0xb5, 0x37, 0xb2, 0xe8, 0x12, 0xaa, 0x68, 0x6f, 0xd4, 0xf1, 0x66, 0x96, 0xea, 0x15, + 0x8d, 0xb7, 0x53, 0xc5, 0x9c, 0x2c, 0x2c, 0x42, 0xf4, 0x6c, 0x68, 0xd7, 0xb2, 0xb5, 0x11, 0xdb, + 0x49, 0x99, 0x36, 0xe1, 0x73, 0x78, 0x79, 0xec, 0x54, 0x27, 0x52, 0x68, 0x86, 0x1e, 0xc2, 0x82, + 0xf3, 0x28, 0x81, 0x2a, 0xa8, 0x2d, 0x37, 0x2a, 0x38, 0x23, 0x03, 0xec, 0x0a, 0x9b, 0xf3, 0x07, + 0xbf, 0x2a, 0xb9, 0xc8, 0x17, 0x85, 0x5f, 0x00, 0x2c, 0xda, 0xb6, 0x5b, 0x0e, 0x61, 0x64, 0x87, + 0x4a, 0xf0, 0x02, 0xed, 0x76, 0x15, 0xd3, 0xae, 0xf1, 0x52, 0x34, 0x7a, 0x45, 0xd7, 0x21, 0xf4, + 0xbc, 0x2f, 0xe3, 0x6e, 0x29, 0x5f, 0x05, 0xb5, 0xf9, 0x68, 0xc9, 0x9f, 0x3c, 0xed, 0xa2, 0x2d, + 0x08, 0x8f, 0xe3, 0x29, 0xcd, 0x59, 0xa8, 0x5b, 0xd8, 0x65, 0x89, 0x87, 0x59, 0x62, 0x37, 0x31, + 0x9f, 0x25, 0x6e, 0x51, 0xce, 0xbc, 0x69, 0x74, 0xa2, 0x32, 0xfc, 0x0a, 0xe0, 0x95, 0x09, 0x32, + 0x7f, 0xe5, 0x26, 0x5c, 0xf4, 0x76, 0x43, 0xb6, 0xb9, 0xda, 0x72, 0xa3, 0x9a, 0x79, 0x69, 0x5f, + 0xec, 0x6f, 0x7d, 0x54, 0x87, 0x9e, 0x8c, 0x51, 0xe6, 0x2d, 0xe5, 0xda, 0x54, 0x4a, 0x07, 0x70, + 0x12, 0xb3, 0xf1, 0x7e, 0x01, 0x2e, 0x58, 0x4c, 0xf4, 0x01, 0xc0, 0x82, 0xcb, 0x18, 0xad, 0x67, + 0xf2, 0x9c, 0x1e, 0x6c, 0xf9, 0xee, 0x6c, 0x62, 0xe7, 0x1d, 0xae, 0xbd, 0xfb, 0xf1, 0xe7, 0x53, + 0x7e, 0x05, 0x55, 0xc8, 0xd9, 0x2b, 0x87, 0xbe, 0x03, 0x78, 0xf1, 0xb1, 0x1b, 0x99, 0x0f, 0x01, + 0xd5, 0xcf, 0x76, 0x9a, 0x58, 0x81, 0x32, 0x9e, 0x55, 0xee, 0xd1, 0x1e, 0x59, 0xb4, 0x07, 0xe8, + 0x3e, 0x99, 0xb2, 0xe7, 0x9a, 0xec, 0xf9, 0x65, 0xda, 0x27, 0x7b, 0xc7, 0xbb, 0xb4, 0x8f, 0xbe, + 0x01, 0x78, 0x69, 0x9c, 0x59, 0xff, 0x6f, 0xe8, 0x4d, 0x0b, 0x5d, 0x47, 0xeb, 0xff, 0x00, 0x8d, + 0x3e, 0x03, 0xb8, 0x78, 0x5e, 0x80, 0xb7, 0x2d, 0xe0, 0x2a, 0x5a, 0x99, 0x0a, 0xd8, 0x6c, 0x1d, + 0xf4, 0x03, 0x70, 0xd8, 0x0f, 0xc0, 0xef, 0x7e, 0x00, 0x3e, 0x0e, 0x82, 0xdc, 0xe1, 0x20, 0xc8, + 0xfd, 0x1c, 0x04, 0xb9, 0x17, 0xf7, 0x78, 0x6c, 0x5e, 0xa7, 0x6d, 0xdc, 0x91, 0xbd, 0x51, 0x9b, + 0xba, 0x54, 0xfc, 0xa8, 0xe5, 0xdb, 0x53, 0x4d, 0xcd, 0x6e, 0xc2, 0x74, 0xbb, 0x60, 0xff, 0x48, + 0x9b, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xb5, 0xbb, 0x34, 0x7e, 0x05, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -276,9 +291,11 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // Parameters queries the parameters of the module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) - // Queries a Failure by address. + // Queries a Failure by contract address and failure ID. + AddressFailure(ctx context.Context, in *QueryFailuresRequest, opts ...grpc.CallOption) (*QueryFailuresResponse, error) + // Queries Failures by contract address. AddressFailures(ctx context.Context, in *QueryFailuresRequest, opts ...grpc.CallOption) (*QueryFailuresResponse, error) - // Queries a list of Failure items. + // Queries a list of Failures occurred on the network. Failures(ctx context.Context, in *QueryFailuresRequest, opts ...grpc.CallOption) (*QueryFailuresResponse, error) } @@ -299,6 +316,15 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . return out, nil } +func (c *queryClient) AddressFailure(ctx context.Context, in *QueryFailuresRequest, opts ...grpc.CallOption) (*QueryFailuresResponse, error) { + out := new(QueryFailuresResponse) + err := c.cc.Invoke(ctx, "/neutron.contractmanager.Query/AddressFailure", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) AddressFailures(ctx context.Context, in *QueryFailuresRequest, opts ...grpc.CallOption) (*QueryFailuresResponse, error) { out := new(QueryFailuresResponse) err := c.cc.Invoke(ctx, "/neutron.contractmanager.Query/AddressFailures", in, out, opts...) @@ -321,9 +347,11 @@ func (c *queryClient) Failures(ctx context.Context, in *QueryFailuresRequest, op type QueryServer interface { // Parameters queries the parameters of the module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - // Queries a Failure by address. + // Queries a Failure by contract address and failure ID. + AddressFailure(context.Context, *QueryFailuresRequest) (*QueryFailuresResponse, error) + // Queries Failures by contract address. AddressFailures(context.Context, *QueryFailuresRequest) (*QueryFailuresResponse, error) - // Queries a list of Failure items. + // Queries a list of Failures occurred on the network. Failures(context.Context, *QueryFailuresRequest) (*QueryFailuresResponse, error) } @@ -334,6 +362,9 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } +func (*UnimplementedQueryServer) AddressFailure(ctx context.Context, req *QueryFailuresRequest) (*QueryFailuresResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddressFailure not implemented") +} func (*UnimplementedQueryServer) AddressFailures(ctx context.Context, req *QueryFailuresRequest) (*QueryFailuresResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddressFailures not implemented") } @@ -363,6 +394,24 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Query_AddressFailure_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryFailuresRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AddressFailure(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/neutron.contractmanager.Query/AddressFailure", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AddressFailure(ctx, req.(*QueryFailuresRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_AddressFailures_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryFailuresRequest) if err := dec(in); err != nil { @@ -407,6 +456,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Params", Handler: _Query_Params_Handler, }, + { + MethodName: "AddressFailure", + Handler: _Query_AddressFailure_Handler, + }, { MethodName: "AddressFailures", Handler: _Query_AddressFailures_Handler, @@ -506,7 +559,12 @@ func (m *QueryFailuresRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a + } + if m.FailureId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.FailureId)) + i-- + dAtA[i] = 0x10 } if len(m.Address) > 0 { i -= len(m.Address) @@ -608,6 +666,9 @@ func (m *QueryFailuresRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + if m.FailureId != 0 { + n += 1 + sovQuery(uint64(m.FailureId)) + } if m.Pagination != nil { l = m.Pagination.Size() n += 1 + l + sovQuery(uint64(l)) @@ -835,6 +896,25 @@ func (m *QueryFailuresRequest) Unmarshal(dAtA []byte) error { m.Address = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FailureId", wireType) + } + m.FailureId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FailureId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) } diff --git a/x/contractmanager/types/query.pb.gw.go b/x/contractmanager/types/query.pb.gw.go index 53090c4e2..2c201192b 100644 --- a/x/contractmanager/types/query.pb.gw.go +++ b/x/contractmanager/types/query.pb.gw.go @@ -51,6 +51,100 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal } +var ( + filter_Query_AddressFailure_0 = &utilities.DoubleArray{Encoding: map[string]int{"address": 0, "failure_id": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} +) + +func request_Query_AddressFailure_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryFailuresRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + val, ok = pathParams["failure_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "failure_id") + } + + protoReq.FailureId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "failure_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_AddressFailure_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.AddressFailure(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AddressFailure_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryFailuresRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + val, ok = pathParams["failure_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "failure_id") + } + + protoReq.FailureId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "failure_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_AddressFailure_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.AddressFailure(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Query_AddressFailures_0 = &utilities.DoubleArray{Encoding: map[string]int{"address": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) @@ -188,6 +282,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_AddressFailure_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AddressFailure_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AddressFailure_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_AddressFailures_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -295,6 +412,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_AddressFailure_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AddressFailure_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AddressFailure_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_AddressFailures_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -341,6 +478,8 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie var ( pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"neutron", "contractmanager", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_AddressFailure_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"neutron", "contractmanager", "failures", "address", "failure_id"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_AddressFailures_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"neutron", "contractmanager", "failures", "address"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_Failures_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"neutron", "contractmanager", "failures"}, "", runtime.AssumeColonVerbOpt(false))) @@ -349,6 +488,8 @@ var ( var ( forward_Query_Params_0 = runtime.ForwardResponseMessage + forward_Query_AddressFailure_0 = runtime.ForwardResponseMessage + forward_Query_AddressFailures_0 = runtime.ForwardResponseMessage forward_Query_Failures_0 = runtime.ForwardResponseMessage diff --git a/x/interchaintxs/keeper/msg_server_test.go b/x/interchaintxs/keeper/msg_server_test.go index c4c173deb..b542bb112 100644 --- a/x/interchaintxs/keeper/msg_server_test.go +++ b/x/interchaintxs/keeper/msg_server_test.go @@ -7,6 +7,7 @@ import ( "github.com/neutron-org/neutron/app/params" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" feerefundertypes "github.com/neutron-org/neutron/x/feerefunder/types" "github.com/neutron-org/neutron/x/interchaintxs/keeper" @@ -54,6 +55,7 @@ func TestRegisterInterchainAccount(t *testing.T) { require.Nil(t, resp) wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) + wmKeeper.EXPECT().GetContractInfo(ctx, contractAddress).Return(&wasmtypes.ContractInfo{CodeID: 1}) resp, err = icak.RegisterInterchainAccount(goCtx, &msgRegAcc) require.ErrorContains(t, err, "failed to charge fees to pay for RegisterInterchainAccount msg") require.Nil(t, resp) @@ -61,6 +63,7 @@ func TestRegisterInterchainAccount(t *testing.T) { msgRegAcc.RegisterFee = sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, sdk.NewInt(1000))) wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) + wmKeeper.EXPECT().GetContractInfo(ctx, contractAddress).Return(&wasmtypes.ContractInfo{CodeID: 1}) bankKeeper.EXPECT().SendCoins(ctx, sdk.MustAccAddressFromBech32(msgRegAcc.FromAddress), sdk.MustAccAddressFromBech32(TestFeeCollectorAddr), msgRegAcc.RegisterFee) icaKeeper.EXPECT().RegisterInterchainAccount(ctx, msgRegAcc.ConnectionId, icaOwner.String(), "").Return(fmt.Errorf("failed to register ica")) resp, err = icak.RegisterInterchainAccount(goCtx, &msgRegAcc) @@ -68,6 +71,7 @@ func TestRegisterInterchainAccount(t *testing.T) { require.Nil(t, resp) wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) + wmKeeper.EXPECT().GetContractInfo(ctx, contractAddress).Return(&wasmtypes.ContractInfo{CodeID: 1}) bankKeeper.EXPECT(). SendCoins(ctx, sdk.MustAccAddressFromBech32(msgRegAcc.FromAddress), sdk.MustAccAddressFromBech32(TestFeeCollectorAddr), msgRegAcc.RegisterFee). Return(fmt.Errorf("failed to send coins")) @@ -76,6 +80,7 @@ func TestRegisterInterchainAccount(t *testing.T) { require.Nil(t, resp) wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) + wmKeeper.EXPECT().GetContractInfo(ctx, contractAddress).Return(&wasmtypes.ContractInfo{CodeID: 1}) bankKeeper.EXPECT().SendCoins(ctx, sdk.MustAccAddressFromBech32(msgRegAcc.FromAddress), sdk.MustAccAddressFromBech32(TestFeeCollectorAddr), msgRegAcc.RegisterFee) icaKeeper.EXPECT().RegisterInterchainAccount(ctx, msgRegAcc.ConnectionId, icaOwner.String(), "").Return(nil) resp, err = icak.RegisterInterchainAccount(goCtx, &msgRegAcc)