diff --git a/CHANGELOG.md b/CHANGELOG.md index 6def9561d..6a75bc5dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Consensus Breaking Changes +* (x/intent) [#139](https://github.com/warden-protocol/wardenprotocol/pull/139) Ability for modules to dynamically resolve variables on Action creation + * x/warden can now resolve `warden.space.owners` in Intent definitions into the list of owners of the space + ### Features ### Bug Fixes diff --git a/api/warden/intent/action.pulsar.go b/api/warden/intent/action.pulsar.go index 3afac7146..02b7b94cb 100644 --- a/api/warden/intent/action.pulsar.go +++ b/api/warden/intent/action.pulsar.go @@ -566,6 +566,52 @@ func (x *_Action_2_list) IsValid() bool { return x.list != nil } +var _ protoreflect.List = (*_Action_12_list)(nil) + +type _Action_12_list struct { + list *[]string +} + +func (x *_Action_12_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Action_12_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Action_12_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Action_12_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Action_12_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Action at list field Mentions as it is not of Message kind")) +} + +func (x *_Action_12_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Action_12_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Action_12_list) IsValid() bool { + return x.list != nil +} + var ( md_Action protoreflect.MessageDescriptor fd_Action_id protoreflect.FieldDescriptor @@ -578,6 +624,7 @@ var ( fd_Action_created_at protoreflect.FieldDescriptor fd_Action_updated_at protoreflect.FieldDescriptor fd_Action_intent protoreflect.FieldDescriptor + fd_Action_mentions protoreflect.FieldDescriptor ) func init() { @@ -593,6 +640,7 @@ func init() { fd_Action_created_at = md_Action.Fields().ByName("created_at") fd_Action_updated_at = md_Action.Fields().ByName("updated_at") fd_Action_intent = md_Action.Fields().ByName("intent") + fd_Action_mentions = md_Action.Fields().ByName("mentions") } var _ protoreflect.Message = (*fastReflection_Action)(nil) @@ -720,6 +768,12 @@ func (x *fastReflection_Action) Range(f func(protoreflect.FieldDescriptor, proto return } } + if len(x.Mentions) != 0 { + value := protoreflect.ValueOfList(&_Action_12_list{list: &x.Mentions}) + if !f(fd_Action_mentions, value) { + return + } + } } // Has reports whether a field is populated. @@ -755,6 +809,8 @@ func (x *fastReflection_Action) Has(fd protoreflect.FieldDescriptor) bool { return x.UpdatedAt != nil case "warden.intent.Action.intent": return x.Intent != nil + case "warden.intent.Action.mentions": + return len(x.Mentions) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Action")) @@ -791,6 +847,8 @@ func (x *fastReflection_Action) Clear(fd protoreflect.FieldDescriptor) { x.UpdatedAt = nil case "warden.intent.Action.intent": x.Intent = nil + case "warden.intent.Action.mentions": + x.Mentions = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Action")) @@ -840,6 +898,12 @@ func (x *fastReflection_Action) Get(descriptor protoreflect.FieldDescriptor) pro case "warden.intent.Action.intent": value := x.Intent return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "warden.intent.Action.mentions": + if len(x.Mentions) == 0 { + return protoreflect.ValueOfList(&_Action_12_list{}) + } + listValue := &_Action_12_list{list: &x.Mentions} + return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Action")) @@ -882,6 +946,10 @@ func (x *fastReflection_Action) Set(fd protoreflect.FieldDescriptor, value proto x.UpdatedAt = value.Message().Interface().(*timestamppb.Timestamp) case "warden.intent.Action.intent": x.Intent = value.Message().Interface().(*Intent) + case "warden.intent.Action.mentions": + lv := value.List() + clv := lv.(*_Action_12_list) + x.Mentions = *clv.list default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Action")) @@ -933,6 +1001,12 @@ func (x *fastReflection_Action) Mutable(fd protoreflect.FieldDescriptor) protore x.Intent = new(Intent) } return protoreflect.ValueOfMessage(x.Intent.ProtoReflect()) + case "warden.intent.Action.mentions": + if x.Mentions == nil { + x.Mentions = []string{} + } + value := &_Action_12_list{list: &x.Mentions} + return protoreflect.ValueOfList(value) case "warden.intent.Action.id": panic(fmt.Errorf("field id of message warden.intent.Action is not mutable")) case "warden.intent.Action.status": @@ -980,6 +1054,9 @@ func (x *fastReflection_Action) NewField(fd protoreflect.FieldDescriptor) protor case "warden.intent.Action.intent": m := new(Intent) return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "warden.intent.Action.mentions": + list := []string{} + return protoreflect.ValueOfList(&_Action_12_list{list: &list}) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Action")) @@ -1088,6 +1165,12 @@ func (x *fastReflection_Action) ProtoMethods() *protoiface.Methods { l = options.Size(x.Intent) n += 1 + l + runtime.Sov(uint64(l)) } + if len(x.Mentions) > 0 { + for _, s := range x.Mentions { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -1117,6 +1200,15 @@ func (x *fastReflection_Action) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.Mentions) > 0 { + for iNdEx := len(x.Mentions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Mentions[iNdEx]) + copy(dAtA[i:], x.Mentions[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Mentions[iNdEx]))) + i-- + dAtA[i] = 0x62 + } + } if x.Intent != nil { encoded, err := options.Marshal(x.Intent) if err != nil { @@ -1577,6 +1669,38 @@ func (x *fastReflection_Action) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex + case 12: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Mentions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Mentions = append(x.Mentions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -2192,6 +2316,8 @@ type Action struct { // storing the intent ID, we store the entire intent object so that is // immutable and cannot be changed later. Intent *Intent `protobuf:"bytes,11,opt,name=intent,proto3" json:"intent,omitempty"` + // mentions is a list of addresses that are mentioned in the intent. + Mentions []string `protobuf:"bytes,12,rep,name=mentions,proto3" json:"mentions,omitempty"` } func (x *Action) Reset() { @@ -2284,6 +2410,13 @@ func (x *Action) GetIntent() *Intent { return nil } +func (x *Action) GetMentions() []string { + if x != nil { + return x.Mentions + } + return nil +} + // MsgActionCreated is returned by rpc that creates an action. type MsgActionCreated struct { state protoimpl.MessageState @@ -2340,7 +2473,7 @@ var file_warden_intent_action_proto_rawDesc = []byte{ 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x41, 0x74, 0x22, 0xcf, + 0x2a, 0x01, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x41, 0x74, 0x22, 0xeb, 0x03, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x77, @@ -2370,32 +2503,34 @@ var file_warden_intent_action_proto_rawDesc = []byte{ 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x22, 0x41, 0x0a, 0x10, 0x4d, 0x73, 0x67, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x2a, 0x9b, 0x01, 0x0a, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1b, - 0x0a, 0x17, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x56, - 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, - 0x04, 0x42, 0xb2, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x2f, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0xa2, 0x02, 0x03, 0x57, 0x49, 0x58, 0xaa, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, - 0x65, 0x6e, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xca, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, - 0x65, 0x6e, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xe2, 0x02, 0x19, 0x57, 0x61, 0x72, 0x64, - 0x65, 0x6e, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x3a, 0x3a, - 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x41, 0x0a, 0x10, + 0x4d, 0x73, 0x67, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x12, 0x2d, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2a, + 0x9b, 0x01, 0x0a, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x19, 0x0a, 0x15, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x41, 0x43, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, + 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, + 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x04, 0x42, 0xb2, 0x01, + 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x42, 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, + 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x77, + 0x61, 0x72, 0x64, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xa2, + 0x02, 0x03, 0x57, 0x49, 0x58, 0xaa, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xca, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x5c, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xe2, 0x02, 0x19, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x5c, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x0e, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/warden/intent/intent.pulsar.go b/api/warden/intent/intent.pulsar.go index 420a8c2fd..e7dc7f713 100644 --- a/api/warden/intent/intent.pulsar.go +++ b/api/warden/intent/intent.pulsar.go @@ -13,59 +13,12 @@ import ( sync "sync" ) -var _ protoreflect.List = (*_Intent_5_list)(nil) - -type _Intent_5_list struct { - list *[]string -} - -func (x *_Intent_5_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Intent_5_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Intent_5_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Intent_5_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Intent_5_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Intent at list field Addresses as it is not of Message kind")) -} - -func (x *_Intent_5_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Intent_5_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Intent_5_list) IsValid() bool { - return x.list != nil -} - var ( md_Intent protoreflect.MessageDescriptor fd_Intent_id protoreflect.FieldDescriptor fd_Intent_creator protoreflect.FieldDescriptor fd_Intent_name protoreflect.FieldDescriptor fd_Intent_definition protoreflect.FieldDescriptor - fd_Intent_addresses protoreflect.FieldDescriptor ) func init() { @@ -75,7 +28,6 @@ func init() { fd_Intent_creator = md_Intent.Fields().ByName("creator") fd_Intent_name = md_Intent.Fields().ByName("name") fd_Intent_definition = md_Intent.Fields().ByName("definition") - fd_Intent_addresses = md_Intent.Fields().ByName("addresses") } var _ protoreflect.Message = (*fastReflection_Intent)(nil) @@ -167,12 +119,6 @@ func (x *fastReflection_Intent) Range(f func(protoreflect.FieldDescriptor, proto return } } - if len(x.Addresses) != 0 { - value := protoreflect.ValueOfList(&_Intent_5_list{list: &x.Addresses}) - if !f(fd_Intent_addresses, value) { - return - } - } } // Has reports whether a field is populated. @@ -196,8 +142,6 @@ func (x *fastReflection_Intent) Has(fd protoreflect.FieldDescriptor) bool { return x.Name != "" case "warden.intent.Intent.definition": return x.Definition != "" - case "warden.intent.Intent.addresses": - return len(x.Addresses) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Intent")) @@ -222,8 +166,6 @@ func (x *fastReflection_Intent) Clear(fd protoreflect.FieldDescriptor) { x.Name = "" case "warden.intent.Intent.definition": x.Definition = "" - case "warden.intent.Intent.addresses": - x.Addresses = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Intent")) @@ -252,12 +194,6 @@ func (x *fastReflection_Intent) Get(descriptor protoreflect.FieldDescriptor) pro case "warden.intent.Intent.definition": value := x.Definition return protoreflect.ValueOfString(value) - case "warden.intent.Intent.addresses": - if len(x.Addresses) == 0 { - return protoreflect.ValueOfList(&_Intent_5_list{}) - } - listValue := &_Intent_5_list{list: &x.Addresses} - return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Intent")) @@ -286,10 +222,6 @@ func (x *fastReflection_Intent) Set(fd protoreflect.FieldDescriptor, value proto x.Name = value.Interface().(string) case "warden.intent.Intent.definition": x.Definition = value.Interface().(string) - case "warden.intent.Intent.addresses": - lv := value.List() - clv := lv.(*_Intent_5_list) - x.Addresses = *clv.list default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Intent")) @@ -310,12 +242,6 @@ func (x *fastReflection_Intent) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Intent) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "warden.intent.Intent.addresses": - if x.Addresses == nil { - x.Addresses = []string{} - } - value := &_Intent_5_list{list: &x.Addresses} - return protoreflect.ValueOfList(value) case "warden.intent.Intent.id": panic(fmt.Errorf("field id of message warden.intent.Intent is not mutable")) case "warden.intent.Intent.creator": @@ -345,9 +271,6 @@ func (x *fastReflection_Intent) NewField(fd protoreflect.FieldDescriptor) protor return protoreflect.ValueOfString("") case "warden.intent.Intent.definition": return protoreflect.ValueOfString("") - case "warden.intent.Intent.addresses": - list := []string{} - return protoreflect.ValueOfList(&_Intent_5_list{list: &list}) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: warden.intent.Intent")) @@ -432,12 +355,6 @@ func (x *fastReflection_Intent) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if len(x.Addresses) > 0 { - for _, s := range x.Addresses { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -467,15 +384,6 @@ func (x *fastReflection_Intent) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if len(x.Addresses) > 0 { - for iNdEx := len(x.Addresses) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.Addresses[iNdEx]) - copy(dAtA[i:], x.Addresses[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Addresses[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } if len(x.Definition) > 0 { i -= len(x.Definition) copy(dAtA[i:], x.Definition) @@ -666,38 +574,6 @@ func (x *fastReflection_Intent) ProtoMethods() *protoiface.Methods { } x.Definition = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Addresses = append(x.Addresses, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -756,8 +632,6 @@ type Intent struct { Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // The definition of the intent written in the Shield language. Definition string `protobuf:"bytes,4,opt,name=definition,proto3" json:"definition,omitempty"` - // The list of addresses referenced from the intent definition. - Addresses []string `protobuf:"bytes,5,rep,name=addresses,proto3" json:"addresses,omitempty"` } func (x *Intent) Reset() { @@ -808,13 +682,6 @@ func (x *Intent) GetDefinition() string { return "" } -func (x *Intent) GetAddresses() []string { - if x != nil { - return x.Addresses - } - return nil -} - var File_warden_intent_intent_proto protoreflect.FileDescriptor var file_warden_intent_intent_proto_rawDesc = []byte{ @@ -822,27 +689,25 @@ var file_warden_intent_intent_proto_rawDesc = []byte{ 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x01, 0x0a, 0x06, 0x49, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x42, 0xb2, 0x01, - 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x42, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, - 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x77, - 0x61, 0x72, 0x64, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xa2, - 0x02, 0x03, 0x57, 0x49, 0x58, 0xaa, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x49, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xca, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x5c, 0x49, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xe2, 0x02, 0x19, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x5c, 0x49, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x0e, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x66, 0x0a, 0x06, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0xb2, + 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x42, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, + 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x77, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0xa2, 0x02, 0x03, 0x57, 0x49, 0x58, 0xaa, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xca, 0x02, 0x0d, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x5c, + 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0xe2, 0x02, 0x19, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x5c, + 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x0e, 0x57, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x3a, 0x3a, 0x49, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/warden/intent/action.proto b/proto/warden/intent/action.proto index 8490a85fc..536d7b89d 100644 --- a/proto/warden/intent/action.proto +++ b/proto/warden/intent/action.proto @@ -41,6 +41,8 @@ message Action { // storing the intent ID, we store the entire intent object so that is // immutable and cannot be changed later. intent.Intent intent = 11 [(gogoproto.nullable) = false]; + // mentions is a list of addresses that are mentioned in the intent. + repeated string mentions = 12; } // MsgActionCreated is returned by rpc that creates an action. diff --git a/proto/warden/intent/intent.proto b/proto/warden/intent/intent.proto index 3abb42144..04b8b651f 100644 --- a/proto/warden/intent/intent.proto +++ b/proto/warden/intent/intent.proto @@ -12,8 +12,5 @@ message Intent { // The definition of the intent written in the Shield language. string definition = 4; - - // The list of addresses referenced from the intent definition. - repeated string addresses = 5; } diff --git a/shield/internal/ast/ast.go b/shield/ast/ast.go similarity index 75% rename from shield/internal/ast/ast.go rename to shield/ast/ast.go index dfc6ee171..c1d049e4b 100644 --- a/shield/internal/ast/ast.go +++ b/shield/ast/ast.go @@ -2,6 +2,7 @@ package ast import ( "fmt" + "strconv" "github.com/warden-protocol/wardenprotocol/shield/internal/token" ) @@ -20,6 +21,16 @@ type Identifier struct { Value string } +func NewIdent(name string) *Identifier { + return &Identifier{ + Token: token.Token{ + Type: token.IDENT, + Literal: name, + }, + Value: name, + } +} + func (i *Identifier) expressionNode() {} func (i *Identifier) TokenLiteral() string { return i.Token.Literal } func (i *Identifier) String() string { return i.Value } @@ -29,6 +40,16 @@ type IntegerLiteral struct { Value int64 } +func NewInt(value int64) *IntegerLiteral { + return &IntegerLiteral{ + Token: token.Token{ + Type: token.INT, + Literal: strconv.FormatInt(value, 10), + }, + Value: value, + } +} + func (il *IntegerLiteral) expressionNode() {} func (il *IntegerLiteral) TokenLiteral() string { return il.Token.Literal } func (il *IntegerLiteral) String() string { return il.Token.Literal } @@ -38,6 +59,25 @@ type BooleanLiteral struct { Value bool } +func NewBool(value bool) *BooleanLiteral { + var ( + tokenType token.TokenType = token.FALSE + tokenLit = "false" + ) + if value { + tokenType = token.TRUE + tokenLit = "true" + } + + return &BooleanLiteral{ + Token: token.Token{ + Type: tokenType, + Literal: tokenLit, + }, + Value: value, + } +} + func (bl *BooleanLiteral) expressionNode() {} func (bl *BooleanLiteral) TokenLiteral() string { return bl.Token.Literal } func (bl *BooleanLiteral) String() string { return bl.Token.Literal } diff --git a/shield/ast/expander.go b/shield/ast/expander.go new file mode 100644 index 000000000..db1abf2c4 --- /dev/null +++ b/shield/ast/expander.go @@ -0,0 +1,18 @@ +package ast + +import "context" + +type Expander interface { + // Expand expands an identifier into another AST node. + // + // The expansion is done as a pre-processing step when an Action is + // created, like a macro in some programming languages. + // Custom modules can implement this interface to provide custom + // expansions for their identifiers. + // + // A no-op expansion is to return the input identifier as a single-element. + // + // After the pre-processing step, the identifiers that are left must be + // able to be resolved by the x/intent modules. + Expand(ctx context.Context, ident *Identifier) (Expression, error) +} diff --git a/shield/ast/stringify.go b/shield/ast/stringify.go new file mode 100644 index 000000000..6ef7ab051 --- /dev/null +++ b/shield/ast/stringify.go @@ -0,0 +1,40 @@ +package ast + +import ( + "fmt" + "strings" +) + +func Stringify(node Node) string { + switch n := node.(type) { + case *Identifier: + return n.String() + case *IntegerLiteral: + return n.String() + case *BooleanLiteral: + return n.String() + case *ArrayLiteral: + return fmt.Sprintf("[%s]", stringifyExpressions(n.Elements)) + case *CallExpression: + return fmt.Sprintf("%s(%s)", n.Function, stringifyExpressions(n.Arguments)) + default: + return "" + } +} + +func stringifyExpressions(exps []Expression) string { + if len(exps) == 0 { + return "" + } + + var sb strings.Builder + + for _, e := range exps[:len(exps)-1] { + sb.WriteString(Stringify(e)) + sb.WriteString(", ") + } + + sb.WriteString(Stringify(exps[len(exps)-1])) + + return sb.String() +} diff --git a/shield/env/env.go b/shield/env/env.go new file mode 100644 index 000000000..7b826a6d8 --- /dev/null +++ b/shield/env/env.go @@ -0,0 +1,7 @@ +package env + +import "github.com/warden-protocol/wardenprotocol/shield/object" + +type Environment interface { + Get(name string) (object.Object, bool) +} diff --git a/shield/internal/evaluator/evaluator.go b/shield/internal/evaluator/evaluator.go index 5ac92cbe7..2acae9e8d 100644 --- a/shield/internal/evaluator/evaluator.go +++ b/shield/internal/evaluator/evaluator.go @@ -3,15 +3,12 @@ package evaluator import ( "fmt" - "github.com/warden-protocol/wardenprotocol/shield/internal/ast" + "github.com/warden-protocol/wardenprotocol/shield/ast" + "github.com/warden-protocol/wardenprotocol/shield/env" "github.com/warden-protocol/wardenprotocol/shield/object" ) -type Environment interface { - Get(name string) (object.Object, bool) -} - -func Eval(exp ast.Expression, env Environment) object.Object { +func Eval(exp ast.Expression, env env.Environment) object.Object { switch exp := exp.(type) { case *ast.IntegerLiteral: return &object.Integer{Value: exp.Value} @@ -46,7 +43,7 @@ func Eval(exp ast.Expression, env Environment) object.Object { return newError("unknown expression: %s (type %T)", exp, exp) } -func evalExpressions(exps []ast.Expression, env Environment) []object.Object { +func evalExpressions(exps []ast.Expression, env env.Environment) []object.Object { result := make([]object.Object, 0, len(exps)) for _, e := range exps { evaluated := Eval(e, env) @@ -55,7 +52,7 @@ func evalExpressions(exps []ast.Expression, env Environment) []object.Object { return result } -func applyFunction(fn object.Object, args []object.Object, env Environment) object.Object { +func applyFunction(fn object.Object, args []object.Object, env env.Environment) object.Object { switch fn := fn.(type) { case *object.Builtin: return fn.Fn(args...) @@ -68,7 +65,7 @@ func newError(format string, a ...interface{}) *object.Error { return &object.Error{Message: fmt.Sprintf(format, a...)} } -func evalInfixExpression(exp *ast.InfixExpression, env Environment) object.Object { +func evalInfixExpression(exp *ast.InfixExpression, env env.Environment) object.Object { left := Eval(exp.Left, env) if isError(left) { return left diff --git a/shield/internal/lexer/lexer.go b/shield/internal/lexer/lexer.go index e8d2b8391..b61218896 100644 --- a/shield/internal/lexer/lexer.go +++ b/shield/internal/lexer/lexer.go @@ -89,7 +89,7 @@ func (l *Lexer) peekChar() byte { func (l *Lexer) readIdentifier() string { position := l.position - for isLetter(l.ch) || isDigit(l.ch) { + for isLetter(l.ch) || isDigit(l.ch) || isDot(l.ch) { l.readChar() } return l.input[position:l.position] @@ -120,3 +120,7 @@ func isLetter(ch byte) bool { func isDigit(ch byte) bool { return '0' <= ch && ch <= '9' } + +func isDot(ch byte) bool { + return ch == '.' +} diff --git a/shield/internal/metadata/metadata.go b/shield/internal/metadata/metadata.go index da3dc5701..00836ec42 100644 --- a/shield/internal/metadata/metadata.go +++ b/shield/internal/metadata/metadata.go @@ -1,7 +1,7 @@ package metadata import ( - "github.com/warden-protocol/wardenprotocol/shield/internal/ast" + "github.com/warden-protocol/wardenprotocol/shield/ast" ) // Metadata contains informations about a parsed program. diff --git a/shield/internal/metadata/metadata_test.go b/shield/internal/metadata/metadata_test.go index 45516086f..920f0fcbc 100644 --- a/shield/internal/metadata/metadata_test.go +++ b/shield/internal/metadata/metadata_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/warden-protocol/wardenprotocol/shield/internal/ast" + "github.com/warden-protocol/wardenprotocol/shield/ast" "github.com/warden-protocol/wardenprotocol/shield/internal/lexer" "github.com/warden-protocol/wardenprotocol/shield/internal/parser" ) diff --git a/shield/internal/parser/parser.go b/shield/internal/parser/parser.go index 3f2dc2764..2e20872be 100644 --- a/shield/internal/parser/parser.go +++ b/shield/internal/parser/parser.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "github.com/warden-protocol/wardenprotocol/shield/internal/ast" + "github.com/warden-protocol/wardenprotocol/shield/ast" "github.com/warden-protocol/wardenprotocol/shield/internal/lexer" "github.com/warden-protocol/wardenprotocol/shield/internal/token" ) diff --git a/shield/internal/parser/parser_test.go b/shield/internal/parser/parser_test.go index 9b40d84cb..cb8f6e851 100644 --- a/shield/internal/parser/parser_test.go +++ b/shield/internal/parser/parser_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/warden-protocol/wardenprotocol/shield/internal/ast" + "github.com/warden-protocol/wardenprotocol/shield/ast" "github.com/warden-protocol/wardenprotocol/shield/internal/lexer" ) diff --git a/shield/internal/preprocess/preprocess.go b/shield/internal/preprocess/preprocess.go new file mode 100644 index 000000000..055f6e59d --- /dev/null +++ b/shield/internal/preprocess/preprocess.go @@ -0,0 +1,48 @@ +package preprocess + +import ( + "context" + + "github.com/warden-protocol/wardenprotocol/shield/ast" +) + +func Preprocess(ctx context.Context, node ast.Expression, expander ast.Expander) (ast.Expression, error) { + switch n := node.(type) { + case *ast.Identifier: + return expander.Expand(ctx, n) + case *ast.ArrayLiteral: + return n, preprocessElements(ctx, n.Elements, expander) + case *ast.CallExpression: + return n, preprocessCallExpression(ctx, n, expander) + case *ast.InfixExpression: + var err error + n.Left, err = Preprocess(ctx, n.Left, expander) + if err != nil { + return nil, err + } + + n.Right, err = Preprocess(ctx, n.Right, expander) + if err != nil { + return nil, err + } + + return n, nil + default: + return n, nil + } +} + +func preprocessElements(ctx context.Context, elements []ast.Expression, expander ast.Expander) error { + for i, elem := range elements { + var err error + elements[i], err = Preprocess(ctx, elem, expander) + if err != nil { + return err + } + } + return nil +} + +func preprocessCallExpression(ctx context.Context, call *ast.CallExpression, expander ast.Expander) error { + return preprocessElements(ctx, call.Arguments, expander) +} diff --git a/shield/shield.go b/shield/shield.go index 3cc0a621a..3a8755943 100644 --- a/shield/shield.go +++ b/shield/shield.go @@ -1,46 +1,63 @@ package shield import ( + "context" "fmt" + "github.com/warden-protocol/wardenprotocol/shield/ast" + "github.com/warden-protocol/wardenprotocol/shield/env" "github.com/warden-protocol/wardenprotocol/shield/internal/evaluator" "github.com/warden-protocol/wardenprotocol/shield/internal/lexer" "github.com/warden-protocol/wardenprotocol/shield/internal/metadata" "github.com/warden-protocol/wardenprotocol/shield/internal/parser" + "github.com/warden-protocol/wardenprotocol/shield/internal/preprocess" "github.com/warden-protocol/wardenprotocol/shield/object" ) -type Environment = evaluator.Environment +type Environment = env.Environment // Run executes the code passed a string and returns the result of the evaluation. // In case of a parsing error, it returns an error. // In case of a runtime error, the resulting object will be an error object. -func Run(input string, env Environment) (object.Object, error) { +func Run(ctx context.Context, input string, expander ast.Expander, env Environment) (object.Object, error) { + root, err := Parse(ctx, input, expander) + if err != nil { + return nil, err + } + + res := evaluator.Eval(root, env) + return res, nil +} + +// Parse parses the input string and returns the root node of the AST. +// In case of syntax errors, it returns an error. +// If not nil, the expander is used to process the AST. +func Parse(ctx context.Context, input string, expander ast.Expander) (ast.Expression, error) { l := lexer.New(input) p := parser.New(l) - res := evaluator.Eval(p.Parse(), env) + root := p.Parse() if len(p.Errors()) > 0 { return nil, fmt.Errorf("parser errors: %v", p.Errors()) } - return res, nil + + if expander != nil { + newRoot, err := preprocess.Preprocess(ctx, root, expander) + if err != nil { + return nil, fmt.Errorf("preprocessor error: %w", err) + } + root = newRoot + } + + return root, nil } type Metadata = metadata.Metadata -// Validate is a static check for parsing the code, ensuring the syntax is correct. -// It also extracts metadata from the code while doing it. -// It returns an error if the input is empty or if there are parsing errors. -func Validate(input string) (Metadata, error) { - if input == "" { +// ExtractMetadata extracts metadata from the given expression. +func ExtractMetadata(root ast.Expression) (Metadata, error) { + if root == nil { return Metadata{}, fmt.Errorf("empty input") } - l := lexer.New(input) - p := parser.New(l) - expr := p.Parse() - if len(p.Errors()) > 0 { - return Metadata{}, fmt.Errorf("parser errors: %v", p.Errors()) - } - - return metadata.ExtractMetadata(expr), nil + return metadata.ExtractMetadata(root), nil } diff --git a/warden/app/app.go b/warden/app/app.go index 2217891bc..cabb1266a 100644 --- a/warden/app/app.go +++ b/warden/app/app.go @@ -58,8 +58,11 @@ import ( ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" + "github.com/warden-protocol/wardenprotocol/shield/ast" + "github.com/warden-protocol/wardenprotocol/warden/x/intent/cosmoshield" intentmodulekeeper "github.com/warden-protocol/wardenprotocol/warden/x/intent/keeper" wardenmodulekeeper "github.com/warden-protocol/wardenprotocol/warden/x/warden/keeper" + wardentypes "github.com/warden-protocol/wardenprotocol/warden/x/warden/types/v1beta2" // this line is used by starport scaffolding # stargate/app/moduleImport @@ -197,6 +200,18 @@ func New( app.GetCapabilityScopedKeeper, // Supply the logger logger, + func() ast.Expander { + // I don't know if a lazy function is the best way to do this. + // x/intent wants to access this ExpanderManager, but the + // ExpanderManager depends on other modules (listed below), + // that might depend on x/intent. + return cosmoshield.NewExpanderManager( + cosmoshield.NewPrefixedExpander( + wardentypes.ModuleName, + app.WardenKeeper.ShieldExpander(), + ), + ) + }, // ADVANCED CONFIGURATION // diff --git a/warden/repo/seqcollection.go b/warden/repo/seqcollection.go index 45cdfd0c2..677cb7523 100644 --- a/warden/repo/seqcollection.go +++ b/warden/repo/seqcollection.go @@ -1,10 +1,10 @@ package repo import ( + "context" "fmt" "cosmossdk.io/collections" - sdk "github.com/cosmos/cosmos-sdk/types" ) var ( @@ -29,18 +29,18 @@ func NewSeqCollection[V any]( return SeqCollection[V]{seq: seq, Map: m, setId: setId} } -func (c SeqCollection[V]) Get(ctx sdk.Context, id uint64) (V, error) { +func (c SeqCollection[V]) Get(ctx context.Context, id uint64) (V, error) { return c.Map.Get(ctx, id) } -func (c SeqCollection[V]) Set(ctx sdk.Context, id uint64, obj V) error { +func (c SeqCollection[V]) Set(ctx context.Context, id uint64, obj V) error { if id == 0 { return ErrInvalidID } return c.Map.Set(ctx, id, obj) } -func (c SeqCollection[V]) Append(ctx sdk.Context, obj *V) (uint64, error) { +func (c SeqCollection[V]) Append(ctx context.Context, obj *V) (uint64, error) { id, err := c.next(ctx) if err != nil { return 0, err @@ -49,7 +49,7 @@ func (c SeqCollection[V]) Append(ctx sdk.Context, obj *V) (uint64, error) { return id, c.Map.Set(ctx, id, *obj) } -func (c SeqCollection[V]) next(ctx sdk.Context) (uint64, error) { +func (c SeqCollection[V]) next(ctx context.Context) (uint64, error) { peek, err := c.seq.Peek(ctx) if err != nil { return 0, err @@ -62,7 +62,7 @@ func (c SeqCollection[V]) next(ctx sdk.Context) (uint64, error) { return c.seq.Next(ctx) } -func (c SeqCollection[V]) Import(ctx sdk.Context, values []V, getIDFn func(V) uint64) error { +func (c SeqCollection[V]) Import(ctx context.Context, values []V, getIDFn func(V) uint64) error { for _, v := range values { id := getIDFn(v) actualID, err := c.Append(ctx, &v) @@ -73,7 +73,7 @@ func (c SeqCollection[V]) Import(ctx sdk.Context, values []V, getIDFn func(V) ui return nil } -func (c SeqCollection[V]) Export(ctx sdk.Context) ([]V, error) { +func (c SeqCollection[V]) Export(ctx context.Context) ([]V, error) { iter, err := c.Iterate(ctx, nil) if err != nil { return nil, err diff --git a/warden/testutil/keeper/intent.go b/warden/testutil/keeper/intent.go index 510d7225f..8494c37a7 100644 --- a/warden/testutil/keeper/intent.go +++ b/warden/testutil/keeper/intent.go @@ -38,6 +38,7 @@ func IntentKeeper(t testing.TB) (keeper.Keeper, sdk.Context) { runtime.NewKVStoreService(storeKey), log.NewNopLogger(), authority.String(), + nil, ) ctx := sdk.NewContext(stateStore, cmtproto.Header{}, false, log.NewNopLogger()) diff --git a/warden/x/intent/cosmoshield/context.go b/warden/x/intent/cosmoshield/context.go new file mode 100644 index 000000000..0990bbc82 --- /dev/null +++ b/warden/x/intent/cosmoshield/context.go @@ -0,0 +1,34 @@ +package cosmoshield + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type Context struct { + context.Context + + actionMsg sdk.Msg +} + +func NewContext(baseContext context.Context, actionMsg sdk.Msg) Context { + return Context{ + Context: baseContext, + actionMsg: actionMsg, + } +} + +func (c Context) Msg() sdk.Msg { + return c.actionMsg +} + +func UnwrapContext(ctx context.Context) Context { + if ctx, ok := ctx.(Context); ok { + return ctx + } + + return Context{ + Context: ctx, + } +} diff --git a/warden/x/intent/cosmoshield/cosmosshield.go b/warden/x/intent/cosmoshield/cosmosshield.go new file mode 100644 index 000000000..6dc2d9786 --- /dev/null +++ b/warden/x/intent/cosmoshield/cosmosshield.go @@ -0,0 +1,72 @@ +// Package cosmoshield provides some utility from integrating the main `shield` +// package with Cosmos SDK apps. +package cosmoshield + +import ( + "context" + "strings" + + "github.com/warden-protocol/wardenprotocol/shield/ast" +) + +// NamespaceExpander is an ast.Expander that can be registered into an +// ExpanderManager to expand identifiers based on their namespace. +type NamespaceExpander struct { + base ast.Expander + Namespace string +} + +func NewPrefixedExpander(namespace string, expander ast.Expander) NamespaceExpander { + return NamespaceExpander{ + base: expander, + Namespace: namespace, + } +} + +func (e NamespaceExpander) Expand(ctx context.Context, ident *ast.Identifier) (ast.Expression, error) { + return e.base.Expand(ctx, ident) +} + +// ExpanderManager implements ast.Expander and allows to register multiple +// NameSpaceExpanders to dispatch the expansion of identifiers based on their +// namespace. +type ExpanderManager struct { + expanders map[string]ast.Expander +} + +func NewExpanderManager(expanders ...NamespaceExpander) ExpanderManager { + m := make(map[string]ast.Expander, len(expanders)) + for _, expander := range expanders { + m[expander.Namespace] = expander + } + + return ExpanderManager{ + expanders: m, + } +} + +func (e ExpanderManager) Expand(ctx context.Context, ident *ast.Identifier) (ast.Expression, error) { + namespace, path := path(ident.Value) + + if namespace == "" { + // if no namespace is present, leave the identifier as is + return ident, nil + } + + expander, ok := e.expanders[namespace] + if !ok { + // if no expander is registered for this namespace, leave the + // identifier as is + return ident, nil + } + + return expander.Expand(ctx, ast.NewIdent(path)) +} + +func path(name string) (string, string) { + parts := strings.SplitN(name, ".", 2) + if len(parts) == 1 { + return "", name + } + return parts[0], parts[1] +} diff --git a/warden/x/intent/keeper/actions.go b/warden/x/intent/keeper/actions.go index 9e57d7e73..0d02c4868 100644 --- a/warden/x/intent/keeper/actions.go +++ b/warden/x/intent/keeper/actions.go @@ -1,19 +1,3 @@ -// Copyright 2024 -// -// This file includes work covered by the following copyright and permission notices: -// -// Copyright 2023 Qredo Ltd. -// Licensed under the Apache License, Version 2.0; -// -// This file is part of the Warden Protocol library. -// -// The Warden Protocol library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the Warden Protocol library. If not, see https://github.com/warden-protocol/wardenprotocol/blob/main/LICENSE package keeper import ( @@ -23,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/warden-protocol/wardenprotocol/shield" "github.com/warden-protocol/wardenprotocol/shield/object" + "github.com/warden-protocol/wardenprotocol/warden/x/intent/cosmoshield" "github.com/warden-protocol/wardenprotocol/warden/x/intent/types" ) @@ -59,7 +44,7 @@ var _ shield.Environment = ApproversEnv{} // If the intent is satisfied, the action is marked as completed and true is // returned, the actual execution of the action is left for the caller. func (k Keeper) CheckActionReady(ctx sdk.Context, act types.Action) (bool, error) { - satisfied, err := act.Intent.Eval(ApproversEnv(act.Approvers)) + satisfied, err := act.Intent.Eval(ctx, ApproversEnv(act.Approvers)) if err != nil { return false, err } @@ -110,12 +95,21 @@ func (k Keeper) AddAction(ctx sdk.Context, creator string, msg sdk.Msg, intent t return nil, err } + ctxWithMsg := cosmoshield.NewContext(ctx, msg) + newDefinition, mentions, err := k.freezeIntent(ctxWithMsg, intent) + if err != nil { + return nil, err + } + + intent.Definition = newDefinition + // create action object timestamp := k.getBlockTime(ctx) act := &types.Action{ Status: types.ActionStatus_ACTION_STATUS_PENDING, Approvers: nil, Intent: intent, + Mentions: mentions, Msg: wrappedMsg, Creator: creator, Btl: btl, diff --git a/warden/x/intent/keeper/actions_keeper.go b/warden/x/intent/keeper/actions_keeper.go index c393de357..a862a198b 100644 --- a/warden/x/intent/keeper/actions_keeper.go +++ b/warden/x/intent/keeper/actions_keeper.go @@ -55,7 +55,7 @@ func (k ActionKeeper) New(ctx sdk.Context, action *types.Action) (uint64, error) return 0, err } - for _, addr := range action.Intent.Addresses { + for _, addr := range action.Mentions { key := collections.Join(sdk.MustAccAddressFromBech32(addr), id) if err := k.actionByAddress.Set(ctx, key, id); err != nil { return 0, err diff --git a/warden/x/intent/keeper/intents.go b/warden/x/intent/keeper/intents.go index 529fc367d..34a9255a2 100644 --- a/warden/x/intent/keeper/intents.go +++ b/warden/x/intent/keeper/intents.go @@ -1,10 +1,51 @@ package keeper import ( + "context" + "sort" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/warden-protocol/wardenprotocol/shield" + "github.com/warden-protocol/wardenprotocol/shield/ast" "github.com/warden-protocol/wardenprotocol/warden/x/intent/types" ) func (k Keeper) GetIntent(ctx sdk.Context, id uint64) (types.Intent, error) { return k.intents.Get(ctx, id) } + +func (k *Keeper) freezeIntent(ctx context.Context, intent types.Intent) (string, []string, error) { + expander := k.shieldExpanderFunc() + + rootAst, err := shield.Parse(ctx, intent.Definition, expander) + if err != nil { + return "", nil, err + } + + metadata, err := shield.ExtractMetadata(rootAst) + if err != nil { + return "", nil, err + } + + // map addresses into bech32 strings + addresses := resolveAddresses(metadata.Identifiers) + addressesBech32 := make([]string, 0, len(addresses)) + for _, addr := range addresses { + addressesBech32 = append(addressesBech32, addr.String()) + } + sort.Strings(addressesBech32) + + return ast.Stringify(rootAst), addressesBech32, nil +} + +// resolveAddresses filters a list of string by returning only the ones that are valid bech32 addresses. +func resolveAddresses(identifiers []string) []sdk.AccAddress { + addresses := make([]sdk.AccAddress, 0, len(identifiers)) + for _, ident := range identifiers { + addr, err := sdk.AccAddressFromBech32(ident) + if err == nil { + addresses = append(addresses, addr) + } + } + return addresses +} diff --git a/warden/x/intent/keeper/keeper.go b/warden/x/intent/keeper/keeper.go index b0a5a8c98..5074d0fde 100644 --- a/warden/x/intent/keeper/keeper.go +++ b/warden/x/intent/keeper/keeper.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/warden-protocol/wardenprotocol/shield/ast" "github.com/warden-protocol/wardenprotocol/warden/repo" "github.com/warden-protocol/wardenprotocol/warden/x/intent/types" ) @@ -20,6 +21,8 @@ type ( storeService store.KVStoreService logger log.Logger + shieldExpanderFunc func() ast.Expander + ActionKeeper ActionKeeper intents repo.SeqCollection[types.Intent] @@ -41,7 +44,7 @@ func NewKeeper( storeService store.KVStoreService, logger log.Logger, authority string, - + shieldExpanderFunc func() ast.Expander, ) Keeper { if _, err := sdk.AccAddressFromBech32(authority); err != nil { panic(fmt.Sprintf("invalid authority address: %s", authority)) @@ -64,6 +67,8 @@ func NewKeeper( authority: authority, logger: logger, + shieldExpanderFunc: shieldExpanderFunc, + ActionKeeper: newActionKeeper(storeService, cdc), intents: intents, diff --git a/warden/x/intent/keeper/msg_server_new_intent.go b/warden/x/intent/keeper/msg_server_new_intent.go index 0e6c07482..a7c2d041a 100644 --- a/warden/x/intent/keeper/msg_server_new_intent.go +++ b/warden/x/intent/keeper/msg_server_new_intent.go @@ -4,26 +4,18 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/warden-protocol/wardenprotocol/shield" "github.com/warden-protocol/wardenprotocol/warden/x/intent/types" ) func (k msgServer) NewIntent(goCtx context.Context, msg *types.MsgNewIntent) (*types.MsgNewIntentResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - metadata, err := shield.Validate(msg.Definition) - if err != nil { - return nil, err - } - - addresses := extractAddresses(metadata.Identifiers) - intentPb := types.Intent{ Creator: msg.Creator, Name: msg.Name, Definition: msg.Definition, - Addresses: addresses, } + id, err := k.intents.Append(ctx, &intentPb) if err != nil { return nil, err @@ -33,16 +25,3 @@ func (k msgServer) NewIntent(goCtx context.Context, msg *types.MsgNewIntent) (*t Id: id, }, nil } - -// extractAddresses filters a list of string by returning only the ones that are valid bech32 addresses. -func extractAddresses(identifiers []string) []string { - addresses := make([]string, 0, len(identifiers)) - for _, identifier := range identifiers { - _, err := sdk.AccAddressFromBech32(identifier) - if err != nil { - continue - } - addresses = append(addresses, identifier) - } - return addresses -} diff --git a/warden/x/intent/keeper/query_actions_by_address_test.go b/warden/x/intent/keeper/query_actions_by_address_test.go index 33880cd8a..e7de0ecfe 100644 --- a/warden/x/intent/keeper/query_actions_by_address_test.go +++ b/warden/x/intent/keeper/query_actions_by_address_test.go @@ -29,9 +29,9 @@ func Benchmark_QueryActionsByAddress(b *testing.B) { &types.Action{ Intent: types.Intent{ Id: uint64(i), - Addresses: []string{ - addr, - }, + }, + Mentions: []string{ + addr, }, }, ) diff --git a/warden/x/intent/migrations/v2/store.go b/warden/x/intent/migrations/v2/store.go index 34bc16676..13132be6c 100644 --- a/warden/x/intent/migrations/v2/store.go +++ b/warden/x/intent/migrations/v2/store.go @@ -1,88 +1,11 @@ package v2 import ( - "fmt" - - "cosmossdk.io/collections" "cosmossdk.io/core/store" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/warden-protocol/wardenprotocol/warden/repo" - "github.com/warden-protocol/wardenprotocol/warden/x/intent/types" -) - -var ( - ActionPrefix = collections.NewPrefix(0) - IntentPrefix = collections.NewPrefix(1) ) func MigrateStore(ctx sdk.Context, storeService store.KVStoreService, cdc codec.BinaryCodec) error { - sb := collections.NewSchemaBuilder(storeService) - actionsStore := collections.NewMap(sb, ActionPrefix, "action", collections.Uint64Key, codec.CollValue[types.Action](cdc)) - actionsCount := collections.NewSequence(sb, types.KeyPrefix(types.ActionCountKey), "actions_count") - actions := repo.NewSeqCollection(actionsCount, actionsStore, func(a *types.Action, u uint64) { a.Id = u }) - - intentsStore := collections.NewMap(sb, IntentPrefix, "intent", collections.Uint64Key, codec.CollValue[types.Intent](cdc)) - intentsCount := collections.NewSequence(sb, types.KeyPrefix(types.IntentCountKey), "intents_count") - intents := repo.NewSeqCollection(intentsCount, intentsStore, func(i *types.Intent, u uint64) { i.Id = u }) - - // delete all intents - intentsIter, err := intents.Iterate(ctx, nil) - if err != nil { - return err - } - defer intentsIter.Close() - - intentsKeys, err := intentsIter.Keys() - if err != nil { - return fmt.Errorf("failed to get intents keys: %w", err) - } - - for _, key := range intentsKeys { - err := intents.Remove(ctx, key) - if err != nil { - return fmt.Errorf("failed to remove intent: %w", err) - } - } - - if err := intentsCount.Set(ctx, 1); err != nil { - return fmt.Errorf("failed to set intents count: %w", err) - } - - // if an action was referring an intent, mark it as failed - actionsIter, err := actions.Iterate(ctx, nil) - if err != nil { - return err - } - defer actionsIter.Close() - - for ; actionsIter.Valid(); actionsIter.Next() { - action, err := actionsIter.Value() - if err != nil { - return fmt.Errorf("failed to get action: %w", err) - } - - clearAction(&action) - - err = actions.Set(ctx, action.Id, action) - if err != nil { - return fmt.Errorf("failed to set action: %w", err) - } - } - return nil } - -func clearAction(act *types.Action) { - act.Intent = types.Intent{ - Id: 0, - Creator: "", - Name: "removed during v0.2 upgrade", - Definition: "false", - Addresses: nil, - } - - if act.Status == types.ActionStatus_ACTION_STATUS_PENDING { - act.Status = types.ActionStatus_ACTION_STATUS_TIMEOUT - } -} diff --git a/warden/x/intent/module/module.go b/warden/x/intent/module/module.go index ecfb54c87..60f628ba0 100644 --- a/warden/x/intent/module/module.go +++ b/warden/x/intent/module/module.go @@ -21,6 +21,8 @@ import ( // this line is used by starport scaffolding # 1 modulev1 "github.com/warden-protocol/wardenprotocol/api/warden/intent/module" + "github.com/warden-protocol/wardenprotocol/shield/ast" + "github.com/warden-protocol/wardenprotocol/warden/x/intent/cosmoshield" "github.com/warden-protocol/wardenprotocol/warden/x/intent/keeper" "github.com/warden-protocol/wardenprotocol/warden/x/intent/types" ) @@ -185,6 +187,8 @@ type ModuleInputs struct { Config *modulev1.Module Logger log.Logger + ShieldExpanderFunc func() ast.Expander `optional:"true"` + AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper } @@ -202,11 +206,20 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { if in.Config.Authority != "" { authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority) } + + shieldExpanderFunc := func() ast.Expander { + return cosmoshield.NewExpanderManager() + } + if in.ShieldExpanderFunc != nil { + shieldExpanderFunc = in.ShieldExpanderFunc + } + k := keeper.NewKeeper( in.Cdc, in.StoreService, in.Logger, authority.String(), + shieldExpanderFunc, ) m := NewAppModule( in.Cdc, diff --git a/warden/x/intent/types/action.pb.go b/warden/x/intent/types/action.pb.go index 7fe32d929..083ee6410 100644 --- a/warden/x/intent/types/action.pb.go +++ b/warden/x/intent/types/action.pb.go @@ -145,6 +145,8 @@ type Action struct { // storing the intent ID, we store the entire intent object so that is // immutable and cannot be changed later. Intent Intent `protobuf:"bytes,11,opt,name=intent,proto3" json:"intent"` + // mentions is a list of addresses that are mentioned in the intent. + Mentions []string `protobuf:"bytes,12,rep,name=mentions,proto3" json:"mentions,omitempty"` } func (m *Action) Reset() { *m = Action{} } @@ -250,6 +252,13 @@ func (m *Action) GetIntent() Intent { return Intent{} } +func (m *Action) GetMentions() []string { + if m != nil { + return m.Mentions + } + return nil +} + // MsgActionCreated is returned by rpc that creates an action. type MsgActionCreated struct { Action *Action `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"` @@ -305,43 +314,44 @@ func init() { func init() { proto.RegisterFile("warden/intent/action.proto", fileDescriptor_e86b754e81df60ca) } var fileDescriptor_e86b754e81df60ca = []byte{ - // 564 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xcf, 0x6e, 0xd3, 0x4a, - 0x14, 0xc6, 0x33, 0x71, 0xae, 0xdb, 0x4c, 0x6e, 0x2b, 0x33, 0x6a, 0x55, 0x27, 0x15, 0x4e, 0x94, - 0x05, 0x8a, 0x2a, 0x6a, 0x4b, 0xa9, 0x58, 0x23, 0x27, 0x31, 0x60, 0x20, 0x7f, 0xe4, 0x38, 0x48, - 0xb0, 0x89, 0x9c, 0xd8, 0x18, 0x4b, 0x89, 0xc7, 0xb2, 0x27, 0x40, 0xde, 0xa2, 0x7b, 0x5e, 0x80, - 0x25, 0x8f, 0xd1, 0x1d, 0x5d, 0xb2, 0x02, 0x94, 0x2c, 0x78, 0x0d, 0xe4, 0x99, 0xb1, 0x20, 0x8e, - 0x84, 0xd4, 0x8d, 0x67, 0x8e, 0xbf, 0xdf, 0x39, 0x67, 0xce, 0x37, 0x36, 0xac, 0x7d, 0x70, 0x62, - 0xd7, 0x0b, 0xb5, 0x20, 0x24, 0x5e, 0x48, 0x34, 0x67, 0x4e, 0x02, 0x1c, 0xaa, 0x51, 0x8c, 0x09, - 0x46, 0x47, 0x4c, 0x53, 0x99, 0x56, 0xbb, 0xe7, 0x2c, 0x83, 0x10, 0x6b, 0xf4, 0xc9, 0x88, 0xda, - 0x89, 0x8f, 0x7d, 0x4c, 0xb7, 0x5a, 0xba, 0xe3, 0x6f, 0xab, 0x3e, 0xc6, 0xfe, 0xc2, 0xd3, 0x68, - 0x34, 0x5b, 0xbd, 0xd5, 0x9c, 0x70, 0xcd, 0xa5, 0x7a, 0x5e, 0x22, 0xc1, 0xd2, 0x4b, 0x88, 0xb3, - 0x8c, 0x38, 0x90, 0x3b, 0x0f, 0x5b, 0x98, 0xd6, 0x8c, 0xe0, 0xa1, 0x1e, 0x45, 0x31, 0x7e, 0xef, - 0xc5, 0x48, 0x86, 0x07, 0x8e, 0xeb, 0xc6, 0x5e, 0x92, 0xc8, 0xa0, 0x01, 0x5a, 0x65, 0x2b, 0x0b, - 0xd1, 0x73, 0x58, 0x71, 0x18, 0xe5, 0x4e, 0x1d, 0x22, 0x17, 0x1b, 0xa0, 0x55, 0x69, 0xd7, 0x54, - 0xd6, 0x58, 0xcd, 0x1a, 0xab, 0x76, 0xd6, 0xb8, 0x73, 0x74, 0xf3, 0xbd, 0x5e, 0xb8, 0xfe, 0x51, - 0x07, 0x9f, 0x7f, 0x7d, 0xb9, 0x00, 0x16, 0xcc, 0xb2, 0x75, 0xd2, 0xfc, 0x2a, 0x40, 0x51, 0xa7, - 0x96, 0xa0, 0x63, 0x58, 0x0c, 0x5c, 0xda, 0xab, 0x64, 0x15, 0x03, 0x17, 0x3d, 0x82, 0x65, 0x0e, - 0xc6, 0x89, 0x5c, 0x6c, 0x08, 0xad, 0x4a, 0xfb, 0x4c, 0xdd, 0x31, 0x4c, 0xcd, 0x0e, 0x6b, 0xfd, - 0x21, 0xd1, 0x15, 0x14, 0x13, 0xe2, 0x90, 0x55, 0x22, 0x0b, 0x0d, 0xd0, 0x3a, 0x6e, 0x9f, 0xe7, - 0x73, 0x68, 0xb7, 0x31, 0x45, 0x2c, 0x8e, 0xa2, 0x07, 0x50, 0x58, 0x26, 0xbe, 0xfc, 0x1f, 0x1d, - 0xe5, 0x64, 0x6f, 0x14, 0x3d, 0x5c, 0x5b, 0x29, 0x80, 0x1e, 0x42, 0x31, 0xf6, 0x92, 0xd5, 0x82, - 0xc8, 0xe2, 0x3f, 0x50, 0xce, 0xa4, 0x16, 0xce, 0x63, 0xcf, 0x21, 0x38, 0x96, 0x0f, 0x98, 0x85, - 0x3c, 0x44, 0x12, 0x14, 0x66, 0x64, 0x21, 0x1f, 0xd2, 0x61, 0xd3, 0x2d, 0x7a, 0x06, 0x21, 0x15, - 0x99, 0xa7, 0xe5, 0xbb, 0x7a, 0x5a, 0xe6, 0xc9, 0x3a, 0x49, 0x2b, 0xad, 0x22, 0x37, 0xab, 0x04, - 0xef, 0x5c, 0x89, 0x27, 0xeb, 0x24, 0xb5, 0x92, 0x99, 0x26, 0x57, 0x68, 0x95, 0xd3, 0x9c, 0x95, - 0x26, 0x5d, 0x3a, 0xa5, 0xb4, 0x80, 0xc5, 0xd1, 0xa6, 0x0e, 0xa5, 0x7e, 0xe2, 0x33, 0x97, 0xbb, - 0xec, 0x50, 0xe8, 0x12, 0x8a, 0xec, 0xbb, 0xa7, 0xd7, 0xbb, 0x5f, 0x88, 0xd1, 0x16, 0x87, 0x2e, - 0x3e, 0x01, 0xf8, 0xff, 0xdf, 0xd7, 0x84, 0xee, 0xc3, 0xaa, 0xde, 0xb5, 0xcd, 0xe1, 0x60, 0x3a, - 0xb6, 0x75, 0x7b, 0x32, 0x9e, 0x4e, 0x06, 0xe3, 0x91, 0xd1, 0x35, 0x9f, 0x98, 0x46, 0x4f, 0x2a, - 0xa0, 0x2a, 0x3c, 0xdd, 0x95, 0x47, 0xc6, 0xa0, 0x67, 0x0e, 0x9e, 0x4a, 0x00, 0x9d, 0xc3, 0xb3, - 0x5d, 0xa9, 0x3b, 0xec, 0x8f, 0x5e, 0x1a, 0xb6, 0xd1, 0x93, 0x8a, 0xfb, 0x79, 0x96, 0xf1, 0x6a, - 0xf8, 0xc2, 0xe8, 0x49, 0xc2, 0xbe, 0x64, 0x9b, 0x7d, 0x63, 0x38, 0xb1, 0xa5, 0x52, 0xe7, 0xf5, - 0xcd, 0x46, 0x01, 0xb7, 0x1b, 0x05, 0xfc, 0xdc, 0x28, 0xe0, 0x7a, 0xab, 0x14, 0x6e, 0xb7, 0x4a, - 0xe1, 0xdb, 0x56, 0x29, 0xbc, 0x79, 0xec, 0x07, 0xe4, 0xdd, 0x6a, 0xa6, 0xce, 0xf1, 0x52, 0x63, - 0x03, 0x5e, 0x52, 0xbf, 0xe7, 0x78, 0xc1, 0xe3, 0x5c, 0xa8, 0x7d, 0xcc, 0x7e, 0x43, 0xb2, 0x8e, - 0xbc, 0x64, 0x26, 0x52, 0xfd, 0xea, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x84, 0x7f, 0x10, 0xcf, - 0x34, 0x04, 0x00, 0x00, + // 581 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xcf, 0x6e, 0xd3, 0x4e, + 0x10, 0xc7, 0xe3, 0xb8, 0x3f, 0xb7, 0xd9, 0xb4, 0x95, 0x7f, 0xab, 0x56, 0x75, 0x52, 0xe1, 0x44, + 0x39, 0xa0, 0xa8, 0xa2, 0xb6, 0x94, 0x8a, 0x33, 0x72, 0x12, 0x03, 0x06, 0xf2, 0x47, 0x8e, 0x83, + 0x04, 0x97, 0xc8, 0x89, 0x8d, 0xb1, 0x14, 0x7b, 0x2d, 0xef, 0x06, 0xc8, 0x5b, 0xf4, 0xce, 0x0b, + 0x70, 0xe4, 0x31, 0x7a, 0xec, 0x91, 0x13, 0xa0, 0xe4, 0xc0, 0x81, 0x97, 0x40, 0xde, 0x5d, 0x03, + 0x49, 0x24, 0xa4, 0x5e, 0xe2, 0x9d, 0x7c, 0x3f, 0x33, 0xb3, 0xf3, 0x1d, 0x2d, 0xa8, 0xbe, 0x77, + 0x53, 0xcf, 0x8f, 0xf5, 0x30, 0x26, 0x7e, 0x4c, 0x74, 0x77, 0x46, 0x42, 0x14, 0x6b, 0x49, 0x8a, + 0x08, 0x82, 0x47, 0x4c, 0xd3, 0x98, 0x56, 0xfd, 0xdf, 0x8d, 0xc2, 0x18, 0xe9, 0xf4, 0x97, 0x11, + 0xd5, 0x93, 0x00, 0x05, 0x88, 0x1e, 0xf5, 0xec, 0xc4, 0xff, 0xad, 0x04, 0x08, 0x05, 0x73, 0x5f, + 0xa7, 0xd1, 0x74, 0xf1, 0x46, 0x77, 0xe3, 0x25, 0x97, 0x6a, 0xdb, 0x12, 0x09, 0x23, 0x1f, 0x13, + 0x37, 0x4a, 0x38, 0xb0, 0x75, 0x1f, 0xf6, 0x61, 0x5a, 0x23, 0x01, 0x07, 0x46, 0x92, 0xa4, 0xe8, + 0x9d, 0x9f, 0x42, 0x05, 0xec, 0xbb, 0x9e, 0x97, 0xfa, 0x18, 0x2b, 0x42, 0x5d, 0x68, 0x96, 0xec, + 0x3c, 0x84, 0xcf, 0x40, 0xd9, 0x65, 0x94, 0x37, 0x71, 0x89, 0x52, 0xac, 0x0b, 0xcd, 0x72, 0xab, + 0xaa, 0xb1, 0xc6, 0x5a, 0xde, 0x58, 0x73, 0xf2, 0xc6, 0xed, 0xa3, 0x9b, 0xaf, 0xb5, 0xc2, 0xf5, + 0xb7, 0x9a, 0xf0, 0xe9, 0xc7, 0xe7, 0x0b, 0xc1, 0x06, 0x79, 0xb6, 0x41, 0x1a, 0x3f, 0x45, 0x20, + 0x19, 0xd4, 0x12, 0x78, 0x0c, 0x8a, 0xa1, 0x47, 0x7b, 0xed, 0xd9, 0xc5, 0xd0, 0x83, 0x0f, 0x41, + 0x89, 0x83, 0x29, 0x56, 0x8a, 0x75, 0xb1, 0x59, 0x6e, 0x9d, 0x69, 0x1b, 0x86, 0x69, 0xf9, 0x65, + 0xed, 0x3f, 0x24, 0xbc, 0x02, 0x12, 0x26, 0x2e, 0x59, 0x60, 0x45, 0xac, 0x0b, 0xcd, 0xe3, 0xd6, + 0xf9, 0x76, 0x0e, 0xed, 0x36, 0xa2, 0x88, 0xcd, 0x51, 0x78, 0x1f, 0x88, 0x11, 0x0e, 0x94, 0xff, + 0xe8, 0x28, 0x27, 0x3b, 0xa3, 0x18, 0xf1, 0xd2, 0xce, 0x00, 0xf8, 0x00, 0x48, 0xa9, 0x8f, 0x17, + 0x73, 0xa2, 0x48, 0xff, 0x40, 0x39, 0x93, 0x59, 0x38, 0x4b, 0x7d, 0x97, 0xa0, 0x54, 0xd9, 0x67, + 0x16, 0xf2, 0x10, 0xca, 0x40, 0x9c, 0x92, 0xb9, 0x72, 0x40, 0x87, 0xcd, 0x8e, 0xf0, 0x29, 0x00, + 0x54, 0x64, 0x9e, 0x96, 0xee, 0xea, 0x69, 0x89, 0x27, 0x1b, 0x24, 0xab, 0xb4, 0x48, 0xbc, 0xbc, + 0x12, 0xb8, 0x73, 0x25, 0x9e, 0x6c, 0x90, 0xcc, 0x4a, 0x66, 0x9a, 0x52, 0xa6, 0x55, 0x4e, 0xb7, + 0xac, 0xb4, 0xe8, 0xa7, 0xbd, 0x97, 0x15, 0xb0, 0x39, 0x0a, 0xab, 0xe0, 0x20, 0xf2, 0xe3, 0xcc, + 0x63, 0xac, 0x1c, 0xd6, 0xc5, 0x66, 0xc9, 0xfe, 0x1d, 0x37, 0x0c, 0x20, 0xf7, 0x70, 0xc0, 0x36, + 0xd0, 0x61, 0x17, 0x86, 0x97, 0x40, 0x62, 0x6f, 0x82, 0xae, 0x7e, 0xb7, 0x09, 0xa3, 0x6d, 0x0e, + 0x5d, 0x7c, 0x14, 0xc0, 0xe1, 0xdf, 0x2b, 0x84, 0xf7, 0x40, 0xc5, 0xe8, 0x38, 0xd6, 0xa0, 0x3f, + 0x19, 0x39, 0x86, 0x33, 0x1e, 0x4d, 0xc6, 0xfd, 0xd1, 0xd0, 0xec, 0x58, 0x8f, 0x2d, 0xb3, 0x2b, + 0x17, 0x60, 0x05, 0x9c, 0x6e, 0xca, 0x43, 0xb3, 0xdf, 0xb5, 0xfa, 0x4f, 0x64, 0x01, 0x9e, 0x83, + 0xb3, 0x4d, 0xa9, 0x33, 0xe8, 0x0d, 0x5f, 0x98, 0x8e, 0xd9, 0x95, 0x8b, 0xbb, 0x79, 0xb6, 0xf9, + 0x72, 0xf0, 0xdc, 0xec, 0xca, 0xe2, 0xae, 0xe4, 0x58, 0x3d, 0x73, 0x30, 0x76, 0xe4, 0xbd, 0xf6, + 0xab, 0x9b, 0x95, 0x2a, 0xdc, 0xae, 0x54, 0xe1, 0xfb, 0x4a, 0x15, 0xae, 0xd7, 0x6a, 0xe1, 0x76, + 0xad, 0x16, 0xbe, 0xac, 0xd5, 0xc2, 0xeb, 0x47, 0x41, 0x48, 0xde, 0x2e, 0xa6, 0xda, 0x0c, 0x45, + 0x3a, 0x1b, 0xf0, 0x92, 0xee, 0x62, 0x86, 0xe6, 0x3c, 0xde, 0x0a, 0xf5, 0x0f, 0xf9, 0x13, 0x25, + 0xcb, 0xc4, 0xc7, 0x53, 0x89, 0xea, 0x57, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x1e, 0x56, + 0xde, 0x50, 0x04, 0x00, 0x00, } func (m *Approver) Marshal() (dAtA []byte, err error) { @@ -402,6 +412,15 @@ func (m *Action) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Mentions) > 0 { + for iNdEx := len(m.Mentions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Mentions[iNdEx]) + copy(dAtA[i:], m.Mentions[iNdEx]) + i = encodeVarintAction(dAtA, i, uint64(len(m.Mentions[iNdEx]))) + i-- + dAtA[i] = 0x62 + } + } { size, err := m.Intent.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -591,6 +610,12 @@ func (m *Action) Size() (n int) { n += 1 + l + sovAction(uint64(l)) l = m.Intent.Size() n += 1 + l + sovAction(uint64(l)) + if len(m.Mentions) > 0 { + for _, s := range m.Mentions { + l = len(s) + n += 1 + l + sovAction(uint64(l)) + } + } return n } @@ -1051,6 +1076,38 @@ func (m *Action) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Mentions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAction + } + 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 ErrInvalidLengthAction + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Mentions = append(m.Mentions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAction(dAtA[iNdEx:]) diff --git a/warden/x/intent/types/intent.go b/warden/x/intent/types/intent.go index 9c99e803e..fc46805e2 100644 --- a/warden/x/intent/types/intent.go +++ b/warden/x/intent/types/intent.go @@ -1,14 +1,18 @@ package types import ( + "context" "fmt" "github.com/warden-protocol/wardenprotocol/shield" "github.com/warden-protocol/wardenprotocol/shield/object" ) -func (i *Intent) Eval(env shield.Environment) (bool, error) { - obj, err := shield.Run(i.Definition, env) +func (i *Intent) Eval(ctx context.Context, env shield.Environment) (bool, error) { + // we pass `nil` as the expander because we don't need to preprocess the AST + // we assume that the AST was already preprocessed at the time of creation + // of the Action + obj, err := shield.Run(ctx, i.Definition, nil, env) if err != nil { return false, err } diff --git a/warden/x/intent/types/intent.pb.go b/warden/x/intent/types/intent.pb.go index 8d18e3862..0cbea6bcc 100644 --- a/warden/x/intent/types/intent.pb.go +++ b/warden/x/intent/types/intent.pb.go @@ -29,8 +29,6 @@ type Intent struct { Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // The definition of the intent written in the Shield language. Definition string `protobuf:"bytes,4,opt,name=definition,proto3" json:"definition,omitempty"` - // The list of addresses referenced from the intent definition. - Addresses []string `protobuf:"bytes,5,rep,name=addresses,proto3" json:"addresses,omitempty"` } func (m *Intent) Reset() { *m = Intent{} } @@ -94,13 +92,6 @@ func (m *Intent) GetDefinition() string { return "" } -func (m *Intent) GetAddresses() []string { - if m != nil { - return m.Addresses - } - return nil -} - func init() { proto.RegisterType((*Intent)(nil), "warden.intent.Intent") } @@ -108,22 +99,21 @@ func init() { func init() { proto.RegisterFile("warden/intent/intent.proto", fileDescriptor_b6f672f53323cb7c) } var fileDescriptor_b6f672f53323cb7c = []byte{ - // 239 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xb1, 0x4e, 0xc3, 0x30, - 0x10, 0x86, 0xe3, 0x34, 0x14, 0xe5, 0x24, 0x18, 0x3c, 0x99, 0x0a, 0x59, 0x11, 0x53, 0x16, 0xe2, - 0x81, 0x07, 0x40, 0x62, 0x63, 0xcd, 0x06, 0x9b, 0x13, 0x5f, 0x83, 0xa5, 0xd6, 0x57, 0x39, 0xae, - 0xa0, 0x3b, 0x0f, 0xc0, 0x63, 0x31, 0x76, 0x64, 0x44, 0xc9, 0x8b, 0x20, 0x39, 0x8d, 0x40, 0x4c, - 0xf6, 0xff, 0x7d, 0xff, 0x70, 0x77, 0xb0, 0x7a, 0xd5, 0xde, 0xa0, 0x53, 0xd6, 0x05, 0x74, 0xe1, - 0xf4, 0x54, 0x3b, 0x4f, 0x81, 0xf8, 0xc5, 0xe4, 0xaa, 0x09, 0xae, 0xae, 0x3a, 0xa2, 0x6e, 0x83, - 0x2a, 0xca, 0x66, 0xbf, 0x56, 0xda, 0x1d, 0xa6, 0xe6, 0xcd, 0x3b, 0x83, 0xe5, 0x63, 0x6c, 0xf1, - 0x4b, 0x48, 0xad, 0x11, 0xac, 0x60, 0x65, 0x56, 0xa7, 0xd6, 0x70, 0x01, 0xe7, 0xad, 0x47, 0x1d, - 0xc8, 0x8b, 0xb4, 0x60, 0x65, 0x5e, 0xcf, 0x91, 0x73, 0xc8, 0x9c, 0xde, 0xa2, 0x58, 0x44, 0x1c, - 0xff, 0x5c, 0x02, 0x18, 0x5c, 0x5b, 0x67, 0x83, 0x25, 0x27, 0xb2, 0x68, 0xfe, 0x10, 0x7e, 0x0d, - 0xb9, 0x36, 0xc6, 0x63, 0xdf, 0x63, 0x2f, 0xce, 0x8a, 0x45, 0x99, 0xd7, 0xbf, 0xe0, 0xe1, 0xe9, - 0x73, 0x90, 0xec, 0x38, 0x48, 0xf6, 0x3d, 0x48, 0xf6, 0x31, 0xca, 0xe4, 0x38, 0xca, 0xe4, 0x6b, - 0x94, 0xc9, 0xf3, 0x7d, 0x67, 0xc3, 0xcb, 0xbe, 0xa9, 0x5a, 0xda, 0xaa, 0x69, 0xab, 0xdb, 0x38, - 0x79, 0x4b, 0x9b, 0x53, 0xfe, 0x17, 0xd5, 0xdb, 0x7c, 0x92, 0x70, 0xd8, 0x61, 0xdf, 0x2c, 0xa3, - 0xbf, 0xfb, 0x09, 0x00, 0x00, 0xff, 0xff, 0xcd, 0x4b, 0x9f, 0x5d, 0x30, 0x01, 0x00, 0x00, + // 216 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2a, 0x4f, 0x2c, 0x4a, + 0x49, 0xcd, 0xd3, 0xcf, 0xcc, 0x2b, 0x49, 0xcd, 0x2b, 0x81, 0x52, 0x7a, 0x05, 0x45, 0xf9, 0x25, + 0xf9, 0x42, 0xbc, 0x10, 0x39, 0x3d, 0x88, 0xa0, 0x94, 0x64, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, + 0x3e, 0x58, 0x32, 0xa9, 0x34, 0x4d, 0x3f, 0x31, 0xaf, 0x12, 0xa2, 0x52, 0x29, 0x8d, 0x8b, 0xcd, + 0x13, 0xac, 0x48, 0x88, 0x8f, 0x8b, 0x29, 0x33, 0x45, 0x82, 0x51, 0x81, 0x51, 0x83, 0x25, 0x88, + 0x29, 0x33, 0x45, 0x48, 0x82, 0x8b, 0x3d, 0xb9, 0x28, 0x35, 0xb1, 0x24, 0xbf, 0x48, 0x82, 0x49, + 0x81, 0x51, 0x83, 0x33, 0x08, 0xc6, 0x15, 0x12, 0xe2, 0x62, 0xc9, 0x4b, 0xcc, 0x4d, 0x95, 0x60, + 0x06, 0x0b, 0x83, 0xd9, 0x42, 0x72, 0x5c, 0x5c, 0x29, 0xa9, 0x69, 0x99, 0x79, 0x99, 0x25, 0x99, + 0xf9, 0x79, 0x12, 0x2c, 0x60, 0x19, 0x24, 0x11, 0xa7, 0xc8, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, + 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, + 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, + 0x87, 0x38, 0x5b, 0x17, 0xec, 0xb4, 0xe4, 0xfc, 0x1c, 0x28, 0x1f, 0x8d, 0xab, 0x5f, 0x01, 0xf3, + 0x73, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x58, 0xde, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, + 0xa5, 0xc4, 0x64, 0x98, 0x11, 0x01, 0x00, 0x00, } func (m *Intent) Marshal() (dAtA []byte, err error) { @@ -146,15 +136,6 @@ func (m *Intent) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Addresses) > 0 { - for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Addresses[iNdEx]) - copy(dAtA[i:], m.Addresses[iNdEx]) - i = encodeVarintIntent(dAtA, i, uint64(len(m.Addresses[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } if len(m.Definition) > 0 { i -= len(m.Definition) copy(dAtA[i:], m.Definition) @@ -216,12 +197,6 @@ func (m *Intent) Size() (n int) { if l > 0 { n += 1 + l + sovIntent(uint64(l)) } - if len(m.Addresses) > 0 { - for _, s := range m.Addresses { - l = len(s) - n += 1 + l + sovIntent(uint64(l)) - } - } return n } @@ -375,38 +350,6 @@ func (m *Intent) Unmarshal(dAtA []byte) error { } m.Definition = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowIntent - } - 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 ErrInvalidLengthIntent - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthIntent - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Addresses = append(m.Addresses, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipIntent(dAtA[iNdEx:]) diff --git a/warden/x/warden/keeper/shield.go b/warden/x/warden/keeper/shield.go new file mode 100644 index 000000000..d396b017e --- /dev/null +++ b/warden/x/warden/keeper/shield.go @@ -0,0 +1,61 @@ +package keeper + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/warden-protocol/wardenprotocol/shield/ast" + "github.com/warden-protocol/wardenprotocol/warden/x/intent/cosmoshield" +) + +var _ ast.Expander = WardenShieldExpander{} + +type WardenShieldExpander struct { + keeper Keeper +} + +func (w WardenShieldExpander) Expand(goCtx context.Context, ident *ast.Identifier) (ast.Expression, error) { + if ident.Value == "space.owners" { + ctx := cosmoshield.UnwrapContext(goCtx) + msg := ctx.Msg() + + spaceID, err := extractSpaceID(msg) + if err != nil { + return nil, err + } + + space, err := w.keeper.SpacesKeeper.Get(ctx, spaceID) + if err != nil { + return nil, err + } + + owners := make([]ast.Expression, 0, len(space.Owners)) + for _, owner := range space.Owners { + owners = append(owners, ast.NewIdent(owner)) + } + + return &ast.ArrayLiteral{ + Elements: owners, + }, nil + } + + return nil, fmt.Errorf("unknown identifier: %s", ident.Value) +} + +type getSpaceIder interface { + GetSpaceId() uint64 +} + +func extractSpaceID(msg sdk.Msg) (uint64, error) { + if msg, ok := msg.(getSpaceIder); ok { + return msg.GetSpaceId(), nil + } + return 0, fmt.Errorf("message does not have a SpaceId field") +} + +func (k Keeper) ShieldExpander() ast.Expander { + return WardenShieldExpander{ + keeper: k, + } +} diff --git a/warden/x/warden/keeper/spaces.go b/warden/x/warden/keeper/spaces.go index a0bf2cc24..813b6366a 100644 --- a/warden/x/warden/keeper/spaces.go +++ b/warden/x/warden/keeper/spaces.go @@ -1,6 +1,7 @@ package keeper import ( + "context" "fmt" "cosmossdk.io/collections" @@ -27,11 +28,11 @@ func NewSpacesKeeper(sb *collections.SchemaBuilder, cdc codec.BinaryCodec) Space } } -func (k SpacesKeeper) Get(ctx sdk.Context, id uint64) (types.Space, error) { +func (k SpacesKeeper) Get(ctx context.Context, id uint64) (types.Space, error) { return k.spaces.Get(ctx, id) } -func (k SpacesKeeper) New(ctx sdk.Context, space *types.Space) (uint64, error) { +func (k SpacesKeeper) New(ctx context.Context, space *types.Space) (uint64, error) { id, err := k.spaces.Append(ctx, space) if err != nil { return 0, err @@ -51,7 +52,7 @@ func (k SpacesKeeper) Set(ctx sdk.Context, space types.Space) error { return k.spaces.Set(ctx, space.Id, space) } -func (k SpacesKeeper) updateSpaceOwners(ctx sdk.Context, space types.Space) error { +func (k SpacesKeeper) updateSpaceOwners(ctx context.Context, space types.Space) error { id := space.Id if id == 0 { return fmt.Errorf("space id is not set") diff --git a/warden/x/warden/types/v1beta2/space.go b/warden/x/warden/types/v1beta2/space.go index b4780e470..6e76b8adc 100644 --- a/warden/x/warden/types/v1beta2/space.go +++ b/warden/x/warden/types/v1beta2/space.go @@ -18,7 +18,6 @@ package v1beta2 import ( "fmt" - "strings" intenttypes "github.com/warden-protocol/wardenprotocol/warden/x/intent/types" ) @@ -83,10 +82,8 @@ func (w *Space) IntentUpdateSpace() intenttypes.Intent { // AnyOwnerIntent returns a intent that is satisfied when at least one of the owners of the space approves. func (w *Space) AnyOwnerIntent() intenttypes.Intent { - def := fmt.Sprintf(`any(1, [%s])`, strings.Join(w.Owners, ",")) return intenttypes.Intent{ Name: "AnyOwner", - Definition: def, - Addresses: w.Owners, + Definition: "any(1, warden.space.owners)", } }