From 6630cc4d025a12ef2a1bb3eceb2e6b25b80b173b Mon Sep 17 00:00:00 2001 From: Sam Davies Date: Fri, 21 Feb 2025 10:24:14 -0500 Subject: [PATCH] Add trigger proto for Data Streams; add ReportFormatCapabilityTrigger --- pkg/capabilities/pb/generate.go | 1 + pkg/capabilities/pb/triggers.pb.go | 340 +++++++++++++++++++++++++++++ pkg/capabilities/pb/triggers.proto | 26 +++ pkg/types/llo/types.go | 9 + 4 files changed, 376 insertions(+) create mode 100644 pkg/capabilities/pb/triggers.pb.go create mode 100644 pkg/capabilities/pb/triggers.proto diff --git a/pkg/capabilities/pb/generate.go b/pkg/capabilities/pb/generate.go index d5b793172..c8372ac39 100644 --- a/pkg/capabilities/pb/generate.go +++ b/pkg/capabilities/pb/generate.go @@ -1,3 +1,4 @@ //go:generate protoc --go_out=../../ --go_opt=paths=source_relative --go-grpc_out=../../ --go-grpc_opt=paths=source_relative --proto_path=../../ capabilities/pb/capabilities.proto values/pb/values.proto //go:generate protoc --go_out=../../ --go_opt=paths=source_relative --go-grpc_out=../../ --go-grpc_opt=paths=source_relative --proto_path=../../ capabilities/pb/registry.proto values/pb/values.proto +//go:generate protoc --go_out=../../ --go_opt=paths=source_relative --go-grpc_out=../../ --go-grpc_opt=paths=source_relative --proto_path=../../ capabilities/pb/triggers.proto values/pb/values.proto package pb diff --git a/pkg/capabilities/pb/triggers.pb.go b/pkg/capabilities/pb/triggers.pb.go new file mode 100644 index 000000000..382cb8e26 --- /dev/null +++ b/pkg/capabilities/pb/triggers.pb.go @@ -0,0 +1,340 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.25.1 +// source: capabilities/pb/triggers.proto + +package pb + +import ( + pb "github.com/smartcontractkit/chainlink-common/pkg/values/pb" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type OCRTriggerEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ConfigDigest []byte `protobuf:"bytes,1,opt,name=configDigest,proto3" json:"configDigest,omitempty"` + SeqNr uint64 `protobuf:"varint,2,opt,name=seqNr,proto3" json:"seqNr,omitempty"` + Report []byte `protobuf:"bytes,3,opt,name=report,proto3" json:"report,omitempty"` // marshalled OCRTriggerReport + Sigs []*OCRAttributedOnchainSignature `protobuf:"bytes,4,rep,name=sigs,proto3" json:"sigs,omitempty"` +} + +func (x *OCRTriggerEvent) Reset() { + *x = OCRTriggerEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_capabilities_pb_triggers_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCRTriggerEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCRTriggerEvent) ProtoMessage() {} + +func (x *OCRTriggerEvent) ProtoReflect() protoreflect.Message { + mi := &file_capabilities_pb_triggers_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCRTriggerEvent.ProtoReflect.Descriptor instead. +func (*OCRTriggerEvent) Descriptor() ([]byte, []int) { + return file_capabilities_pb_triggers_proto_rawDescGZIP(), []int{0} +} + +func (x *OCRTriggerEvent) GetConfigDigest() []byte { + if x != nil { + return x.ConfigDigest + } + return nil +} + +func (x *OCRTriggerEvent) GetSeqNr() uint64 { + if x != nil { + return x.SeqNr + } + return 0 +} + +func (x *OCRTriggerEvent) GetReport() []byte { + if x != nil { + return x.Report + } + return nil +} + +func (x *OCRTriggerEvent) GetSigs() []*OCRAttributedOnchainSignature { + if x != nil { + return x.Sigs + } + return nil +} + +type OCRAttributedOnchainSignature struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` + // signer is actually a uint8 but uint32 is the smallest supported by protobuf + Signer uint32 `protobuf:"varint,2,opt,name=signer,proto3" json:"signer,omitempty"` +} + +func (x *OCRAttributedOnchainSignature) Reset() { + *x = OCRAttributedOnchainSignature{} + if protoimpl.UnsafeEnabled { + mi := &file_capabilities_pb_triggers_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCRAttributedOnchainSignature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCRAttributedOnchainSignature) ProtoMessage() {} + +func (x *OCRAttributedOnchainSignature) ProtoReflect() protoreflect.Message { + mi := &file_capabilities_pb_triggers_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCRAttributedOnchainSignature.ProtoReflect.Descriptor instead. +func (*OCRAttributedOnchainSignature) Descriptor() ([]byte, []int) { + return file_capabilities_pb_triggers_proto_rawDescGZIP(), []int{1} +} + +func (x *OCRAttributedOnchainSignature) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +func (x *OCRAttributedOnchainSignature) GetSigner() uint32 { + if x != nil { + return x.Signer + } + return 0 +} + +type OCRTriggerReport struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EventID string `protobuf:"bytes,1,opt,name=eventID,proto3" json:"eventID,omitempty"` // unique, scoped to the trigger capability + Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // used to enforce freshness + Outputs *pb.Map `protobuf:"bytes,3,opt,name=outputs,proto3" json:"outputs,omitempty"` // contains trigger-specific data +} + +func (x *OCRTriggerReport) Reset() { + *x = OCRTriggerReport{} + if protoimpl.UnsafeEnabled { + mi := &file_capabilities_pb_triggers_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OCRTriggerReport) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCRTriggerReport) ProtoMessage() {} + +func (x *OCRTriggerReport) ProtoReflect() protoreflect.Message { + mi := &file_capabilities_pb_triggers_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCRTriggerReport.ProtoReflect.Descriptor instead. +func (*OCRTriggerReport) Descriptor() ([]byte, []int) { + return file_capabilities_pb_triggers_proto_rawDescGZIP(), []int{2} +} + +func (x *OCRTriggerReport) GetEventID() string { + if x != nil { + return x.EventID + } + return "" +} + +func (x *OCRTriggerReport) GetTimestamp() int64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *OCRTriggerReport) GetOutputs() *pb.Map { + if x != nil { + return x.Outputs + } + return nil +} + +var File_capabilities_pb_triggers_proto protoreflect.FileDescriptor + +var file_capabilities_pb_triggers_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f, 0x70, + 0x62, 0x2f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x02, 0x76, 0x31, 0x1a, 0x16, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x70, 0x62, 0x2f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, 0x01, 0x0a, + 0x0f, 0x4f, 0x43, 0x52, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x43, 0x52, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x52, 0x04, 0x73, 0x69, 0x67, 0x73, 0x22, 0x55, 0x0a, 0x1d, 0x4f, 0x43, 0x52, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, + 0x22, 0x71, 0x0a, 0x10, 0x4f, 0x43, 0x52, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x07, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x73, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, + 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2d, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_capabilities_pb_triggers_proto_rawDescOnce sync.Once + file_capabilities_pb_triggers_proto_rawDescData = file_capabilities_pb_triggers_proto_rawDesc +) + +func file_capabilities_pb_triggers_proto_rawDescGZIP() []byte { + file_capabilities_pb_triggers_proto_rawDescOnce.Do(func() { + file_capabilities_pb_triggers_proto_rawDescData = protoimpl.X.CompressGZIP(file_capabilities_pb_triggers_proto_rawDescData) + }) + return file_capabilities_pb_triggers_proto_rawDescData +} + +var file_capabilities_pb_triggers_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_capabilities_pb_triggers_proto_goTypes = []interface{}{ + (*OCRTriggerEvent)(nil), // 0: v1.OCRTriggerEvent + (*OCRAttributedOnchainSignature)(nil), // 1: v1.OCRAttributedOnchainSignature + (*OCRTriggerReport)(nil), // 2: v1.OCRTriggerReport + (*pb.Map)(nil), // 3: values.Map +} +var file_capabilities_pb_triggers_proto_depIdxs = []int32{ + 1, // 0: v1.OCRTriggerEvent.sigs:type_name -> v1.OCRAttributedOnchainSignature + 3, // 1: v1.OCRTriggerReport.outputs:type_name -> values.Map + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_capabilities_pb_triggers_proto_init() } +func file_capabilities_pb_triggers_proto_init() { + if File_capabilities_pb_triggers_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_capabilities_pb_triggers_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCRTriggerEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_capabilities_pb_triggers_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCRAttributedOnchainSignature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_capabilities_pb_triggers_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OCRTriggerReport); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_capabilities_pb_triggers_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_capabilities_pb_triggers_proto_goTypes, + DependencyIndexes: file_capabilities_pb_triggers_proto_depIdxs, + MessageInfos: file_capabilities_pb_triggers_proto_msgTypes, + }.Build() + File_capabilities_pb_triggers_proto = out.File + file_capabilities_pb_triggers_proto_rawDesc = nil + file_capabilities_pb_triggers_proto_goTypes = nil + file_capabilities_pb_triggers_proto_depIdxs = nil +} diff --git a/pkg/capabilities/pb/triggers.proto b/pkg/capabilities/pb/triggers.proto new file mode 100644 index 000000000..64cbbd62f --- /dev/null +++ b/pkg/capabilities/pb/triggers.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package v1; + +option go_package = "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"; + +import "values/pb/values.proto"; + +message OCRTriggerEvent { + bytes configDigest = 1; + uint64 seqNr = 2; + bytes report = 3; // marshalled OCRTriggerReport + repeated OCRAttributedOnchainSignature sigs = 4; +} + +message OCRAttributedOnchainSignature { + bytes signature = 1; + // signer is actually a uint8 but uint32 is the smallest supported by protobuf + uint32 signer = 2; +} + +message OCRTriggerReport { + string eventID = 1; // unique, scoped to the trigger capability + int64 timestamp = 2; // used to enforce freshness + values.Map outputs = 3; // contains trigger-specific data +} diff --git a/pkg/types/llo/types.go b/pkg/types/llo/types.go index e204c1e8d..f69143752 100644 --- a/pkg/types/llo/types.go +++ b/pkg/types/llo/types.go @@ -48,6 +48,9 @@ const ( // ReportFormatEVMABIEncodeUnpacked supports encoding reports with a fixed // schema followed by an arbitrary ABI-encoded payload ReportFormatEVMABIEncodeUnpacked = 4 + // ReportFormatCapabilityTrigger is a protobuf binary format compatible + // with CRE capability triggers + ReportFormatCapabilityTrigger = 5 _ ReportFormat = math.MaxUint32 // reserved ) @@ -56,6 +59,8 @@ var ReportFormats = []ReportFormat{ ReportFormatEVMPremiumLegacy, ReportFormatJSON, ReportFormatRetirement, + ReportFormatEVMABIEncodeUnpacked, + ReportFormatCapabilityTrigger, } func (rf ReportFormat) String() string { @@ -68,6 +73,8 @@ func (rf ReportFormat) String() string { return "retirement" case ReportFormatEVMABIEncodeUnpacked: return "evm_abi_encode_unpacked" + case ReportFormatCapabilityTrigger: + return "capability_trigger" default: return fmt.Sprintf("unknown(%d)", rf) } @@ -83,6 +90,8 @@ func ReportFormatFromString(s string) (ReportFormat, error) { return ReportFormatRetirement, nil case "evm_abi_encode_unpacked": return ReportFormatEVMABIEncodeUnpacked, nil + case "capability_trigger": + return ReportFormatCapabilityTrigger, nil default: return 0, fmt.Errorf("unknown report format: %q", s) }