From 9ae2fd32be39a9d9a06ad35532cf18508d4017c9 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Sat, 27 Aug 2022 17:00:29 -0500 Subject: [PATCH 01/16] Add contract authz proto --- docs/proto/proto-docs.md | 36 +++ proto/cosmwasm/wasm/v1/authz.proto | 21 ++ x/wasm/types/authz.pb.go | 421 +++++++++++++++++++++++++++++ 3 files changed, 478 insertions(+) create mode 100644 proto/cosmwasm/wasm/v1/authz.proto create mode 100644 x/wasm/types/authz.pb.go diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index d6e5aee1d6..d561b638bf 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -4,6 +4,9 @@ ## Table of Contents +- [cosmwasm/wasm/v1/authz.proto](#cosmwasm/wasm/v1/authz.proto) + - [ContractAuthorization](#cosmwasm.wasm.v1.ContractAuthorization) + - [cosmwasm/wasm/v1/types.proto](#cosmwasm/wasm/v1/types.proto) - [AbsoluteTxPosition](#cosmwasm.wasm.v1.AbsoluteTxPosition) - [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) @@ -90,6 +93,39 @@ + +

Top

+ +## cosmwasm/wasm/v1/authz.proto + + + + + +### ContractAuthorization +ContractAuthorization defines authorization for wasm execute. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `messages` | [string](#string) | repeated | Messages is the list of messages that can be executed | +| `once` | [bool](#bool) | | Once specifies if the contract can only be called once | + + + + + + + + + + + + + + +

Top

diff --git a/proto/cosmwasm/wasm/v1/authz.proto b/proto/cosmwasm/wasm/v1/authz.proto new file mode 100644 index 0000000000..c6d0e39add --- /dev/null +++ b/proto/cosmwasm/wasm/v1/authz.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; + +// ContractAuthorization defines authorization for wasm execute. +message ContractAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + // Contract is the address of the smart contract + string contract = 1; + + // Messages is the list of messages that can be executed + repeated string messages = 2; + + // Once specifies if the contract can only be called once + bool once = 3; +} diff --git a/x/wasm/types/authz.pb.go b/x/wasm/types/authz.pb.go new file mode 100644 index 0000000000..252426fada --- /dev/null +++ b/x/wasm/types/authz.pb.go @@ -0,0 +1,421 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmwasm/wasm/v1/authz.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + _ "github.com/regen-network/cosmos-proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// ContractAuthorization defines authorization for wasm execute. +type ContractAuthorization struct { + // Contract is the address of the smart contract + Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` + // Messages is the list of messages that can be executed + Messages []string `protobuf:"bytes,2,rep,name=messages,proto3" json:"messages,omitempty"` + // Once specifies if the contract can only be called once + Once bool `protobuf:"varint,3,opt,name=once,proto3" json:"once,omitempty"` +} + +func (m *ContractAuthorization) Reset() { *m = ContractAuthorization{} } +func (m *ContractAuthorization) String() string { return proto.CompactTextString(m) } +func (*ContractAuthorization) ProtoMessage() {} +func (*ContractAuthorization) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{0} +} +func (m *ContractAuthorization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractAuthorization.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ContractAuthorization) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractAuthorization.Merge(m, src) +} +func (m *ContractAuthorization) XXX_Size() int { + return m.Size() +} +func (m *ContractAuthorization) XXX_DiscardUnknown() { + xxx_messageInfo_ContractAuthorization.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractAuthorization proto.InternalMessageInfo + +func (m *ContractAuthorization) GetContract() string { + if m != nil { + return m.Contract + } + return "" +} + +func (m *ContractAuthorization) GetMessages() []string { + if m != nil { + return m.Messages + } + return nil +} + +func (m *ContractAuthorization) GetOnce() bool { + if m != nil { + return m.Once + } + return false +} + +func init() { + proto.RegisterType((*ContractAuthorization)(nil), "cosmwasm.wasm.v1.ContractAuthorization") +} + +func init() { proto.RegisterFile("cosmwasm/wasm/v1/authz.proto", fileDescriptor_36ff3a20cf32b258) } + +var fileDescriptor_36ff3a20cf32b258 = []byte{ + // 231 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xce, 0x2f, 0xce, + 0x2d, 0x4f, 0x2c, 0xce, 0xd5, 0x07, 0x13, 0x65, 0x86, 0xfa, 0x89, 0xa5, 0x25, 0x19, 0x55, 0x7a, + 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x02, 0x30, 0x59, 0x3d, 0x30, 0x51, 0x66, 0x28, 0x25, 0x92, + 0x9e, 0x9f, 0x9e, 0x0f, 0x96, 0xd4, 0x07, 0xb1, 0x20, 0xea, 0xa4, 0x24, 0x41, 0xea, 0xf2, 0x8b, + 0xe3, 0x21, 0x12, 0x10, 0x0e, 0x44, 0x4a, 0xa9, 0x8c, 0x4b, 0xd4, 0x39, 0x3f, 0xaf, 0xa4, 0x28, + 0x31, 0xb9, 0xc4, 0xb1, 0xb4, 0x24, 0x23, 0xbf, 0x28, 0xb3, 0x2a, 0xb1, 0x24, 0x33, 0x3f, 0x4f, + 0x48, 0x8a, 0x8b, 0x23, 0x19, 0x2a, 0x21, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe7, 0x83, + 0xe4, 0x72, 0x53, 0x8b, 0x8b, 0x13, 0xd3, 0x53, 0x8b, 0x25, 0x98, 0x14, 0x98, 0x41, 0x72, 0x30, + 0xbe, 0x90, 0x10, 0x17, 0x4b, 0x7e, 0x5e, 0x72, 0xaa, 0x04, 0xb3, 0x02, 0xa3, 0x06, 0x47, 0x10, + 0x98, 0x6d, 0x25, 0x78, 0x69, 0x8b, 0x2e, 0x2f, 0x8a, 0xf1, 0x4e, 0x0e, 0x27, 0x1e, 0xc9, 0x31, + 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, + 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x96, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, + 0x9f, 0xab, 0xef, 0x9c, 0x5f, 0x9c, 0x1b, 0x0e, 0xf3, 0x7d, 0x8a, 0x7e, 0x05, 0x24, 0x14, 0x4a, + 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x1e, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xc8, + 0x96, 0x56, 0x12, 0x23, 0x01, 0x00, 0x00, +} + +func (m *ContractAuthorization) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractAuthorization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Once { + i-- + if m.Once { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.Messages) > 0 { + for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Messages[iNdEx]) + copy(dAtA[i:], m.Messages[iNdEx]) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Messages[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintAuthz(dAtA []byte, offset int, v uint64) int { + offset -= sovAuthz(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ContractAuthorization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovAuthz(uint64(l)) + } + if len(m.Messages) > 0 { + for _, s := range m.Messages { + l = len(s) + n += 1 + l + sovAuthz(uint64(l)) + } + } + if m.Once { + n += 2 + } + return n +} + +func sovAuthz(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAuthz(x uint64) (n int) { + return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ContractAuthorization) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + 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 ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + 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 ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Messages = append(m.Messages, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Once", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Once = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAuthz(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthAuthz + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAuthz + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAuthz + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAuthz = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAuthz = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAuthz = fmt.Errorf("proto: unexpected end of group") +) From 13585026d2befd2335c057b16060f460c2d6ec2b Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Sat, 27 Aug 2022 17:30:01 -0500 Subject: [PATCH 02/16] Implement contract autorization --- x/wasm/types/authz.go | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 x/wasm/types/authz.go diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go new file mode 100644 index 0000000000..65b5935fdb --- /dev/null +++ b/x/wasm/types/authz.go @@ -0,0 +1,57 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authztypes "github.com/cosmos/cosmos-sdk/x/authz" +) + +var ( + _ authztypes.Authorization = &ContractAuthorization{} +) + +// NewContractAuthorization creates a new ContractAuthorization object. +func NewContractAuthorization(contract string, messages []string, once bool) *ContractAuthorization { + return &ContractAuthorization{ + Contract: contract, + Messages: messages, + Once: once, + } +} + +// MsgTypeURL implements Authorization.MsgTypeURL. +func (a ContractAuthorization) MsgTypeURL() string { + return sdk.MsgTypeURL(&MsgExecuteContract{}) +} + +// Accept implements Authorization.Accept. +func (a ContractAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) { + exec, ok := msg.(*MsgExecuteContract) + if !ok { + return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("type mismatch") + } + + if a.Contract != exec.Contract { + return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("cannot run %s contract", exec.Contract) + } + + if err := IsJSONObjectWithTopLevelKey(exec.Msg, a.Messages); err != nil { + return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("no allowed msg, %s", err.Error()) + } + + return authztypes.AcceptResponse{Accept: true, Delete: a.Once}, nil +} + +// ValidateBasic implements Authorization.ValidateBasic. +func (a ContractAuthorization) ValidateBasic() error { + if len(a.Contract) == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "contract address cannot be empty") + } + if _, err := sdk.AccAddressFromBech32(a.Contract); err != nil { + return sdkerrors.Wrap(err, "contract address") + } + if len(a.Messages) == 0 { + return sdkerrors.ErrInvalidRequest.Wrap("empty msg list") + } + return nil +} From 8f3035791d461ee63a9b91d87e0e2131ebe17fbe Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Sat, 27 Aug 2022 17:30:11 -0500 Subject: [PATCH 03/16] Register contract authz --- x/wasm/types/codec.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x/wasm/types/codec.go b/x/wasm/types/codec.go index f1cd6f557f..48609a0277 100644 --- a/x/wasm/types/codec.go +++ b/x/wasm/types/codec.go @@ -6,6 +6,7 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" + "github.com/cosmos/cosmos-sdk/x/authz" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -29,6 +30,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { //nolint:staticcheck cdc.RegisterConcrete(&UpdateAdminProposal{}, "wasm/UpdateAdminProposal", nil) cdc.RegisterConcrete(&ClearAdminProposal{}, "wasm/ClearAdminProposal", nil) cdc.RegisterConcrete(&UpdateInstantiateConfigProposal{}, "wasm/UpdateInstantiateConfigProposal", nil) + cdc.RegisterConcrete(&ContractAuthorization{}, "wasm/ContractAuthorization", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -60,6 +62,11 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { registry.RegisterInterface("ContractInfoExtension", (*ContractInfoExtension)(nil)) + registry.RegisterImplementations( + (*authz.Authorization)(nil), + &ContractAuthorization{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } From 6dec6ade7e9150ba81f4dce9b02ac2fe4e911f27 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Sat, 27 Aug 2022 19:19:56 -0500 Subject: [PATCH 04/16] Add contract-authz tests --- x/wasm/types/authz.go | 4 +- x/wasm/types/authz_test.go | 95 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 x/wasm/types/authz_test.go diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index 65b5935fdb..44c6767a71 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -11,9 +11,9 @@ var ( ) // NewContractAuthorization creates a new ContractAuthorization object. -func NewContractAuthorization(contract string, messages []string, once bool) *ContractAuthorization { +func NewContractAuthorization(contractAddr sdk.AccAddress, messages []string, once bool) *ContractAuthorization { return &ContractAuthorization{ - Contract: contract, + Contract: contractAddr.String(), Messages: messages, Once: once, } diff --git a/x/wasm/types/authz_test.go b/x/wasm/types/authz_test.go new file mode 100644 index 0000000000..df0c39ea01 --- /dev/null +++ b/x/wasm/types/authz_test.go @@ -0,0 +1,95 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestAuthzAuthorizations(t *testing.T) { + ctx := sdk.Context{} + + contractAuth := NewContractAuthorization(sdk.AccAddress{}, []string{"bond"}, false) + require.Equal(t, contractAuth.MsgTypeURL(), "/cosmwasm.wasm.v1.MsgExecuteContract") + require.Error(t, contractAuth.ValidateBasic()) + + contractAuth = NewContractAuthorization(sdk.AccAddress("cw-contract"), []string{}, false) + require.Error(t, contractAuth.ValidateBasic()) + + testCases := map[string]struct { + contract string + allowed []string + once bool + srvMsg sdk.Msg + expectErr bool + }{ + "invalid cosmos msg": { + "cw-staking-1", + []string{"claim"}, + false, + &MsgClearAdmin{}, + true, + }, + "no allowed contract": { + "cw-staking-1", + []string{"claim"}, + false, + newGranteeExecuteMsg("cw-staking-2", `{"claim": {}}`), + true, + }, + "no allowed msg": { + "cw-staking-1", + []string{"claim", "harvest", "bond"}, + false, + newGranteeExecuteMsg("cw-staking-1", `{"unbond": {}}`), + true, + }, + "many msgs in execute msg": { + "cw-staking-1", + []string{"bond", "claim"}, + false, + newGranteeExecuteMsg("cw-staking-1", `{"claim": {}, "bond":{}}`), + true, + }, + "valid contract and msgs": { + "cw-staking-1", + []string{"bond", "claim"}, + false, + newGranteeExecuteMsg("cw-staking-1", `{"claim": {}}`), + false, + }, + "allowed once": { + "cw-staking-1", + []string{"bond", "claim"}, + true, + newGranteeExecuteMsg("cw-staking-1", `{"bond": {}}`), + false, + }, + } + + for name, tc := range testCases { + tc := tc + t.Run(name, func(t *testing.T) { + contractAuth = NewContractAuthorization(sdk.AccAddress(tc.contract), tc.allowed, tc.once) + resp, err := contractAuth.Accept(ctx, tc.srvMsg) + if tc.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.once, resp.Delete) + require.Nil(t, resp.Updated) + } + }) + } +} + +func newGranteeExecuteMsg(contract, msg string) *MsgExecuteContract { + return &MsgExecuteContract{ + Sender: "grantee", + Contract: sdk.AccAddress(contract).String(), + Msg: []byte(msg), + Funds: sdk.Coins{}, + } +} From 1cb6bd0380835feafa036061ed0270ae66780a10 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Sat, 27 Aug 2022 20:31:09 -0500 Subject: [PATCH 05/16] Consume gas for contract authz --- x/wasm/types/authz.go | 10 ++++++---- x/wasm/types/authz_test.go | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index 44c6767a71..ad93c05284 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -6,9 +6,9 @@ import ( authztypes "github.com/cosmos/cosmos-sdk/x/authz" ) -var ( - _ authztypes.Authorization = &ContractAuthorization{} -) +const gasDeserializationCostPerByte = uint64(1) + +var _ authztypes.Authorization = &ContractAuthorization{} // NewContractAuthorization creates a new ContractAuthorization object. func NewContractAuthorization(contractAddr sdk.AccAddress, messages []string, once bool) *ContractAuthorization { @@ -35,6 +35,8 @@ func (a ContractAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes. return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("cannot run %s contract", exec.Contract) } + gasForDeserialization := gasDeserializationCostPerByte * uint64(len(exec.Msg)) + ctx.GasMeter().ConsumeGas(gasForDeserialization, "contract authorization") if err := IsJSONObjectWithTopLevelKey(exec.Msg, a.Messages); err != nil { return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("no allowed msg, %s", err.Error()) } @@ -48,7 +50,7 @@ func (a ContractAuthorization) ValidateBasic() error { return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "contract address cannot be empty") } if _, err := sdk.AccAddressFromBech32(a.Contract); err != nil { - return sdkerrors.Wrap(err, "contract address") + return sdkerrors.Wrap(err, "contract") } if len(a.Messages) == 0 { return sdkerrors.ErrInvalidRequest.Wrap("empty msg list") diff --git a/x/wasm/types/authz_test.go b/x/wasm/types/authz_test.go index df0c39ea01..e842b67e2c 100644 --- a/x/wasm/types/authz_test.go +++ b/x/wasm/types/authz_test.go @@ -4,12 +4,15 @@ import ( "testing" "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" ) func TestAuthzAuthorizations(t *testing.T) { - ctx := sdk.Context{} + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) contractAuth := NewContractAuthorization(sdk.AccAddress{}, []string{"bond"}, false) require.Equal(t, contractAuth.MsgTypeURL(), "/cosmwasm.wasm.v1.MsgExecuteContract") From fa235fded7ae19e50609a4fede1a673182765196 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Sat, 27 Aug 2022 20:55:30 -0500 Subject: [PATCH 06/16] Add contract authz cli --- x/wasm/client/cli/tx.go | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index 9a2eebfda8..d627328b45 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "strconv" + "time" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -13,6 +14,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/authz" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -32,6 +34,9 @@ const ( flagInstantiateByAddress = "instantiate-only-address" flagInstantiateByAnyOfAddress = "instantiate-anyof-addresses" flagUnpinCode = "unpin-code" + flagAllowedMsgs = "allow-msgs" + flagRunOnce = "run-once" + flagExpiration = "expiration" ) // GetTxCmd returns the transaction commands for this module @@ -51,6 +56,7 @@ func GetTxCmd() *cobra.Command { MigrateContractCmd(), UpdateContractAdminCmd(), ClearContractAdminCmd(), + GrantAuthorizationCmd(), ) return txCmd } @@ -372,3 +378,59 @@ func parseExecuteArgs(contractAddr string, execMsg string, sender sdk.AccAddress Msg: []byte(execMsg), }, nil } + +func GrantAuthorizationCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "grant [grantee] [contract_addr_bech32] --msgs [msg1,msg2,...]", + Short: "Grant authorization to an address", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + grantee, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + contract, err := sdk.AccAddressFromBech32(args[1]) + if err != nil { + return err + } + + msgs, err := cmd.Flags().GetStringSlice(flagAllowedMsgs) + if err != nil { + return err + } + + once, err := cmd.Flags().GetBool(flagRunOnce) + if err != nil { + return err + } + + exp, err := cmd.Flags().GetInt64(flagExpiration) + if err != nil { + return err + } + + authorization := types.NewContractAuthorization(contract, msgs, once) + if err = authorization.ValidateBasic(); err != nil { + return err + } + + msg, err := authz.NewMsgGrant(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(exp, 0)) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + flags.AddTxFlagsToCmd(cmd) + cmd.Flags().StringSlice(flagAllowedMsgs, []string{}, "Allowed msgs") + cmd.Flags().Bool(flagRunOnce, false, "Allow to execute only once") + cmd.Flags().Int64(flagExpiration, time.Now().AddDate(1, 0, 0).Unix(), "The Unix timestamp. Default is one year.") + return cmd +} From 14cedff715defc586cd9915b8b6f43a6891ee8eb Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Sun, 28 Aug 2022 12:06:27 -0500 Subject: [PATCH 07/16] Update cli usage --- x/wasm/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index d627328b45..55ad814d9b 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -381,7 +381,7 @@ func parseExecuteArgs(contractAddr string, execMsg string, sender sdk.AccAddress func GrantAuthorizationCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "grant [grantee] [contract_addr_bech32] --msgs [msg1,msg2,...]", + Use: "grant [grantee] [contract_addr_bech32] --allow-msgs [msg1,msg2,...]", Short: "Grant authorization to an address", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { From 46aba003022f8a5c24f9a8e85f13f23b32305ac9 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 6 Sep 2022 08:44:42 +0200 Subject: [PATCH 08/16] Model spike --- docs/proto/proto-docs.md | 121 +- proto/cosmwasm/wasm/v1/authz.proto | 67 +- x/wasm/types/authz.go | 149 +- x/wasm/types/authz.pb.go | 2062 +++++++++++++++++++++++++--- x/wasm/types/codec.go | 4 +- x/wasm/types/json_matching_test.go | 19 +- 6 files changed, 2203 insertions(+), 219 deletions(-) diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index d561b638bf..ae5b884b66 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -5,7 +5,14 @@ ## Table of Contents - [cosmwasm/wasm/v1/authz.proto](#cosmwasm/wasm/v1/authz.proto) - - [ContractAuthorization](#cosmwasm.wasm.v1.ContractAuthorization) + - [AcceptedMessageKeysFilter](#cosmwasm.wasm.v1.AcceptedMessageKeysFilter) + - [AllowAllWildcard](#cosmwasm.wasm.v1.AllowAllWildcard) + - [ContractExecutionAuthorization](#cosmwasm.wasm.v1.ContractExecutionAuthorization) + - [ContractExecutionAuthorization.ContractExecutionGrant](#cosmwasm.wasm.v1.ContractExecutionAuthorization.ContractExecutionGrant) + - [ContractMigrationAuthorization](#cosmwasm.wasm.v1.ContractMigrationAuthorization) + - [ContractMigrationAuthorization.ContractMigrationGrant](#cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant) + - [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) + - [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) - [cosmwasm/wasm/v1/types.proto](#cosmwasm/wasm/v1/types.proto) - [AbsoluteTxPosition](#cosmwasm.wasm.v1.AbsoluteTxPosition) @@ -100,17 +107,119 @@ - + -### ContractAuthorization -ContractAuthorization defines authorization for wasm execute. +### AcceptedMessageKeysFilter +AcceptedMessageKeysFilter accept specific contract message keys in the json +object that can be executed + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `messages` | [string](#string) | repeated | Messages is the list of unique keys | + + + + + + + + +### AllowAllWildcard +AllowAllWildcard is a wildcard to allow any type of contract execution +message + + + + + + + + +### ContractExecutionAuthorization +ContractExecutionAuthorization defines authorization for wasm execute. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `grants` | [ContractExecutionAuthorization.ContractExecutionGrant](#cosmwasm.wasm.v1.ContractExecutionAuthorization.ContractExecutionGrant) | repeated | | + + + + + + + + +### ContractExecutionAuthorization.ContractExecutionGrant +ContractExecutionGrant a granted execute permission for a single contract + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `infinite_calls` | [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) | | | +| `max_calls` | [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) | | | +| `accepted_message_keys` | [AcceptedMessageKeysFilter](#cosmwasm.wasm.v1.AcceptedMessageKeysFilter) | | | +| `allow_all_wildcard` | [AllowAllWildcard](#cosmwasm.wasm.v1.AllowAllWildcard) | | | + + + + + + + + +### ContractMigrationAuthorization +ContractMigrationAuthorization defines authorization for wasm contract +migration. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `grants` | [ContractMigrationAuthorization.ContractMigrationGrant](#cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant) | repeated | | + + + + + + + + +### ContractMigrationAuthorization.ContractMigrationGrant +ContractExecutionGrant a granted migrate permission for a single contract | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `contract` | [string](#string) | | Contract is the address of the smart contract | -| `messages` | [string](#string) | repeated | Messages is the list of messages that can be executed | -| `once` | [bool](#bool) | | Once specifies if the contract can only be called once | +| `infinite_calls` | [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) | | | +| `max_calls` | [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) | | | + + + + + + + + +### InfiniteCalls +InfiniteCalls unlimited number of calls + + + + + + + + +### MaxCalls +MaxCalls limited number of calls + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `remaining` | [uint64](#uint64) | | Remaining number that is decremented on each execution | diff --git a/proto/cosmwasm/wasm/v1/authz.proto b/proto/cosmwasm/wasm/v1/authz.proto index c6d0e39add..d0f3c6b3aa 100644 --- a/proto/cosmwasm/wasm/v1/authz.proto +++ b/proto/cosmwasm/wasm/v1/authz.proto @@ -6,16 +6,67 @@ import "cosmos_proto/cosmos.proto"; option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; -// ContractAuthorization defines authorization for wasm execute. -message ContractAuthorization { +// ContractExecutionAuthorization defines authorization for wasm execute. +message ContractExecutionAuthorization { option (cosmos_proto.implements_interface) = "Authorization"; - // Contract is the address of the smart contract - string contract = 1; + repeated ContractExecutionGrant grants = 1 [ (gogoproto.nullable) = false ]; - // Messages is the list of messages that can be executed - repeated string messages = 2; + // ContractExecutionGrant a granted execute permission for a single contract + message ContractExecutionGrant { + // Contract is the address of the smart contract + string contract = 1; - // Once specifies if the contract can only be called once - bool once = 3; + // MaxExecutions specifies the number of authorized executions remaining + oneof max_executions { + InfiniteCalls infinite_calls = 2; + MaxCalls max_calls = 3; + } + + // Filter rules to apply + oneof filter { + AcceptedMessageKeysFilter accepted_message_keys = 4; + AllowAllWildcard allow_all_wildcard = 5; + } + } +} + +// ContractMigrationAuthorization defines authorization for wasm contract +// migration. +message ContractMigrationAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + repeated ContractMigrationGrant grants = 1 [ (gogoproto.nullable) = false ]; + + // ContractExecutionGrant a granted migrate permission for a single contract + message ContractMigrationGrant { + // Contract is the address of the smart contract + string contract = 1; + + // MaxExecutions specifies the number of authorized migrations remaining + oneof max_executions { + InfiniteCalls infinite_calls = 2; + MaxCalls max_calls = 3; + } + } +} + +// InfiniteCalls unlimited number of calls +message InfiniteCalls {} + +// MaxCalls limited number of calls +message MaxCalls { + // Remaining number that is decremented on each execution + uint64 remaining = 1; +} + +// AllowAllWildcard is a wildcard to allow any type of contract execution +// message +message AllowAllWildcard {} + +// AcceptedMessageKeysFilter accept specific contract message keys in the json +// object that can be executed +message AcceptedMessageKeysFilter { + // Messages is the list of unique keys + repeated string messages = 1; } diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index ad93c05284..fd5a372a64 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -1,6 +1,8 @@ package types import ( + "strings" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authztypes "github.com/cosmos/cosmos-sdk/x/authz" @@ -8,52 +10,153 @@ import ( const gasDeserializationCostPerByte = uint64(1) -var _ authztypes.Authorization = &ContractAuthorization{} +var _ authztypes.Authorization = &ContractExecutionAuthorization{} -// NewContractAuthorization creates a new ContractAuthorization object. -func NewContractAuthorization(contractAddr sdk.AccAddress, messages []string, once bool) *ContractAuthorization { - return &ContractAuthorization{ - Contract: contractAddr.String(), - Messages: messages, - Once: once, +// NewContractAuthorization creates a new ContractExecutionAuthorization object. +func NewContractAuthorization(contractAddr sdk.AccAddress, filter isContractExecutionAuthorization_ContractExecutionGrant_Filter, max isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions) *ContractExecutionAuthorization { + return &ContractExecutionAuthorization{ + Grants: []ContractExecutionAuthorization_ContractExecutionGrant{ + { + Contract: contractAddr.String(), + MaxExecutions: max, + Filter: filter, + }, + }, } } // MsgTypeURL implements Authorization.MsgTypeURL. -func (a ContractAuthorization) MsgTypeURL() string { +func (a ContractExecutionAuthorization) MsgTypeURL() string { return sdk.MsgTypeURL(&MsgExecuteContract{}) } // Accept implements Authorization.Accept. -func (a ContractAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) { +func (a *ContractExecutionAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) { exec, ok := msg.(*MsgExecuteContract) if !ok { return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("type mismatch") } - - if a.Contract != exec.Contract { - return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("cannot run %s contract", exec.Contract) + if exec == nil || exec.Msg == nil { + return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("empty message") } - gasForDeserialization := gasDeserializationCostPerByte * uint64(len(exec.Msg)) - ctx.GasMeter().ConsumeGas(gasForDeserialization, "contract authorization") - if err := IsJSONObjectWithTopLevelKey(exec.Msg, a.Messages); err != nil { - return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("no allowed msg, %s", err.Error()) + updatedGrants, modified, err := a.applyGrants(ctx, exec) + switch { + case err != nil: + return authztypes.AcceptResponse{}, err + case len(updatedGrants) == 0: + return authztypes.AcceptResponse{Accept: true, Delete: true}, nil + case modified: + return authztypes.AcceptResponse{Accept: true, Updated: &ContractExecutionAuthorization{ + Grants: updatedGrants, + }}, nil + default: + return authztypes.AcceptResponse{Accept: true}, nil } +} - return authztypes.AcceptResponse{Accept: true, Delete: a.Once}, nil +func (a ContractExecutionAuthorization) applyGrants(ctx sdk.Context, exec *MsgExecuteContract) ([]ContractExecutionAuthorization_ContractExecutionGrant, bool, error) { + for i, g := range a.Grants { + if g.Contract != exec.Contract { + continue + } + // first check execution counter + var modified bool + var newGrants []ContractExecutionAuthorization_ContractExecutionGrant + switch { + case g.GetInfiniteCalls() != nil: + newGrants = a.GetGrants() + case g.GetMaxCalls() != nil: + switch n := g.GetMaxCalls().Remaining; n { + case 0: + return nil, false, sdkerrors.ErrUnauthorized.Wrap("no executions allowed") + case 1: // remove + newGrants = append(a.Grants[0:i], a.Grants[i+1:]...) + modified = true + default: + obj := ContractExecutionAuthorization_ContractExecutionGrant{ + Contract: g.Contract, + MaxExecutions: &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{ + MaxCalls: &MaxCalls{Remaining: n - 1}, + }, + Filter: g.Filter, + } + newGrants = append(append(a.Grants[0:i], obj), a.Grants[i+1:]...) + modified = true + } + default: + return nil, false, sdkerrors.ErrUnauthorized.Wrapf("unsupported max execution type: %T", g.MaxExecutions) + } + // then check permission set + switch { + case g.GetAllowAllWildcard() != nil: + case g.GetAcceptedMessageKeys().GetMessages() != nil: + gasForDeserialization := gasDeserializationCostPerByte * uint64(len(exec.Msg)) + ctx.GasMeter().ConsumeGas(gasForDeserialization, "contract authorization") + + if err := IsJSONObjectWithTopLevelKey(exec.Msg, g.GetAcceptedMessageKeys().GetMessages()); err != nil { + return nil, false, sdkerrors.ErrUnauthorized.Wrapf("not an allowed msg: %s", err.Error()) + } + default: + return nil, false, sdkerrors.ErrUnauthorized.Wrapf("unsupported filter type: %T", g.Filter) + } + return newGrants, modified, nil + } + return nil, false, sdkerrors.ErrUnauthorized.Wrap("contract address") } // ValidateBasic implements Authorization.ValidateBasic. -func (a ContractAuthorization) ValidateBasic() error { - if len(a.Contract) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "contract address cannot be empty") +func (a ContractExecutionAuthorization) ValidateBasic() error { + if len(a.Grants) == 0 { + return ErrEmpty.Wrap("grants") } - if _, err := sdk.AccAddressFromBech32(a.Contract); err != nil { + for i, v := range a.Grants { + if err := v.ValidateBasic(); err != nil { + return sdkerrors.Wrapf(err, "position %d", i) + } + } + // todo (Alex): do we want to allow multiple grants for a contract or enforce a unique constraint + // example: contractA:doThis:1 , applyGrants:doThat:* has with different counters for different methods + // example: contractA:doThis:1 , applyGrants:*:* would not be great but works as well + return nil +} + +func (g ContractExecutionAuthorization_ContractExecutionGrant) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(g.Contract); err != nil { return sdkerrors.Wrap(err, "contract") } - if len(a.Messages) == 0 { - return sdkerrors.ErrInvalidRequest.Wrap("empty msg list") + // execution counter + switch { + case g.GetInfiniteCalls() != nil: + case g.GetMaxCalls() != nil: + if g.GetMaxCalls().Remaining == 0 { + return ErrEmpty.Wrap("remaining calls") + } + default: + return ErrInvalid.Wrapf("unsupported max execution type: %T", g.MaxExecutions) + } + // filter + switch { + case g.GetAllowAllWildcard() != nil: + case g.GetAcceptedMessageKeys().GetMessages() != nil: + if len(g.GetAcceptedMessageKeys().GetMessages()) == 0 { + return ErrEmpty.Wrap("messages") + } + idx := make(map[string]struct{}, len(g.GetAcceptedMessageKeys().GetMessages())) + for i, m := range g.GetAcceptedMessageKeys().GetMessages() { + if m == "" { + return ErrEmpty.Wrap("message") + } + if m != strings.TrimSpace(m) { // TODO (Alex): does this make sense? We should not make assumptions about payload + return ErrInvalid.Wrapf("message %d contains whitespaces", i) + } + if _, exists := idx[m]; exists { + return ErrDuplicate.Wrap("message") + } + idx[m] = struct{}{} + } + default: + return ErrInvalid.Wrapf("unsupported filter type: %T", g.Filter) } return nil } diff --git a/x/wasm/types/authz.pb.go b/x/wasm/types/authz.pb.go index 252426fada..f337e0ecc3 100644 --- a/x/wasm/types/authz.pb.go +++ b/x/wasm/types/authz.pb.go @@ -5,18 +5,22 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - _ "github.com/regen-network/cosmos-proto" io "io" math "math" math_bits "math/bits" + + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + _ "github.com/regen-network/cosmos-proto" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf + +var ( + _ = fmt.Errorf + _ = math.Inf +) // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -24,28 +28,294 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// ContractAuthorization defines authorization for wasm execute. -type ContractAuthorization struct { +// ContractExecutionAuthorization defines authorization for wasm execute. +type ContractExecutionAuthorization struct { + Grants []ContractExecutionAuthorization_ContractExecutionGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` +} + +func (m *ContractExecutionAuthorization) Reset() { *m = ContractExecutionAuthorization{} } +func (m *ContractExecutionAuthorization) String() string { return proto.CompactTextString(m) } +func (*ContractExecutionAuthorization) ProtoMessage() {} +func (*ContractExecutionAuthorization) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{0} +} + +func (m *ContractExecutionAuthorization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *ContractExecutionAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractExecutionAuthorization.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *ContractExecutionAuthorization) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractExecutionAuthorization.Merge(m, src) +} + +func (m *ContractExecutionAuthorization) XXX_Size() int { + return m.Size() +} + +func (m *ContractExecutionAuthorization) XXX_DiscardUnknown() { + xxx_messageInfo_ContractExecutionAuthorization.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractExecutionAuthorization proto.InternalMessageInfo + +func (m *ContractExecutionAuthorization) GetGrants() []ContractExecutionAuthorization_ContractExecutionGrant { + if m != nil { + return m.Grants + } + return nil +} + +// ContractExecutionGrant a granted execute permission for a single contract +type ContractExecutionAuthorization_ContractExecutionGrant struct { // Contract is the address of the smart contract Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` - // Messages is the list of messages that can be executed - Messages []string `protobuf:"bytes,2,rep,name=messages,proto3" json:"messages,omitempty"` - // Once specifies if the contract can only be called once - Once bool `protobuf:"varint,3,opt,name=once,proto3" json:"once,omitempty"` + // MaxExecutions specifies the number of authorized executions remaining + // + // Types that are valid to be assigned to MaxExecutions: + // *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls + // *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls + MaxExecutions isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions `protobuf_oneof:"max_executions"` + // Filter rules to apply + // + // Types that are valid to be assigned to Filter: + // *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys + // *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard + Filter isContractExecutionAuthorization_ContractExecutionGrant_Filter `protobuf_oneof:"filter"` } -func (m *ContractAuthorization) Reset() { *m = ContractAuthorization{} } -func (m *ContractAuthorization) String() string { return proto.CompactTextString(m) } -func (*ContractAuthorization) ProtoMessage() {} -func (*ContractAuthorization) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{0} +func (m *ContractExecutionAuthorization_ContractExecutionGrant) Reset() { + *m = ContractExecutionAuthorization_ContractExecutionGrant{} +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) String() string { + return proto.CompactTextString(m) +} +func (*ContractExecutionAuthorization_ContractExecutionGrant) ProtoMessage() {} +func (*ContractExecutionAuthorization_ContractExecutionGrant) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{0, 0} +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant.Merge(m, src) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Size() int { + return m.Size() +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_DiscardUnknown() { + xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant proto.InternalMessageInfo + +type isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions interface { + isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions() + MarshalTo([]byte) (int, error) + Size() int +} +type isContractExecutionAuthorization_ContractExecutionGrant_Filter interface { + isContractExecutionAuthorization_ContractExecutionGrant_Filter() + MarshalTo([]byte) (int, error) + Size() int +} + +type ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls struct { + InfiniteCalls *InfiniteCalls `protobuf:"bytes,2,opt,name=infinite_calls,json=infiniteCalls,proto3,oneof" json:"infinite_calls,omitempty"` +} +type ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls struct { + MaxCalls *MaxCalls `protobuf:"bytes,3,opt,name=max_calls,json=maxCalls,proto3,oneof" json:"max_calls,omitempty"` +} +type ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys struct { + AcceptedMessageKeys *AcceptedMessageKeysFilter `protobuf:"bytes,4,opt,name=accepted_message_keys,json=acceptedMessageKeys,proto3,oneof" json:"accepted_message_keys,omitempty"` +} +type ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard struct { + AllowAllWildcard *AllowAllWildcard `protobuf:"bytes,5,opt,name=allow_all_wildcard,json=allowAllWildcard,proto3,oneof" json:"allow_all_wildcard,omitempty"` +} + +func (*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions() { +} + +func (*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions() { +} + +func (*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) isContractExecutionAuthorization_ContractExecutionGrant_Filter() { +} + +func (*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) isContractExecutionAuthorization_ContractExecutionGrant_Filter() { +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetMaxExecutions() isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions { + if m != nil { + return m.MaxExecutions + } + return nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetFilter() isContractExecutionAuthorization_ContractExecutionGrant_Filter { + if m != nil { + return m.Filter + } + return nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetContract() string { + if m != nil { + return m.Contract + } + return "" +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetInfiniteCalls() *InfiniteCalls { + if x, ok := m.GetMaxExecutions().(*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls); ok { + return x.InfiniteCalls + } + return nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetMaxCalls() *MaxCalls { + if x, ok := m.GetMaxExecutions().(*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls); ok { + return x.MaxCalls + } + return nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetAcceptedMessageKeys() *AcceptedMessageKeysFilter { + if x, ok := m.GetFilter().(*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys); ok { + return x.AcceptedMessageKeys + } + return nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetAllowAllWildcard() *AllowAllWildcard { + if x, ok := m.GetFilter().(*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard); ok { + return x.AllowAllWildcard + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*ContractExecutionAuthorization_ContractExecutionGrant) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls)(nil), + (*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls)(nil), + (*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys)(nil), + (*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard)(nil), + } +} + +// ContractMigrationAuthorization defines authorization for wasm contract +// migration. +type ContractMigrationAuthorization struct { + Grants []ContractMigrationAuthorization_ContractMigrationGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` +} + +func (m *ContractMigrationAuthorization) Reset() { *m = ContractMigrationAuthorization{} } +func (m *ContractMigrationAuthorization) String() string { return proto.CompactTextString(m) } +func (*ContractMigrationAuthorization) ProtoMessage() {} +func (*ContractMigrationAuthorization) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{1} +} + +func (m *ContractMigrationAuthorization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *ContractMigrationAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractMigrationAuthorization.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *ContractMigrationAuthorization) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractMigrationAuthorization.Merge(m, src) +} + +func (m *ContractMigrationAuthorization) XXX_Size() int { + return m.Size() +} + +func (m *ContractMigrationAuthorization) XXX_DiscardUnknown() { + xxx_messageInfo_ContractMigrationAuthorization.DiscardUnknown(m) } -func (m *ContractAuthorization) XXX_Unmarshal(b []byte) error { + +var xxx_messageInfo_ContractMigrationAuthorization proto.InternalMessageInfo + +func (m *ContractMigrationAuthorization) GetGrants() []ContractMigrationAuthorization_ContractMigrationGrant { + if m != nil { + return m.Grants + } + return nil +} + +// ContractExecutionGrant a granted migrate permission for a single contract +type ContractMigrationAuthorization_ContractMigrationGrant struct { + // Contract is the address of the smart contract + Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` + // MaxExecutions specifies the number of authorized migrations remaining + // + // Types that are valid to be assigned to MaxExecutions: + // *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls + // *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls + MaxExecutions isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions `protobuf_oneof:"max_executions"` +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) Reset() { + *m = ContractMigrationAuthorization_ContractMigrationGrant{} +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) String() string { + return proto.CompactTextString(m) +} +func (*ContractMigrationAuthorization_ContractMigrationGrant) ProtoMessage() {} +func (*ContractMigrationAuthorization_ContractMigrationGrant) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{1, 0} +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *ContractAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_ContractAuthorization.Marshal(b, m, deterministic) + return xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -55,153 +325,1517 @@ func (m *ContractAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byt return b[:n], nil } } -func (m *ContractAuthorization) XXX_Merge(src proto.Message) { - xxx_messageInfo_ContractAuthorization.Merge(m, src) + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant.Merge(m, src) } -func (m *ContractAuthorization) XXX_Size() int { + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Size() int { return m.Size() } -func (m *ContractAuthorization) XXX_DiscardUnknown() { - xxx_messageInfo_ContractAuthorization.DiscardUnknown(m) + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_DiscardUnknown() { + xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant proto.InternalMessageInfo + +type isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions interface { + isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions() + MarshalTo([]byte) (int, error) + Size() int +} + +type ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls struct { + InfiniteCalls *InfiniteCalls `protobuf:"bytes,2,opt,name=infinite_calls,json=infiniteCalls,proto3,oneof" json:"infinite_calls,omitempty"` +} +type ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls struct { + MaxCalls *MaxCalls `protobuf:"bytes,3,opt,name=max_calls,json=maxCalls,proto3,oneof" json:"max_calls,omitempty"` +} + +func (*ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions() { } -var xxx_messageInfo_ContractAuthorization proto.InternalMessageInfo +func (*ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions() { +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetMaxExecutions() isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions { + if m != nil { + return m.MaxExecutions + } + return nil +} -func (m *ContractAuthorization) GetContract() string { +func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetContract() string { if m != nil { return m.Contract } - return "" -} + return "" +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetInfiniteCalls() *InfiniteCalls { + if x, ok := m.GetMaxExecutions().(*ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls); ok { + return x.InfiniteCalls + } + return nil +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetMaxCalls() *MaxCalls { + if x, ok := m.GetMaxExecutions().(*ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls); ok { + return x.MaxCalls + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*ContractMigrationAuthorization_ContractMigrationGrant) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls)(nil), + (*ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls)(nil), + } +} + +// InfiniteCalls unlimited number of calls +type InfiniteCalls struct{} + +func (m *InfiniteCalls) Reset() { *m = InfiniteCalls{} } +func (m *InfiniteCalls) String() string { return proto.CompactTextString(m) } +func (*InfiniteCalls) ProtoMessage() {} +func (*InfiniteCalls) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{2} +} + +func (m *InfiniteCalls) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *InfiniteCalls) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InfiniteCalls.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *InfiniteCalls) XXX_Merge(src proto.Message) { + xxx_messageInfo_InfiniteCalls.Merge(m, src) +} + +func (m *InfiniteCalls) XXX_Size() int { + return m.Size() +} + +func (m *InfiniteCalls) XXX_DiscardUnknown() { + xxx_messageInfo_InfiniteCalls.DiscardUnknown(m) +} + +var xxx_messageInfo_InfiniteCalls proto.InternalMessageInfo + +// MaxCalls limited number of calls +type MaxCalls struct { + // Remaining number that is decremented on each execution + Remaining uint64 `protobuf:"varint,1,opt,name=remaining,proto3" json:"remaining,omitempty"` +} + +func (m *MaxCalls) Reset() { *m = MaxCalls{} } +func (m *MaxCalls) String() string { return proto.CompactTextString(m) } +func (*MaxCalls) ProtoMessage() {} +func (*MaxCalls) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{3} +} + +func (m *MaxCalls) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *MaxCalls) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MaxCalls.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *MaxCalls) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxCalls.Merge(m, src) +} + +func (m *MaxCalls) XXX_Size() int { + return m.Size() +} + +func (m *MaxCalls) XXX_DiscardUnknown() { + xxx_messageInfo_MaxCalls.DiscardUnknown(m) +} + +var xxx_messageInfo_MaxCalls proto.InternalMessageInfo + +func (m *MaxCalls) GetRemaining() uint64 { + if m != nil { + return m.Remaining + } + return 0 +} + +// AllowAllWildcard is a wildcard to allow any type of contract execution +// message +type AllowAllWildcard struct{} + +func (m *AllowAllWildcard) Reset() { *m = AllowAllWildcard{} } +func (m *AllowAllWildcard) String() string { return proto.CompactTextString(m) } +func (*AllowAllWildcard) ProtoMessage() {} +func (*AllowAllWildcard) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{4} +} + +func (m *AllowAllWildcard) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *AllowAllWildcard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AllowAllWildcard.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *AllowAllWildcard) XXX_Merge(src proto.Message) { + xxx_messageInfo_AllowAllWildcard.Merge(m, src) +} + +func (m *AllowAllWildcard) XXX_Size() int { + return m.Size() +} + +func (m *AllowAllWildcard) XXX_DiscardUnknown() { + xxx_messageInfo_AllowAllWildcard.DiscardUnknown(m) +} + +var xxx_messageInfo_AllowAllWildcard proto.InternalMessageInfo + +// AcceptedMessageKeysFilter accept specific contract message keys in the json +// object that can be executed +type AcceptedMessageKeysFilter struct { + // Messages is the list of unique keys + Messages []string `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` +} + +func (m *AcceptedMessageKeysFilter) Reset() { *m = AcceptedMessageKeysFilter{} } +func (m *AcceptedMessageKeysFilter) String() string { return proto.CompactTextString(m) } +func (*AcceptedMessageKeysFilter) ProtoMessage() {} +func (*AcceptedMessageKeysFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{5} +} + +func (m *AcceptedMessageKeysFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *AcceptedMessageKeysFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AcceptedMessageKeysFilter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *AcceptedMessageKeysFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_AcceptedMessageKeysFilter.Merge(m, src) +} + +func (m *AcceptedMessageKeysFilter) XXX_Size() int { + return m.Size() +} + +func (m *AcceptedMessageKeysFilter) XXX_DiscardUnknown() { + xxx_messageInfo_AcceptedMessageKeysFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_AcceptedMessageKeysFilter proto.InternalMessageInfo + +func (m *AcceptedMessageKeysFilter) GetMessages() []string { + if m != nil { + return m.Messages + } + return nil +} + +func init() { + proto.RegisterType((*ContractExecutionAuthorization)(nil), "cosmwasm.wasm.v1.ContractExecutionAuthorization") + proto.RegisterType((*ContractExecutionAuthorization_ContractExecutionGrant)(nil), "cosmwasm.wasm.v1.ContractExecutionAuthorization.ContractExecutionGrant") + proto.RegisterType((*ContractMigrationAuthorization)(nil), "cosmwasm.wasm.v1.ContractMigrationAuthorization") + proto.RegisterType((*ContractMigrationAuthorization_ContractMigrationGrant)(nil), "cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant") + proto.RegisterType((*InfiniteCalls)(nil), "cosmwasm.wasm.v1.InfiniteCalls") + proto.RegisterType((*MaxCalls)(nil), "cosmwasm.wasm.v1.MaxCalls") + proto.RegisterType((*AllowAllWildcard)(nil), "cosmwasm.wasm.v1.AllowAllWildcard") + proto.RegisterType((*AcceptedMessageKeysFilter)(nil), "cosmwasm.wasm.v1.AcceptedMessageKeysFilter") +} + +func init() { proto.RegisterFile("cosmwasm/wasm/v1/authz.proto", fileDescriptor_36ff3a20cf32b258) } + +var fileDescriptor_36ff3a20cf32b258 = []byte{ + // 514 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x94, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0xe3, 0xb5, 0x54, 0xad, 0xa7, 0x8e, 0x62, 0xfe, 0x28, 0x8b, 0xa6, 0xac, 0xca, 0x01, + 0x55, 0x42, 0x24, 0xda, 0x38, 0x20, 0x38, 0xd1, 0x56, 0xb0, 0x22, 0xd4, 0x4b, 0x2e, 0x93, 0xb8, + 0x44, 0x5e, 0xea, 0xa5, 0x16, 0x4e, 0x5c, 0xc5, 0xee, 0xda, 0xee, 0x33, 0x70, 0xe0, 0x6b, 0x70, + 0xe7, 0x43, 0x4c, 0xe2, 0x32, 0x71, 0xe2, 0x84, 0x50, 0x7b, 0xe1, 0x63, 0xa0, 0x38, 0xc9, 0x4a, + 0x9b, 0xc0, 0x85, 0xcb, 0x2e, 0x96, 0x5f, 0x3f, 0x4f, 0x7e, 0xb1, 0x5f, 0x3f, 0x32, 0x3c, 0xf0, + 0xb9, 0x08, 0x67, 0x58, 0x84, 0x8e, 0x1a, 0x2e, 0x8e, 0x1c, 0x3c, 0x95, 0xe3, 0x4b, 0x7b, 0x12, + 0x73, 0xc9, 0x51, 0x2b, 0x57, 0x6d, 0x35, 0x5c, 0x1c, 0x19, 0x0f, 0x02, 0x1e, 0x70, 0x25, 0x3a, + 0xc9, 0x2c, 0xf5, 0x19, 0xfb, 0x89, 0x8f, 0x0b, 0x2f, 0x15, 0xd2, 0x22, 0x95, 0xac, 0xcf, 0x55, + 0x68, 0xf6, 0x79, 0x24, 0x63, 0xec, 0xcb, 0xd7, 0x73, 0xe2, 0x4f, 0x25, 0xe5, 0x51, 0x77, 0x2a, + 0xc7, 0x3c, 0xa6, 0x97, 0x38, 0x29, 0x10, 0x81, 0xb5, 0x20, 0xc6, 0x91, 0x14, 0x3a, 0x68, 0x57, + 0x3a, 0xbb, 0xc7, 0x27, 0xf6, 0xf6, 0x6f, 0xed, 0x7f, 0x13, 0x8a, 0xf2, 0x49, 0xc2, 0xeb, 0x55, + 0xaf, 0x7e, 0x1c, 0x6a, 0x6e, 0x06, 0x37, 0x3e, 0x56, 0xe0, 0xa3, 0x72, 0x23, 0x32, 0x60, 0xdd, + 0xcf, 0x14, 0x1d, 0xb4, 0x41, 0xa7, 0xe1, 0xde, 0xd4, 0x68, 0x00, 0xf7, 0x68, 0x74, 0x4e, 0x23, + 0x2a, 0x89, 0xe7, 0x63, 0xc6, 0x84, 0xbe, 0xd3, 0x06, 0x9d, 0xdd, 0xe3, 0xc3, 0xe2, 0x2e, 0xdf, + 0x66, 0xbe, 0x7e, 0x62, 0x1b, 0x68, 0x6e, 0x93, 0xfe, 0xb9, 0x80, 0x5e, 0xc0, 0x46, 0x88, 0xe7, + 0x19, 0xa4, 0xa2, 0x20, 0x46, 0x11, 0x32, 0xc4, 0xf3, 0xfc, 0xfb, 0x7a, 0x98, 0xcd, 0x11, 0x86, + 0x0f, 0xb1, 0xef, 0x93, 0x89, 0x24, 0x23, 0x2f, 0x24, 0x42, 0xe0, 0x80, 0x78, 0x1f, 0xc8, 0x42, + 0xe8, 0x55, 0x85, 0x79, 0x52, 0xc4, 0x74, 0x33, 0xfb, 0x30, 0x75, 0xbf, 0x23, 0x0b, 0xf1, 0x86, + 0x32, 0x49, 0xe2, 0x01, 0x70, 0xef, 0xe3, 0xa2, 0x88, 0x5c, 0x88, 0x30, 0x63, 0x7c, 0xe6, 0x61, + 0xc6, 0xbc, 0x19, 0x65, 0x23, 0x1f, 0xc7, 0x23, 0xfd, 0x8e, 0xe2, 0x5b, 0x25, 0xfc, 0xc4, 0xdb, + 0x65, 0xec, 0x34, 0x73, 0x0e, 0x80, 0xdb, 0xc2, 0x5b, 0x6b, 0xbd, 0x16, 0xdc, 0x4b, 0x4e, 0x4c, + 0xf2, 0x6e, 0x8b, 0x5e, 0x1d, 0xd6, 0xce, 0xd5, 0x36, 0x5e, 0xde, 0xfb, 0xf6, 0xe5, 0x69, 0x73, + 0xe3, 0x1a, 0xad, 0x5f, 0x3b, 0xeb, 0xac, 0x0c, 0x69, 0x10, 0xe3, 0xff, 0xca, 0x4a, 0x39, 0xa1, + 0x28, 0x97, 0x65, 0xe5, 0x2b, 0x58, 0x67, 0x65, 0xd3, 0x78, 0xeb, 0xb3, 0x52, 0x6c, 0x7a, 0x59, + 0xab, 0xef, 0xc2, 0xe6, 0xc6, 0x0e, 0xac, 0x0e, 0xac, 0xe7, 0x34, 0x74, 0x00, 0x1b, 0x31, 0x09, + 0x31, 0x8d, 0x68, 0x14, 0xa8, 0x33, 0x56, 0xdd, 0xf5, 0x82, 0x85, 0x60, 0x6b, 0xfb, 0xf2, 0xad, + 0xe7, 0x70, 0xff, 0xaf, 0x81, 0x4b, 0x3a, 0x96, 0x65, 0x36, 0xbd, 0xb5, 0x86, 0x7b, 0x53, 0xf7, + 0x5e, 0x5d, 0x2d, 0x4d, 0x70, 0xbd, 0x34, 0xc1, 0xcf, 0xa5, 0x09, 0x3e, 0xad, 0x4c, 0xed, 0x7a, + 0x65, 0x6a, 0xdf, 0x57, 0xa6, 0xf6, 0xfe, 0x71, 0x40, 0xe5, 0x78, 0x7a, 0x66, 0xfb, 0x3c, 0x74, + 0xfa, 0x5c, 0x84, 0xa7, 0xf9, 0x23, 0x35, 0x72, 0xe6, 0xe9, 0x63, 0x25, 0x17, 0x13, 0x22, 0xce, + 0x6a, 0xea, 0x9d, 0x79, 0xf6, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x2b, 0xf7, 0x8b, 0x46, 0xca, 0x04, + 0x00, 0x00, +} + +func (m *ContractExecutionAuthorization) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractExecutionAuthorization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Grants) > 0 { + for iNdEx := len(m.Grants) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Grants[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Filter != nil { + { + size := m.Filter.Size() + i -= size + if _, err := m.Filter.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.MaxExecutions != nil { + { + size := m.MaxExecutions.Size() + i -= size + if _, err := m.MaxExecutions.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.InfiniteCalls != nil { + { + size, err := m.InfiniteCalls.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.MaxCalls != nil { + { + size, err := m.MaxCalls.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.AcceptedMessageKeys != nil { + { + size, err := m.AcceptedMessageKeys.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.AllowAllWildcard != nil { + { + size, err := m.AllowAllWildcard.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + return len(dAtA) - i, nil +} + +func (m *ContractMigrationAuthorization) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractMigrationAuthorization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractMigrationAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Grants) > 0 { + for iNdEx := len(m.Grants) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Grants[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MaxExecutions != nil { + { + size := m.MaxExecutions.Size() + i -= size + if _, err := m.MaxExecutions.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.InfiniteCalls != nil { + { + size, err := m.InfiniteCalls.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.MaxCalls != nil { + { + size, err := m.MaxCalls.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} + +func (m *InfiniteCalls) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InfiniteCalls) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InfiniteCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MaxCalls) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MaxCalls) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MaxCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Remaining != 0 { + i = encodeVarintAuthz(dAtA, i, uint64(m.Remaining)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *AllowAllWildcard) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AllowAllWildcard) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AllowAllWildcard) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *AcceptedMessageKeysFilter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AcceptedMessageKeysFilter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AcceptedMessageKeysFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Messages) > 0 { + for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Messages[iNdEx]) + copy(dAtA[i:], m.Messages[iNdEx]) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Messages[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintAuthz(dAtA []byte, offset int, v uint64) int { + offset -= sovAuthz(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} + +func (m *ContractExecutionAuthorization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Grants) > 0 { + for _, e := range m.Grants { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovAuthz(uint64(l)) + } + if m.MaxExecutions != nil { + n += m.MaxExecutions.Size() + } + if m.Filter != nil { + n += m.Filter.Size() + } + return n +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.InfiniteCalls != nil { + l = m.InfiniteCalls.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MaxCalls != nil { + l = m.MaxCalls.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AcceptedMessageKeys != nil { + l = m.AcceptedMessageKeys.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AllowAllWildcard != nil { + l = m.AllowAllWildcard.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *ContractMigrationAuthorization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Grants) > 0 { + for _, e := range m.Grants { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovAuthz(uint64(l)) + } + if m.MaxExecutions != nil { + n += m.MaxExecutions.Size() + } + return n +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.InfiniteCalls != nil { + l = m.InfiniteCalls.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MaxCalls != nil { + l = m.MaxCalls.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *InfiniteCalls) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MaxCalls) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Remaining != 0 { + n += 1 + sovAuthz(uint64(m.Remaining)) + } + return n +} + +func (m *AllowAllWildcard) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *AcceptedMessageKeysFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Messages) > 0 { + for _, s := range m.Messages { + l = len(s) + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func sovAuthz(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} + +func sozAuthz(x uint64) (n int) { + return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +func (m *ContractExecutionAuthorization) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractExecutionAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractExecutionAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Grants", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Grants = append(m.Grants, ContractExecutionAuthorization_ContractExecutionGrant{}) + if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractExecutionGrant: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractExecutionGrant: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + 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 ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InfiniteCalls", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &InfiniteCalls{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.MaxExecutions = &ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxCalls", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &MaxCalls{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.MaxExecutions = &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptedMessageKeys", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &AcceptedMessageKeysFilter{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Filter = &ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys{v} + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowAllWildcard", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &AllowAllWildcard{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Filter = &ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *ContractMigrationAuthorization) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractMigrationAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractMigrationAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Grants", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Grants = append(m.Grants, ContractMigrationAuthorization_ContractMigrationGrant{}) + if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *ContractMigrationAuthorization_ContractMigrationGrant) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractMigrationGrant: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractMigrationGrant: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + 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 ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InfiniteCalls", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &InfiniteCalls{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.MaxExecutions = &ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxCalls", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &MaxCalls{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.MaxExecutions = &ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -func (m *ContractAuthorization) GetMessages() []string { - if m != nil { - return m.Messages + if iNdEx > l { + return io.ErrUnexpectedEOF } return nil } -func (m *ContractAuthorization) GetOnce() bool { - if m != nil { - return m.Once - } - return false -} - -func init() { - proto.RegisterType((*ContractAuthorization)(nil), "cosmwasm.wasm.v1.ContractAuthorization") -} - -func init() { proto.RegisterFile("cosmwasm/wasm/v1/authz.proto", fileDescriptor_36ff3a20cf32b258) } - -var fileDescriptor_36ff3a20cf32b258 = []byte{ - // 231 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xce, 0x2f, 0xce, - 0x2d, 0x4f, 0x2c, 0xce, 0xd5, 0x07, 0x13, 0x65, 0x86, 0xfa, 0x89, 0xa5, 0x25, 0x19, 0x55, 0x7a, - 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x02, 0x30, 0x59, 0x3d, 0x30, 0x51, 0x66, 0x28, 0x25, 0x92, - 0x9e, 0x9f, 0x9e, 0x0f, 0x96, 0xd4, 0x07, 0xb1, 0x20, 0xea, 0xa4, 0x24, 0x41, 0xea, 0xf2, 0x8b, - 0xe3, 0x21, 0x12, 0x10, 0x0e, 0x44, 0x4a, 0xa9, 0x8c, 0x4b, 0xd4, 0x39, 0x3f, 0xaf, 0xa4, 0x28, - 0x31, 0xb9, 0xc4, 0xb1, 0xb4, 0x24, 0x23, 0xbf, 0x28, 0xb3, 0x2a, 0xb1, 0x24, 0x33, 0x3f, 0x4f, - 0x48, 0x8a, 0x8b, 0x23, 0x19, 0x2a, 0x21, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe7, 0x83, - 0xe4, 0x72, 0x53, 0x8b, 0x8b, 0x13, 0xd3, 0x53, 0x8b, 0x25, 0x98, 0x14, 0x98, 0x41, 0x72, 0x30, - 0xbe, 0x90, 0x10, 0x17, 0x4b, 0x7e, 0x5e, 0x72, 0xaa, 0x04, 0xb3, 0x02, 0xa3, 0x06, 0x47, 0x10, - 0x98, 0x6d, 0x25, 0x78, 0x69, 0x8b, 0x2e, 0x2f, 0x8a, 0xf1, 0x4e, 0x0e, 0x27, 0x1e, 0xc9, 0x31, - 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, - 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x96, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, - 0x9f, 0xab, 0xef, 0x9c, 0x5f, 0x9c, 0x1b, 0x0e, 0xf3, 0x7d, 0x8a, 0x7e, 0x05, 0x24, 0x14, 0x4a, - 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x1e, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xc8, - 0x96, 0x56, 0x12, 0x23, 0x01, 0x00, 0x00, -} - -func (m *ContractAuthorization) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ContractAuthorization) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContractAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Once { - i-- - if m.Once { - dAtA[i] = 1 - } else { - dAtA[i] = 0 +func (m *InfiniteCalls) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - i-- - dAtA[i] = 0x18 - } - if len(m.Messages) > 0 { - for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Messages[iNdEx]) - copy(dAtA[i:], m.Messages[iNdEx]) - i = encodeVarintAuthz(dAtA, i, uint64(len(m.Messages[iNdEx]))) - i-- - dAtA[i] = 0x12 + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: InfiniteCalls: wiretype end group for non-group") } - } - if len(m.Contract) > 0 { - i -= len(m.Contract) - copy(dAtA[i:], m.Contract) - i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintAuthz(dAtA []byte, offset int, v uint64) int { - offset -= sovAuthz(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *ContractAuthorization) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Contract) - if l > 0 { - n += 1 + l + sovAuthz(uint64(l)) - } - if len(m.Messages) > 0 { - for _, s := range m.Messages { - l = len(s) - n += 1 + l + sovAuthz(uint64(l)) + if fieldNum <= 0 { + return fmt.Errorf("proto: InfiniteCalls: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy } } - if m.Once { - n += 2 + + if iNdEx > l { + return io.ErrUnexpectedEOF } - return n + return nil } -func sovAuthz(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozAuthz(x uint64) (n int) { - return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *ContractAuthorization) Unmarshal(dAtA []byte) error { +func (m *MaxCalls) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224,17 +1858,17 @@ func (m *ContractAuthorization) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ContractAuthorization: wiretype end group for non-group") + return fmt.Errorf("proto: MaxCalls: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ContractAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MaxCalls: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Remaining", wireType) } - var stringLen uint64 + m.Remaining = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthz @@ -244,25 +1878,114 @@ func (m *ContractAuthorization) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Remaining |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthAuthz } - postIndex := iNdEx + intStringLen - if postIndex < 0 { + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *AllowAllWildcard) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AllowAllWildcard: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AllowAllWildcard: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthAuthz } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.Contract = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *AcceptedMessageKeysFilter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AcceptedMessageKeysFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AcceptedMessageKeysFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) } @@ -294,26 +2017,6 @@ func (m *ContractAuthorization) Unmarshal(dAtA []byte) error { } m.Messages = append(m.Messages, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Once", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Once = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuthz(dAtA[iNdEx:]) @@ -335,6 +2038,7 @@ func (m *ContractAuthorization) Unmarshal(dAtA []byte) error { } return nil } + func skipAuthz(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/wasm/types/codec.go b/x/wasm/types/codec.go index 48609a0277..5abaf1d0a6 100644 --- a/x/wasm/types/codec.go +++ b/x/wasm/types/codec.go @@ -30,7 +30,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { //nolint:staticcheck cdc.RegisterConcrete(&UpdateAdminProposal{}, "wasm/UpdateAdminProposal", nil) cdc.RegisterConcrete(&ClearAdminProposal{}, "wasm/ClearAdminProposal", nil) cdc.RegisterConcrete(&UpdateInstantiateConfigProposal{}, "wasm/UpdateInstantiateConfigProposal", nil) - cdc.RegisterConcrete(&ContractAuthorization{}, "wasm/ContractAuthorization", nil) + cdc.RegisterConcrete(&ContractExecutionAuthorization{}, "wasm/ContractExecutionAuthorization", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -64,7 +64,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { registry.RegisterImplementations( (*authz.Authorization)(nil), - &ContractAuthorization{}, + &ContractExecutionAuthorization{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/wasm/types/json_matching_test.go b/x/wasm/types/json_matching_test.go index 17f7684872..f1b1c2d09c 100644 --- a/x/wasm/types/json_matching_test.go +++ b/x/wasm/types/json_matching_test.go @@ -1,8 +1,11 @@ package types import ( + "encoding/json" "testing" + "github.com/stretchr/testify/assert" + // sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" ) @@ -54,7 +57,7 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { allowedKeys: []string{"msg"}, exp: nil, }, - "happy with excaped key": { + "happy with escaped key": { src: []byte(`{"event\u2468thing": {"foo":"bar"}}`), allowedKeys: []string{"event⑨thing"}, exp: nil, @@ -76,6 +79,11 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { allowedKeys: []string{"claim"}, exp: ErrNotAJSONObject, }, + "errors for duplicate key": { + src: []byte(`{"claim": "foo", "claim":"bar"}`), + allowedKeys: []string{"claim"}, + exp: ErrNotAJSONObject, + }, // Not one top-level key "errors for no top-level key": { @@ -113,3 +121,12 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { }) } } + +func TestName(t *testing.T) { + jsonBytes := []byte(`{"event⑨thing": "foo", "event⑨thing":"bar"}`) + for i := 0; i < 10000; i++ { + document := map[string]interface{}{} + require.NoError(t, json.Unmarshal(jsonBytes, &document)) + assert.Equal(t, "bar", document["event⑨thing"]) + } +} From 443dbf4bbb461cbc4f43f91177ce0756c7637f39 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Wed, 14 Sep 2022 16:36:54 +0200 Subject: [PATCH 09/16] Add max funds limit --- docs/proto/proto-docs.md | 17 ++ proto/cosmwasm/wasm/v1/authz.proto | 18 +- x/wasm/types/authz.go | 44 +++- x/wasm/types/authz.pb.go | 398 ++++++++++++++++++++++++----- 4 files changed, 406 insertions(+), 71 deletions(-) diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index ae5b884b66..ad218feb42 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -13,6 +13,7 @@ - [ContractMigrationAuthorization.ContractMigrationGrant](#cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant) - [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) - [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) + - [MaxFunds](#cosmwasm.wasm.v1.MaxFunds) - [cosmwasm/wasm/v1/types.proto](#cosmwasm/wasm/v1/types.proto) - [AbsoluteTxPosition](#cosmwasm.wasm.v1.AbsoluteTxPosition) @@ -160,6 +161,7 @@ ContractExecutionGrant a granted execute permission for a single contract | `contract` | [string](#string) | | Contract is the address of the smart contract | | `infinite_calls` | [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) | | | | `max_calls` | [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) | | | +| `max_funds` | [MaxFunds](#cosmwasm.wasm.v1.MaxFunds) | | | | `accepted_message_keys` | [AcceptedMessageKeysFilter](#cosmwasm.wasm.v1.AcceptedMessageKeysFilter) | | | | `allow_all_wildcard` | [AllowAllWildcard](#cosmwasm.wasm.v1.AllowAllWildcard) | | | @@ -225,6 +227,21 @@ MaxCalls limited number of calls + + + +### MaxFunds +MaxFunds defines the max amounts that can be sent to a contract + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `amounts` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | | + + + + + diff --git a/proto/cosmwasm/wasm/v1/authz.proto b/proto/cosmwasm/wasm/v1/authz.proto index d0f3c6b3aa..418a56fecf 100644 --- a/proto/cosmwasm/wasm/v1/authz.proto +++ b/proto/cosmwasm/wasm/v1/authz.proto @@ -3,6 +3,7 @@ package cosmwasm.wasm.v1; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; @@ -17,16 +18,17 @@ message ContractExecutionAuthorization { // Contract is the address of the smart contract string contract = 1; - // MaxExecutions specifies the number of authorized executions remaining - oneof max_executions { + // ExecutionLimit specifies number of executions or spendable amounts + oneof execution_limit { InfiniteCalls infinite_calls = 2; MaxCalls max_calls = 3; + MaxFunds max_funds = 4; } // Filter rules to apply oneof filter { - AcceptedMessageKeysFilter accepted_message_keys = 4; - AllowAllWildcard allow_all_wildcard = 5; + AcceptedMessageKeysFilter accepted_message_keys = 5; + AllowAllWildcard allow_all_wildcard = 6; } } } @@ -60,6 +62,14 @@ message MaxCalls { uint64 remaining = 1; } +// MaxFunds defines the max amounts that can be sent to a contract +message MaxFunds { + repeated cosmos.base.v1beta1.Coin amounts = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + // AllowAllWildcard is a wildcard to allow any type of contract execution // message message AllowAllWildcard {} diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index fd5a372a64..2cd000fec1 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -13,13 +13,13 @@ const gasDeserializationCostPerByte = uint64(1) var _ authztypes.Authorization = &ContractExecutionAuthorization{} // NewContractAuthorization creates a new ContractExecutionAuthorization object. -func NewContractAuthorization(contractAddr sdk.AccAddress, filter isContractExecutionAuthorization_ContractExecutionGrant_Filter, max isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions) *ContractExecutionAuthorization { +func NewContractAuthorization(contractAddr sdk.AccAddress, filter isContractExecutionAuthorization_ContractExecutionGrant_Filter, execLimit isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit) *ContractExecutionAuthorization { return &ContractExecutionAuthorization{ Grants: []ContractExecutionAuthorization_ContractExecutionGrant{ { - Contract: contractAddr.String(), - MaxExecutions: max, - Filter: filter, + Contract: contractAddr.String(), + ExecutionLimit: execLimit, + Filter: filter, }, }, } @@ -60,13 +60,37 @@ func (a ContractExecutionAuthorization) applyGrants(ctx sdk.Context, exec *MsgEx if g.Contract != exec.Contract { continue } - // first check execution counter + // first check limits var modified bool var newGrants []ContractExecutionAuthorization_ContractExecutionGrant + switch { + case g.GetMaxFunds() != nil: + if !exec.Funds.Empty() { + if exec.Funds.IsAnyGT(g.GetMaxFunds().GetAmounts()) { + return nil, false, sdkerrors.ErrUnauthorized.Wrap("funds amount not granted") + } + obj := ContractExecutionAuthorization_ContractExecutionGrant{ + Contract: g.Contract, + ExecutionLimit: &ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds{ + MaxFunds: &MaxFunds{Amounts: g.GetMaxFunds().GetAmounts().Sub(exec.Funds)}, + }, + Filter: g.Filter, + } + newGrants = append(append(a.Grants[0:i], obj), a.Grants[i+1:]...) + modified = true + } case g.GetInfiniteCalls() != nil: + if !exec.Funds.Empty() { + return nil, false, sdkerrors.ErrUnauthorized.Wrap("funds amount not granted") + } newGrants = a.GetGrants() + modified = true + case g.GetMaxCalls() != nil: + if !exec.Funds.Empty() { + return nil, false, sdkerrors.ErrUnauthorized.Wrap("funds amount not granted") + } switch n := g.GetMaxCalls().Remaining; n { case 0: return nil, false, sdkerrors.ErrUnauthorized.Wrap("no executions allowed") @@ -76,7 +100,7 @@ func (a ContractExecutionAuthorization) applyGrants(ctx sdk.Context, exec *MsgEx default: obj := ContractExecutionAuthorization_ContractExecutionGrant{ Contract: g.Contract, - MaxExecutions: &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{ + ExecutionLimit: &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{ MaxCalls: &MaxCalls{Remaining: n - 1}, }, Filter: g.Filter, @@ -85,7 +109,7 @@ func (a ContractExecutionAuthorization) applyGrants(ctx sdk.Context, exec *MsgEx modified = true } default: - return nil, false, sdkerrors.ErrUnauthorized.Wrapf("unsupported max execution type: %T", g.MaxExecutions) + return nil, false, sdkerrors.ErrUnauthorized.Wrapf("unsupported max execution type: %T", g.ExecutionLimit) } // then check permission set switch { @@ -122,18 +146,22 @@ func (a ContractExecutionAuthorization) ValidateBasic() error { } func (g ContractExecutionAuthorization_ContractExecutionGrant) ValidateBasic() error { + // some sanity checks only, need more + if _, err := sdk.AccAddressFromBech32(g.Contract); err != nil { return sdkerrors.Wrap(err, "contract") } // execution counter switch { + case g.GetMaxFunds() != nil: + return g.GetMaxFunds().GetAmounts().Validate() case g.GetInfiniteCalls() != nil: case g.GetMaxCalls() != nil: if g.GetMaxCalls().Remaining == 0 { return ErrEmpty.Wrap("remaining calls") } default: - return ErrInvalid.Wrapf("unsupported max execution type: %T", g.MaxExecutions) + return ErrInvalid.Wrapf("unsupported max execution type: %T", g.ExecutionLimit) } // filter switch { diff --git a/x/wasm/types/authz.pb.go b/x/wasm/types/authz.pb.go index f337e0ecc3..7e248aa0a3 100644 --- a/x/wasm/types/authz.pb.go +++ b/x/wasm/types/authz.pb.go @@ -9,6 +9,8 @@ import ( math "math" math_bits "math/bits" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" _ "github.com/regen-network/cosmos-proto" @@ -82,12 +84,13 @@ func (m *ContractExecutionAuthorization) GetGrants() []ContractExecutionAuthoriz type ContractExecutionAuthorization_ContractExecutionGrant struct { // Contract is the address of the smart contract Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` - // MaxExecutions specifies the number of authorized executions remaining + // ExecutionLimit specifies number of executions or spendable amounts // - // Types that are valid to be assigned to MaxExecutions: + // Types that are valid to be assigned to ExecutionLimit: // *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls // *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls - MaxExecutions isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions `protobuf_oneof:"max_executions"` + // *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds + ExecutionLimit isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit `protobuf_oneof:"execution_limit"` // Filter rules to apply // // Types that are valid to be assigned to Filter: @@ -139,8 +142,8 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_DiscardUnkno var xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant proto.InternalMessageInfo -type isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions interface { - isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions() +type isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit interface { + isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() MarshalTo([]byte) (int, error) Size() int } @@ -156,17 +159,23 @@ type ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls struct type ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls struct { MaxCalls *MaxCalls `protobuf:"bytes,3,opt,name=max_calls,json=maxCalls,proto3,oneof" json:"max_calls,omitempty"` } +type ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds struct { + MaxFunds *MaxFunds `protobuf:"bytes,4,opt,name=max_funds,json=maxFunds,proto3,oneof" json:"max_funds,omitempty"` +} type ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys struct { - AcceptedMessageKeys *AcceptedMessageKeysFilter `protobuf:"bytes,4,opt,name=accepted_message_keys,json=acceptedMessageKeys,proto3,oneof" json:"accepted_message_keys,omitempty"` + AcceptedMessageKeys *AcceptedMessageKeysFilter `protobuf:"bytes,5,opt,name=accepted_message_keys,json=acceptedMessageKeys,proto3,oneof" json:"accepted_message_keys,omitempty"` } type ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard struct { - AllowAllWildcard *AllowAllWildcard `protobuf:"bytes,5,opt,name=allow_all_wildcard,json=allowAllWildcard,proto3,oneof" json:"allow_all_wildcard,omitempty"` + AllowAllWildcard *AllowAllWildcard `protobuf:"bytes,6,opt,name=allow_all_wildcard,json=allowAllWildcard,proto3,oneof" json:"allow_all_wildcard,omitempty"` +} + +func (*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() { } -func (*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions() { +func (*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() { } -func (*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions() { +func (*ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() { } func (*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) isContractExecutionAuthorization_ContractExecutionGrant_Filter() { @@ -175,9 +184,9 @@ func (*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys func (*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) isContractExecutionAuthorization_ContractExecutionGrant_Filter() { } -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetMaxExecutions() isContractExecutionAuthorization_ContractExecutionGrant_MaxExecutions { +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetExecutionLimit() isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit { if m != nil { - return m.MaxExecutions + return m.ExecutionLimit } return nil } @@ -197,19 +206,26 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetContract() st } func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetInfiniteCalls() *InfiniteCalls { - if x, ok := m.GetMaxExecutions().(*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls); ok { + if x, ok := m.GetExecutionLimit().(*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls); ok { return x.InfiniteCalls } return nil } func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetMaxCalls() *MaxCalls { - if x, ok := m.GetMaxExecutions().(*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls); ok { + if x, ok := m.GetExecutionLimit().(*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls); ok { return x.MaxCalls } return nil } +func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetMaxFunds() *MaxFunds { + if x, ok := m.GetExecutionLimit().(*ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds); ok { + return x.MaxFunds + } + return nil +} + func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetAcceptedMessageKeys() *AcceptedMessageKeysFilter { if x, ok := m.GetFilter().(*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys); ok { return x.AcceptedMessageKeys @@ -229,6 +245,7 @@ func (*ContractExecutionAuthorization_ContractExecutionGrant) XXX_OneofWrappers( return []interface{}{ (*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls)(nil), (*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls)(nil), + (*ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds)(nil), (*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys)(nil), (*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard)(nil), } @@ -487,6 +504,56 @@ func (m *MaxCalls) GetRemaining() uint64 { return 0 } +// MaxFunds defines the max amounts that can be sent to a contract +type MaxFunds struct { + Amounts github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=amounts,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amounts"` +} + +func (m *MaxFunds) Reset() { *m = MaxFunds{} } +func (m *MaxFunds) String() string { return proto.CompactTextString(m) } +func (*MaxFunds) ProtoMessage() {} +func (*MaxFunds) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{4} +} + +func (m *MaxFunds) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *MaxFunds) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MaxFunds.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *MaxFunds) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxFunds.Merge(m, src) +} + +func (m *MaxFunds) XXX_Size() int { + return m.Size() +} + +func (m *MaxFunds) XXX_DiscardUnknown() { + xxx_messageInfo_MaxFunds.DiscardUnknown(m) +} + +var xxx_messageInfo_MaxFunds proto.InternalMessageInfo + +func (m *MaxFunds) GetAmounts() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Amounts + } + return nil +} + // AllowAllWildcard is a wildcard to allow any type of contract execution // message type AllowAllWildcard struct{} @@ -495,7 +562,7 @@ func (m *AllowAllWildcard) Reset() { *m = AllowAllWildcard{} } func (m *AllowAllWildcard) String() string { return proto.CompactTextString(m) } func (*AllowAllWildcard) ProtoMessage() {} func (*AllowAllWildcard) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{4} + return fileDescriptor_36ff3a20cf32b258, []int{5} } func (m *AllowAllWildcard) XXX_Unmarshal(b []byte) error { @@ -540,7 +607,7 @@ func (m *AcceptedMessageKeysFilter) Reset() { *m = AcceptedMessageKeysFi func (m *AcceptedMessageKeysFilter) String() string { return proto.CompactTextString(m) } func (*AcceptedMessageKeysFilter) ProtoMessage() {} func (*AcceptedMessageKeysFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{5} + return fileDescriptor_36ff3a20cf32b258, []int{6} } func (m *AcceptedMessageKeysFilter) XXX_Unmarshal(b []byte) error { @@ -588,6 +655,7 @@ func init() { proto.RegisterType((*ContractMigrationAuthorization_ContractMigrationGrant)(nil), "cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant") proto.RegisterType((*InfiniteCalls)(nil), "cosmwasm.wasm.v1.InfiniteCalls") proto.RegisterType((*MaxCalls)(nil), "cosmwasm.wasm.v1.MaxCalls") + proto.RegisterType((*MaxFunds)(nil), "cosmwasm.wasm.v1.MaxFunds") proto.RegisterType((*AllowAllWildcard)(nil), "cosmwasm.wasm.v1.AllowAllWildcard") proto.RegisterType((*AcceptedMessageKeysFilter)(nil), "cosmwasm.wasm.v1.AcceptedMessageKeysFilter") } @@ -595,40 +663,45 @@ func init() { func init() { proto.RegisterFile("cosmwasm/wasm/v1/authz.proto", fileDescriptor_36ff3a20cf32b258) } var fileDescriptor_36ff3a20cf32b258 = []byte{ - // 514 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x94, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0xc6, 0xe3, 0xb5, 0x54, 0xad, 0xa7, 0x8e, 0x62, 0xfe, 0x28, 0x8b, 0xa6, 0xac, 0xca, 0x01, - 0x55, 0x42, 0x24, 0xda, 0x38, 0x20, 0x38, 0xd1, 0x56, 0xb0, 0x22, 0xd4, 0x4b, 0x2e, 0x93, 0xb8, - 0x44, 0x5e, 0xea, 0xa5, 0x16, 0x4e, 0x5c, 0xc5, 0xee, 0xda, 0xee, 0x33, 0x70, 0xe0, 0x6b, 0x70, - 0xe7, 0x43, 0x4c, 0xe2, 0x32, 0x71, 0xe2, 0x84, 0x50, 0x7b, 0xe1, 0x63, 0xa0, 0x38, 0xc9, 0x4a, - 0x9b, 0xc0, 0x85, 0xcb, 0x2e, 0x96, 0x5f, 0x3f, 0x4f, 0x7e, 0xb1, 0x5f, 0x3f, 0x32, 0x3c, 0xf0, - 0xb9, 0x08, 0x67, 0x58, 0x84, 0x8e, 0x1a, 0x2e, 0x8e, 0x1c, 0x3c, 0x95, 0xe3, 0x4b, 0x7b, 0x12, - 0x73, 0xc9, 0x51, 0x2b, 0x57, 0x6d, 0x35, 0x5c, 0x1c, 0x19, 0x0f, 0x02, 0x1e, 0x70, 0x25, 0x3a, - 0xc9, 0x2c, 0xf5, 0x19, 0xfb, 0x89, 0x8f, 0x0b, 0x2f, 0x15, 0xd2, 0x22, 0x95, 0xac, 0xcf, 0x55, - 0x68, 0xf6, 0x79, 0x24, 0x63, 0xec, 0xcb, 0xd7, 0x73, 0xe2, 0x4f, 0x25, 0xe5, 0x51, 0x77, 0x2a, - 0xc7, 0x3c, 0xa6, 0x97, 0x38, 0x29, 0x10, 0x81, 0xb5, 0x20, 0xc6, 0x91, 0x14, 0x3a, 0x68, 0x57, - 0x3a, 0xbb, 0xc7, 0x27, 0xf6, 0xf6, 0x6f, 0xed, 0x7f, 0x13, 0x8a, 0xf2, 0x49, 0xc2, 0xeb, 0x55, - 0xaf, 0x7e, 0x1c, 0x6a, 0x6e, 0x06, 0x37, 0x3e, 0x56, 0xe0, 0xa3, 0x72, 0x23, 0x32, 0x60, 0xdd, - 0xcf, 0x14, 0x1d, 0xb4, 0x41, 0xa7, 0xe1, 0xde, 0xd4, 0x68, 0x00, 0xf7, 0x68, 0x74, 0x4e, 0x23, - 0x2a, 0x89, 0xe7, 0x63, 0xc6, 0x84, 0xbe, 0xd3, 0x06, 0x9d, 0xdd, 0xe3, 0xc3, 0xe2, 0x2e, 0xdf, - 0x66, 0xbe, 0x7e, 0x62, 0x1b, 0x68, 0x6e, 0x93, 0xfe, 0xb9, 0x80, 0x5e, 0xc0, 0x46, 0x88, 0xe7, - 0x19, 0xa4, 0xa2, 0x20, 0x46, 0x11, 0x32, 0xc4, 0xf3, 0xfc, 0xfb, 0x7a, 0x98, 0xcd, 0x11, 0x86, - 0x0f, 0xb1, 0xef, 0x93, 0x89, 0x24, 0x23, 0x2f, 0x24, 0x42, 0xe0, 0x80, 0x78, 0x1f, 0xc8, 0x42, - 0xe8, 0x55, 0x85, 0x79, 0x52, 0xc4, 0x74, 0x33, 0xfb, 0x30, 0x75, 0xbf, 0x23, 0x0b, 0xf1, 0x86, - 0x32, 0x49, 0xe2, 0x01, 0x70, 0xef, 0xe3, 0xa2, 0x88, 0x5c, 0x88, 0x30, 0x63, 0x7c, 0xe6, 0x61, - 0xc6, 0xbc, 0x19, 0x65, 0x23, 0x1f, 0xc7, 0x23, 0xfd, 0x8e, 0xe2, 0x5b, 0x25, 0xfc, 0xc4, 0xdb, - 0x65, 0xec, 0x34, 0x73, 0x0e, 0x80, 0xdb, 0xc2, 0x5b, 0x6b, 0xbd, 0x16, 0xdc, 0x4b, 0x4e, 0x4c, - 0xf2, 0x6e, 0x8b, 0x5e, 0x1d, 0xd6, 0xce, 0xd5, 0x36, 0x5e, 0xde, 0xfb, 0xf6, 0xe5, 0x69, 0x73, - 0xe3, 0x1a, 0xad, 0x5f, 0x3b, 0xeb, 0xac, 0x0c, 0x69, 0x10, 0xe3, 0xff, 0xca, 0x4a, 0x39, 0xa1, - 0x28, 0x97, 0x65, 0xe5, 0x2b, 0x58, 0x67, 0x65, 0xd3, 0x78, 0xeb, 0xb3, 0x52, 0x6c, 0x7a, 0x59, - 0xab, 0xef, 0xc2, 0xe6, 0xc6, 0x0e, 0xac, 0x0e, 0xac, 0xe7, 0x34, 0x74, 0x00, 0x1b, 0x31, 0x09, - 0x31, 0x8d, 0x68, 0x14, 0xa8, 0x33, 0x56, 0xdd, 0xf5, 0x82, 0x85, 0x60, 0x6b, 0xfb, 0xf2, 0xad, - 0xe7, 0x70, 0xff, 0xaf, 0x81, 0x4b, 0x3a, 0x96, 0x65, 0x36, 0xbd, 0xb5, 0x86, 0x7b, 0x53, 0xf7, - 0x5e, 0x5d, 0x2d, 0x4d, 0x70, 0xbd, 0x34, 0xc1, 0xcf, 0xa5, 0x09, 0x3e, 0xad, 0x4c, 0xed, 0x7a, - 0x65, 0x6a, 0xdf, 0x57, 0xa6, 0xf6, 0xfe, 0x71, 0x40, 0xe5, 0x78, 0x7a, 0x66, 0xfb, 0x3c, 0x74, - 0xfa, 0x5c, 0x84, 0xa7, 0xf9, 0x23, 0x35, 0x72, 0xe6, 0xe9, 0x63, 0x25, 0x17, 0x13, 0x22, 0xce, - 0x6a, 0xea, 0x9d, 0x79, 0xf6, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x2b, 0xf7, 0x8b, 0x46, 0xca, 0x04, - 0x00, 0x00, + // 605 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0x4f, 0x6f, 0xd3, 0x30, + 0x1c, 0x6d, 0xb6, 0x52, 0x5a, 0x4f, 0xdb, 0xba, 0xf0, 0x47, 0x59, 0x35, 0x65, 0x53, 0x0e, 0xa8, + 0x12, 0x5a, 0x42, 0xc7, 0x01, 0xc1, 0x89, 0xa6, 0x62, 0x2b, 0x42, 0xbd, 0xe4, 0x32, 0x89, 0x4b, + 0xe4, 0x26, 0x6e, 0x6a, 0x2d, 0x89, 0x4b, 0xec, 0xf4, 0xcf, 0x3e, 0x05, 0x9f, 0x83, 0x33, 0x1f, + 0xa2, 0x12, 0x97, 0x89, 0x13, 0x27, 0x40, 0xad, 0x90, 0xf8, 0x18, 0x28, 0x8e, 0xd3, 0xae, 0x4d, + 0xd9, 0x85, 0x0b, 0x17, 0xd7, 0x3f, 0xbf, 0xf7, 0x7b, 0xfa, 0xd5, 0x7e, 0x79, 0xe0, 0xc8, 0x21, + 0x34, 0x18, 0x41, 0x1a, 0x18, 0x7c, 0x19, 0x36, 0x0c, 0x18, 0xb3, 0xfe, 0xb5, 0x3e, 0x88, 0x08, + 0x23, 0x72, 0x35, 0x43, 0x75, 0xbe, 0x0c, 0x1b, 0xb5, 0x87, 0x1e, 0xf1, 0x08, 0x07, 0x8d, 0x64, + 0x97, 0xf2, 0x6a, 0x87, 0x09, 0x8f, 0x50, 0x3b, 0x05, 0xd2, 0x42, 0x40, 0x6a, 0x5a, 0x19, 0x5d, + 0x48, 0x91, 0x31, 0x6c, 0x74, 0x11, 0x83, 0x0d, 0xc3, 0x21, 0x38, 0x4c, 0x71, 0xed, 0x57, 0x11, + 0xa8, 0x2d, 0x12, 0xb2, 0x08, 0x3a, 0xec, 0xcd, 0x18, 0x39, 0x31, 0xc3, 0x24, 0x6c, 0xc6, 0xac, + 0x4f, 0x22, 0x7c, 0x0d, 0x93, 0x42, 0x46, 0xa0, 0xe4, 0x45, 0x30, 0x64, 0x54, 0x91, 0x4e, 0xb6, + 0xeb, 0x3b, 0x67, 0x17, 0xfa, 0xfa, 0x58, 0xfa, 0xdd, 0x0a, 0x79, 0xf8, 0x22, 0xd1, 0x33, 0x8b, + 0xd3, 0xef, 0xc7, 0x05, 0x4b, 0x88, 0xd7, 0xa6, 0xdb, 0xe0, 0xf1, 0x66, 0xa2, 0x5c, 0x03, 0x65, + 0x47, 0x20, 0x8a, 0x74, 0x22, 0xd5, 0x2b, 0xd6, 0xa2, 0x96, 0xdb, 0x60, 0x0f, 0x87, 0x3d, 0x1c, + 0x62, 0x86, 0x6c, 0x07, 0xfa, 0x3e, 0x55, 0xb6, 0x4e, 0xa4, 0xfa, 0xce, 0xd9, 0x71, 0x7e, 0xca, + 0xb7, 0x82, 0xd7, 0x4a, 0x68, 0xed, 0x82, 0xb5, 0x8b, 0x6f, 0x1f, 0xc8, 0x2f, 0x41, 0x25, 0x80, + 0x63, 0x21, 0xb2, 0xcd, 0x45, 0x6a, 0x79, 0x91, 0x0e, 0x1c, 0x67, 0xfd, 0xe5, 0x40, 0xec, 0xb3, + 0xd6, 0x5e, 0x1c, 0xba, 0x54, 0x29, 0xde, 0xd1, 0x7a, 0x9e, 0x30, 0x44, 0x2b, 0xdf, 0xcb, 0x10, + 0x3c, 0x82, 0x8e, 0x83, 0x06, 0x0c, 0xb9, 0x76, 0x80, 0x28, 0x85, 0x1e, 0xb2, 0xaf, 0xd0, 0x84, + 0x2a, 0xf7, 0xb8, 0xcc, 0xd3, 0xbc, 0x4c, 0x53, 0xd0, 0x3b, 0x29, 0xfb, 0x1d, 0x9a, 0xd0, 0x73, + 0xec, 0x33, 0x14, 0xb5, 0x25, 0xeb, 0x01, 0xcc, 0x83, 0xb2, 0x05, 0x64, 0xe8, 0xfb, 0x64, 0x64, + 0x43, 0xdf, 0xb7, 0x47, 0xd8, 0x77, 0x1d, 0x18, 0xb9, 0x4a, 0x89, 0xeb, 0x6b, 0x1b, 0xf4, 0x13, + 0x6e, 0xd3, 0xf7, 0x2f, 0x05, 0xb3, 0x2d, 0x59, 0x55, 0xb8, 0x76, 0x66, 0x1e, 0x80, 0x7d, 0x94, + 0x3d, 0x92, 0xed, 0xe3, 0x00, 0x33, 0xb3, 0x0c, 0x4a, 0x3d, 0x3e, 0xc7, 0xab, 0x83, 0xaf, 0x9f, + 0x4f, 0x77, 0x57, 0x2c, 0xa0, 0xfd, 0xde, 0x5a, 0xfa, 0xac, 0x83, 0xbd, 0x08, 0xfe, 0x93, 0xcf, + 0x36, 0x2b, 0xe4, 0xe1, 0x4d, 0x3e, 0xfb, 0x22, 0x2d, 0x7d, 0xb6, 0x4a, 0xfc, 0xef, 0x7d, 0x66, + 0x56, 0xc1, 0x5e, 0xd2, 0xba, 0xb8, 0x79, 0xba, 0xe9, 0xaa, 0xf7, 0xc1, 0xee, 0xca, 0x04, 0x5a, + 0x1d, 0x94, 0x33, 0x35, 0xf9, 0x08, 0x54, 0x22, 0x14, 0x40, 0x1c, 0xe2, 0xd0, 0xe3, 0xff, 0xb1, + 0x68, 0x2d, 0x0f, 0xb4, 0x0f, 0x9c, 0x99, 0x1a, 0x13, 0x81, 0xfb, 0x30, 0x20, 0xf1, 0xf2, 0x3d, + 0x0e, 0x75, 0x91, 0x2c, 0x49, 0x96, 0xe8, 0x22, 0x4b, 0xf4, 0x16, 0xc1, 0xa1, 0xf9, 0x2c, 0xb9, + 0xe1, 0x4f, 0x3f, 0x8e, 0xeb, 0x1e, 0x66, 0xfd, 0xb8, 0xab, 0x3b, 0x24, 0x10, 0x31, 0x24, 0x7e, + 0x4e, 0xa9, 0x7b, 0x65, 0xb0, 0xc9, 0x00, 0x51, 0xde, 0x40, 0xad, 0x4c, 0x5b, 0x93, 0x41, 0x75, + 0xdd, 0x70, 0xda, 0x0b, 0x70, 0xf8, 0x57, 0x93, 0x27, 0x8f, 0x24, 0xbe, 0x93, 0x74, 0xb0, 0x8a, + 0xb5, 0xa8, 0xcd, 0xd7, 0xd3, 0x99, 0x2a, 0xdd, 0xcc, 0x54, 0xe9, 0xe7, 0x4c, 0x95, 0x3e, 0xce, + 0xd5, 0xc2, 0xcd, 0x5c, 0x2d, 0x7c, 0x9b, 0xab, 0x85, 0xf7, 0x4f, 0x6e, 0x4d, 0xd6, 0x22, 0x34, + 0xb8, 0xcc, 0x32, 0xd7, 0x35, 0xc6, 0x69, 0xf6, 0xf2, 0xe9, 0xba, 0x25, 0x1e, 0x8b, 0xcf, 0xff, + 0x04, 0x00, 0x00, 0xff, 0xff, 0xd0, 0x9f, 0xfa, 0xa4, 0x99, 0x05, 0x00, 0x00, } func (m *ContractExecutionAuthorization) Marshal() (dAtA []byte, err error) { @@ -697,11 +770,11 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) MarshalToSizedBu } } } - if m.MaxExecutions != nil { + if m.ExecutionLimit != nil { { - size := m.MaxExecutions.Size() + size := m.ExecutionLimit.Size() i -= size - if _, err := m.MaxExecutions.MarshalTo(dAtA[i:]); err != nil { + if _, err := m.ExecutionLimit.MarshalTo(dAtA[i:]); err != nil { return 0, err } } @@ -760,6 +833,28 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) Marshal return len(dAtA) - i, nil } +func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.MaxFunds != nil { + { + size, err := m.MaxFunds.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} + func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) @@ -777,7 +872,7 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKe i = encodeVarintAuthz(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x2a } return len(dAtA) - i, nil } @@ -799,7 +894,7 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) i = encodeVarintAuthz(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x32 } return len(dAtA) - i, nil } @@ -975,6 +1070,43 @@ func (m *MaxCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *MaxFunds) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MaxFunds) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MaxFunds) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Amounts) > 0 { + for iNdEx := len(m.Amounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *AllowAllWildcard) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1067,8 +1199,8 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) Size() (n int) { if l > 0 { n += 1 + l + sovAuthz(uint64(l)) } - if m.MaxExecutions != nil { - n += m.MaxExecutions.Size() + if m.ExecutionLimit != nil { + n += m.ExecutionLimit.Size() } if m.Filter != nil { n += m.Filter.Size() @@ -1102,6 +1234,19 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) Size() return n } +func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MaxFunds != nil { + l = m.MaxFunds.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) Size() (n int) { if m == nil { return 0 @@ -1206,6 +1351,21 @@ func (m *MaxCalls) Size() (n int) { return n } +func (m *MaxFunds) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Amounts) > 0 { + for _, e := range m.Amounts { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + func (m *AllowAllWildcard) Size() (n int) { if m == nil { return 0 @@ -1417,7 +1577,7 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) Unmarshal(dAtA [ if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.MaxExecutions = &ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls{v} + m.ExecutionLimit = &ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls{v} iNdEx = postIndex case 3: if wireType != 2 { @@ -1452,9 +1612,44 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) Unmarshal(dAtA [ if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.MaxExecutions = &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{v} + m.ExecutionLimit = &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{v} iNdEx = postIndex case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxFunds", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &MaxFunds{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.ExecutionLimit = &ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds{v} + iNdEx = postIndex + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AcceptedMessageKeys", wireType) } @@ -1489,7 +1684,7 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) Unmarshal(dAtA [ } m.Filter = &ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys{v} iNdEx = postIndex - case 5: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AllowAllWildcard", wireType) } @@ -1905,6 +2100,91 @@ func (m *MaxCalls) Unmarshal(dAtA []byte) error { return nil } +func (m *MaxFunds) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MaxFunds: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MaxFunds: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amounts = append(m.Amounts, types.Coin{}) + if err := m.Amounts[len(m.Amounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + func (m *AllowAllWildcard) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 From 8809e4fea15f234d5596ca4c644238a254026138 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 4 Nov 2022 14:22:14 +0100 Subject: [PATCH 10/16] Redesign authz model --- docs/proto/proto-docs.md | 109 +- proto/cosmwasm/wasm/v1/authz.proto | 117 +- x/wasm/client/cli/tx.go | 41 +- x/wasm/types/authz.go | 531 +++++++-- x/wasm/types/authz.pb.go | 1756 ++++++++++------------------ x/wasm/types/authz_test.go | 98 -- x/wasm/types/codec.go | 31 + x/wasm/types/json_matching.go | 14 +- x/wasm/types/json_matching_test.go | 66 +- x/wasm/types/query.pb.gw.go | 7 +- x/wasm/types/tx.go | 36 + 11 files changed, 1286 insertions(+), 1520 deletions(-) delete mode 100644 x/wasm/types/authz_test.go diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index ad218feb42..98282a8118 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -6,14 +6,14 @@ - [cosmwasm/wasm/v1/authz.proto](#cosmwasm/wasm/v1/authz.proto) - [AcceptedMessageKeysFilter](#cosmwasm.wasm.v1.AcceptedMessageKeysFilter) - - [AllowAllWildcard](#cosmwasm.wasm.v1.AllowAllWildcard) + - [AcceptedMessagesFilter](#cosmwasm.wasm.v1.AcceptedMessagesFilter) + - [AllowAllMessagesFilter](#cosmwasm.wasm.v1.AllowAllMessagesFilter) + - [CombinedLimit](#cosmwasm.wasm.v1.CombinedLimit) - [ContractExecutionAuthorization](#cosmwasm.wasm.v1.ContractExecutionAuthorization) - - [ContractExecutionAuthorization.ContractExecutionGrant](#cosmwasm.wasm.v1.ContractExecutionAuthorization.ContractExecutionGrant) + - [ContractGrant](#cosmwasm.wasm.v1.ContractGrant) - [ContractMigrationAuthorization](#cosmwasm.wasm.v1.ContractMigrationAuthorization) - - [ContractMigrationAuthorization.ContractMigrationGrant](#cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant) - - [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) - - [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) - - [MaxFunds](#cosmwasm.wasm.v1.MaxFunds) + - [MaxCallsLimit](#cosmwasm.wasm.v1.MaxCallsLimit) + - [MaxFundsLimit](#cosmwasm.wasm.v1.MaxFundsLimit) - [cosmwasm/wasm/v1/types.proto](#cosmwasm/wasm/v1/types.proto) - [AbsoluteTxPosition](#cosmwasm.wasm.v1.AbsoluteTxPosition) @@ -111,112 +111,122 @@ ### AcceptedMessageKeysFilter -AcceptedMessageKeysFilter accept specific contract message keys in the json -object that can be executed +AcceptedMessageKeysFilter accept only the specific contract message keys in +the json object to be executed. +Since: wasmd 0.30 | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `messages` | [string](#string) | repeated | Messages is the list of unique keys | +| `keys` | [string](#string) | repeated | Messages is the list of unique keys | - + -### AllowAllWildcard -AllowAllWildcard is a wildcard to allow any type of contract execution -message +### AcceptedMessagesFilter +AcceptedMessagesFilter accept only the specific raw contract messages to be +executed. +Since: wasmd 0.30 +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `messages` | [bytes](#bytes) | repeated | Messages is the list of raw contract messages | - -### ContractExecutionAuthorization -ContractExecutionAuthorization defines authorization for wasm execute. + -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `grants` | [ContractExecutionAuthorization.ContractExecutionGrant](#cosmwasm.wasm.v1.ContractExecutionAuthorization.ContractExecutionGrant) | repeated | | +### AllowAllMessagesFilter +AllowAllMessagesFilter is a wildcard to allow any type of contract payload +message. +Since: wasmd 0.30 - + -### ContractExecutionAuthorization.ContractExecutionGrant -ContractExecutionGrant a granted execute permission for a single contract +### CombinedLimit +CombinedLimit defines the maximal amounts that can be sent to a contract and +the maximal number of calls executable. Both need to remain >0 to be valid. +Since: wasmd 0.30 | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `contract` | [string](#string) | | Contract is the address of the smart contract | -| `infinite_calls` | [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) | | | -| `max_calls` | [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) | | | -| `max_funds` | [MaxFunds](#cosmwasm.wasm.v1.MaxFunds) | | | -| `accepted_message_keys` | [AcceptedMessageKeysFilter](#cosmwasm.wasm.v1.AcceptedMessageKeysFilter) | | | -| `allow_all_wildcard` | [AllowAllWildcard](#cosmwasm.wasm.v1.AllowAllWildcard) | | | +| `calls_remaining` | [uint64](#uint64) | | Remaining number that is decremented on each execution | +| `amounts` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Amounts is the maximal amount of tokens transferable to the contract. | - + -### ContractMigrationAuthorization -ContractMigrationAuthorization defines authorization for wasm contract -migration. +### ContractExecutionAuthorization +ContractExecutionAuthorization defines authorization for wasm execute. +Since: wasmd 0.30 | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `grants` | [ContractMigrationAuthorization.ContractMigrationGrant](#cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant) | repeated | | +| `grants` | [ContractGrant](#cosmwasm.wasm.v1.ContractGrant) | repeated | Grants for contract executions | - + -### ContractMigrationAuthorization.ContractMigrationGrant -ContractExecutionGrant a granted migrate permission for a single contract +### ContractGrant +ContractGrant a granted permission for a single contract +Since: wasmd 0.30 | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `contract` | [string](#string) | | Contract is the address of the smart contract | -| `infinite_calls` | [InfiniteCalls](#cosmwasm.wasm.v1.InfiniteCalls) | | | -| `max_calls` | [MaxCalls](#cosmwasm.wasm.v1.MaxCalls) | | | +| `contract` | [string](#string) | | Contract is the bech32 address of the smart contract | +| `limit` | [google.protobuf.Any](#google.protobuf.Any) | | Limit defines execution limits that are enforced and updated when the grant is applied. When the limit lapsed the grant is removed. | +| `filter` | [google.protobuf.Any](#google.protobuf.Any) | | Filter define more fine-grained control on the message payload passed to the contract in the operation. When no filter applies on execution, the operation is prohibited. | - + -### InfiniteCalls -InfiniteCalls unlimited number of calls +### ContractMigrationAuthorization +ContractMigrationAuthorization defines authorization for wasm contract +migration. Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `grants` | [ContractGrant](#cosmwasm.wasm.v1.ContractGrant) | repeated | Grants for contract migrations | - + -### MaxCalls -MaxCalls limited number of calls +### MaxCallsLimit +MaxCallsLimit limited number of calls to the contract. No funds transferable. +Since: wasmd 0.30 | Field | Type | Label | Description | @@ -228,15 +238,16 @@ MaxCalls limited number of calls - + -### MaxFunds -MaxFunds defines the max amounts that can be sent to a contract +### MaxFundsLimit +MaxFundsLimit defines the maximal amounts that can be sent to the contract. +Since: wasmd 0.30 | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `amounts` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | | +| `amounts` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Amounts is the maximal amount of tokens transferable to the contract. | diff --git a/proto/cosmwasm/wasm/v1/authz.proto b/proto/cosmwasm/wasm/v1/authz.proto index 418a56fecf..96ecbfb38d 100644 --- a/proto/cosmwasm/wasm/v1/authz.proto +++ b/proto/cosmwasm/wasm/v1/authz.proto @@ -4,79 +4,106 @@ package cosmwasm.wasm.v1; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; import "cosmos/base/v1beta1/coin.proto"; +import "google/protobuf/any.proto"; option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; // ContractExecutionAuthorization defines authorization for wasm execute. +// Since: wasmd 0.30 message ContractExecutionAuthorization { option (cosmos_proto.implements_interface) = "Authorization"; - repeated ContractExecutionGrant grants = 1 [ (gogoproto.nullable) = false ]; - - // ContractExecutionGrant a granted execute permission for a single contract - message ContractExecutionGrant { - // Contract is the address of the smart contract - string contract = 1; - - // ExecutionLimit specifies number of executions or spendable amounts - oneof execution_limit { - InfiniteCalls infinite_calls = 2; - MaxCalls max_calls = 3; - MaxFunds max_funds = 4; - } - - // Filter rules to apply - oneof filter { - AcceptedMessageKeysFilter accepted_message_keys = 5; - AllowAllWildcard allow_all_wildcard = 6; - } - } + // Grants for contract executions + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; } // ContractMigrationAuthorization defines authorization for wasm contract -// migration. +// migration. Since: wasmd 0.30 message ContractMigrationAuthorization { option (cosmos_proto.implements_interface) = "Authorization"; - repeated ContractMigrationGrant grants = 1 [ (gogoproto.nullable) = false ]; - - // ContractExecutionGrant a granted migrate permission for a single contract - message ContractMigrationGrant { - // Contract is the address of the smart contract - string contract = 1; + // Grants for contract migrations + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; +} - // MaxExecutions specifies the number of authorized migrations remaining - oneof max_executions { - InfiniteCalls infinite_calls = 2; - MaxCalls max_calls = 3; - } - } +// ContractGrant a granted permission for a single contract +// Since: wasmd 0.30 +message ContractGrant { + // Contract is the bech32 address of the smart contract + string contract = 1; + + // Limit defines execution limits that are enforced and updated when the grant + // is applied. When the limit lapsed the grant is removed. + google.protobuf.Any limit = 2 + [ (cosmos_proto.accepts_interface) = "ContractAuthzLimitX" ]; + + // Filter define more fine-grained control on the message payload passed + // to the contract in the operation. When no filter applies on execution, the + // operation is prohibited. + google.protobuf.Any filter = 3 + [ (cosmos_proto.accepts_interface) = "ContractAuthzFilterX" ]; } -// InfiniteCalls unlimited number of calls -message InfiniteCalls {} +// MaxCallsLimit limited number of calls to the contract. No funds transferable. +// Since: wasmd 0.30 +message MaxCallsLimit { + option (cosmos_proto.implements_interface) = "ContractAuthzLimitX"; -// MaxCalls limited number of calls -message MaxCalls { // Remaining number that is decremented on each execution uint64 remaining = 1; } -// MaxFunds defines the max amounts that can be sent to a contract -message MaxFunds { +// MaxFundsLimit defines the maximal amounts that can be sent to the contract. +// Since: wasmd 0.30 +message MaxFundsLimit { + option (cosmos_proto.implements_interface) = "ContractAuthzLimitX"; + + // Amounts is the maximal amount of tokens transferable to the contract. repeated cosmos.base.v1beta1.Coin amounts = 1 [ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; } -// AllowAllWildcard is a wildcard to allow any type of contract execution -// message -message AllowAllWildcard {} +// CombinedLimit defines the maximal amounts that can be sent to a contract and +// the maximal number of calls executable. Both need to remain >0 to be valid. +// Since: wasmd 0.30 +message CombinedLimit { + option (cosmos_proto.implements_interface) = "ContractAuthzLimitX"; -// AcceptedMessageKeysFilter accept specific contract message keys in the json -// object that can be executed + // Remaining number that is decremented on each execution + uint64 calls_remaining = 1; + // Amounts is the maximal amount of tokens transferable to the contract. + repeated cosmos.base.v1beta1.Coin amounts = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// AllowAllMessagesFilter is a wildcard to allow any type of contract payload +// message. +// Since: wasmd 0.30 +message AllowAllMessagesFilter { + option (cosmos_proto.implements_interface) = "ContractAuthzFilterX"; +} + +// AcceptedMessageKeysFilter accept only the specific contract message keys in +// the json object to be executed. +// Since: wasmd 0.30 message AcceptedMessageKeysFilter { + option (cosmos_proto.implements_interface) = "ContractAuthzFilterX"; + // Messages is the list of unique keys - repeated string messages = 1; + repeated string keys = 1; +} + +// AcceptedMessagesFilter accept only the specific raw contract messages to be +// executed. +// Since: wasmd 0.30 +message AcceptedMessagesFilter { + option (cosmos_proto.implements_interface) = "ContractAuthzFilterX"; + + // Messages is the list of raw contract messages + repeated bytes messages = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; } diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index 55ad814d9b..d6ff653922 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -6,7 +6,6 @@ import ( "fmt" "os" "strconv" - "time" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -14,7 +13,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/authz" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -34,9 +32,9 @@ const ( flagInstantiateByAddress = "instantiate-only-address" flagInstantiateByAnyOfAddress = "instantiate-anyof-addresses" flagUnpinCode = "unpin-code" - flagAllowedMsgs = "allow-msgs" - flagRunOnce = "run-once" - flagExpiration = "expiration" + flagAllowedMsgs = "allow-msgs" + flagRunOnce = "run-once" + flagExpiration = "expiration" ) // GetTxCmd returns the transaction commands for this module @@ -414,23 +412,32 @@ func GrantAuthorizationCmd() *cobra.Command { if err != nil { return err } - - authorization := types.NewContractAuthorization(contract, msgs, once) - if err = authorization.ValidateBasic(); err != nil { - return err - } - - msg, err := authz.NewMsgGrant(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(exp, 0)) - if err != nil { - return err + if exp == 0 { + return errors.New("expiration must be set") } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + _ = clientCtx + _ = grantee + _ = msgs + _ = once + _ = contract + + return errors.New("not implemented") + //authorization := types.NewContractAuthorization(contract, msgs, once) + //if err = authorization.ValidateBasic(); err != nil { + // return err + //} + + //msg, err := authz.NewMsgGrant(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(exp, 0)) + //if err != nil { + // return err + //} + // + //return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, } flags.AddTxFlagsToCmd(cmd) cmd.Flags().StringSlice(flagAllowedMsgs, []string{}, "Allowed msgs") cmd.Flags().Bool(flagRunOnce, false, "Allow to execute only once") - cmd.Flags().Int64(flagExpiration, time.Now().AddDate(1, 0, 0).Unix(), "The Unix timestamp. Default is one year.") + cmd.Flags().Int64(flagExpiration, 0, "The Unix timestamp.") return cmd } diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index 2cd000fec1..99dadc57bb 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -3,6 +3,10 @@ package types import ( "strings" + "github.com/gogo/protobuf/proto" + + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authztypes "github.com/cosmos/cosmos-sdk/x/authz" @@ -10,18 +14,23 @@ import ( const gasDeserializationCostPerByte = uint64(1) -var _ authztypes.Authorization = &ContractExecutionAuthorization{} +var ( + _ authztypes.Authorization = &ContractExecutionAuthorization{} + _ authztypes.Authorization = &ContractMigrationAuthorization{} +) + +// AuthzableWasmMsg is abstract wasm tx message that is supported in authz +type AuthzableWasmMsg interface { + GetFunds() sdk.Coins + GetMsg() RawContractMessage + GetContract() string + ValidateBasic() error +} -// NewContractAuthorization creates a new ContractExecutionAuthorization object. -func NewContractAuthorization(contractAddr sdk.AccAddress, filter isContractExecutionAuthorization_ContractExecutionGrant_Filter, execLimit isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit) *ContractExecutionAuthorization { +// NewContractExecutionAuthorization constructor +func NewContractExecutionAuthorization(grants ...ContractGrant) *ContractExecutionAuthorization { return &ContractExecutionAuthorization{ - Grants: []ContractExecutionAuthorization_ContractExecutionGrant{ - { - Contract: contractAddr.String(), - ExecutionLimit: execLimit, - Filter: filter, - }, - }, + Grants: grants, } } @@ -30,161 +39,439 @@ func (a ContractExecutionAuthorization) MsgTypeURL() string { return sdk.MsgTypeURL(&MsgExecuteContract{}) } +// NewAuthz factory method to create an Authorization with updated grants +func (a ContractExecutionAuthorization) NewAuthz(g []ContractGrant) authztypes.Authorization { + return NewContractExecutionAuthorization(g...) +} + // Accept implements Authorization.Accept. func (a *ContractExecutionAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) { - exec, ok := msg.(*MsgExecuteContract) + return AcceptGrantedMessage[*MsgExecuteContract](ctx, a.Grants, msg, a) +} + +// ValidateBasic implements Authorization.ValidateBasic. +func (a ContractExecutionAuthorization) ValidateBasic() error { + return validateGrants(a.Grants) +} + +// NewContractMigrationAuthorization constructor +func NewContractMigrationAuthorization(grants ...ContractGrant) *ContractMigrationAuthorization { + return &ContractMigrationAuthorization{ + Grants: grants, + } +} + +// MsgTypeURL implements Authorization.MsgTypeURL. +func (a ContractMigrationAuthorization) MsgTypeURL() string { + return sdk.MsgTypeURL(&MsgMigrateContract{}) +} + +// Accept implements Authorization.Accept. +func (a *ContractMigrationAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) { + return AcceptGrantedMessage[*MsgMigrateContract](ctx, a.Grants, msg, a) +} + +// NewAuthz factory method to create an Authorization with updated grants +func (a ContractMigrationAuthorization) NewAuthz(g []ContractGrant) authztypes.Authorization { + return NewContractMigrationAuthorization(g...) +} + +// ValidateBasic implements Authorization.ValidateBasic. +func (a ContractMigrationAuthorization) ValidateBasic() error { + return validateGrants(a.Grants) +} + +func validateGrants(g []ContractGrant) error { + if len(g) == 0 { + return ErrEmpty.Wrap("grants") + } + for i, v := range g { + if err := v.ValidateBasic(); err != nil { + return sdkerrors.Wrapf(err, "position %d", i) + } + } + // allow multiple grants for a contract: + // contractA:doThis:1,doThat:* has with different counters for different methods + return nil +} + +// ContractAuthzFactory factory to create an updated Authorization object +type ContractAuthzFactory interface { + NewAuthz([]ContractGrant) authztypes.Authorization +} + +// AcceptGrantedMessage determines whether this grant permits the provided sdk.Msg to be performed, +// and if so provides an upgraded authorization instance. +func AcceptGrantedMessage[T AuthzableWasmMsg](ctx sdk.Context, grants []ContractGrant, msg sdk.Msg, factory ContractAuthzFactory) (authztypes.AcceptResponse, error) { + exec, ok := msg.(T) if !ok { return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("type mismatch") } - if exec == nil || exec.Msg == nil { + if exec.GetMsg() == nil { return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("empty message") } + if err := exec.ValidateBasic(); err != nil { + return authztypes.AcceptResponse{}, err + } - updatedGrants, modified, err := a.applyGrants(ctx, exec) + updatedGrants, modified, err := applyGrants(ctx, grants, exec) switch { case err != nil: return authztypes.AcceptResponse{}, err - case len(updatedGrants) == 0: - return authztypes.AcceptResponse{Accept: true, Delete: true}, nil case modified: - return authztypes.AcceptResponse{Accept: true, Updated: &ContractExecutionAuthorization{ - Grants: updatedGrants, - }}, nil + if len(updatedGrants) == 0 { + return authztypes.AcceptResponse{Accept: true, Delete: true}, nil + } + newAuthz := factory.NewAuthz(updatedGrants) + if err := newAuthz.ValidateBasic(); err != nil { // sanity check + return authztypes.AcceptResponse{}, ErrInvalid.Wrapf("new grant state: %s", err) + } + return authztypes.AcceptResponse{Accept: true, Updated: newAuthz}, nil default: return authztypes.AcceptResponse{Accept: true}, nil } } -func (a ContractExecutionAuthorization) applyGrants(ctx sdk.Context, exec *MsgExecuteContract) ([]ContractExecutionAuthorization_ContractExecutionGrant, bool, error) { - for i, g := range a.Grants { - if g.Contract != exec.Contract { +// iterate through the grants to find an applicable grant. Returns an error when none is found +func applyGrants(ctx sdk.Context, grants []ContractGrant, exec AuthzableWasmMsg) ([]ContractGrant, bool, error) { + for i, g := range grants { + if g.Contract != exec.GetContract() { continue } - // first check limits - var modified bool - var newGrants []ContractExecutionAuthorization_ContractExecutionGrant + // first check limits + result, err := g.GetLimit().Accept(ctx, exec) switch { - case g.GetMaxFunds() != nil: - if !exec.Funds.Empty() { - if exec.Funds.IsAnyGT(g.GetMaxFunds().GetAmounts()) { - return nil, false, sdkerrors.ErrUnauthorized.Wrap("funds amount not granted") - } - obj := ContractExecutionAuthorization_ContractExecutionGrant{ - Contract: g.Contract, - ExecutionLimit: &ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds{ - MaxFunds: &MaxFunds{Amounts: g.GetMaxFunds().GetAmounts().Sub(exec.Funds)}, - }, - Filter: g.Filter, - } - newGrants = append(append(a.Grants[0:i], obj), a.Grants[i+1:]...) - modified = true - } - case g.GetInfiniteCalls() != nil: - if !exec.Funds.Empty() { - return nil, false, sdkerrors.ErrUnauthorized.Wrap("funds amount not granted") - } - newGrants = a.GetGrants() - modified = true - - case g.GetMaxCalls() != nil: - if !exec.Funds.Empty() { - return nil, false, sdkerrors.ErrUnauthorized.Wrap("funds amount not granted") - } - switch n := g.GetMaxCalls().Remaining; n { - case 0: - return nil, false, sdkerrors.ErrUnauthorized.Wrap("no executions allowed") - case 1: // remove - newGrants = append(a.Grants[0:i], a.Grants[i+1:]...) - modified = true - default: - obj := ContractExecutionAuthorization_ContractExecutionGrant{ - Contract: g.Contract, - ExecutionLimit: &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{ - MaxCalls: &MaxCalls{Remaining: n - 1}, - }, - Filter: g.Filter, - } - newGrants = append(append(a.Grants[0:i], obj), a.Grants[i+1:]...) - modified = true - } - default: - return nil, false, sdkerrors.ErrUnauthorized.Wrapf("unsupported max execution type: %T", g.ExecutionLimit) + case err != nil: + return nil, false, sdkerrors.Wrap(err, "limit") + case result == nil: // sanity check + return nil, false, sdkerrors.ErrInvalidType.Wrap("limit result must not be nil") + case !result.Accepted: + // not applicable, continue with next grant + continue } + // then check permission set + ok, err := g.GetFilter().Accept(ctx, exec.GetMsg()) switch { - case g.GetAllowAllWildcard() != nil: - case g.GetAcceptedMessageKeys().GetMessages() != nil: - gasForDeserialization := gasDeserializationCostPerByte * uint64(len(exec.Msg)) - ctx.GasMeter().ConsumeGas(gasForDeserialization, "contract authorization") + case err != nil: + return nil, false, sdkerrors.Wrap(err, "filter") + case !ok: + // no limit update and continue with next grant + continue + } - if err := IsJSONObjectWithTopLevelKey(exec.Msg, g.GetAcceptedMessageKeys().GetMessages()); err != nil { - return nil, false, sdkerrors.ErrUnauthorized.Wrapf("not an allowed msg: %s", err.Error()) + // finally do limit state updates + switch { + case result.DeleteLimit: + return append(grants[0:i], grants[i+1:]...), true, nil + case result.UpdateLimit != nil: + obj, err := g.WithNewLimits(result.UpdateLimit) + if err != nil { + return nil, false, err } - default: - return nil, false, sdkerrors.ErrUnauthorized.Wrapf("unsupported filter type: %T", g.Filter) + return append(append(grants[0:i], *obj), grants[i+1:]...), true, nil + default: // accepted without a limit state update + return grants, false, nil } - return newGrants, modified, nil } - return nil, false, sdkerrors.ErrUnauthorized.Wrap("contract address") + return nil, false, sdkerrors.ErrUnauthorized.Wrap("no matching contract grants") } -// ValidateBasic implements Authorization.ValidateBasic. -func (a ContractExecutionAuthorization) ValidateBasic() error { - if len(a.Grants) == 0 { - return ErrEmpty.Wrap("grants") +// ContractAuthzLimitX define execution limits that are enforced and updated when the grant +// is applied. When the limit lapsed the grant is removed. +type ContractAuthzLimitX interface { + Accept(ctx sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) + ValidateBasic() error +} + +// ContractAuthzLimitAcceptResult result of the ContractAuthzLimitX.Accept method +type ContractAuthzLimitAcceptResult struct { + // Accepted is true when limit applies + Accepted bool + // DeleteLimit when set it is the end of life for this limit. Grant is removed from persistent store + DeleteLimit bool + // UpdateLimit update persistent state with new value + UpdateLimit ContractAuthzLimitX +} + +// ContractAuthzFilterX define more fine-grained control on the message payload passed +// to the contract in the operation. When no filter applies on execution, the +// operation is prohibited. +type ContractAuthzFilterX interface { + // Accept returns applicable or error + Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) + ValidateBasic() error +} + +var _ cdctypes.UnpackInterfacesMessage = &ContractGrant{} + +// NewContractGrant constructor +func NewContractGrant(contract sdk.AccAddress, limit ContractAuthzLimitX, filter ContractAuthzFilterX) (*ContractGrant, error) { + pFilter, ok := filter.(proto.Message) + if !ok { + return nil, sdkerrors.ErrInvalidType.Wrap("filter is not a proto type") } - for i, v := range a.Grants { - if err := v.ValidateBasic(); err != nil { - return sdkerrors.Wrapf(err, "position %d", i) + anyFilter, err := cdctypes.NewAnyWithValue(pFilter) + if err != nil { + return nil, sdkerrors.Wrap(err, "filter") + } + return ContractGrant{ + Contract: contract.String(), + Filter: anyFilter, + }.WithNewLimits(limit) +} + +// WithNewLimits factory method to create a new grant with given limit +func (g ContractGrant) WithNewLimits(limit ContractAuthzLimitX) (*ContractGrant, error) { + pLimit, ok := limit.(proto.Message) + if !ok { + return nil, sdkerrors.ErrInvalidType.Wrap("limit is not a proto type") + } + anyLimit, err := cdctypes.NewAnyWithValue(pLimit) + if err != nil { + return nil, sdkerrors.Wrap(err, "limit") + } + + return &ContractGrant{ + Contract: g.Contract, + Limit: anyLimit, + Filter: g.Filter, + }, nil +} + +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (g ContractGrant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error { + var f ContractAuthzFilterX + if err := unpacker.UnpackAny(g.Filter, &f); err != nil { + return sdkerrors.Wrap(err, "filter") + } + var l ContractAuthzLimitX + if err := unpacker.UnpackAny(g.Limit, &l); err != nil { + return sdkerrors.Wrap(err, "limit") + } + return nil +} + +// GetLimit returns the cached value from the ContractGrant.Limit if present. +func (g ContractGrant) GetLimit() ContractAuthzLimitX { + if g.Limit == nil { + return &UndefinedLimit{} + } + a, ok := g.Filter.GetCachedValue().(ContractAuthzLimitX) + if !ok { + return &UndefinedLimit{} + } + return a +} + +// UndefinedLimit null object that is always rejected in execution +type UndefinedLimit struct{} + +// ValidateBasic always returns error +func (u UndefinedLimit) ValidateBasic() error { + return sdkerrors.ErrInvalidType.Wrapf("undefined limit") +} + +// Accept always returns error +func (u UndefinedLimit) Accept(ctx sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + return nil, sdkerrors.ErrNotFound.Wrapf("undefined filter") +} + +// GetFilter returns the cached value from the ContractGrant.Filter if present. +func (g ContractGrant) GetFilter() ContractAuthzFilterX { + if g.Filter == nil { + return &UndefinedFilter{} + } + a, ok := g.Filter.GetCachedValue().(ContractAuthzFilterX) + if !ok { + return &UndefinedFilter{} + } + return a +} + +// UndefinedFilter null object that is always rejected in execution +type UndefinedFilter struct{} + +// Accept always returns error +func (f *UndefinedFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + return false, sdkerrors.ErrNotFound.Wrapf("undefined filter") +} + +// ValidateBasic always returns error +func (f UndefinedFilter) ValidateBasic() error { + return sdkerrors.ErrInvalidType.Wrapf("undefined filter") +} + +// Accept accepts any message content. +func (f *AllowAllMessagesFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + return true, nil +} + +// ValidateBasic returns always nil +func (f AllowAllMessagesFilter) ValidateBasic() error { + return nil +} + +// Accept only payload messages which contain one of the accepted key names in the json object. +func (f *AcceptedMessageKeysFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + gasForDeserialization := gasDeserializationCostPerByte * uint64(len(msg)) + ctx.GasMeter().ConsumeGas(gasForDeserialization, "contract authorization") + + ok, err := IsJSONObjectWithTopLevelKey(msg, f.Keys) + if err != nil { + return false, sdkerrors.ErrUnauthorized.Wrapf("not an allowed msg: %s", err.Error()) + } + return ok, nil +} + +// ValidateBasic validates the filter +func (f AcceptedMessageKeysFilter) ValidateBasic() error { + if len(f.Keys) == 0 { + return ErrEmpty.Wrap("keys") + } + idx := make(map[string]struct{}, len(f.Keys)) + for _, m := range f.Keys { + if m == "" { + return ErrEmpty.Wrap("key") + } + if m != strings.TrimSpace(m) { + return ErrInvalid.Wrapf("key %q contains whitespaces", m) + } + if _, exists := idx[m]; exists { + return ErrDuplicate.Wrapf("key %q", m) } + idx[m] = struct{}{} } - // todo (Alex): do we want to allow multiple grants for a contract or enforce a unique constraint - // example: contractA:doThis:1 , applyGrants:doThat:* has with different counters for different methods - // example: contractA:doThis:1 , applyGrants:*:* would not be great but works as well return nil } -func (g ContractExecutionAuthorization_ContractExecutionGrant) ValidateBasic() error { - // some sanity checks only, need more +// Accept only payload messages which are equal to the granted one. +func (f *AcceptedMessagesFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + var found bool + for _, v := range f.Messages { + if v.Equal(msg) { + found = true + break + } + } + if !found { + return false, sdkerrors.ErrUnauthorized.Wrap("not an accepted payload msg") + } + return false, nil +} + +// ValidateBasic validates the filter +func (f AcceptedMessagesFilter) ValidateBasic() error { + if len(f.Messages) == 0 { + return ErrEmpty.Wrap("messages") + } + idx := make(map[string]struct{}, len(f.Messages)) + for _, m := range f.Messages { + if m == nil { + return ErrEmpty.Wrap("message") + } + if _, exists := idx[string(m)]; exists { + return ErrDuplicate.Wrap("message") + } + idx[string(m)] = struct{}{} + } + return nil +} +// ValidateBasic validates the grant +func (g ContractGrant) ValidateBasic() error { + // some sanity checks only, need more if _, err := sdk.AccAddressFromBech32(g.Contract); err != nil { return sdkerrors.Wrap(err, "contract") } - // execution counter - switch { - case g.GetMaxFunds() != nil: - return g.GetMaxFunds().GetAmounts().Validate() - case g.GetInfiniteCalls() != nil: - case g.GetMaxCalls() != nil: - if g.GetMaxCalls().Remaining == 0 { - return ErrEmpty.Wrap("remaining calls") - } - default: - return ErrInvalid.Wrapf("unsupported max execution type: %T", g.ExecutionLimit) + // execution limits + if err := g.GetLimit().ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "limit") } // filter - switch { - case g.GetAllowAllWildcard() != nil: - case g.GetAcceptedMessageKeys().GetMessages() != nil: - if len(g.GetAcceptedMessageKeys().GetMessages()) == 0 { - return ErrEmpty.Wrap("messages") - } - idx := make(map[string]struct{}, len(g.GetAcceptedMessageKeys().GetMessages())) - for i, m := range g.GetAcceptedMessageKeys().GetMessages() { - if m == "" { - return ErrEmpty.Wrap("message") - } - if m != strings.TrimSpace(m) { // TODO (Alex): does this make sense? We should not make assumptions about payload - return ErrInvalid.Wrapf("message %d contains whitespaces", i) - } - if _, exists := idx[m]; exists { - return ErrDuplicate.Wrap("message") - } - idx[m] = struct{}{} - } + if err := g.GetFilter().ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "filter") + } + return nil +} + +// Accept only the defined number of message calls. No token transfers to the contract allowed. +func (m MaxCallsLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + if !msg.GetFunds().Empty() { + return &ContractAuthzLimitAcceptResult{Accepted: false}, nil + } + switch n := m.Remaining; n { + case 0: // sanity check + return nil, sdkerrors.ErrUnauthorized.Wrap("no calls left") + case 1: + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil default: - return ErrInvalid.Wrapf("unsupported filter type: %T", g.Filter) + return &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: &MaxCallsLimit{Remaining: n - 1}}, nil + } +} + +// ValidateBasic validates the limit +func (m MaxCallsLimit) ValidateBasic() error { + if m.Remaining == 0 { + return ErrEmpty.Wrap("remaining calls") + } + return nil +} + +// Accept until the defined budget for token transfers to the contract is spent +func (m MaxFundsLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + if msg.GetFunds().Empty() { // no state changes required + return &ContractAuthzLimitAcceptResult{Accepted: true}, nil + } + if msg.GetFunds().IsAnyGT(m.Amounts) { + return &ContractAuthzLimitAcceptResult{Accepted: false}, nil + } + newAmounts := m.Amounts.Sub(msg.GetFunds()) + if newAmounts.IsZero() { + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil + } + return &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: &MaxFundsLimit{Amounts: newAmounts}}, nil +} + +// ValidateBasic validates the limit +func (m MaxFundsLimit) ValidateBasic() error { + if err := m.Amounts.Validate(); err != nil { + return err + } + if m.Amounts.IsZero() { + return ErrEmpty.Wrap("amounts") + } + return nil +} + +// Accept until the max calls is reached or the token budget is spent. +func (l CombinedLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + transferFunds := msg.GetFunds() + if !transferFunds.Empty() && transferFunds.IsAnyGT(l.Amounts) { + return &ContractAuthzLimitAcceptResult{Accepted: false}, nil // does not apply + } + switch n := l.CallsRemaining; n { + case 0: // sanity check + return nil, sdkerrors.ErrUnauthorized.Wrap("no calls left") + case 1: + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil + default: + remainingAmounts := l.Amounts.Sub(transferFunds) + if remainingAmounts.IsZero() { + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil + } + return &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: &CombinedLimit{CallsRemaining: n - 1, Amounts: remainingAmounts}}, nil + } +} + +// ValidateBasic validates the limit +func (l CombinedLimit) ValidateBasic() error { + if err := l.Amounts.Validate(); err != nil { + return sdkerrors.Wrap(err, "amounts") + } + if l.CallsRemaining == 0 { + return ErrEmpty.Wrap("remaining calls") } return nil } diff --git a/x/wasm/types/authz.pb.go b/x/wasm/types/authz.pb.go index 7e248aa0a3..549b558aa1 100644 --- a/x/wasm/types/authz.pb.go +++ b/x/wasm/types/authz.pb.go @@ -9,11 +9,12 @@ import ( math "math" math_bits "math/bits" + _ "github.com/cosmos/cosmos-proto" + types "github.com/cosmos/cosmos-sdk/codec/types" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" - types "github.com/cosmos/cosmos-sdk/types" - _ "github.com/gogo/protobuf/gogoproto" + types1 "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/gogo/protobuf/proto" - _ "github.com/regen-network/cosmos-proto" ) // Reference imports to suppress errors if they are not otherwise used. @@ -31,8 +32,10 @@ var ( const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // ContractExecutionAuthorization defines authorization for wasm execute. +// Since: wasmd 0.30 type ContractExecutionAuthorization struct { - Grants []ContractExecutionAuthorization_ContractExecutionGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` + // Grants for contract executions + Grants []ContractGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` } func (m *ContractExecutionAuthorization) Reset() { *m = ContractExecutionAuthorization{} } @@ -73,188 +76,11 @@ func (m *ContractExecutionAuthorization) XXX_DiscardUnknown() { var xxx_messageInfo_ContractExecutionAuthorization proto.InternalMessageInfo -func (m *ContractExecutionAuthorization) GetGrants() []ContractExecutionAuthorization_ContractExecutionGrant { - if m != nil { - return m.Grants - } - return nil -} - -// ContractExecutionGrant a granted execute permission for a single contract -type ContractExecutionAuthorization_ContractExecutionGrant struct { - // Contract is the address of the smart contract - Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` - // ExecutionLimit specifies number of executions or spendable amounts - // - // Types that are valid to be assigned to ExecutionLimit: - // *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls - // *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls - // *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds - ExecutionLimit isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit `protobuf_oneof:"execution_limit"` - // Filter rules to apply - // - // Types that are valid to be assigned to Filter: - // *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys - // *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard - Filter isContractExecutionAuthorization_ContractExecutionGrant_Filter `protobuf_oneof:"filter"` -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) Reset() { - *m = ContractExecutionAuthorization_ContractExecutionGrant{} -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) String() string { - return proto.CompactTextString(m) -} -func (*ContractExecutionAuthorization_ContractExecutionGrant) ProtoMessage() {} -func (*ContractExecutionAuthorization_ContractExecutionGrant) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{0, 0} -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Merge(src proto.Message) { - xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant.Merge(m, src) -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_Size() int { - return m.Size() -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) XXX_DiscardUnknown() { - xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant.DiscardUnknown(m) -} - -var xxx_messageInfo_ContractExecutionAuthorization_ContractExecutionGrant proto.InternalMessageInfo - -type isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit interface { - isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() - MarshalTo([]byte) (int, error) - Size() int -} -type isContractExecutionAuthorization_ContractExecutionGrant_Filter interface { - isContractExecutionAuthorization_ContractExecutionGrant_Filter() - MarshalTo([]byte) (int, error) - Size() int -} - -type ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls struct { - InfiniteCalls *InfiniteCalls `protobuf:"bytes,2,opt,name=infinite_calls,json=infiniteCalls,proto3,oneof" json:"infinite_calls,omitempty"` -} -type ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls struct { - MaxCalls *MaxCalls `protobuf:"bytes,3,opt,name=max_calls,json=maxCalls,proto3,oneof" json:"max_calls,omitempty"` -} -type ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds struct { - MaxFunds *MaxFunds `protobuf:"bytes,4,opt,name=max_funds,json=maxFunds,proto3,oneof" json:"max_funds,omitempty"` -} -type ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys struct { - AcceptedMessageKeys *AcceptedMessageKeysFilter `protobuf:"bytes,5,opt,name=accepted_message_keys,json=acceptedMessageKeys,proto3,oneof" json:"accepted_message_keys,omitempty"` -} -type ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard struct { - AllowAllWildcard *AllowAllWildcard `protobuf:"bytes,6,opt,name=allow_all_wildcard,json=allowAllWildcard,proto3,oneof" json:"allow_all_wildcard,omitempty"` -} - -func (*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() { -} - -func (*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() { -} - -func (*ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit() { -} - -func (*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) isContractExecutionAuthorization_ContractExecutionGrant_Filter() { -} - -func (*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) isContractExecutionAuthorization_ContractExecutionGrant_Filter() { -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetExecutionLimit() isContractExecutionAuthorization_ContractExecutionGrant_ExecutionLimit { - if m != nil { - return m.ExecutionLimit - } - return nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetFilter() isContractExecutionAuthorization_ContractExecutionGrant_Filter { - if m != nil { - return m.Filter - } - return nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetContract() string { - if m != nil { - return m.Contract - } - return "" -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetInfiniteCalls() *InfiniteCalls { - if x, ok := m.GetExecutionLimit().(*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls); ok { - return x.InfiniteCalls - } - return nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetMaxCalls() *MaxCalls { - if x, ok := m.GetExecutionLimit().(*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls); ok { - return x.MaxCalls - } - return nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetMaxFunds() *MaxFunds { - if x, ok := m.GetExecutionLimit().(*ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds); ok { - return x.MaxFunds - } - return nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetAcceptedMessageKeys() *AcceptedMessageKeysFilter { - if x, ok := m.GetFilter().(*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys); ok { - return x.AcceptedMessageKeys - } - return nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) GetAllowAllWildcard() *AllowAllWildcard { - if x, ok := m.GetFilter().(*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard); ok { - return x.AllowAllWildcard - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*ContractExecutionAuthorization_ContractExecutionGrant) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls)(nil), - (*ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls)(nil), - (*ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds)(nil), - (*ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys)(nil), - (*ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard)(nil), - } -} - // ContractMigrationAuthorization defines authorization for wasm contract -// migration. +// migration. Since: wasmd 0.30 type ContractMigrationAuthorization struct { - Grants []ContractMigrationAuthorization_ContractMigrationGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` + // Grants for contract migrations + Grants []ContractGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` } func (m *ContractMigrationAuthorization) Reset() { *m = ContractMigrationAuthorization{} } @@ -295,44 +121,34 @@ func (m *ContractMigrationAuthorization) XXX_DiscardUnknown() { var xxx_messageInfo_ContractMigrationAuthorization proto.InternalMessageInfo -func (m *ContractMigrationAuthorization) GetGrants() []ContractMigrationAuthorization_ContractMigrationGrant { - if m != nil { - return m.Grants - } - return nil -} - -// ContractExecutionGrant a granted migrate permission for a single contract -type ContractMigrationAuthorization_ContractMigrationGrant struct { - // Contract is the address of the smart contract +// ContractGrant a granted permission for a single contract +// Since: wasmd 0.30 +type ContractGrant struct { + // Contract is the bech32 address of the smart contract Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` - // MaxExecutions specifies the number of authorized migrations remaining - // - // Types that are valid to be assigned to MaxExecutions: - // *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls - // *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls - MaxExecutions isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions `protobuf_oneof:"max_executions"` -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant) Reset() { - *m = ContractMigrationAuthorization_ContractMigrationGrant{} -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant) String() string { - return proto.CompactTextString(m) -} -func (*ContractMigrationAuthorization_ContractMigrationGrant) ProtoMessage() {} -func (*ContractMigrationAuthorization_ContractMigrationGrant) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{1, 0} + // Limit defines execution limits that are enforced and updated when the grant + // is applied. When the limit lapsed the grant is removed. + Limit *types.Any `protobuf:"bytes,2,opt,name=limit,proto3" json:"limit,omitempty"` + // Filter define more fine-grained control on the message payload passed + // to the contract in the operation. When no filter applies on execution, the + // operation is prohibited. + Filter *types.Any `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (m *ContractGrant) Reset() { *m = ContractGrant{} } +func (m *ContractGrant) String() string { return proto.CompactTextString(m) } +func (*ContractGrant) ProtoMessage() {} +func (*ContractGrant) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{2} } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Unmarshal(b []byte) error { +func (m *ContractGrant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ContractGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant.Marshal(b, m, deterministic) + return xxx_messageInfo_ContractGrant.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -343,92 +159,41 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Marshal(b [] } } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Merge(src proto.Message) { - xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant.Merge(m, src) +func (m *ContractGrant) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractGrant.Merge(m, src) } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_Size() int { +func (m *ContractGrant) XXX_Size() int { return m.Size() } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) XXX_DiscardUnknown() { - xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant.DiscardUnknown(m) -} - -var xxx_messageInfo_ContractMigrationAuthorization_ContractMigrationGrant proto.InternalMessageInfo - -type isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions interface { - isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions() - MarshalTo([]byte) (int, error) - Size() int -} - -type ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls struct { - InfiniteCalls *InfiniteCalls `protobuf:"bytes,2,opt,name=infinite_calls,json=infiniteCalls,proto3,oneof" json:"infinite_calls,omitempty"` -} -type ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls struct { - MaxCalls *MaxCalls `protobuf:"bytes,3,opt,name=max_calls,json=maxCalls,proto3,oneof" json:"max_calls,omitempty"` -} - -func (*ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions() { -} - -func (*ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions() { -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetMaxExecutions() isContractMigrationAuthorization_ContractMigrationGrant_MaxExecutions { - if m != nil { - return m.MaxExecutions - } - return nil -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetContract() string { - if m != nil { - return m.Contract - } - return "" -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetInfiniteCalls() *InfiniteCalls { - if x, ok := m.GetMaxExecutions().(*ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls); ok { - return x.InfiniteCalls - } - return nil +func (m *ContractGrant) XXX_DiscardUnknown() { + xxx_messageInfo_ContractGrant.DiscardUnknown(m) } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) GetMaxCalls() *MaxCalls { - if x, ok := m.GetMaxExecutions().(*ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls); ok { - return x.MaxCalls - } - return nil -} +var xxx_messageInfo_ContractGrant proto.InternalMessageInfo -// XXX_OneofWrappers is for the internal use of the proto package. -func (*ContractMigrationAuthorization_ContractMigrationGrant) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls)(nil), - (*ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls)(nil), - } +// MaxCallsLimit limited number of calls to the contract. No funds transferable. +// Since: wasmd 0.30 +type MaxCallsLimit struct { + // Remaining number that is decremented on each execution + Remaining uint64 `protobuf:"varint,1,opt,name=remaining,proto3" json:"remaining,omitempty"` } -// InfiniteCalls unlimited number of calls -type InfiniteCalls struct{} - -func (m *InfiniteCalls) Reset() { *m = InfiniteCalls{} } -func (m *InfiniteCalls) String() string { return proto.CompactTextString(m) } -func (*InfiniteCalls) ProtoMessage() {} -func (*InfiniteCalls) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{2} +func (m *MaxCallsLimit) Reset() { *m = MaxCallsLimit{} } +func (m *MaxCallsLimit) String() string { return proto.CompactTextString(m) } +func (*MaxCallsLimit) ProtoMessage() {} +func (*MaxCallsLimit) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{3} } -func (m *InfiniteCalls) XXX_Unmarshal(b []byte) error { +func (m *MaxCallsLimit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *InfiniteCalls) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MaxCallsLimit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_InfiniteCalls.Marshal(b, m, deterministic) + return xxx_messageInfo_MaxCallsLimit.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -439,40 +204,41 @@ func (m *InfiniteCalls) XXX_Marshal(b []byte, deterministic bool) ([]byte, error } } -func (m *InfiniteCalls) XXX_Merge(src proto.Message) { - xxx_messageInfo_InfiniteCalls.Merge(m, src) +func (m *MaxCallsLimit) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxCallsLimit.Merge(m, src) } -func (m *InfiniteCalls) XXX_Size() int { +func (m *MaxCallsLimit) XXX_Size() int { return m.Size() } -func (m *InfiniteCalls) XXX_DiscardUnknown() { - xxx_messageInfo_InfiniteCalls.DiscardUnknown(m) +func (m *MaxCallsLimit) XXX_DiscardUnknown() { + xxx_messageInfo_MaxCallsLimit.DiscardUnknown(m) } -var xxx_messageInfo_InfiniteCalls proto.InternalMessageInfo +var xxx_messageInfo_MaxCallsLimit proto.InternalMessageInfo -// MaxCalls limited number of calls -type MaxCalls struct { - // Remaining number that is decremented on each execution - Remaining uint64 `protobuf:"varint,1,opt,name=remaining,proto3" json:"remaining,omitempty"` +// MaxFundsLimit defines the maximal amounts that can be sent to the contract. +// Since: wasmd 0.30 +type MaxFundsLimit struct { + // Amounts is the maximal amount of tokens transferable to the contract. + Amounts github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=amounts,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amounts"` } -func (m *MaxCalls) Reset() { *m = MaxCalls{} } -func (m *MaxCalls) String() string { return proto.CompactTextString(m) } -func (*MaxCalls) ProtoMessage() {} -func (*MaxCalls) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{3} +func (m *MaxFundsLimit) Reset() { *m = MaxFundsLimit{} } +func (m *MaxFundsLimit) String() string { return proto.CompactTextString(m) } +func (*MaxFundsLimit) ProtoMessage() {} +func (*MaxFundsLimit) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{4} } -func (m *MaxCalls) XXX_Unmarshal(b []byte) error { +func (m *MaxFundsLimit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MaxCalls) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MaxFundsLimit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MaxCalls.Marshal(b, m, deterministic) + return xxx_messageInfo_MaxFundsLimit.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -483,46 +249,44 @@ func (m *MaxCalls) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { } } -func (m *MaxCalls) XXX_Merge(src proto.Message) { - xxx_messageInfo_MaxCalls.Merge(m, src) +func (m *MaxFundsLimit) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxFundsLimit.Merge(m, src) } -func (m *MaxCalls) XXX_Size() int { +func (m *MaxFundsLimit) XXX_Size() int { return m.Size() } -func (m *MaxCalls) XXX_DiscardUnknown() { - xxx_messageInfo_MaxCalls.DiscardUnknown(m) +func (m *MaxFundsLimit) XXX_DiscardUnknown() { + xxx_messageInfo_MaxFundsLimit.DiscardUnknown(m) } -var xxx_messageInfo_MaxCalls proto.InternalMessageInfo +var xxx_messageInfo_MaxFundsLimit proto.InternalMessageInfo -func (m *MaxCalls) GetRemaining() uint64 { - if m != nil { - return m.Remaining - } - return 0 -} - -// MaxFunds defines the max amounts that can be sent to a contract -type MaxFunds struct { - Amounts github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=amounts,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amounts"` +// CombinedLimit defines the maximal amounts that can be sent to a contract and +// the maximal number of calls executable. Both need to remain >0 to be valid. +// Since: wasmd 0.30 +type CombinedLimit struct { + // Remaining number that is decremented on each execution + CallsRemaining uint64 `protobuf:"varint,1,opt,name=calls_remaining,json=callsRemaining,proto3" json:"calls_remaining,omitempty"` + // Amounts is the maximal amount of tokens transferable to the contract. + Amounts github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amounts,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amounts"` } -func (m *MaxFunds) Reset() { *m = MaxFunds{} } -func (m *MaxFunds) String() string { return proto.CompactTextString(m) } -func (*MaxFunds) ProtoMessage() {} -func (*MaxFunds) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{4} +func (m *CombinedLimit) Reset() { *m = CombinedLimit{} } +func (m *CombinedLimit) String() string { return proto.CompactTextString(m) } +func (*CombinedLimit) ProtoMessage() {} +func (*CombinedLimit) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{5} } -func (m *MaxFunds) XXX_Unmarshal(b []byte) error { +func (m *CombinedLimit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MaxFunds) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *CombinedLimit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MaxFunds.Marshal(b, m, deterministic) + return xxx_messageInfo_CombinedLimit.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -533,45 +297,39 @@ func (m *MaxFunds) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { } } -func (m *MaxFunds) XXX_Merge(src proto.Message) { - xxx_messageInfo_MaxFunds.Merge(m, src) +func (m *CombinedLimit) XXX_Merge(src proto.Message) { + xxx_messageInfo_CombinedLimit.Merge(m, src) } -func (m *MaxFunds) XXX_Size() int { +func (m *CombinedLimit) XXX_Size() int { return m.Size() } -func (m *MaxFunds) XXX_DiscardUnknown() { - xxx_messageInfo_MaxFunds.DiscardUnknown(m) +func (m *CombinedLimit) XXX_DiscardUnknown() { + xxx_messageInfo_CombinedLimit.DiscardUnknown(m) } -var xxx_messageInfo_MaxFunds proto.InternalMessageInfo - -func (m *MaxFunds) GetAmounts() github_com_cosmos_cosmos_sdk_types.Coins { - if m != nil { - return m.Amounts - } - return nil -} +var xxx_messageInfo_CombinedLimit proto.InternalMessageInfo -// AllowAllWildcard is a wildcard to allow any type of contract execution -// message -type AllowAllWildcard struct{} +// AllowAllMessagesFilter is a wildcard to allow any type of contract payload +// message. +// Since: wasmd 0.30 +type AllowAllMessagesFilter struct{} -func (m *AllowAllWildcard) Reset() { *m = AllowAllWildcard{} } -func (m *AllowAllWildcard) String() string { return proto.CompactTextString(m) } -func (*AllowAllWildcard) ProtoMessage() {} -func (*AllowAllWildcard) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{5} +func (m *AllowAllMessagesFilter) Reset() { *m = AllowAllMessagesFilter{} } +func (m *AllowAllMessagesFilter) String() string { return proto.CompactTextString(m) } +func (*AllowAllMessagesFilter) ProtoMessage() {} +func (*AllowAllMessagesFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{6} } -func (m *AllowAllWildcard) XXX_Unmarshal(b []byte) error { +func (m *AllowAllMessagesFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *AllowAllWildcard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *AllowAllMessagesFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_AllowAllWildcard.Marshal(b, m, deterministic) + return xxx_messageInfo_AllowAllMessagesFilter.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -582,32 +340,33 @@ func (m *AllowAllWildcard) XXX_Marshal(b []byte, deterministic bool) ([]byte, er } } -func (m *AllowAllWildcard) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowAllWildcard.Merge(m, src) +func (m *AllowAllMessagesFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_AllowAllMessagesFilter.Merge(m, src) } -func (m *AllowAllWildcard) XXX_Size() int { +func (m *AllowAllMessagesFilter) XXX_Size() int { return m.Size() } -func (m *AllowAllWildcard) XXX_DiscardUnknown() { - xxx_messageInfo_AllowAllWildcard.DiscardUnknown(m) +func (m *AllowAllMessagesFilter) XXX_DiscardUnknown() { + xxx_messageInfo_AllowAllMessagesFilter.DiscardUnknown(m) } -var xxx_messageInfo_AllowAllWildcard proto.InternalMessageInfo +var xxx_messageInfo_AllowAllMessagesFilter proto.InternalMessageInfo -// AcceptedMessageKeysFilter accept specific contract message keys in the json -// object that can be executed +// AcceptedMessageKeysFilter accept only the specific contract message keys in +// the json object to be executed. +// Since: wasmd 0.30 type AcceptedMessageKeysFilter struct { // Messages is the list of unique keys - Messages []string `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` + Keys []string `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` } func (m *AcceptedMessageKeysFilter) Reset() { *m = AcceptedMessageKeysFilter{} } func (m *AcceptedMessageKeysFilter) String() string { return proto.CompactTextString(m) } func (*AcceptedMessageKeysFilter) ProtoMessage() {} func (*AcceptedMessageKeysFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_36ff3a20cf32b258, []int{6} + return fileDescriptor_36ff3a20cf32b258, []int{7} } func (m *AcceptedMessageKeysFilter) XXX_Unmarshal(b []byte) error { @@ -641,67 +400,105 @@ func (m *AcceptedMessageKeysFilter) XXX_DiscardUnknown() { var xxx_messageInfo_AcceptedMessageKeysFilter proto.InternalMessageInfo -func (m *AcceptedMessageKeysFilter) GetMessages() []string { - if m != nil { - return m.Messages +// AcceptedMessagesFilter accept only the specific raw contract messages to be +// executed. +// Since: wasmd 0.30 +type AcceptedMessagesFilter struct { + // Messages is the list of raw contract messages + Messages []RawContractMessage `protobuf:"bytes,1,rep,name=messages,proto3,casttype=RawContractMessage" json:"messages,omitempty"` +} + +func (m *AcceptedMessagesFilter) Reset() { *m = AcceptedMessagesFilter{} } +func (m *AcceptedMessagesFilter) String() string { return proto.CompactTextString(m) } +func (*AcceptedMessagesFilter) ProtoMessage() {} +func (*AcceptedMessagesFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{8} +} + +func (m *AcceptedMessagesFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *AcceptedMessagesFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AcceptedMessagesFilter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return nil } +func (m *AcceptedMessagesFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_AcceptedMessagesFilter.Merge(m, src) +} + +func (m *AcceptedMessagesFilter) XXX_Size() int { + return m.Size() +} + +func (m *AcceptedMessagesFilter) XXX_DiscardUnknown() { + xxx_messageInfo_AcceptedMessagesFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_AcceptedMessagesFilter proto.InternalMessageInfo + func init() { proto.RegisterType((*ContractExecutionAuthorization)(nil), "cosmwasm.wasm.v1.ContractExecutionAuthorization") - proto.RegisterType((*ContractExecutionAuthorization_ContractExecutionGrant)(nil), "cosmwasm.wasm.v1.ContractExecutionAuthorization.ContractExecutionGrant") proto.RegisterType((*ContractMigrationAuthorization)(nil), "cosmwasm.wasm.v1.ContractMigrationAuthorization") - proto.RegisterType((*ContractMigrationAuthorization_ContractMigrationGrant)(nil), "cosmwasm.wasm.v1.ContractMigrationAuthorization.ContractMigrationGrant") - proto.RegisterType((*InfiniteCalls)(nil), "cosmwasm.wasm.v1.InfiniteCalls") - proto.RegisterType((*MaxCalls)(nil), "cosmwasm.wasm.v1.MaxCalls") - proto.RegisterType((*MaxFunds)(nil), "cosmwasm.wasm.v1.MaxFunds") - proto.RegisterType((*AllowAllWildcard)(nil), "cosmwasm.wasm.v1.AllowAllWildcard") + proto.RegisterType((*ContractGrant)(nil), "cosmwasm.wasm.v1.ContractGrant") + proto.RegisterType((*MaxCallsLimit)(nil), "cosmwasm.wasm.v1.MaxCallsLimit") + proto.RegisterType((*MaxFundsLimit)(nil), "cosmwasm.wasm.v1.MaxFundsLimit") + proto.RegisterType((*CombinedLimit)(nil), "cosmwasm.wasm.v1.CombinedLimit") + proto.RegisterType((*AllowAllMessagesFilter)(nil), "cosmwasm.wasm.v1.AllowAllMessagesFilter") proto.RegisterType((*AcceptedMessageKeysFilter)(nil), "cosmwasm.wasm.v1.AcceptedMessageKeysFilter") + proto.RegisterType((*AcceptedMessagesFilter)(nil), "cosmwasm.wasm.v1.AcceptedMessagesFilter") } func init() { proto.RegisterFile("cosmwasm/wasm/v1/authz.proto", fileDescriptor_36ff3a20cf32b258) } var fileDescriptor_36ff3a20cf32b258 = []byte{ - // 605 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0x4f, 0x6f, 0xd3, 0x30, - 0x1c, 0x6d, 0xb6, 0x52, 0x5a, 0x4f, 0xdb, 0xba, 0xf0, 0x47, 0x59, 0x35, 0x65, 0x53, 0x0e, 0xa8, - 0x12, 0x5a, 0x42, 0xc7, 0x01, 0xc1, 0x89, 0xa6, 0x62, 0x2b, 0x42, 0xbd, 0xe4, 0x32, 0x89, 0x4b, - 0xe4, 0x26, 0x6e, 0x6a, 0x2d, 0x89, 0x4b, 0xec, 0xf4, 0xcf, 0x3e, 0x05, 0x9f, 0x83, 0x33, 0x1f, - 0xa2, 0x12, 0x97, 0x89, 0x13, 0x27, 0x40, 0xad, 0x90, 0xf8, 0x18, 0x28, 0x8e, 0xd3, 0xae, 0x4d, - 0xd9, 0x85, 0x0b, 0x17, 0xd7, 0x3f, 0xbf, 0xf7, 0x7b, 0xfa, 0xd5, 0x7e, 0x79, 0xe0, 0xc8, 0x21, - 0x34, 0x18, 0x41, 0x1a, 0x18, 0x7c, 0x19, 0x36, 0x0c, 0x18, 0xb3, 0xfe, 0xb5, 0x3e, 0x88, 0x08, - 0x23, 0x72, 0x35, 0x43, 0x75, 0xbe, 0x0c, 0x1b, 0xb5, 0x87, 0x1e, 0xf1, 0x08, 0x07, 0x8d, 0x64, - 0x97, 0xf2, 0x6a, 0x87, 0x09, 0x8f, 0x50, 0x3b, 0x05, 0xd2, 0x42, 0x40, 0x6a, 0x5a, 0x19, 0x5d, - 0x48, 0x91, 0x31, 0x6c, 0x74, 0x11, 0x83, 0x0d, 0xc3, 0x21, 0x38, 0x4c, 0x71, 0xed, 0x57, 0x11, - 0xa8, 0x2d, 0x12, 0xb2, 0x08, 0x3a, 0xec, 0xcd, 0x18, 0x39, 0x31, 0xc3, 0x24, 0x6c, 0xc6, 0xac, - 0x4f, 0x22, 0x7c, 0x0d, 0x93, 0x42, 0x46, 0xa0, 0xe4, 0x45, 0x30, 0x64, 0x54, 0x91, 0x4e, 0xb6, - 0xeb, 0x3b, 0x67, 0x17, 0xfa, 0xfa, 0x58, 0xfa, 0xdd, 0x0a, 0x79, 0xf8, 0x22, 0xd1, 0x33, 0x8b, - 0xd3, 0xef, 0xc7, 0x05, 0x4b, 0x88, 0xd7, 0xa6, 0xdb, 0xe0, 0xf1, 0x66, 0xa2, 0x5c, 0x03, 0x65, - 0x47, 0x20, 0x8a, 0x74, 0x22, 0xd5, 0x2b, 0xd6, 0xa2, 0x96, 0xdb, 0x60, 0x0f, 0x87, 0x3d, 0x1c, - 0x62, 0x86, 0x6c, 0x07, 0xfa, 0x3e, 0x55, 0xb6, 0x4e, 0xa4, 0xfa, 0xce, 0xd9, 0x71, 0x7e, 0xca, - 0xb7, 0x82, 0xd7, 0x4a, 0x68, 0xed, 0x82, 0xb5, 0x8b, 0x6f, 0x1f, 0xc8, 0x2f, 0x41, 0x25, 0x80, - 0x63, 0x21, 0xb2, 0xcd, 0x45, 0x6a, 0x79, 0x91, 0x0e, 0x1c, 0x67, 0xfd, 0xe5, 0x40, 0xec, 0xb3, - 0xd6, 0x5e, 0x1c, 0xba, 0x54, 0x29, 0xde, 0xd1, 0x7a, 0x9e, 0x30, 0x44, 0x2b, 0xdf, 0xcb, 0x10, - 0x3c, 0x82, 0x8e, 0x83, 0x06, 0x0c, 0xb9, 0x76, 0x80, 0x28, 0x85, 0x1e, 0xb2, 0xaf, 0xd0, 0x84, - 0x2a, 0xf7, 0xb8, 0xcc, 0xd3, 0xbc, 0x4c, 0x53, 0xd0, 0x3b, 0x29, 0xfb, 0x1d, 0x9a, 0xd0, 0x73, - 0xec, 0x33, 0x14, 0xb5, 0x25, 0xeb, 0x01, 0xcc, 0x83, 0xb2, 0x05, 0x64, 0xe8, 0xfb, 0x64, 0x64, - 0x43, 0xdf, 0xb7, 0x47, 0xd8, 0x77, 0x1d, 0x18, 0xb9, 0x4a, 0x89, 0xeb, 0x6b, 0x1b, 0xf4, 0x13, - 0x6e, 0xd3, 0xf7, 0x2f, 0x05, 0xb3, 0x2d, 0x59, 0x55, 0xb8, 0x76, 0x66, 0x1e, 0x80, 0x7d, 0x94, - 0x3d, 0x92, 0xed, 0xe3, 0x00, 0x33, 0xb3, 0x0c, 0x4a, 0x3d, 0x3e, 0xc7, 0xab, 0x83, 0xaf, 0x9f, - 0x4f, 0x77, 0x57, 0x2c, 0xa0, 0xfd, 0xde, 0x5a, 0xfa, 0xac, 0x83, 0xbd, 0x08, 0xfe, 0x93, 0xcf, - 0x36, 0x2b, 0xe4, 0xe1, 0x4d, 0x3e, 0xfb, 0x22, 0x2d, 0x7d, 0xb6, 0x4a, 0xfc, 0xef, 0x7d, 0x66, - 0x56, 0xc1, 0x5e, 0xd2, 0xba, 0xb8, 0x79, 0xba, 0xe9, 0xaa, 0xf7, 0xc1, 0xee, 0xca, 0x04, 0x5a, - 0x1d, 0x94, 0x33, 0x35, 0xf9, 0x08, 0x54, 0x22, 0x14, 0x40, 0x1c, 0xe2, 0xd0, 0xe3, 0xff, 0xb1, - 0x68, 0x2d, 0x0f, 0xb4, 0x0f, 0x9c, 0x99, 0x1a, 0x13, 0x81, 0xfb, 0x30, 0x20, 0xf1, 0xf2, 0x3d, - 0x0e, 0x75, 0x91, 0x2c, 0x49, 0x96, 0xe8, 0x22, 0x4b, 0xf4, 0x16, 0xc1, 0xa1, 0xf9, 0x2c, 0xb9, - 0xe1, 0x4f, 0x3f, 0x8e, 0xeb, 0x1e, 0x66, 0xfd, 0xb8, 0xab, 0x3b, 0x24, 0x10, 0x31, 0x24, 0x7e, - 0x4e, 0xa9, 0x7b, 0x65, 0xb0, 0xc9, 0x00, 0x51, 0xde, 0x40, 0xad, 0x4c, 0x5b, 0x93, 0x41, 0x75, - 0xdd, 0x70, 0xda, 0x0b, 0x70, 0xf8, 0x57, 0x93, 0x27, 0x8f, 0x24, 0xbe, 0x93, 0x74, 0xb0, 0x8a, - 0xb5, 0xa8, 0xcd, 0xd7, 0xd3, 0x99, 0x2a, 0xdd, 0xcc, 0x54, 0xe9, 0xe7, 0x4c, 0x95, 0x3e, 0xce, - 0xd5, 0xc2, 0xcd, 0x5c, 0x2d, 0x7c, 0x9b, 0xab, 0x85, 0xf7, 0x4f, 0x6e, 0x4d, 0xd6, 0x22, 0x34, - 0xb8, 0xcc, 0x32, 0xd7, 0x35, 0xc6, 0x69, 0xf6, 0xf2, 0xe9, 0xba, 0x25, 0x1e, 0x8b, 0xcf, 0xff, - 0x04, 0x00, 0x00, 0xff, 0xff, 0xd0, 0x9f, 0xfa, 0xa4, 0x99, 0x05, 0x00, 0x00, + // 578 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0x4d, 0x8f, 0xd2, 0x40, + 0x18, 0xa6, 0xbb, 0x2b, 0x2e, 0xb3, 0xe2, 0x47, 0x25, 0x08, 0x64, 0x53, 0x08, 0x07, 0xe5, 0x42, + 0x2b, 0x78, 0x23, 0xf1, 0x00, 0x28, 0xc6, 0x28, 0x97, 0x5e, 0xdc, 0x78, 0xd9, 0x4c, 0xcb, 0x50, + 0x26, 0xdb, 0x76, 0x48, 0x67, 0xca, 0xd7, 0x9f, 0xd0, 0xdf, 0xe1, 0x99, 0x83, 0x3f, 0x81, 0x70, + 0xda, 0xa3, 0xa7, 0x55, 0xe1, 0x5f, 0x78, 0x32, 0x9d, 0x99, 0xb2, 0x40, 0xc2, 0x1e, 0xf5, 0x52, + 0xe6, 0xfd, 0x78, 0x9e, 0xf7, 0x99, 0xf7, 0x7d, 0x19, 0x70, 0x6e, 0x13, 0xea, 0x8d, 0x21, 0xf5, + 0x0c, 0xfe, 0x19, 0xd5, 0x0c, 0x18, 0xb2, 0xc1, 0x4c, 0x1f, 0x06, 0x84, 0x11, 0xf5, 0x71, 0x1c, + 0xd5, 0xf9, 0x67, 0x54, 0x2b, 0x64, 0x1c, 0xe2, 0x10, 0x1e, 0x34, 0xa2, 0x93, 0xc8, 0x2b, 0xe4, + 0xa3, 0x3c, 0x42, 0x2f, 0x45, 0x40, 0x18, 0x32, 0xa4, 0x09, 0xcb, 0xb0, 0x20, 0x45, 0xc6, 0xa8, + 0x66, 0x21, 0x06, 0x6b, 0x86, 0x4d, 0xb0, 0x1f, 0x43, 0x1d, 0x42, 0x1c, 0x17, 0x19, 0xdc, 0xb2, + 0xc2, 0xbe, 0x01, 0xfd, 0xa9, 0x08, 0x95, 0x03, 0xa0, 0xb5, 0x89, 0xcf, 0x02, 0x68, 0xb3, 0xb7, + 0x13, 0x64, 0x87, 0x0c, 0x13, 0xbf, 0x19, 0xb2, 0x01, 0x09, 0xf0, 0x0c, 0x46, 0x86, 0xfa, 0x1a, + 0x24, 0x9d, 0x00, 0xfa, 0x8c, 0xe6, 0x94, 0xd2, 0x71, 0xe5, 0xac, 0x5e, 0xd4, 0xf7, 0x05, 0xeb, + 0x31, 0xc3, 0xbb, 0x28, 0xaf, 0x75, 0xb2, 0xb8, 0x29, 0x26, 0x4c, 0x09, 0x6a, 0x3c, 0x59, 0xce, + 0xab, 0xe9, 0x1d, 0xc6, 0xed, 0x9a, 0x5d, 0xec, 0x04, 0xf0, 0x5f, 0xd4, 0xfc, 0xae, 0x80, 0xf4, + 0x0e, 0x44, 0x2d, 0x80, 0x53, 0x5b, 0x3a, 0x72, 0x4a, 0x49, 0xa9, 0xa4, 0xcc, 0x8d, 0xad, 0xb6, + 0xc1, 0x3d, 0x17, 0x7b, 0x98, 0xe5, 0x8e, 0x4a, 0x4a, 0xe5, 0xac, 0x9e, 0xd1, 0x45, 0x03, 0xf5, + 0xb8, 0x81, 0x7a, 0xd3, 0x9f, 0xb6, 0x9e, 0x2d, 0xe7, 0xd5, 0xa7, 0x31, 0x67, 0x54, 0x6d, 0xf6, + 0x31, 0xc2, 0x5c, 0x98, 0x02, 0xab, 0x76, 0x40, 0xb2, 0x8f, 0x5d, 0x86, 0x82, 0xdc, 0xf1, 0x1d, + 0x2c, 0xb9, 0xe5, 0xbc, 0x9a, 0xd9, 0x61, 0xe9, 0x70, 0xd0, 0x85, 0x29, 0xd1, 0xe5, 0x0e, 0x48, + 0x77, 0xe1, 0xa4, 0x0d, 0x5d, 0x97, 0xf2, 0x02, 0xea, 0x39, 0x48, 0x05, 0xc8, 0x83, 0xd8, 0xc7, + 0xbe, 0xc3, 0xa5, 0x9f, 0x98, 0xb7, 0x8e, 0xc6, 0x21, 0x59, 0xe5, 0x2f, 0x0a, 0x27, 0xea, 0x84, + 0x7e, 0x4f, 0x12, 0x21, 0x70, 0x1f, 0x7a, 0x24, 0xbc, 0xed, 0x73, 0x5e, 0x97, 0x7b, 0x15, 0x6d, + 0x92, 0x2e, 0x37, 0x49, 0x6f, 0x13, 0xec, 0xb7, 0x5e, 0x46, 0x1d, 0xfe, 0xf6, 0xb3, 0x58, 0x71, + 0x30, 0x1b, 0x84, 0x96, 0x6e, 0x13, 0x4f, 0x2e, 0xa1, 0xfc, 0xa9, 0xd2, 0xde, 0x95, 0xc1, 0xa6, + 0x43, 0x44, 0x39, 0x80, 0x9a, 0x31, 0xf7, 0x61, 0x45, 0x62, 0x28, 0x9e, 0x85, 0x7d, 0xd4, 0x13, + 0x8a, 0x5e, 0x80, 0x47, 0x76, 0x74, 0xd1, 0xcb, 0xfd, 0x0b, 0x3e, 0xe4, 0x6e, 0x33, 0xf6, 0x6e, + 0x4b, 0x3f, 0xfa, 0x1f, 0xd2, 0xeb, 0x20, 0xdb, 0x74, 0x5d, 0x32, 0x6e, 0xba, 0x6e, 0x17, 0x51, + 0x0a, 0x1d, 0x44, 0xc5, 0xdc, 0x1a, 0x07, 0x07, 0x5a, 0x7e, 0x0f, 0xf2, 0x4d, 0xdb, 0x46, 0x43, + 0x86, 0x7a, 0x12, 0xf3, 0x01, 0x4d, 0x25, 0x4c, 0x55, 0xc1, 0xc9, 0x15, 0x9a, 0x8a, 0x41, 0xa4, + 0x4c, 0x7e, 0xbe, 0x83, 0xaa, 0x0f, 0xb2, 0x7b, 0x54, 0x31, 0x4f, 0x1d, 0x9c, 0x7a, 0xd2, 0xc3, + 0xb9, 0x1e, 0xb4, 0xb2, 0x7f, 0x6e, 0x8a, 0xaa, 0x09, 0xc7, 0x9b, 0xff, 0x9c, 0x08, 0x9b, 0x9b, + 0xbc, 0xc3, 0x75, 0x5a, 0x6f, 0x16, 0xbf, 0xb5, 0xc4, 0x62, 0xa5, 0x29, 0xd7, 0x2b, 0x4d, 0xf9, + 0xb5, 0xd2, 0x94, 0xaf, 0x6b, 0x2d, 0x71, 0xbd, 0xd6, 0x12, 0x3f, 0xd6, 0x5a, 0xe2, 0xf3, 0xf3, + 0xad, 0x86, 0xb6, 0x09, 0xf5, 0x3e, 0xc5, 0x6f, 0x5c, 0xcf, 0x98, 0x88, 0xb7, 0x8e, 0x37, 0xd5, + 0x4a, 0xf2, 0x8d, 0x7f, 0xf5, 0x37, 0x00, 0x00, 0xff, 0xff, 0x13, 0xc8, 0x1d, 0x99, 0x09, 0x05, + 0x00, 0x00, } func (m *ContractExecutionAuthorization) Marshal() (dAtA []byte, err error) { @@ -741,7 +538,7 @@ func (m *ContractExecutionAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *ContractExecutionAuthorization_ContractExecutionGrant) Marshal() (dAtA []byte, err error) { +func (m *ContractMigrationAuthorization) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -751,54 +548,56 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) Marshal() (dAtA return dAtA[:n], nil } -func (m *ContractExecutionAuthorization_ContractExecutionGrant) MarshalTo(dAtA []byte) (int, error) { +func (m *ContractMigrationAuthorization) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ContractExecutionAuthorization_ContractExecutionGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ContractMigrationAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Filter != nil { - { - size := m.Filter.Size() - i -= size - if _, err := m.Filter.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.ExecutionLimit != nil { - { - size := m.ExecutionLimit.Size() - i -= size - if _, err := m.ExecutionLimit.MarshalTo(dAtA[i:]); err != nil { - return 0, err + if len(m.Grants) > 0 { + for iNdEx := len(m.Grants) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Grants[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0xa } } - if len(m.Contract) > 0 { - i -= len(m.Contract) - copy(dAtA[i:], m.Contract) - i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) - i-- - dAtA[i] = 0xa - } return len(dAtA) - i, nil } -func (m *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) MarshalTo(dAtA []byte) (int, error) { +func (m *ContractGrant) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractGrant) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ContractGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.InfiniteCalls != nil { + _ = i + var l int + _ = l + if m.Filter != nil { { - size, err := m.InfiniteCalls.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Filter.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -806,21 +605,11 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) Ma i = encodeVarintAuthz(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } - return len(dAtA) - i, nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.MaxCalls != nil { + if m.Limit != nil { { - size, err := m.MaxCalls.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Limit.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -828,78 +617,47 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) Marshal i = encodeVarintAuthz(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x12 + } + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) MarshalTo(dAtA []byte) (int, error) { +func (m *MaxCallsLimit) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MaxCallsLimit) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MaxCallsLimit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.MaxFunds != nil { - { - size, err := m.MaxFunds.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAuthz(dAtA, i, uint64(size)) - } + _ = i + var l int + _ = l + if m.Remaining != 0 { + i = encodeVarintAuthz(dAtA, i, uint64(m.Remaining)) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x8 } return len(dAtA) - i, nil } -func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.AcceptedMessageKeys != nil { - { - size, err := m.AcceptedMessageKeys.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAuthz(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - return len(dAtA) - i, nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.AllowAllWildcard != nil { - { - size, err := m.AllowAllWildcard.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAuthz(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 - } - return len(dAtA) - i, nil -} - -func (m *ContractMigrationAuthorization) Marshal() (dAtA []byte, err error) { +func (m *MaxFundsLimit) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -909,20 +667,20 @@ func (m *ContractMigrationAuthorization) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ContractMigrationAuthorization) MarshalTo(dAtA []byte) (int, error) { +func (m *MaxFundsLimit) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ContractMigrationAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MaxFundsLimit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Grants) > 0 { - for iNdEx := len(m.Grants) - 1; iNdEx >= 0; iNdEx-- { + if len(m.Amounts) > 0 { + for iNdEx := len(m.Amounts) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.Grants[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Amounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -936,7 +694,7 @@ func (m *ContractMigrationAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) Marshal() (dAtA []byte, err error) { +func (m *CombinedLimit) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -946,103 +704,39 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) Marshal() (dAtA return dAtA[:n], nil } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) MarshalTo(dAtA []byte) (int, error) { +func (m *CombinedLimit) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *CombinedLimit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.MaxExecutions != nil { - { - size := m.MaxExecutions.Size() - i -= size - if _, err := m.MaxExecutions.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if len(m.Contract) > 0 { - i -= len(m.Contract) - copy(dAtA[i:], m.Contract) - i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.InfiniteCalls != nil { - { - size, err := m.InfiniteCalls.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.Amounts) > 0 { + for iNdEx := len(m.Amounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintAuthz(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 } - i-- - dAtA[i] = 0x12 } - return len(dAtA) - i, nil -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.MaxCalls != nil { - { - size, err := m.MaxCalls.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAuthz(dAtA, i, uint64(size)) - } + if m.CallsRemaining != 0 { + i = encodeVarintAuthz(dAtA, i, uint64(m.CallsRemaining)) i-- - dAtA[i] = 0x1a - } - return len(dAtA) - i, nil -} - -func (m *InfiniteCalls) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err + dAtA[i] = 0x8 } - return dAtA[:n], nil -} - -func (m *InfiniteCalls) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *InfiniteCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l return len(dAtA) - i, nil } -func (m *MaxCalls) Marshal() (dAtA []byte, err error) { +func (m *AllowAllMessagesFilter) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1052,25 +746,20 @@ func (m *MaxCalls) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MaxCalls) MarshalTo(dAtA []byte) (int, error) { +func (m *AllowAllMessagesFilter) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MaxCalls) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AllowAllMessagesFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Remaining != 0 { - i = encodeVarintAuthz(dAtA, i, uint64(m.Remaining)) - i-- - dAtA[i] = 0x8 - } return len(dAtA) - i, nil } -func (m *MaxFunds) Marshal() (dAtA []byte, err error) { +func (m *AcceptedMessageKeysFilter) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1080,26 +769,21 @@ func (m *MaxFunds) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MaxFunds) MarshalTo(dAtA []byte) (int, error) { +func (m *AcceptedMessageKeysFilter) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MaxFunds) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AcceptedMessageKeysFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Amounts) > 0 { - for iNdEx := len(m.Amounts) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Amounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAuthz(dAtA, i, uint64(size)) - } + if len(m.Keys) > 0 { + for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Keys[iNdEx]) + copy(dAtA[i:], m.Keys[iNdEx]) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Keys[iNdEx]))) i-- dAtA[i] = 0xa } @@ -1107,30 +791,7 @@ func (m *MaxFunds) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *AllowAllWildcard) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AllowAllWildcard) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowAllWildcard) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *AcceptedMessageKeysFilter) Marshal() (dAtA []byte, err error) { +func (m *AcceptedMessagesFilter) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1140,12 +801,12 @@ func (m *AcceptedMessageKeysFilter) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *AcceptedMessageKeysFilter) MarshalTo(dAtA []byte) (int, error) { +func (m *AcceptedMessagesFilter) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AcceptedMessageKeysFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AcceptedMessagesFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1189,90 +850,6 @@ func (m *ContractExecutionAuthorization) Size() (n int) { return n } -func (m *ContractExecutionAuthorization_ContractExecutionGrant) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Contract) - if l > 0 { - n += 1 + l + sovAuthz(uint64(l)) - } - if m.ExecutionLimit != nil { - n += m.ExecutionLimit.Size() - } - if m.Filter != nil { - n += m.Filter.Size() - } - return n -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.InfiniteCalls != nil { - l = m.InfiniteCalls.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - return n -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.MaxCalls != nil { - l = m.MaxCalls.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - return n -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.MaxFunds != nil { - l = m.MaxFunds.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - return n -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.AcceptedMessageKeys != nil { - l = m.AcceptedMessageKeys.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - return n -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.AllowAllWildcard != nil { - l = m.AllowAllWildcard.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - return n -} - func (m *ContractMigrationAuthorization) Size() (n int) { if m == nil { return 0 @@ -1288,7 +865,7 @@ func (m *ContractMigrationAuthorization) Size() (n int) { return n } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) Size() (n int) { +func (m *ContractGrant) Size() (n int) { if m == nil { return 0 } @@ -1296,397 +873,143 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) Size() (n int) { _ = l l = len(m.Contract) if l > 0 { - n += 1 + l + sovAuthz(uint64(l)) - } - if m.MaxExecutions != nil { - n += m.MaxExecutions.Size() - } - return n -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.InfiniteCalls != nil { - l = m.InfiniteCalls.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - return n -} - -func (m *ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.MaxCalls != nil { - l = m.MaxCalls.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - return n -} - -func (m *InfiniteCalls) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *MaxCalls) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Remaining != 0 { - n += 1 + sovAuthz(uint64(m.Remaining)) - } - return n -} - -func (m *MaxFunds) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Amounts) > 0 { - for _, e := range m.Amounts { - l = e.Size() - n += 1 + l + sovAuthz(uint64(l)) - } - } - return n -} - -func (m *AllowAllWildcard) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *AcceptedMessageKeysFilter) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Messages) > 0 { - for _, s := range m.Messages { - l = len(s) - n += 1 + l + sovAuthz(uint64(l)) - } - } - return n -} - -func sovAuthz(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} - -func sozAuthz(x uint64) (n int) { - return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} - -func (m *ContractExecutionAuthorization) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContractExecutionAuthorization: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContractExecutionAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Grants", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthz - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthz - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Grants = append(m.Grants, ContractExecutionAuthorization_ContractExecutionGrant{}) - if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAuthz(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAuthz - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} - -func (m *ContractExecutionAuthorization_ContractExecutionGrant) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContractExecutionGrant: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContractExecutionGrant: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - 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 ErrInvalidLengthAuthz - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthz - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Contract = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InfiniteCalls", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthz - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthz - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &InfiniteCalls{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.ExecutionLimit = &ContractExecutionAuthorization_ContractExecutionGrant_InfiniteCalls{v} - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxCalls", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthz - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthz - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &MaxCalls{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.ExecutionLimit = &ContractExecutionAuthorization_ContractExecutionGrant_MaxCalls{v} - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxFunds", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthz - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthz - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &MaxFunds{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.ExecutionLimit = &ContractExecutionAuthorization_ContractExecutionGrant_MaxFunds{v} - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AcceptedMessageKeys", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthz - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthz - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthz + n += 1 + l + sovAuthz(uint64(l)) + } + if m.Limit != nil { + l = m.Limit.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + if m.Filter != nil { + l = m.Filter.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *MaxCallsLimit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Remaining != 0 { + n += 1 + sovAuthz(uint64(m.Remaining)) + } + return n +} + +func (m *MaxFundsLimit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Amounts) > 0 { + for _, e := range m.Amounts { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *CombinedLimit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CallsRemaining != 0 { + n += 1 + sovAuthz(uint64(m.CallsRemaining)) + } + if len(m.Amounts) > 0 { + for _, e := range m.Amounts { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *AllowAllMessagesFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *AcceptedMessageKeysFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Keys) > 0 { + for _, s := range m.Keys { + l = len(s) + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *AcceptedMessagesFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Messages) > 0 { + for _, b := range m.Messages { + l = len(b) + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func sovAuthz(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} + +func sozAuthz(x uint64) (n int) { + return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +func (m *ContractExecutionAuthorization) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz } - if postIndex > l { + if iNdEx >= l { return io.ErrUnexpectedEOF } - v := &AcceptedMessageKeysFilter{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - m.Filter = &ContractExecutionAuthorization_ContractExecutionGrant_AcceptedMessageKeys{v} - iNdEx = postIndex - case 6: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractExecutionAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractExecutionAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowAllWildcard", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Grants", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1713,11 +1036,10 @@ func (m *ContractExecutionAuthorization_ContractExecutionGrant) Unmarshal(dAtA [ if postIndex > l { return io.ErrUnexpectedEOF } - v := &AllowAllWildcard{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Grants = append(m.Grants, ContractGrant{}) + if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Filter = &ContractExecutionAuthorization_ContractExecutionGrant_AllowAllWildcard{v} iNdEx = postIndex default: iNdEx = preIndex @@ -1799,7 +1121,7 @@ func (m *ContractMigrationAuthorization) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Grants = append(m.Grants, ContractMigrationAuthorization_ContractMigrationGrant{}) + m.Grants = append(m.Grants, ContractGrant{}) if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -1826,7 +1148,7 @@ func (m *ContractMigrationAuthorization) Unmarshal(dAtA []byte) error { return nil } -func (m *ContractMigrationAuthorization_ContractMigrationGrant) Unmarshal(dAtA []byte) error { +func (m *ContractGrant) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1849,10 +1171,10 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) Unmarshal(dAtA [ fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ContractMigrationGrant: wiretype end group for non-group") + return fmt.Errorf("proto: ContractGrant: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ContractMigrationGrant: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ContractGrant: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1889,7 +1211,7 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) Unmarshal(dAtA [ iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InfiniteCalls", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1916,15 +1238,16 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) Unmarshal(dAtA [ if postIndex > l { return io.ErrUnexpectedEOF } - v := &InfiniteCalls{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Limit == nil { + m.Limit = &types.Any{} + } + if err := m.Limit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.MaxExecutions = &ContractMigrationAuthorization_ContractMigrationGrant_InfiniteCalls{v} iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxCalls", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1951,11 +1274,12 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) Unmarshal(dAtA [ if postIndex > l { return io.ErrUnexpectedEOF } - v := &MaxCalls{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Filter == nil { + m.Filter = &types.Any{} + } + if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.MaxExecutions = &ContractMigrationAuthorization_ContractMigrationGrant_MaxCalls{v} iNdEx = postIndex default: iNdEx = preIndex @@ -1979,7 +1303,7 @@ func (m *ContractMigrationAuthorization_ContractMigrationGrant) Unmarshal(dAtA [ return nil } -func (m *InfiniteCalls) Unmarshal(dAtA []byte) error { +func (m *MaxCallsLimit) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2002,12 +1326,31 @@ func (m *InfiniteCalls) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: InfiniteCalls: wiretype end group for non-group") + return fmt.Errorf("proto: MaxCallsLimit: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: InfiniteCalls: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MaxCallsLimit: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Remaining", wireType) + } + m.Remaining = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Remaining |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipAuthz(dAtA[iNdEx:]) @@ -2030,7 +1373,7 @@ func (m *InfiniteCalls) Unmarshal(dAtA []byte) error { return nil } -func (m *MaxCalls) Unmarshal(dAtA []byte) error { +func (m *MaxFundsLimit) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2053,17 +1396,17 @@ func (m *MaxCalls) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MaxCalls: wiretype end group for non-group") + return fmt.Errorf("proto: MaxFundsLimit: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MaxCalls: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MaxFundsLimit: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Remaining", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amounts", wireType) } - m.Remaining = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuthz @@ -2073,11 +1416,26 @@ func (m *MaxCalls) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Remaining |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amounts = append(m.Amounts, types1.Coin{}) + if err := m.Amounts[len(m.Amounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuthz(dAtA[iNdEx:]) @@ -2100,7 +1458,7 @@ func (m *MaxCalls) Unmarshal(dAtA []byte) error { return nil } -func (m *MaxFunds) Unmarshal(dAtA []byte) error { +func (m *CombinedLimit) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2123,13 +1481,32 @@ func (m *MaxFunds) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MaxFunds: wiretype end group for non-group") + return fmt.Errorf("proto: CombinedLimit: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MaxFunds: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CombinedLimit: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CallsRemaining", wireType) + } + m.CallsRemaining = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CallsRemaining |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Amounts", wireType) } @@ -2158,7 +1535,7 @@ func (m *MaxFunds) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Amounts = append(m.Amounts, types.Coin{}) + m.Amounts = append(m.Amounts, types1.Coin{}) if err := m.Amounts[len(m.Amounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -2185,7 +1562,7 @@ func (m *MaxFunds) Unmarshal(dAtA []byte) error { return nil } -func (m *AllowAllWildcard) Unmarshal(dAtA []byte) error { +func (m *AllowAllMessagesFilter) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2208,10 +1585,10 @@ func (m *AllowAllWildcard) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AllowAllWildcard: wiretype end group for non-group") + return fmt.Errorf("proto: AllowAllMessagesFilter: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AllowAllWildcard: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AllowAllMessagesFilter: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -2267,7 +1644,7 @@ func (m *AcceptedMessageKeysFilter) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2295,7 +1672,90 @@ func (m *AcceptedMessageKeysFilter) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Messages = append(m.Messages, string(dAtA[iNdEx:postIndex])) + m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *AcceptedMessagesFilter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AcceptedMessagesFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AcceptedMessagesFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Messages = append(m.Messages, make([]byte, postIndex-iNdEx)) + copy(m.Messages[len(m.Messages)-1], dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/wasm/types/authz_test.go b/x/wasm/types/authz_test.go deleted file mode 100644 index e842b67e2c..0000000000 --- a/x/wasm/types/authz_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - "github.com/cosmos/cosmos-sdk/simapp" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func TestAuthzAuthorizations(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - - contractAuth := NewContractAuthorization(sdk.AccAddress{}, []string{"bond"}, false) - require.Equal(t, contractAuth.MsgTypeURL(), "/cosmwasm.wasm.v1.MsgExecuteContract") - require.Error(t, contractAuth.ValidateBasic()) - - contractAuth = NewContractAuthorization(sdk.AccAddress("cw-contract"), []string{}, false) - require.Error(t, contractAuth.ValidateBasic()) - - testCases := map[string]struct { - contract string - allowed []string - once bool - srvMsg sdk.Msg - expectErr bool - }{ - "invalid cosmos msg": { - "cw-staking-1", - []string{"claim"}, - false, - &MsgClearAdmin{}, - true, - }, - "no allowed contract": { - "cw-staking-1", - []string{"claim"}, - false, - newGranteeExecuteMsg("cw-staking-2", `{"claim": {}}`), - true, - }, - "no allowed msg": { - "cw-staking-1", - []string{"claim", "harvest", "bond"}, - false, - newGranteeExecuteMsg("cw-staking-1", `{"unbond": {}}`), - true, - }, - "many msgs in execute msg": { - "cw-staking-1", - []string{"bond", "claim"}, - false, - newGranteeExecuteMsg("cw-staking-1", `{"claim": {}, "bond":{}}`), - true, - }, - "valid contract and msgs": { - "cw-staking-1", - []string{"bond", "claim"}, - false, - newGranteeExecuteMsg("cw-staking-1", `{"claim": {}}`), - false, - }, - "allowed once": { - "cw-staking-1", - []string{"bond", "claim"}, - true, - newGranteeExecuteMsg("cw-staking-1", `{"bond": {}}`), - false, - }, - } - - for name, tc := range testCases { - tc := tc - t.Run(name, func(t *testing.T) { - contractAuth = NewContractAuthorization(sdk.AccAddress(tc.contract), tc.allowed, tc.once) - resp, err := contractAuth.Accept(ctx, tc.srvMsg) - if tc.expectErr { - require.Error(t, err) - } else { - require.NoError(t, err) - require.Equal(t, tc.once, resp.Delete) - require.Nil(t, resp.Updated) - } - }) - } -} - -func newGranteeExecuteMsg(contract, msg string) *MsgExecuteContract { - return &MsgExecuteContract{ - Sender: "grantee", - Contract: sdk.AccAddress(contract).String(), - Msg: []byte(msg), - Funds: sdk.Coins{}, - } -} diff --git a/x/wasm/types/codec.go b/x/wasm/types/codec.go index 5abaf1d0a6..5148da1346 100644 --- a/x/wasm/types/codec.go +++ b/x/wasm/types/codec.go @@ -30,7 +30,21 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { //nolint:staticcheck cdc.RegisterConcrete(&UpdateAdminProposal{}, "wasm/UpdateAdminProposal", nil) cdc.RegisterConcrete(&ClearAdminProposal{}, "wasm/ClearAdminProposal", nil) cdc.RegisterConcrete(&UpdateInstantiateConfigProposal{}, "wasm/UpdateInstantiateConfigProposal", nil) + + cdc.RegisterInterface((*ContractInfoExtension)(nil), nil) + + cdc.RegisterInterface((*ContractAuthzFilterX)(nil), nil) + cdc.RegisterConcrete(&AllowAllMessagesFilter{}, "wasm/AllowAllMessagesFilter", nil) + cdc.RegisterConcrete(&AcceptedMessageKeysFilter{}, "wasm/AcceptedMessageKeysFilter", nil) + cdc.RegisterConcrete(&AcceptedMessagesFilter{}, "wasm/AcceptedMessagesFilter", nil) + + cdc.RegisterInterface((*ContractAuthzLimitX)(nil), nil) + cdc.RegisterConcrete(&MaxCallsLimit{}, "wasm/MaxCallsLimit", nil) + cdc.RegisterConcrete(&MaxFundsLimit{}, "wasm/MaxFundsLimit", nil) + cdc.RegisterConcrete(&CombinedLimit{}, "wasm/CombinedLimit", nil) + cdc.RegisterConcrete(&ContractExecutionAuthorization{}, "wasm/ContractExecutionAuthorization", nil) + cdc.RegisterConcrete(&ContractMigrationAuthorization{}, "wasm/ContractMigrationAuthorization", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -62,9 +76,26 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { registry.RegisterInterface("ContractInfoExtension", (*ContractInfoExtension)(nil)) + registry.RegisterInterface("ContractAuthzFilterX", (*ContractAuthzFilterX)(nil)) + registry.RegisterImplementations( + (*ContractAuthzFilterX)(nil), + &AllowAllMessagesFilter{}, + &AcceptedMessageKeysFilter{}, + &AcceptedMessagesFilter{}, + ) + + registry.RegisterInterface("ContractAuthzLimitX", (*ContractAuthzLimitX)(nil)) + registry.RegisterImplementations( + (*ContractAuthzLimitX)(nil), + &MaxCallsLimit{}, + &MaxFundsLimit{}, + &CombinedLimit{}, + ) + registry.RegisterImplementations( (*authz.Authorization)(nil), &ContractExecutionAuthorization{}, + &ContractMigrationAuthorization{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/wasm/types/json_matching.go b/x/wasm/types/json_matching.go index cfa8522650..218035792b 100644 --- a/x/wasm/types/json_matching.go +++ b/x/wasm/types/json_matching.go @@ -6,30 +6,30 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// IsJSONObjectWithTopLevelKey checks if the given bytes are a valid JSON object +// IsJSONObjectWithTopLevelKey returns if the given bytes are a valid JSON object // with exactly one top-level key that is contained in the list of allowed keys. -func IsJSONObjectWithTopLevelKey(jsonBytes []byte, allowedKeys []string) error { +func IsJSONObjectWithTopLevelKey(jsonBytes []byte, allowedKeys []string) (bool, error) { document := map[string]interface{}{} if err := json.Unmarshal(jsonBytes, &document); err != nil { - return sdkerrors.Wrap(ErrNotAJSONObject, "failed to unmarshal JSON to map") + return false, sdkerrors.Wrap(ErrNotAJSONObject, "failed to unmarshal JSON to map") } if len(document) == 0 { - return sdkerrors.Wrap(ErrNoTopLevelKey, "JSON object has no top-level key") + return false, sdkerrors.Wrap(ErrNoTopLevelKey, "JSON object has no top-level key") } if len(document) > 1 { - return sdkerrors.Wrap(ErrMultipleTopLevelKeys, "JSON object has multiple top-level keys") + return false, sdkerrors.Wrap(ErrMultipleTopLevelKeys, "JSON object has multiple top-level keys") } // Loop is executed exactly once for topLevelKey := range document { for _, allowedKey := range allowedKeys { if allowedKey == topLevelKey { - return nil + return true, nil } } - return sdkerrors.Wrapf(ErrTopKevelKeyNotAllowed, "JSON object has a top-level key which is not allowed: '%s'", topLevelKey) + return false, nil } panic("Reached unreachable code. This is a bug.") diff --git a/x/wasm/types/json_matching_test.go b/x/wasm/types/json_matching_test.go index f1b1c2d09c..e2899fca83 100644 --- a/x/wasm/types/json_matching_test.go +++ b/x/wasm/types/json_matching_test.go @@ -14,115 +14,117 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { specs := map[string]struct { src []byte allowedKeys []string - exp error + expResult bool + expErr error }{ "happy": { src: []byte(`{"msg": {"foo":"bar"}}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with many allowed keys 1": { src: []byte(`{"claim": {"foo":"bar"}}`), allowedKeys: []string{"claim", "swap", "burn", "mint"}, - exp: nil, + expResult: true, }, "happy with many allowed keys 2": { src: []byte(`{"burn": {"foo":"bar"}}`), allowedKeys: []string{"claim", "swap", "burn", "mint"}, - exp: nil, + expResult: true, }, "happy with many allowed keys 3": { src: []byte(`{"mint": {"foo":"bar"}}`), allowedKeys: []string{"claim", "swap", "burn", "mint"}, - exp: nil, + expResult: true, }, "happy with number": { src: []byte(`{"msg": 123}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with array": { src: []byte(`{"msg": [1, 2, 3, 4]}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with null": { src: []byte(`{"msg": null}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with whitespace": { src: []byte(`{ "msg": null }`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with escaped key": { src: []byte(`{"event\u2468thing": {"foo":"bar"}}`), allowedKeys: []string{"event⑨thing"}, - exp: nil, + expResult: true, }, // Invalid JSON object "errors for bytes that are no JSON": { src: []byte(`nope`), allowedKeys: []string{"claim"}, - exp: ErrNotAJSONObject, + expErr: ErrNotAJSONObject, }, "errors for valid JSON (string)": { src: []byte(`"nope"`), allowedKeys: []string{"claim"}, - exp: ErrNotAJSONObject, + expErr: ErrNotAJSONObject, }, "errors for valid JSON (array)": { src: []byte(`[1, 2, 3]`), allowedKeys: []string{"claim"}, - exp: ErrNotAJSONObject, - }, - "errors for duplicate key": { - src: []byte(`{"claim": "foo", "claim":"bar"}`), - allowedKeys: []string{"claim"}, - exp: ErrNotAJSONObject, - }, + expErr: ErrNotAJSONObject, + }, + // not supported: https://github.com/golang/go/issues/24415 + //"errors for duplicate key": { + // src: []byte(`{"claim": "foo", "claim":"bar"}`), + // allowedKeys: []string{"claim"}, + // expErr: ErrNotAJSONObject, + //}, // Not one top-level key "errors for no top-level key": { src: []byte(`{}`), allowedKeys: []string{"claim"}, - exp: ErrNoTopLevelKey, + expErr: ErrNoTopLevelKey, }, "errors for multiple top-level keys": { src: []byte(`{"claim": {}, "and_swap": {}}`), allowedKeys: []string{"claim"}, - exp: ErrMultipleTopLevelKeys, + expErr: ErrMultipleTopLevelKeys, }, // Wrong top-level key - "errors for wrong top-level key 1": { + "wrong top-level key 1": { src: []byte(`{"claim": {}}`), allowedKeys: []string{""}, - exp: ErrTopKevelKeyNotAllowed, + expResult: false, }, - "errors for wrong top-level key 2": { + "wrong top-level key 2": { src: []byte(`{"claim": {}}`), allowedKeys: []string{"swap", "burn", "mint"}, - exp: ErrTopKevelKeyNotAllowed, + expResult: false, }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { - result := IsJSONObjectWithTopLevelKey(spec.src, spec.allowedKeys) - if spec.exp == nil { - require.NoError(t, result) - } else { - require.Error(t, result) - require.Contains(t, result.Error(), spec.exp.Error()) + exists, gotErr := IsJSONObjectWithTopLevelKey(spec.src, spec.allowedKeys) + if spec.expErr != nil { + assert.ErrorIs(t, gotErr, spec.expErr) + return } + require.NoError(t, gotErr) + assert.Equal(t, spec.expResult, exists) }) } } -func TestName(t *testing.T) { +func TestDuplicateKeyGivesSameResult(t *testing.T) { jsonBytes := []byte(`{"event⑨thing": "foo", "event⑨thing":"bar"}`) for i := 0; i < 10000; i++ { document := map[string]interface{}{} diff --git a/x/wasm/types/query.pb.gw.go b/x/wasm/types/query.pb.gw.go index 527cac4e74..4bffee3d7c 100644 --- a/x/wasm/types/query.pb.gw.go +++ b/x/wasm/types/query.pb.gw.go @@ -868,6 +868,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ContractsByCreator_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 { @@ -875,6 +877,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ContractsByCreator_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) @@ -1155,9 +1158,9 @@ var ( pattern_Query_PinnedCodes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "pinned"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "params"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ContractsByCreator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmwasm", "wasm", "v1", "contracts", "creator", "creator_address"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ContractsByCreator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmwasm", "wasm", "v1", "contracts", "creator", "creator_address"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/x/wasm/types/tx.go b/x/wasm/types/tx.go index 9630777f29..f4f4f45350 100644 --- a/x/wasm/types/tx.go +++ b/x/wasm/types/tx.go @@ -1,6 +1,7 @@ package types import ( + "bytes" "encoding/json" "errors" "strings" @@ -41,6 +42,11 @@ func (r RawContractMessage) Bytes() []byte { return r } +// Equal content is equal json. Byte equal but this can change in the future. +func (r RawContractMessage) Equal(o RawContractMessage) bool { + return bytes.Equal(r, o) +} + func (msg MsgStoreCode) Route() string { return RouterKey } @@ -163,6 +169,21 @@ func (msg MsgExecuteContract) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{senderAddr} } +// GetMsg returns the payload message send to the contract +func (msg MsgExecuteContract) GetMsg() RawContractMessage { + return msg.Msg +} + +// GetFunds returns tokens send to the contract +func (msg MsgExecuteContract) GetFunds() sdk.Coins { + return msg.Funds +} + +// GetContract returns the bech32 address of the contract +func (msg MsgExecuteContract) GetContract() string { + return msg.Contract +} + func (msg MsgMigrateContract) Route() string { return RouterKey } @@ -201,6 +222,21 @@ func (msg MsgMigrateContract) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{senderAddr} } +// GetMsg returns the payload message send to the contract +func (msg MsgMigrateContract) GetMsg() RawContractMessage { + return msg.Msg +} + +// GetFunds returns tokens send to the contract +func (msg MsgMigrateContract) GetFunds() sdk.Coins { + return sdk.NewCoins() +} + +// GetContract returns the bech32 address of the contract +func (msg MsgMigrateContract) GetContract() string { + return msg.Contract +} + func (msg MsgUpdateAdmin) Route() string { return RouterKey } From b1acbbd3a7a9532b91616785f35f1560f0132fd3 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 4 Nov 2022 19:13:21 +0100 Subject: [PATCH 11/16] Start e2e test --- Makefile | 3 +- tests/e2e/README.md | 3 ++ tests/e2e/grants_test.go | 44 +++++++++++++++++++ tests/e2e/setup.go | 44 +++++++++++++++++++ x/wasm/client/cli/tx.go | 11 ----- x/wasm/ibctesting/chain.go | 2 +- x/wasm/ibctesting/faucet.go | 16 +++++++ x/wasm/types/authz.go | 86 ++++++++++++++++++++++++++++++------- x/wasm/types/query.pb.go | 6 ++- x/wasm/types/tx.pb.go | 6 ++- 10 files changed, 188 insertions(+), 33 deletions(-) create mode 100644 tests/e2e/README.md create mode 100644 tests/e2e/grants_test.go create mode 100644 tests/e2e/setup.go create mode 100644 x/wasm/ibctesting/faucet.go diff --git a/Makefile b/Makefile index 6ca03f3e38..d85996fbe9 100644 --- a/Makefile +++ b/Makefile @@ -149,8 +149,9 @@ test-sim-multi-seed-short: runsim ############################################################################### format-tools: - go install mvdan.cc/gofumpt@v0.3.1 + go install mvdan.cc/gofumpt@v0.4.0 go install github.com/client9/misspell/cmd/misspell@v0.3.4 + go install golang.org/x/tools/cmd/goimports@latest lint: format-tools golangci-lint run --tests=false diff --git a/tests/e2e/README.md b/tests/e2e/README.md new file mode 100644 index 0000000000..dae38fe2df --- /dev/null +++ b/tests/e2e/README.md @@ -0,0 +1,3 @@ +# End To End Testing - e2e + +Scenario tests that run against on or multiple chain instances. diff --git a/tests/e2e/grants_test.go b/tests/e2e/grants_test.go new file mode 100644 index 0000000000..1778b1e5f2 --- /dev/null +++ b/tests/e2e/grants_test.go @@ -0,0 +1,44 @@ +package e2e_test + +import ( + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/x/wasm/ibctesting" + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +func TestGrants(t *testing.T) { + // given a contract by address A + // and grant for address B by A created + // When B sends an execute with tokens from A + // then + // - balance A reduced + // - balance B not touched + + chain := ibctesting.NewCoordinator(t, 1).GetChain(ibctesting.GetChainID(0)) + codeID := chain.StoreCodeFile("../../x/wasm/keeper/testdata/reflect_1_1.wasm").CodeID + contractAddr := chain.InstantiateContract(codeID, []byte(`{}`)) + require.NotEmpty(t, contractAddr) + + granteePrivKey := secp256k1.GenPrivKey() + granteeAddr := granteePrivKey.PubKey().Bytes() + chain.Fund(granteeAddr, sdk.NewInt(1_000_000)) + assert.Equal(t, sdk.NewInt(1_000_000), chain.Balance(granteeAddr, sdk.DefaultBondDenom).Amount) + // setup grant + grant, err := types.NewContractGrant(contractAddr, types.NewMaxCallsLimit(1), types.NewAllowAllMessagesFilter()) + require.NoError(t, err) + a := types.NewContractExecutionAuthorization(*grant) + grantMsg, err := authz.NewMsgGrant(chain.SenderAccount.GetAddress(), granteeAddr, a, time.Now().Add(time.Hour)) + require.NoError(t, err) + _, err = chain.SendMsgs(grantMsg) + require.NoError(t, err) + + // todo: verify execution of grant +} diff --git a/tests/e2e/setup.go b/tests/e2e/setup.go new file mode 100644 index 0000000000..bcb82fab30 --- /dev/null +++ b/tests/e2e/setup.go @@ -0,0 +1,44 @@ +package e2e + +import ( + "testing" + + ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types" + "github.com/stretchr/testify/suite" + + "github.com/CosmWasm/wasmd/x/wasm/ibctesting" +) + +// CCVTestSuite is an in-mem test suite which implements the standard group of tests validating +// the e2e functionality of ccv enabled chains. +// Any method implemented for this struct will be ran when suite.Run() is called. +type CCVTestSuite struct { + suite.Suite + coordinator *ibctesting.Coordinator + providerChain *ibctesting.TestChain + consumerChain *ibctesting.TestChain + // providerApp e2e.ProviderApp + // consumerApp e2e.ConsumerApp + providerClient *ibctmtypes.ClientState + providerConsState *ibctmtypes.ConsensusState + path *ibctesting.Path + transferPath *ibctesting.Path + setupCallback SetupCallback +} + +// NewCCVTestSuite returns a new instance of CCVTestSuite, ready to be tested against using suite.Run(). +func NewCCVTestSuite(setupCallback SetupCallback) *CCVTestSuite { + ccvSuite := new(CCVTestSuite) + ccvSuite.setupCallback = setupCallback + return ccvSuite +} + +// Callback for instantiating a new coordinator, provider/consumer test chains, and provider/consumer app +// before every test defined on the suite. +type SetupCallback func(t *testing.T) ( + coord *ibctesting.Coordinator, + providerChain *ibctesting.TestChain, + consumerChain *ibctesting.TestChain, + // providerApp e2e.ProviderApp, + // consumerApp e2e.ConsumerApp, +) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index d6ff653922..69f463fd02 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -422,17 +422,6 @@ func GrantAuthorizationCmd() *cobra.Command { _ = contract return errors.New("not implemented") - //authorization := types.NewContractAuthorization(contract, msgs, once) - //if err = authorization.ValidateBasic(); err != nil { - // return err - //} - - //msg, err := authz.NewMsgGrant(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(exp, 0)) - //if err != nil { - // return err - //} - // - //return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, } flags.AddTxFlagsToCmd(cmd) diff --git a/x/wasm/ibctesting/chain.go b/x/wasm/ibctesting/chain.go index 8d0adfb72a..1caa7f6319 100644 --- a/x/wasm/ibctesting/chain.go +++ b/x/wasm/ibctesting/chain.go @@ -145,7 +145,7 @@ func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) { return chain.QueryProofAtHeight(key, chain.App.LastBlockHeight()) } -// QueryProof performs an abci query with the given key and returns the proto encoded merkle proof +// QueryProofAtHeight performs an abci query with the given key and returns the proto encoded merkle proof // for the query and the height at which the proof will succeed on a tendermint verifier. func (chain *TestChain) QueryProofAtHeight(key []byte, height int64) ([]byte, clienttypes.Height) { res := chain.App.Query(abci.RequestQuery{ diff --git a/x/wasm/ibctesting/faucet.go b/x/wasm/ibctesting/faucet.go new file mode 100644 index 0000000000..e43e86989f --- /dev/null +++ b/x/wasm/ibctesting/faucet.go @@ -0,0 +1,16 @@ +package ibctesting + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/require" +) + +// Fund an address with the given amount in default denom +func (chain *TestChain) Fund(addr sdk.AccAddress, amount sdk.Int) { + require.NoError(chain.t, chain.sendMsgs(&banktypes.MsgSend{ + FromAddress: chain.SenderAccount.GetAddress().String(), + ToAddress: addr.String(), + Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), + })) +} diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index 99dadc57bb..fb433804e3 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -15,8 +15,10 @@ import ( const gasDeserializationCostPerByte = uint64(1) var ( - _ authztypes.Authorization = &ContractExecutionAuthorization{} - _ authztypes.Authorization = &ContractMigrationAuthorization{} + _ authztypes.Authorization = &ContractExecutionAuthorization{} + _ authztypes.Authorization = &ContractMigrationAuthorization{} + _ cdctypes.UnpackInterfacesMessage = &ContractExecutionAuthorization{} + _ cdctypes.UnpackInterfacesMessage = &ContractMigrationAuthorization{} ) // AuthzableWasmMsg is abstract wasm tx message that is supported in authz @@ -54,6 +56,16 @@ func (a ContractExecutionAuthorization) ValidateBasic() error { return validateGrants(a.Grants) } +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (a ContractExecutionAuthorization) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error { + for _, g := range a.Grants { + if err := g.UnpackInterfaces(unpacker); err != nil { + return err + } + } + return nil +} + // NewContractMigrationAuthorization constructor func NewContractMigrationAuthorization(grants ...ContractGrant) *ContractMigrationAuthorization { return &ContractMigrationAuthorization{ @@ -81,6 +93,16 @@ func (a ContractMigrationAuthorization) ValidateBasic() error { return validateGrants(a.Grants) } +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (a ContractMigrationAuthorization) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error { + for _, g := range a.Grants { + if err := g.UnpackInterfaces(unpacker); err != nil { + return err + } + } + return nil +} + func validateGrants(g []ContractGrant) error { if len(g) == 0 { return ErrEmpty.Wrap("grants") @@ -258,26 +280,13 @@ func (g ContractGrant) GetLimit() ContractAuthzLimitX { if g.Limit == nil { return &UndefinedLimit{} } - a, ok := g.Filter.GetCachedValue().(ContractAuthzLimitX) + a, ok := g.Limit.GetCachedValue().(ContractAuthzLimitX) if !ok { return &UndefinedLimit{} } return a } -// UndefinedLimit null object that is always rejected in execution -type UndefinedLimit struct{} - -// ValidateBasic always returns error -func (u UndefinedLimit) ValidateBasic() error { - return sdkerrors.ErrInvalidType.Wrapf("undefined limit") -} - -// Accept always returns error -func (u UndefinedLimit) Accept(ctx sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { - return nil, sdkerrors.ErrNotFound.Wrapf("undefined filter") -} - // GetFilter returns the cached value from the ContractGrant.Filter if present. func (g ContractGrant) GetFilter() ContractAuthzFilterX { if g.Filter == nil { @@ -303,6 +312,11 @@ func (f UndefinedFilter) ValidateBasic() error { return sdkerrors.ErrInvalidType.Wrapf("undefined filter") } +// NewAllowAllMessagesFilter constructor +func NewAllowAllMessagesFilter() *AllowAllMessagesFilter { + return &AllowAllMessagesFilter{} +} + // Accept accepts any message content. func (f *AllowAllMessagesFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { return true, nil @@ -313,6 +327,11 @@ func (f AllowAllMessagesFilter) ValidateBasic() error { return nil } +// NewAcceptedMessageKeysFilter constructor +func NewAcceptedMessageKeysFilter(acceptedKeys []string) *AcceptedMessageKeysFilter { + return &AcceptedMessageKeysFilter{Keys: acceptedKeys} +} + // Accept only payload messages which contain one of the accepted key names in the json object. func (f *AcceptedMessageKeysFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { gasForDeserialization := gasDeserializationCostPerByte * uint64(len(msg)) @@ -396,6 +415,31 @@ func (g ContractGrant) ValidateBasic() error { return nil } +var ( + _ ContractAuthzLimitX = &UndefinedLimit{} + _ ContractAuthzLimitX = &MaxCallsLimit{} + _ ContractAuthzLimitX = &MaxFundsLimit{} + _ ContractAuthzLimitX = &CombinedLimit{} +) + +// UndefinedLimit null object that is always rejected in execution +type UndefinedLimit struct{} + +// ValidateBasic always returns error +func (u UndefinedLimit) ValidateBasic() error { + return sdkerrors.ErrInvalidType.Wrapf("undefined limit") +} + +// Accept always returns error +func (u UndefinedLimit) Accept(ctx sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + return nil, sdkerrors.ErrNotFound.Wrapf("undefined filter") +} + +// NewMaxCallsLimit constructor +func NewMaxCallsLimit(number uint64) *MaxCallsLimit { + return &MaxCallsLimit{Remaining: number} +} + // Accept only the defined number of message calls. No token transfers to the contract allowed. func (m MaxCallsLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { if !msg.GetFunds().Empty() { @@ -419,6 +463,11 @@ func (m MaxCallsLimit) ValidateBasic() error { return nil } +// NewMaxFundsLimit constructor +func NewMaxFundsLimit(max sdk.Coins) *MaxFundsLimit { + return &MaxFundsLimit{Amounts: max} +} + // Accept until the defined budget for token transfers to the contract is spent func (m MaxFundsLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { if msg.GetFunds().Empty() { // no state changes required @@ -445,6 +494,11 @@ func (m MaxFundsLimit) ValidateBasic() error { return nil } +// NewCombinedLimit constructor +func NewCombinedLimit(maxCalls uint64, maxAmounts sdk.Coins) *CombinedLimit { + return &CombinedLimit{CallsRemaining: maxCalls, Amounts: maxAmounts} +} + // Accept until the max calls is reached or the token budget is spent. func (l CombinedLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { transferFunds := msg.GetFunds() diff --git a/x/wasm/types/query.pb.go b/x/wasm/types/query.pb.go index bb08b7571c..68b15e39fa 100644 --- a/x/wasm/types/query.pb.go +++ b/x/wasm/types/query.pb.go @@ -1288,8 +1288,10 @@ func (this *QueryCodeResponse) Equal(that interface{}) bool { } // Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn +var ( + _ context.Context + _ grpc.ClientConn +) // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. diff --git a/x/wasm/types/tx.pb.go b/x/wasm/types/tx.pb.go index f81b1106e0..4670ba2b0b 100644 --- a/x/wasm/types/tx.pb.go +++ b/x/wasm/types/tx.pb.go @@ -778,8 +778,10 @@ var fileDescriptor_4f74d82755520264 = []byte{ } // Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn +var ( + _ context.Context + _ grpc.ClientConn +) // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. From 2d92e1298079103544dbc4802fa2972a6edc961c Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Sat, 5 Nov 2022 10:56:54 +0100 Subject: [PATCH 12/16] Full e2e test --- app/test_helpers.go | 10 +--- tests/e2e/grants_test.go | 102 ++++++++++++++++++++++++++++++------ x/wasm/ibctesting/chain.go | 39 +------------- x/wasm/ibctesting/faucet.go | 36 +++++++++++++ x/wasm/relay_test.go | 4 +- x/wasm/types/authz.go | 2 +- 6 files changed, 129 insertions(+), 64 deletions(-) diff --git a/app/test_helpers.go b/app/test_helpers.go index ceff625168..d15e155560 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -363,7 +363,7 @@ func SignCheckDeliver( // ibc testing package causes checkState and deliverState to diverge in block time. func SignAndDeliver( t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, - chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, + chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey, ) (sdk.GasInfo, *sdk.Result, error) { tx, err := helpers.GenTx( txCfg, @@ -381,14 +381,6 @@ func SignAndDeliver( app.BeginBlock(abci.RequestBeginBlock{Header: header}) gInfo, res, err := app.Deliver(txCfg.TxEncoder(), tx) - if expPass { - require.NoError(t, err) - require.NotNil(t, res) - } else { - require.Error(t, err) - require.Nil(t, res) - } - app.EndBlock(abci.RequestEndBlock{}) app.Commit() diff --git a/tests/e2e/grants_test.go b/tests/e2e/grants_test.go index 1778b1e5f2..f2afae10f1 100644 --- a/tests/e2e/grants_test.go +++ b/tests/e2e/grants_test.go @@ -1,11 +1,14 @@ package e2e_test import ( + "fmt" "testing" "time" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/authz" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -15,11 +18,12 @@ import ( ) func TestGrants(t *testing.T) { - // given a contract by address A - // and grant for address B by A created + // Given a contract by address A + // And a grant for address B by A created // When B sends an execute with tokens from A - // then - // - balance A reduced + // Then the grant is executed as defined + // And + // - balance A reduced (on success) // - balance B not touched chain := ibctesting.NewCoordinator(t, 1).GetChain(ibctesting.GetChainID(0)) @@ -27,18 +31,86 @@ func TestGrants(t *testing.T) { contractAddr := chain.InstantiateContract(codeID, []byte(`{}`)) require.NotEmpty(t, contractAddr) + granterAddr := chain.SenderAccount.GetAddress() granteePrivKey := secp256k1.GenPrivKey() - granteeAddr := granteePrivKey.PubKey().Bytes() + granteeAddr := sdk.AccAddress(granteePrivKey.PubKey().Address().Bytes()) + otherPrivKey := secp256k1.GenPrivKey() + otherAddr := sdk.AccAddress(otherPrivKey.PubKey().Address().Bytes()) + chain.Fund(granteeAddr, sdk.NewInt(1_000_000)) + chain.Fund(otherAddr, sdk.NewInt(1_000_000)) assert.Equal(t, sdk.NewInt(1_000_000), chain.Balance(granteeAddr, sdk.DefaultBondDenom).Amount) - // setup grant - grant, err := types.NewContractGrant(contractAddr, types.NewMaxCallsLimit(1), types.NewAllowAllMessagesFilter()) - require.NoError(t, err) - a := types.NewContractExecutionAuthorization(*grant) - grantMsg, err := authz.NewMsgGrant(chain.SenderAccount.GetAddress(), granteeAddr, a, time.Now().Add(time.Hour)) - require.NoError(t, err) - _, err = chain.SendMsgs(grantMsg) - require.NoError(t, err) - - // todo: verify execution of grant + + myAmount := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2_000_000)) + + specs := map[string]struct { + limit types.ContractAuthzLimitX + filter types.ContractAuthzFilterX + transferAmount sdk.Coin + senderKey cryptotypes.PrivKey + expErr *sdkerrors.Error + }{ + "in limits and filter": { + limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + filter: types.NewAllowAllMessagesFilter(), + transferAmount: myAmount, + senderKey: granteePrivKey, + }, + "exceed limits": { + limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + filter: types.NewAllowAllMessagesFilter(), + transferAmount: myAmount.Add(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + senderKey: granteePrivKey, + expErr: sdkerrors.ErrUnauthorized, + }, + "not match filter": { + limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + filter: types.NewAcceptedMessageKeysFilter("foo"), + transferAmount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()), + senderKey: granteePrivKey, + expErr: sdkerrors.ErrUnauthorized, + }, + "non authorized sender address": { // sanity check - testing sdk + limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + filter: types.NewAllowAllMessagesFilter(), + senderKey: otherPrivKey, + transferAmount: myAmount, + expErr: sdkerrors.ErrUnauthorized, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup grant + grant, err := types.NewContractGrant(contractAddr, spec.limit, spec.filter) + require.NoError(t, err) + authorization := types.NewContractExecutionAuthorization(*grant) + grantMsg, err := authz.NewMsgGrant(granterAddr, granteeAddr, authorization, time.Now().Add(time.Hour)) + require.NoError(t, err) + _, err = chain.SendMsgs(grantMsg) + require.NoError(t, err) + + granterStartBalance := chain.Balance(granterAddr, sdk.DefaultBondDenom).Amount + + // when + anyValidReflectMsg := []byte(fmt.Sprintf(`{"reflect_msg": {"msgs": [{"bank":{"burn":{"amount":[{"denom":%q, "amount": %q}]}}}]}}`, sdk.DefaultBondDenom, myAmount.Amount.String())) + execMsg := authz.NewMsgExec(spec.senderKey.PubKey().Address().Bytes(), []sdk.Msg{&types.MsgExecuteContract{ + Sender: granterAddr.String(), + Contract: contractAddr.String(), + Msg: anyValidReflectMsg, + Funds: sdk.NewCoins(spec.transferAmount), + }}) + _, gotErr := chain.SendNonDefaultSenderMsgs(spec.senderKey, &execMsg) + + // then + if spec.expErr != nil { + require.ErrorIs(t, gotErr, spec.expErr) + assert.Equal(t, sdk.NewInt(1_000_000), chain.Balance(granteeAddr, sdk.DefaultBondDenom).Amount) + assert.Equal(t, granterStartBalance, chain.Balance(granterAddr, sdk.DefaultBondDenom).Amount) + return + } + require.NoError(t, gotErr) + assert.Equal(t, sdk.NewInt(1_000_000), chain.Balance(granteeAddr, sdk.DefaultBondDenom).Amount) + assert.Equal(t, granterStartBalance.Sub(spec.transferAmount.Amount), chain.Balance(granterAddr, sdk.DefaultBondDenom).Amount) + }) + } } diff --git a/x/wasm/ibctesting/chain.go b/x/wasm/ibctesting/chain.go index 1caa7f6319..fb24372d8a 100644 --- a/x/wasm/ibctesting/chain.go +++ b/x/wasm/ibctesting/chain.go @@ -251,50 +251,15 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { chain.ChainID, []uint64{chain.SenderAccount.GetAccountNumber()}, []uint64{chain.SenderAccount.GetSequence()}, - true, true, chain.SenderPrivKey, + chain.SenderPrivKey, ) - if err != nil { - return nil, err - } // SignAndDeliver calls app.Commit() chain.NextBlock() - - // increment sequence for successful transaction execution - err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) - if err != nil { - return nil, err - } - - chain.Coordinator.IncrementTime() - - chain.captureIBCEvents(r) - - return r, nil -} - -func (chain *TestChain) SendMsgsExpPass(expPass bool, msgs ...sdk.Msg) (*sdk.Result, error) { - // ensure the chain has the latest time - chain.Coordinator.UpdateTimeForChain(chain) - - _, r, err := app.SignAndDeliver( - chain.t, - chain.TxConfig, - chain.App.BaseApp, - chain.GetContext().BlockHeader(), - msgs, - chain.ChainID, - []uint64{chain.SenderAccount.GetAccountNumber()}, - []uint64{chain.SenderAccount.GetSequence()}, - true, expPass, chain.SenderPrivKey, - ) if err != nil { - return nil, err + return r, err } - // SignAndDeliver calls app.Commit() - chain.NextBlock() - // increment sequence for successful transaction execution err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) if err != nil { diff --git a/x/wasm/ibctesting/faucet.go b/x/wasm/ibctesting/faucet.go index e43e86989f..d5098c34c8 100644 --- a/x/wasm/ibctesting/faucet.go +++ b/x/wasm/ibctesting/faucet.go @@ -1,9 +1,12 @@ package ibctesting import ( + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/app" ) // Fund an address with the given amount in default denom @@ -14,3 +17,36 @@ func (chain *TestChain) Fund(addr sdk.AccAddress, amount sdk.Int) { Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), })) } + +// SendNonDefaultSenderMsgs delivers a transaction through the application. It returns the result and error if one +// occurred. +func (chain *TestChain) SendNonDefaultSenderMsgs(senderPrivKey cryptotypes.PrivKey, msgs ...sdk.Msg) (*sdk.Result, error) { + require.NotEqual(chain.t, chain.SenderPrivKey, senderPrivKey, "use SendMsgs method") + + // ensure the chain has the latest time + chain.Coordinator.UpdateTimeForChain(chain) + + addr := sdk.AccAddress(senderPrivKey.PubKey().Address().Bytes()) + account := chain.App.AccountKeeper.GetAccount(chain.GetContext(), addr) + require.NotNil(chain.t, account) + _, r, err := app.SignAndDeliver( + chain.t, + chain.TxConfig, + chain.App.BaseApp, + chain.GetContext().BlockHeader(), + msgs, + chain.ChainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + senderPrivKey, + ) + + // SignAndDeliver calls app.Commit() + chain.NextBlock() + chain.Coordinator.IncrementTime() + if err != nil { + return r, err + } + chain.captureIBCEvents(r) + return r, nil +} diff --git a/x/wasm/relay_test.go b/x/wasm/relay_test.go index 7645f42365..4e72bd84f6 100644 --- a/x/wasm/relay_test.go +++ b/x/wasm/relay_test.go @@ -416,7 +416,7 @@ func TestContractEmulateIBCTransferMessageOnDiffContractIBCChannel(t *testing.T) }.GetBytes(), Funds: sdk.NewCoins(coinToSendToB), } - _, err := chainA.SendMsgsExpPass(false, startMsg) + _, err := chainA.SendMsgs(startMsg) require.Error(t, err) } @@ -519,7 +519,7 @@ func TestContractHandlesChannelCloseNotOwned(t *testing.T) { Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), } - _, err := chainA.SendMsgsExpPass(false, closeIBCChannelMsg) + _, err := chainA.SendMsgs(closeIBCChannelMsg) require.Error(t, err) } diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index fb433804e3..ba3ee4e1a5 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -328,7 +328,7 @@ func (f AllowAllMessagesFilter) ValidateBasic() error { } // NewAcceptedMessageKeysFilter constructor -func NewAcceptedMessageKeysFilter(acceptedKeys []string) *AcceptedMessageKeysFilter { +func NewAcceptedMessageKeysFilter(acceptedKeys ...string) *AcceptedMessageKeysFilter { return &AcceptedMessageKeysFilter{Keys: acceptedKeys} } From 3eb6e2d3d7c5653d54ff07f103f593867806f579 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 8 Nov 2022 11:55:12 +0100 Subject: [PATCH 13/16] Test filter and limits --- tests/e2e/grants_test.go | 8 +- tests/e2e/setup.go | 44 --- x/wasm/types/authz.go | 85 +++--- x/wasm/types/authz_test.go | 474 +++++++++++++++++++++++++++++ x/wasm/types/errors.go | 12 +- x/wasm/types/json_matching.go | 20 +- x/wasm/types/json_matching_test.go | 20 +- x/wasm/types/tx.go | 2 +- 8 files changed, 547 insertions(+), 118 deletions(-) delete mode 100644 tests/e2e/setup.go create mode 100644 x/wasm/types/authz_test.go diff --git a/tests/e2e/grants_test.go b/tests/e2e/grants_test.go index f2afae10f1..0920fa0a3d 100644 --- a/tests/e2e/grants_test.go +++ b/tests/e2e/grants_test.go @@ -51,27 +51,27 @@ func TestGrants(t *testing.T) { expErr *sdkerrors.Error }{ "in limits and filter": { - limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + limit: types.NewMaxFundsLimit(myAmount), filter: types.NewAllowAllMessagesFilter(), transferAmount: myAmount, senderKey: granteePrivKey, }, "exceed limits": { - limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + limit: types.NewMaxFundsLimit(myAmount), filter: types.NewAllowAllMessagesFilter(), transferAmount: myAmount.Add(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), senderKey: granteePrivKey, expErr: sdkerrors.ErrUnauthorized, }, "not match filter": { - limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + limit: types.NewMaxFundsLimit(myAmount), filter: types.NewAcceptedMessageKeysFilter("foo"), transferAmount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()), senderKey: granteePrivKey, expErr: sdkerrors.ErrUnauthorized, }, "non authorized sender address": { // sanity check - testing sdk - limit: types.NewMaxFundsLimit(sdk.NewCoins(myAmount)), + limit: types.NewMaxFundsLimit(myAmount), filter: types.NewAllowAllMessagesFilter(), senderKey: otherPrivKey, transferAmount: myAmount, diff --git a/tests/e2e/setup.go b/tests/e2e/setup.go deleted file mode 100644 index bcb82fab30..0000000000 --- a/tests/e2e/setup.go +++ /dev/null @@ -1,44 +0,0 @@ -package e2e - -import ( - "testing" - - ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types" - "github.com/stretchr/testify/suite" - - "github.com/CosmWasm/wasmd/x/wasm/ibctesting" -) - -// CCVTestSuite is an in-mem test suite which implements the standard group of tests validating -// the e2e functionality of ccv enabled chains. -// Any method implemented for this struct will be ran when suite.Run() is called. -type CCVTestSuite struct { - suite.Suite - coordinator *ibctesting.Coordinator - providerChain *ibctesting.TestChain - consumerChain *ibctesting.TestChain - // providerApp e2e.ProviderApp - // consumerApp e2e.ConsumerApp - providerClient *ibctmtypes.ClientState - providerConsState *ibctmtypes.ConsensusState - path *ibctesting.Path - transferPath *ibctesting.Path - setupCallback SetupCallback -} - -// NewCCVTestSuite returns a new instance of CCVTestSuite, ready to be tested against using suite.Run(). -func NewCCVTestSuite(setupCallback SetupCallback) *CCVTestSuite { - ccvSuite := new(CCVTestSuite) - ccvSuite.setupCallback = setupCallback - return ccvSuite -} - -// Callback for instantiating a new coordinator, provider/consumer test chains, and provider/consumer app -// before every test defined on the suite. -type SetupCallback func(t *testing.T) ( - coord *ibctesting.Coordinator, - providerChain *ibctesting.TestChain, - consumerChain *ibctesting.TestChain, - // providerApp e2e.ProviderApp, - // consumerApp e2e.ConsumerApp, -) diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index ba3ee4e1a5..32a1fd672a 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -299,6 +299,23 @@ func (g ContractGrant) GetFilter() ContractAuthzFilterX { return a } +// ValidateBasic validates the grant +func (g ContractGrant) ValidateBasic() error { + // some sanity checks only, need more + if _, err := sdk.AccAddressFromBech32(g.Contract); err != nil { + return sdkerrors.Wrap(err, "contract") + } + // execution limits + if err := g.GetLimit().ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "limit") + } + // filter + if err := g.GetFilter().ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "filter") + } + return nil +} + // UndefinedFilter null object that is always rejected in execution type UndefinedFilter struct{} @@ -317,9 +334,9 @@ func NewAllowAllMessagesFilter() *AllowAllMessagesFilter { return &AllowAllMessagesFilter{} } -// Accept accepts any message content. +// Accept accepts any valid json message content. func (f *AllowAllMessagesFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { - return true, nil + return true, msg.ValidateBasic() } // ValidateBasic returns always nil @@ -337,7 +354,7 @@ func (f *AcceptedMessageKeysFilter) Accept(ctx sdk.Context, msg RawContractMessa gasForDeserialization := gasDeserializationCostPerByte * uint64(len(msg)) ctx.GasMeter().ConsumeGas(gasForDeserialization, "contract authorization") - ok, err := IsJSONObjectWithTopLevelKey(msg, f.Keys) + ok, err := isJSONObjectWithTopLevelKey(msg, f.Keys) if err != nil { return false, sdkerrors.ErrUnauthorized.Wrapf("not an allowed msg: %s", err.Error()) } @@ -365,18 +382,18 @@ func (f AcceptedMessageKeysFilter) ValidateBasic() error { return nil } +// NewAcceptedMessagesFilter constructor +func NewAcceptedMessagesFilter(msgs ...RawContractMessage) *AcceptedMessagesFilter { + return &AcceptedMessagesFilter{Messages: msgs} +} + // Accept only payload messages which are equal to the granted one. func (f *AcceptedMessagesFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { - var found bool for _, v := range f.Messages { if v.Equal(msg) { - found = true - break + return true, nil } } - if !found { - return false, sdkerrors.ErrUnauthorized.Wrap("not an accepted payload msg") - } return false, nil } @@ -387,9 +404,12 @@ func (f AcceptedMessagesFilter) ValidateBasic() error { } idx := make(map[string]struct{}, len(f.Messages)) for _, m := range f.Messages { - if m == nil { + if len(m) == 0 { return ErrEmpty.Wrap("message") } + if err := m.ValidateBasic(); err != nil { + return err + } if _, exists := idx[string(m)]; exists { return ErrDuplicate.Wrap("message") } @@ -398,23 +418,6 @@ func (f AcceptedMessagesFilter) ValidateBasic() error { return nil } -// ValidateBasic validates the grant -func (g ContractGrant) ValidateBasic() error { - // some sanity checks only, need more - if _, err := sdk.AccAddressFromBech32(g.Contract); err != nil { - return sdkerrors.Wrap(err, "contract") - } - // execution limits - if err := g.GetLimit().ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "limit") - } - // filter - if err := g.GetFilter().ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "filter") - } - return nil -} - var ( _ ContractAuthzLimitX = &UndefinedLimit{} _ ContractAuthzLimitX = &MaxCallsLimit{} @@ -464,8 +467,9 @@ func (m MaxCallsLimit) ValidateBasic() error { } // NewMaxFundsLimit constructor -func NewMaxFundsLimit(max sdk.Coins) *MaxFundsLimit { - return &MaxFundsLimit{Amounts: max} +// A panic will occur if the coin set is not valid. +func NewMaxFundsLimit(max ...sdk.Coin) *MaxFundsLimit { + return &MaxFundsLimit{Amounts: sdk.NewCoins(max...)} } // Accept until the defined budget for token transfers to the contract is spent @@ -473,7 +477,7 @@ func (m MaxFundsLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAut if msg.GetFunds().Empty() { // no state changes required return &ContractAuthzLimitAcceptResult{Accepted: true}, nil } - if msg.GetFunds().IsAnyGT(m.Amounts) { + if !msg.GetFunds().IsAllLTE(m.Amounts) { return &ContractAuthzLimitAcceptResult{Accepted: false}, nil } newAmounts := m.Amounts.Sub(msg.GetFunds()) @@ -495,14 +499,15 @@ func (m MaxFundsLimit) ValidateBasic() error { } // NewCombinedLimit constructor -func NewCombinedLimit(maxCalls uint64, maxAmounts sdk.Coins) *CombinedLimit { - return &CombinedLimit{CallsRemaining: maxCalls, Amounts: maxAmounts} +// A panic will occur if the coin set is not valid. +func NewCombinedLimit(maxCalls uint64, maxAmounts ...sdk.Coin) *CombinedLimit { + return &CombinedLimit{CallsRemaining: maxCalls, Amounts: sdk.NewCoins(maxAmounts...)} } // Accept until the max calls is reached or the token budget is spent. func (l CombinedLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { transferFunds := msg.GetFunds() - if !transferFunds.Empty() && transferFunds.IsAnyGT(l.Amounts) { + if !transferFunds.IsAllLTE(l.Amounts) { return &ContractAuthzLimitAcceptResult{Accepted: false}, nil // does not apply } switch n := l.CallsRemaining; n { @@ -515,17 +520,23 @@ func (l CombinedLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAut if remainingAmounts.IsZero() { return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil } - return &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: &CombinedLimit{CallsRemaining: n - 1, Amounts: remainingAmounts}}, nil + return &ContractAuthzLimitAcceptResult{ + Accepted: true, + UpdateLimit: NewCombinedLimit(n-1, remainingAmounts...), + }, nil } } // ValidateBasic validates the limit func (l CombinedLimit) ValidateBasic() error { - if err := l.Amounts.Validate(); err != nil { - return sdkerrors.Wrap(err, "amounts") - } if l.CallsRemaining == 0 { return ErrEmpty.Wrap("remaining calls") } + if l.Amounts.IsZero() { + return ErrEmpty.Wrap("amounts") + } + if err := l.Amounts.Validate(); err != nil { + return sdkerrors.Wrap(err, "amounts") + } return nil } diff --git a/x/wasm/types/authz_test.go b/x/wasm/types/authz_test.go new file mode 100644 index 0000000000..aac6c2a02e --- /dev/null +++ b/x/wasm/types/authz_test.go @@ -0,0 +1,474 @@ +package types + +import ( + "math" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestContractAuthzFilterValidate(t *testing.T) { + specs := map[string]struct { + src ContractAuthzFilterX + expErr bool + }{ + "allow all": { + src: &AllowAllMessagesFilter{}, + }, + "allow keys - single": { + src: NewAcceptedMessageKeysFilter("foo"), + }, + "allow keys - multi": { + src: NewAcceptedMessageKeysFilter("foo", "bar"), + }, + "allow keys - empty": { + src: NewAcceptedMessageKeysFilter(), + expErr: true, + }, + "allow keys - duplicates": { + src: NewAcceptedMessageKeysFilter("foo", "foo"), + expErr: true, + }, + "allow keys - whitespaces": { + src: NewAcceptedMessageKeysFilter(" foo"), + expErr: true, + }, + "allow keys - empty key": { + src: NewAcceptedMessageKeysFilter("", "bar"), + expErr: true, + }, + "allow keys - whitespace key": { + src: NewAcceptedMessageKeysFilter(" ", "bar"), + expErr: true, + }, + "allow message - single": { + src: NewAcceptedMessagesFilter([]byte(`{}`)), + }, + "allow message - multiple": { + src: NewAcceptedMessagesFilter([]byte(`{}`), []byte(`{"foo":"bar"}`)), + }, + "allow message - multiple with empty": { + src: NewAcceptedMessagesFilter([]byte(`{}`), nil), + expErr: true, + }, + "allow message - duplicate": { + src: NewAcceptedMessagesFilter([]byte(`{}`), []byte(`{}`)), + expErr: true, + }, + "allow message - non json": { + src: NewAcceptedMessagesFilter([]byte("non-json")), + expErr: true, + }, + "allow message - empty": { + src: NewAcceptedMessagesFilter(), + expErr: true, + }, + "allow all message - always valid": { + src: NewAllowAllMessagesFilter(), + }, + "undefined - always invalid": { + src: &UndefinedFilter{}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestContractAuthzFilterAccept(t *testing.T) { + specs := map[string]struct { + filter ContractAuthzFilterX + src RawContractMessage + exp bool + expGasConsumed sdk.Gas + expErr bool + }{ + "allow all - accepts json obj": { + filter: &AllowAllMessagesFilter{}, + src: []byte(`{}`), + exp: true, + }, + "allow all - accepts json array": { + filter: &AllowAllMessagesFilter{}, + src: []byte(`[{},{}]`), + exp: true, + }, + "allow all - rejects non json msg": { + filter: &AllowAllMessagesFilter{}, + src: []byte(``), + expErr: true, + }, + "allowed key - single": { + filter: NewAcceptedMessageKeysFilter("foo"), + src: []byte(`{"foo": "bar"}`), + exp: true, + expGasConsumed: sdk.Gas(len(`{"foo": "bar"}`)), + }, + "allowed key - multiple": { + filter: NewAcceptedMessageKeysFilter("foo", "other"), + src: []byte(`{"other": "value"}`), + exp: true, + expGasConsumed: sdk.Gas(len(`{"other": "value"}`)), + }, + "allowed key - non accepted key": { + filter: NewAcceptedMessageKeysFilter("foo"), + src: []byte(`{"bar": "value"}`), + exp: false, + expGasConsumed: sdk.Gas(len(`{"bar": "value"}`)), + }, + "allowed key - unsupported array msg": { + filter: NewAcceptedMessageKeysFilter("foo", "other"), + src: []byte(`[{"foo":"bar"}]`), + expErr: false, + expGasConsumed: sdk.Gas(len(`[{"foo":"bar"}]`)), + }, + "allowed key - invalid msg": { + filter: NewAcceptedMessageKeysFilter("foo", "other"), + src: []byte(`not a json msg`), + expErr: true, + }, + "allow message - single": { + filter: NewAcceptedMessagesFilter([]byte(`{}`)), + src: []byte(`{}`), + exp: true, + }, + "allow message - multiple": { + filter: NewAcceptedMessagesFilter([]byte(`[{"foo":"bar"}]`), []byte(`{"other":"value"}`)), + src: []byte(`[{"foo":"bar"}]`), + exp: true, + }, + "allow message - no match": { + filter: NewAcceptedMessagesFilter([]byte(`{"foo":"bar"}`)), + src: []byte(`{"other":"value"}`), + exp: false, + }, + "allow all message - always accept valid": { + filter: NewAllowAllMessagesFilter(), + src: []byte(`{"other":"value"}`), + exp: true, + }, + "allow all message - always reject invalid json": { + filter: NewAllowAllMessagesFilter(), + src: []byte(`not json`), + expErr: true, + }, + "undefined - always errors": { + filter: &UndefinedFilter{}, + src: []byte(`{"foo":"bar"}`), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gm := sdk.NewGasMeter(1_000_000) + allowed, gotErr := spec.filter.Accept(sdk.Context{}.WithGasMeter(gm), spec.src) + + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.exp, allowed) + assert.Equal(t, spec.expGasConsumed, gm.GasConsumed()) + }) + } +} + +func TestContractAuthzLimitValidate(t *testing.T) { + oneToken := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()) + specs := map[string]struct { + src ContractAuthzLimitX + expErr bool + }{ + "max calls": { + src: NewMaxCallsLimit(1), + }, + "max calls - max uint64": { + src: NewMaxCallsLimit(math.MaxUint64), + }, + "max calls - empty": { + src: NewMaxCallsLimit(0), + expErr: true, + }, + "max funds": { + src: NewMaxFundsLimit(oneToken), + }, + "max funds - empty coins": { + src: NewMaxFundsLimit(), + expErr: true, + }, + "max funds - duplicates": { + src: &MaxFundsLimit{Amounts: sdk.Coins{oneToken, oneToken}}, + expErr: true, + }, + "max funds - contains empty value": { + src: &MaxFundsLimit{Amounts: sdk.Coins{oneToken, sdk.NewCoin("other", sdk.ZeroInt())}.Sort()}, + expErr: true, + }, + "max funds - unsorted": { + src: &MaxFundsLimit{Amounts: sdk.Coins{oneToken, sdk.NewCoin("other", sdk.OneInt())}}, + expErr: true, + }, + "combined": { + src: NewCombinedLimit(1, oneToken), + }, + "combined - empty calls": { + src: NewCombinedLimit(0, oneToken), + expErr: true, + }, + "combined - empty amounts": { + src: NewCombinedLimit(1), + expErr: true, + }, + "combined - invalid amounts": { + src: &CombinedLimit{CallsRemaining: 1, Amounts: sdk.Coins{oneToken, oneToken}}, + expErr: true, + }, + "undefined": { + src: &UndefinedLimit{}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestContractAuthzLimitAccept(t *testing.T) { + oneToken := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()) + otherToken := sdk.NewCoin("other", sdk.OneInt()) + specs := map[string]struct { + limit ContractAuthzLimitX + src AuthzableWasmMsg + exp *ContractAuthzLimitAcceptResult + expErr bool + }{ + "max calls - updated": { + limit: NewMaxCallsLimit(2), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewMaxCallsLimit(1)}, + }, + "max calls - removed": { + limit: NewMaxCallsLimit(1), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max calls - accepted with zero fund set": { + limit: NewMaxCallsLimit(1), + src: &MsgExecuteContract{Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.ZeroInt()))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max calls - rejected with some fund transfer": { + limit: NewMaxCallsLimit(1), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max calls - invalid": { + limit: &MaxCallsLimit{}, + src: &MsgExecuteContract{}, + expErr: true, + }, + "max funds - single updated": { + limit: NewMaxFundsLimit(oneToken.Add(oneToken)), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewMaxFundsLimit(oneToken)}, + }, + "max funds - single removed": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max funds - single with unknown token": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max funds - single exceeds limit": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken.Add(oneToken))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max funds - single with additional token send": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max funds - multi with other left": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewMaxFundsLimit(otherToken)}, + }, + "max funds - multi with all used": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max funds - multi with no tokens sent": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true}, + }, + "max funds - multi with other exceeds limit": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken.Add(otherToken))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max combined - multi amounts one consumed": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewCombinedLimit(1, otherToken)}, + }, + "max combined - multi amounts none consumed": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewCombinedLimit(1, oneToken, otherToken)}, + }, + "max combined - removed on last execution": { + limit: NewCombinedLimit(1, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max combined - removed on last token": { + limit: NewCombinedLimit(2, oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max combined - update with token and calls remaining": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewCombinedLimit(1, otherToken)}, + }, + "max combined - multi with other exceeds limit": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken.Add(otherToken))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max combined - with unknown token": { + limit: NewCombinedLimit(2, oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "undefined": { + limit: &UndefinedLimit{}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotResult, gotErr := spec.limit.Accept(sdk.Context{}, spec.src) + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.exp, gotResult) + }) + } +} + +func TestValidateContractGrant(t *testing.T) { + specs := map[string]struct { + setup func(t *testing.T) *ContractGrant + expErr bool + }{ + "all good": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + require.NoError(t, err) + return r + }, + }, + "invalid address": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant([]byte{}, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + require.NoError(t, err) + return r + }, + expErr: true, + }, + "invalid limit": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) + require.NoError(t, err) + return r + }, + expErr: true, + }, + + "invalid filter ": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) + require.NoError(t, err) + return r + }, + expErr: true, + }, + "empty limit": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) + require.NoError(t, err) + r.Limit = nil + return r + }, + expErr: true, + }, + + "empty filter ": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) + require.NoError(t, err) + r.Filter = nil + return r + }, + expErr: true, + }, + "wrong limit type": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) + require.NoError(t, err) + r.Limit = r.Filter + return r + }, + expErr: true, + }, + + "wrong filter type": { + setup: func(t *testing.T) *ContractGrant { + r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) + require.NoError(t, err) + r.Filter = r.Limit + return r + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.setup(t).ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} diff --git a/x/wasm/types/errors.go b/x/wasm/types/errors.go index 7accd72bcb..a7e0464612 100644 --- a/x/wasm/types/errors.go +++ b/x/wasm/types/errors.go @@ -73,17 +73,7 @@ var ( // error if an address does not belong to a contract (just for registration) _ = sdkErrors.Register(DefaultCodespace, 22, "no such contract") - // ErrNotAJSONObject error if given data is not a JSON object - ErrNotAJSONObject = sdkErrors.Register(DefaultCodespace, 23, "not a JSON object") - - // ErrNoTopLevelKey error if a JSON object has no top-level key - ErrNoTopLevelKey = sdkErrors.Register(DefaultCodespace, 24, "no top-level key") - - // ErrMultipleTopLevelKeys error if a JSON object has more than one top-level key - ErrMultipleTopLevelKeys = sdkErrors.Register(DefaultCodespace, 25, "multiple top-level keys") - - // ErrTopKevelKeyNotAllowed error if a JSON object has a top-level key that is not allowed - ErrTopKevelKeyNotAllowed = sdkErrors.Register(DefaultCodespace, 26, "top-level key is not allowed") + // code 23 -26 were used for json parser // ErrExceedMaxQueryStackSize error if max query stack size is exceeded ErrExceedMaxQueryStackSize = sdkErrors.Register(DefaultCodespace, 27, "max query stack size exceeded") diff --git a/x/wasm/types/json_matching.go b/x/wasm/types/json_matching.go index 218035792b..34ff76d35d 100644 --- a/x/wasm/types/json_matching.go +++ b/x/wasm/types/json_matching.go @@ -2,24 +2,22 @@ package types import ( "encoding/json" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// IsJSONObjectWithTopLevelKey returns if the given bytes are a valid JSON object +// isJSONObjectWithTopLevelKey returns true if the given bytes are a valid JSON object // with exactly one top-level key that is contained in the list of allowed keys. -func IsJSONObjectWithTopLevelKey(jsonBytes []byte, allowedKeys []string) (bool, error) { - document := map[string]interface{}{} - if err := json.Unmarshal(jsonBytes, &document); err != nil { - return false, sdkerrors.Wrap(ErrNotAJSONObject, "failed to unmarshal JSON to map") +func isJSONObjectWithTopLevelKey(jsonBytes RawContractMessage, allowedKeys []string) (bool, error) { + if err := jsonBytes.ValidateBasic(); err != nil { + return false, err } - if len(document) == 0 { - return false, sdkerrors.Wrap(ErrNoTopLevelKey, "JSON object has no top-level key") + document := map[string]interface{}{} + if err := json.Unmarshal(jsonBytes, &document); err != nil { + return false, nil // not a map } - if len(document) > 1 { - return false, sdkerrors.Wrap(ErrMultipleTopLevelKeys, "JSON object has multiple top-level keys") + if len(document) != 1 { + return false, nil // unsupported type } // Loop is executed exactly once diff --git a/x/wasm/types/json_matching_test.go b/x/wasm/types/json_matching_test.go index e2899fca83..01d2d3efd3 100644 --- a/x/wasm/types/json_matching_test.go +++ b/x/wasm/types/json_matching_test.go @@ -68,17 +68,17 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { "errors for bytes that are no JSON": { src: []byte(`nope`), allowedKeys: []string{"claim"}, - expErr: ErrNotAJSONObject, + expErr: ErrInvalid, }, - "errors for valid JSON (string)": { + "false for valid JSON (string)": { src: []byte(`"nope"`), allowedKeys: []string{"claim"}, - expErr: ErrNotAJSONObject, + expResult: false, }, - "errors for valid JSON (array)": { + "false for valid JSON (array)": { src: []byte(`[1, 2, 3]`), allowedKeys: []string{"claim"}, - expErr: ErrNotAJSONObject, + expResult: false, }, // not supported: https://github.com/golang/go/issues/24415 //"errors for duplicate key": { @@ -88,15 +88,15 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { //}, // Not one top-level key - "errors for no top-level key": { + "false for no top-level key": { src: []byte(`{}`), allowedKeys: []string{"claim"}, - expErr: ErrNoTopLevelKey, + expResult: false, }, - "errors for multiple top-level keys": { + "false for multiple top-level keys": { src: []byte(`{"claim": {}, "and_swap": {}}`), allowedKeys: []string{"claim"}, - expErr: ErrMultipleTopLevelKeys, + expResult: false, }, // Wrong top-level key @@ -113,7 +113,7 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - exists, gotErr := IsJSONObjectWithTopLevelKey(spec.src, spec.allowedKeys) + exists, gotErr := isJSONObjectWithTopLevelKey(spec.src, spec.allowedKeys) if spec.expErr != nil { assert.ErrorIs(t, gotErr, spec.expErr) return diff --git a/x/wasm/types/tx.go b/x/wasm/types/tx.go index f4f4f45350..dd6f6284cd 100644 --- a/x/wasm/types/tx.go +++ b/x/wasm/types/tx.go @@ -44,7 +44,7 @@ func (r RawContractMessage) Bytes() []byte { // Equal content is equal json. Byte equal but this can change in the future. func (r RawContractMessage) Equal(o RawContractMessage) bool { - return bytes.Equal(r, o) + return bytes.Equal(r.Bytes(), o.Bytes()) } func (msg MsgStoreCode) Route() string { From 40bdb6c6ac30abe404da674b3cfea6a512d756d4 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 8 Nov 2022 15:46:03 +0100 Subject: [PATCH 14/16] Test accept --- x/wasm/types/authz.go | 52 +++---- x/wasm/types/authz_test.go | 312 +++++++++++++++++++++++++++++++++---- 2 files changed, 305 insertions(+), 59 deletions(-) diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index 32a1fd672a..13fb7a8dd8 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -136,26 +136,7 @@ func AcceptGrantedMessage[T AuthzableWasmMsg](ctx sdk.Context, grants []Contract return authztypes.AcceptResponse{}, err } - updatedGrants, modified, err := applyGrants(ctx, grants, exec) - switch { - case err != nil: - return authztypes.AcceptResponse{}, err - case modified: - if len(updatedGrants) == 0 { - return authztypes.AcceptResponse{Accept: true, Delete: true}, nil - } - newAuthz := factory.NewAuthz(updatedGrants) - if err := newAuthz.ValidateBasic(); err != nil { // sanity check - return authztypes.AcceptResponse{}, ErrInvalid.Wrapf("new grant state: %s", err) - } - return authztypes.AcceptResponse{Accept: true, Updated: newAuthz}, nil - default: - return authztypes.AcceptResponse{Accept: true}, nil - } -} - -// iterate through the grants to find an applicable grant. Returns an error when none is found -func applyGrants(ctx sdk.Context, grants []ContractGrant, exec AuthzableWasmMsg) ([]ContractGrant, bool, error) { + // iterate though all grants for i, g := range grants { if g.Contract != exec.GetContract() { continue @@ -165,9 +146,9 @@ func applyGrants(ctx sdk.Context, grants []ContractGrant, exec AuthzableWasmMsg) result, err := g.GetLimit().Accept(ctx, exec) switch { case err != nil: - return nil, false, sdkerrors.Wrap(err, "limit") + return authztypes.AcceptResponse{}, sdkerrors.Wrap(err, "limit") case result == nil: // sanity check - return nil, false, sdkerrors.ErrInvalidType.Wrap("limit result must not be nil") + return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("limit result must not be nil") case !result.Accepted: // not applicable, continue with next grant continue @@ -177,27 +158,39 @@ func applyGrants(ctx sdk.Context, grants []ContractGrant, exec AuthzableWasmMsg) ok, err := g.GetFilter().Accept(ctx, exec.GetMsg()) switch { case err != nil: - return nil, false, sdkerrors.Wrap(err, "filter") + return authztypes.AcceptResponse{}, sdkerrors.Wrap(err, "filter") case !ok: // no limit update and continue with next grant continue } - // finally do limit state updates + // finally do limit state updates in result switch { case result.DeleteLimit: - return append(grants[0:i], grants[i+1:]...), true, nil + updatedGrants := append(grants[0:i], grants[i+1:]...) + if len(updatedGrants) == 0 { // remove when empty + return authztypes.AcceptResponse{Accept: true, Delete: true}, nil + } + newAuthz := factory.NewAuthz(updatedGrants) + if err := newAuthz.ValidateBasic(); err != nil { // sanity check + return authztypes.AcceptResponse{}, ErrInvalid.Wrapf("new grant state: %s", err) + } + return authztypes.AcceptResponse{Accept: true, Updated: newAuthz}, nil case result.UpdateLimit != nil: obj, err := g.WithNewLimits(result.UpdateLimit) if err != nil { - return nil, false, err + return authztypes.AcceptResponse{}, err + } + newAuthz := factory.NewAuthz(append(append(grants[0:i], *obj), grants[i+1:]...)) + if err := newAuthz.ValidateBasic(); err != nil { // sanity check + return authztypes.AcceptResponse{}, ErrInvalid.Wrapf("new grant state: %s", err) } - return append(append(grants[0:i], *obj), grants[i+1:]...), true, nil + return authztypes.AcceptResponse{Accept: true, Updated: newAuthz}, nil default: // accepted without a limit state update - return grants, false, nil + return authztypes.AcceptResponse{Accept: true}, nil } } - return nil, false, sdkerrors.ErrUnauthorized.Wrap("no matching contract grants") + return authztypes.AcceptResponse{Accept: false}, nil } // ContractAuthzLimitX define execution limits that are enforced and updated when the grant @@ -301,7 +294,6 @@ func (g ContractGrant) GetFilter() ContractAuthzFilterX { // ValidateBasic validates the grant func (g ContractGrant) ValidateBasic() error { - // some sanity checks only, need more if _, err := sdk.AccAddressFromBech32(g.Contract); err != nil { return sdkerrors.Wrap(err, "contract") } diff --git a/x/wasm/types/authz_test.go b/x/wasm/types/authz_test.go index aac6c2a02e..e8c1e44007 100644 --- a/x/wasm/types/authz_test.go +++ b/x/wasm/types/authz_test.go @@ -4,6 +4,9 @@ import ( "math" "testing" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authztypes "github.com/cosmos/cosmos-sdk/x/authz" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -387,45 +390,36 @@ func TestContractAuthzLimitAccept(t *testing.T) { func TestValidateContractGrant(t *testing.T) { specs := map[string]struct { - setup func(t *testing.T) *ContractGrant + setup func(t *testing.T) ContractGrant expErr bool }{ "all good": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) - require.NoError(t, err) - return r + setup: func(t *testing.T) ContractGrant { + return mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) }, }, "invalid address": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant([]byte{}, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) - require.NoError(t, err) - return r + setup: func(t *testing.T) ContractGrant { + return mustGrant([]byte{}, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) }, expErr: true, }, "invalid limit": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) - require.NoError(t, err) - return r + setup: func(t *testing.T) ContractGrant { + return mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) }, expErr: true, }, "invalid filter ": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) - require.NoError(t, err) - return r + setup: func(t *testing.T) ContractGrant { + return mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) }, expErr: true, }, "empty limit": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) - require.NoError(t, err) + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) r.Limit = nil return r }, @@ -433,18 +427,16 @@ func TestValidateContractGrant(t *testing.T) { }, "empty filter ": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) - require.NoError(t, err) + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) r.Filter = nil return r }, expErr: true, }, "wrong limit type": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) - require.NoError(t, err) + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) r.Limit = r.Filter return r }, @@ -452,9 +444,8 @@ func TestValidateContractGrant(t *testing.T) { }, "wrong filter type": { - setup: func(t *testing.T) *ContractGrant { - r, err := NewContractGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) - require.NoError(t, err) + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) r.Filter = r.Limit return r }, @@ -472,3 +463,266 @@ func TestValidateContractGrant(t *testing.T) { }) } } + +func TestValidateContractAuthorization(t *testing.T) { + validGrant, err := NewContractGrant(randBytes(SDKAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + require.NoError(t, err) + invalidGrant, err := NewContractGrant(randBytes(SDKAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + require.NoError(t, err) + invalidGrant.Limit = nil + + specs := map[string]struct { + setup func(t *testing.T) validatable + expErr bool + }{ + "contract execution": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant) + }, + }, + "contract execution - duplicate grants": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *validGrant) + }, + }, + "contract execution - invalid grant": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *invalidGrant) + }, + expErr: true, + }, + "contract execution - empty grants": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization() + }, + expErr: true, + }, + "contract migration": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant) + }, + }, + "contract migration - duplicate grants": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *validGrant) + }, + }, + "contract migration - invalid grant": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *invalidGrant) + }, + expErr: true, + }, + "contract migration - empty grant": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization() + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.setup(t).ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestAcceptGrantedMessage(t *testing.T) { + myContractAddr := sdk.AccAddress(randBytes(SDKAddrLen)) + otherContractAddr := sdk.AccAddress(randBytes(SDKAddrLen)) + specs := map[string]struct { + auth authztypes.Authorization + msg sdk.Msg + expResult authztypes.AcceptResponse + expErr *sdkerrors.Error + }{ + "accepted and updated - contract execution": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(2), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + }, + }, + "accepted and not updated - limit not touched": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{Accept: true}, + }, + "accepted and removed - single": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{Accept: true, Delete: true}, + }, + "accepted and updated - multi, one removed": { + auth: NewContractExecutionAuthorization( + mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + ), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + }, + }, + "accepted and updated - multi, one updated": { + auth: NewContractExecutionAuthorization( + mustGrant(otherContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), NewAcceptedMessageKeysFilter("bar")), + mustGrant(myContractAddr, NewCombinedLimit(2, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), NewAcceptedMessageKeysFilter("foo")), + ), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractExecutionAuthorization( + mustGrant(otherContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), NewAcceptedMessageKeysFilter("bar")), + mustGrant(myContractAddr, NewCombinedLimit(1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))), NewAcceptedMessageKeysFilter("foo")), + ), + }, + }, + "not accepted - no matching contract address": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "not accepted - max calls but tokens": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "not accepted - max calls exceeds limit": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "not accepted - no matching filter": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter("other"))), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "invalid msg type - contract execution": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgMigrateContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + CodeID: 1, + Msg: []byte(`{"foo":"bar"}`), + }, + expErr: sdkerrors.ErrInvalidType, + }, + "payload is empty": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + }, + expErr: sdkerrors.ErrInvalidType, + }, + "payload is invalid": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`not json`), + }, + expErr: ErrInvalid, + }, + "invalid grant": { + auth: NewContractExecutionAuthorization(ContractGrant{Contract: myContractAddr.String()}), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expErr: sdkerrors.ErrNotFound, + }, + "invalid msg type - contract migration": { + auth: NewContractMigrationAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expErr: sdkerrors.ErrInvalidType, + }, + "accepted and updated - contract migration": { + auth: NewContractMigrationAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(2), NewAllowAllMessagesFilter())), + msg: &MsgMigrateContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + CodeID: 1, + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractMigrationAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + }, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx := sdk.Context{}.WithGasMeter(sdk.NewInfiniteGasMeter()) + gotResult, gotErr := spec.auth.Accept(ctx, spec.msg) + if spec.expErr != nil { + require.ErrorIs(t, gotErr, spec.expErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.expResult, gotResult) + }) + } +} + +func mustGrant(contract sdk.AccAddress, limit ContractAuthzLimitX, filter ContractAuthzFilterX) ContractGrant { + g, err := NewContractGrant(contract, limit, filter) + if err != nil { + panic(err) + } + return *g +} From 5aed79c21466cfd192f114a17df655790819b096 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 8 Nov 2022 15:47:01 +0100 Subject: [PATCH 15/16] Fix description --- x/wasm/types/authz_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/wasm/types/authz_test.go b/x/wasm/types/authz_test.go index e8c1e44007..06747693fc 100644 --- a/x/wasm/types/authz_test.go +++ b/x/wasm/types/authz_test.go @@ -626,7 +626,7 @@ func TestAcceptGrantedMessage(t *testing.T) { }, expResult: authztypes.AcceptResponse{Accept: false}, }, - "not accepted - max calls exceeds limit": { + "not accepted - funds exceeds limit": { auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), NewAllowAllMessagesFilter())), msg: &MsgExecuteContract{ Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), From cc8d9bd7320b99e22f34f84b83c7f590466b1e67 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 8 Nov 2022 15:55:11 +0100 Subject: [PATCH 16/16] No linter warning --- x/wasm/types/authz.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go index 13fb7a8dd8..10dd2606c9 100644 --- a/x/wasm/types/authz.go +++ b/x/wasm/types/authz.go @@ -167,8 +167,8 @@ func AcceptGrantedMessage[T AuthzableWasmMsg](ctx sdk.Context, grants []Contract // finally do limit state updates in result switch { case result.DeleteLimit: - updatedGrants := append(grants[0:i], grants[i+1:]...) - if len(updatedGrants) == 0 { // remove when empty + updatedGrants := append(grants[0:i], grants[i+1:]...) //nolint:gocritic + if len(updatedGrants) == 0 { // remove when empty return authztypes.AcceptResponse{Accept: true, Delete: true}, nil } newAuthz := factory.NewAuthz(updatedGrants)