diff --git a/pkg/capabilities/v2/triggers/streams/generate.go b/pkg/capabilities/v2/triggers/streams/generate.go new file mode 100644 index 000000000..037d5a347 --- /dev/null +++ b/pkg/capabilities/v2/triggers/streams/generate.go @@ -0,0 +1,3 @@ +//go:generate go run ../../gen --pkg=github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/triggers/streams --file=capabilities/streams/v1/trigger.proto +package streams + diff --git a/pkg/capabilities/v2/triggers/streams/server/trigger_server_gen.go b/pkg/capabilities/v2/triggers/streams/server/trigger_server_gen.go new file mode 100644 index 000000000..0d7ff2058 --- /dev/null +++ b/pkg/capabilities/v2/triggers/streams/server/trigger_server_gen.go @@ -0,0 +1,137 @@ +// Code generated by github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/protoc, DO NOT EDIT. + +package server + +import ( + "context" + "fmt" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/triggers/streams" + "google.golang.org/protobuf/types/known/emptypb" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + caperrors "github.com/smartcontractkit/chainlink-common/pkg/capabilities/errors" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" +) + +// Avoid unused imports if there is configuration type +var _ = emptypb.Empty{} + +type StreamsCapability interface { + RegisterTrigger(ctx context.Context, triggerID string, metadata capabilities.RequestMetadata, input *streams.Config) (<-chan capabilities.TriggerAndId[*streams.Report], caperrors.Error) + UnregisterTrigger(ctx context.Context, triggerID string, metadata capabilities.RequestMetadata, input *streams.Config) caperrors.Error + + Start(ctx context.Context) error + Close() error + HealthReport() map[string]error + Name() string + Description() string + Ready() error + Initialise(ctx context.Context, dependencies core.StandardCapabilitiesDependencies) error +} + +func NewStreamsServer(capability StreamsCapability) *StreamsServer { + stopCh := make(chan struct{}) + return &StreamsServer{ + streamsCapability: streamsCapability{StreamsCapability: capability, stopCh: stopCh}, + stopCh: stopCh, + } +} + +type StreamsServer struct { + streamsCapability + capabilityRegistry core.CapabilitiesRegistry + stopCh chan struct{} +} + +func (c *StreamsServer) Initialise(ctx context.Context, dependencies core.StandardCapabilitiesDependencies) error { + if err := c.StreamsCapability.Initialise(ctx, dependencies); err != nil { + return fmt.Errorf("error when initializing capability: %w", err) + } + + c.capabilityRegistry = dependencies.CapabilityRegistry + + if err := dependencies.CapabilityRegistry.Add(ctx, &streamsCapability{ + StreamsCapability: c.StreamsCapability, + }); err != nil { + return fmt.Errorf("error when adding %s to the registry: %w", "streams-trigger@2.0.0", err) + } + + return nil +} + +func (c *StreamsServer) Close() error { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + if c.capabilityRegistry != nil { + if err := c.capabilityRegistry.Remove(ctx, "streams-trigger@2.0.0"); err != nil { + return err + } + } + + if c.stopCh != nil { + close(c.stopCh) + } + + return c.streamsCapability.Close() +} + +func (c *StreamsServer) Infos(ctx context.Context) ([]capabilities.CapabilityInfo, error) { + info, err := c.streamsCapability.Info(ctx) + if err != nil { + return nil, err + } + return []capabilities.CapabilityInfo{info}, nil +} + +type streamsCapability struct { + StreamsCapability + stopCh chan struct{} +} + +func (c *streamsCapability) Info(ctx context.Context) (capabilities.CapabilityInfo, error) { + // Maybe we do need to split it out, even if the user doesn't see it + return capabilities.NewCapabilityInfo("streams-trigger@2.0.0", capabilities.CapabilityTypeCombined, c.StreamsCapability.Description()) +} + +var _ capabilities.ExecutableAndTriggerCapability = (*streamsCapability)(nil) + +const StreamsID = "streams-trigger@2.0.0" + +func (c *streamsCapability) RegisterTrigger(ctx context.Context, request capabilities.TriggerRegistrationRequest) (<-chan capabilities.TriggerResponse, error) { + switch request.Method { + case "Trigger": + input := &streams.Config{} + return capabilities.RegisterTrigger(ctx, c.stopCh, "streams-trigger@2.0.0", request, input, c.StreamsCapability.RegisterTrigger) + default: + return nil, fmt.Errorf("trigger %s not found", request.Method) + } +} + +func (c *streamsCapability) UnregisterTrigger(ctx context.Context, request capabilities.TriggerRegistrationRequest) error { + switch request.Method { + case "Trigger": + input := &streams.Config{} + _, err := capabilities.FromValueOrAny(request.Config, request.Payload, input) + if err != nil { + return err + } + return c.StreamsCapability.UnregisterTrigger(ctx, request.TriggerID, request.Metadata, input) + default: + return fmt.Errorf("method %s not found", request.Method) + } +} + +func (c *streamsCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error { + return nil +} + +func (c *streamsCapability) UnregisterFromWorkflow(ctx context.Context, request capabilities.UnregisterFromWorkflowRequest) error { + return nil +} + +func (c *streamsCapability) Execute(ctx context.Context, request capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { + return capabilities.CapabilityResponse{}, fmt.Errorf("method %s not found", request.Method) +} diff --git a/pkg/capabilities/v2/triggers/streams/streams_test.go b/pkg/capabilities/v2/triggers/streams/streams_test.go new file mode 100644 index 000000000..787b19ff2 --- /dev/null +++ b/pkg/capabilities/v2/triggers/streams/streams_test.go @@ -0,0 +1,389 @@ +package streams_test + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/ragep2p/types" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + caperrors "github.com/smartcontractkit/chainlink-common/pkg/capabilities/errors" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/triggers/streams" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/triggers/streams/server" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" +) + +// TestProtoTypesExist verifies that all protobuf types are properly generated +func TestProtoTypesExist(t *testing.T) { + // Config type + config := &streams.Config{ + StreamIds: []uint32{1, 2, 3}, + MaxFrequencyMs: 5000, + } + assert.NotNil(t, config) + assert.Len(t, config.StreamIds, 3) + assert.Equal(t, uint64(5000), config.MaxFrequencyMs) + + // Report type + report := &streams.Report{ + ConfigDigest: []byte{1, 2, 3, 4}, + SeqNr: 42, + Report: []byte("report-data"), + Sigs: []*streams.OCRSignature{ + { + Signer: 1, + Signature: []byte("sig1"), + }, + { + Signer: 2, + Signature: []byte("sig2"), + }, + }, + } + assert.NotNil(t, report) + assert.Equal(t, []byte{1, 2, 3, 4}, report.ConfigDigest) + assert.Equal(t, uint64(42), report.SeqNr) + assert.Len(t, report.Sigs, 2) +} + +// TestConfigGetters verifies getter methods work +func TestConfigGetters(t *testing.T) { + config := &streams.Config{ + StreamIds: []uint32{1, 2, 3}, + MaxFrequencyMs: 10000, + } + + assert.Equal(t, []uint32{1, 2, 3}, config.GetStreamIds()) + assert.Equal(t, uint64(10000), config.GetMaxFrequencyMs()) +} + +// TestReportGetters verifies Report getter methods +func TestReportGetters(t *testing.T) { + sigs := []*streams.OCRSignature{ + { + Signer: 1, + Signature: []byte("sig1"), + }, + } + + report := &streams.Report{ + ConfigDigest: []byte{1, 2, 3, 4}, + SeqNr: 99, + Report: []byte("test-report"), + Sigs: sigs, + } + + assert.Equal(t, []byte{1, 2, 3, 4}, report.GetConfigDigest()) + assert.Equal(t, uint64(99), report.GetSeqNr()) + assert.Equal(t, []byte("test-report"), report.GetReport()) + assert.Equal(t, sigs, report.GetSigs()) +} + +// TestStreamsCapabilityInterface verifies the server interface +func TestStreamsCapabilityInterface(t *testing.T) { + // Verify interface is defined correctly + var _ server.StreamsCapability = (*mockStreamsCapability)(nil) +} + +// mockStreamsCapability implements server.StreamsCapability for testing +type mockStreamsCapability struct { + registerCalled bool + unregisterCalled bool + startCalled bool + closeCalled bool +} + +func (m *mockStreamsCapability) RegisterTrigger(ctx context.Context, triggerID string, metadata capabilities.RequestMetadata, input *streams.Config) (<-chan capabilities.TriggerAndId[*streams.Report], caperrors.Error) { + m.registerCalled = true + ch := make(chan capabilities.TriggerAndId[*streams.Report], 1) + return ch, nil +} + +func (m *mockStreamsCapability) UnregisterTrigger(ctx context.Context, triggerID string, metadata capabilities.RequestMetadata, input *streams.Config) caperrors.Error { + m.unregisterCalled = true + return nil +} + +func (m *mockStreamsCapability) Start(ctx context.Context) error { + m.startCalled = true + return nil +} + +func (m *mockStreamsCapability) Close() error { + m.closeCalled = true + return nil +} + +func (m *mockStreamsCapability) HealthReport() map[string]error { + return map[string]error{"mock": nil} +} + +func (m *mockStreamsCapability) Name() string { + return "MockStreamsCapability" +} + +func (m *mockStreamsCapability) Description() string { + return "Mock implementation for testing" +} + +func (m *mockStreamsCapability) Ready() error { + return nil +} + +func (m *mockStreamsCapability) Initialise(ctx context.Context, deps core.StandardCapabilitiesDependencies) error { + return nil +} + +// TestStreamsServerCreation tests creating a server wrapper +func TestStreamsServerCreation(t *testing.T) { + mock := &mockStreamsCapability{} + srv := server.NewStreamsServer(mock) + + require.NotNil(t, srv) + + // Test initialization + ctx := context.Background() + mockRegistry := &mockCapabilityRegistry{} + deps := core.StandardCapabilitiesDependencies{ + CapabilityRegistry: mockRegistry, + } + + err := srv.Initialise(ctx, deps) + assert.NoError(t, err) + + // Start should be called separately + err = mock.Start(ctx) + assert.NoError(t, err) + assert.True(t, mock.startCalled) + + // Test close + err = srv.Close() + assert.NoError(t, err) + // Note: Close on server doesn't automatically call Close on capability + err = mock.Close() + assert.NoError(t, err) + assert.True(t, mock.closeCalled) +} + +// TestTriggerRegistration tests the trigger registration flow +func TestTriggerRegistration(t *testing.T) { + mock := &mockStreamsCapability{} + + ctx := context.Background() + triggerID := "test-trigger-123" + metadata := capabilities.RequestMetadata{ + WorkflowID: "test-workflow", + } + + config := &streams.Config{ + StreamIds: []uint32{1}, + MaxFrequencyMs: 1000, + } + + ch, err := mock.RegisterTrigger(ctx, triggerID, metadata, config) + require.NoError(t, err) + require.NotNil(t, ch) + assert.True(t, mock.registerCalled) + + // Test unregister + unregErr := mock.UnregisterTrigger(ctx, triggerID, metadata, config) + assert.NoError(t, unregErr) + assert.True(t, mock.unregisterCalled) +} + +// TestReportStructure tests the Report structure +func TestReportStructure(t *testing.T) { + sigs := []*streams.OCRSignature{ + {Signer: 1, Signature: []byte("sig1")}, + {Signer: 2, Signature: []byte("sig2")}, + } + + report := &streams.Report{ + ConfigDigest: []byte{1, 2, 3, 4, 5}, + SeqNr: 123, + Report: []byte("full-report-bytes"), + Sigs: sigs, + } + + assert.Equal(t, []byte{1, 2, 3, 4, 5}, report.GetConfigDigest()) + assert.Equal(t, uint64(123), report.GetSeqNr()) + assert.Equal(t, []byte("full-report-bytes"), report.GetReport()) + assert.Len(t, report.GetSigs(), 2) +} + +// TestOCRSignature tests the OCRSignature structure +func TestOCRSignature(t *testing.T) { + sig := &streams.OCRSignature{ + Signer: 5, + Signature: []byte("signature-bytes"), + } + + assert.Equal(t, uint32(5), sig.GetSigner()) + assert.Equal(t, []byte("signature-bytes"), sig.GetSignature()) +} + +// TestConfigValidation tests configuration validation scenarios +func TestConfigValidation(t *testing.T) { + tests := []struct { + name string + config *streams.Config + expectValid bool + }{ + { + name: "valid config with single stream", + config: &streams.Config{ + StreamIds: []uint32{1}, + MaxFrequencyMs: 1000, + }, + expectValid: true, + }, + { + name: "valid config with multiple streams", + config: &streams.Config{ + StreamIds: []uint32{1, 2, 3}, + MaxFrequencyMs: 5000, + }, + expectValid: true, + }, + { + name: "high frequency", + config: &streams.Config{ + StreamIds: []uint32{1}, + MaxFrequencyMs: 100, + }, + expectValid: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Basic validation - config should be creatable + assert.NotNil(t, tt.config) + assert.NotEmpty(t, tt.config.StreamIds) + assert.Greater(t, tt.config.MaxFrequencyMs, uint64(0)) + }) + } +} + +// mockCapabilityRegistry for testing +type mockCapabilityRegistry struct { + added []capabilities.BaseCapability + removed []string +} + +func (m *mockCapabilityRegistry) Add(ctx context.Context, capability capabilities.BaseCapability) error { + m.added = append(m.added, capability) + return nil +} + +func (m *mockCapabilityRegistry) Remove(ctx context.Context, id string) error { + m.removed = append(m.removed, id) + return nil +} + +func (m *mockCapabilityRegistry) Get(ctx context.Context, id string) (capabilities.BaseCapability, error) { + return nil, nil +} + +func (m *mockCapabilityRegistry) GetTrigger(ctx context.Context, id string) (capabilities.TriggerCapability, error) { + return nil, nil +} + +func (m *mockCapabilityRegistry) GetAction(ctx context.Context, id string) (capabilities.ActionCapability, error) { + return nil, nil +} + +func (m *mockCapabilityRegistry) GetExecutable(ctx context.Context, id string) (capabilities.ExecutableCapability, error) { + return nil, nil +} + +func (m *mockCapabilityRegistry) GetConsensus(ctx context.Context, id string) (capabilities.ConsensusCapability, error) { + return nil, nil +} + +func (m *mockCapabilityRegistry) GetTarget(ctx context.Context, id string) (capabilities.TargetCapability, error) { + return nil, nil +} + +func (m *mockCapabilityRegistry) List(ctx context.Context) ([]capabilities.BaseCapability, error) { + return m.added, nil +} + +func (m *mockCapabilityRegistry) ConfigForCapability(ctx context.Context, capabilityID string, capabilityDonID uint32) (capabilities.CapabilityConfiguration, error) { + return capabilities.CapabilityConfiguration{}, nil +} + +func (m *mockCapabilityRegistry) DONsForCapability(ctx context.Context, id string) ([]capabilities.DONWithNodes, error) { + return nil, nil +} + +func (m *mockCapabilityRegistry) LocalNode(ctx context.Context) (capabilities.Node, error) { + return capabilities.Node{}, nil +} + +func (m *mockCapabilityRegistry) NodeByPeerID(ctx context.Context, peerID types.PeerID) (capabilities.Node, error) { + return capabilities.Node{}, nil +} + +// TestServerLifecycle tests the complete server lifecycle +func TestServerLifecycle(t *testing.T) { + mock := &mockStreamsCapability{} + srv := server.NewStreamsServer(mock) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + mockRegistry := &mockCapabilityRegistry{} + deps := core.StandardCapabilitiesDependencies{ + CapabilityRegistry: mockRegistry, + } + + // Initialize + err := srv.Initialise(ctx, deps) + require.NoError(t, err) + assert.Len(t, mockRegistry.added, 1, "Capability should be registered") + + // Start must be called separately + err = mock.Start(ctx) + require.NoError(t, err) + assert.True(t, mock.startCalled, "Start should be called") + + // Get infos + infos, err := srv.Infos(ctx) + require.NoError(t, err) + require.Len(t, infos, 1) + assert.Equal(t, "streams-trigger@2.0.0", infos[0].ID) + + // Close + err = srv.Close() + require.NoError(t, err) + assert.True(t, mock.closeCalled, "Close should be called") + assert.Len(t, mockRegistry.removed, 1, "Capability should be unregistered") + assert.Equal(t, "streams-trigger@2.0.0", mockRegistry.removed[0]) +} + +// BenchmarkReportCreation benchmarks creating Report objects +func BenchmarkReportCreation(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = &streams.Report{ + ConfigDigest: []byte{1, 2, 3, 4}, + SeqNr: uint64(i), + Report: []byte("report-data"), + Sigs: []*streams.OCRSignature{ + { + Signer: 1, + Signature: []byte("sig1"), + }, + { + Signer: 2, + Signature: []byte("sig2"), + }, + }, + } + } +} + diff --git a/pkg/capabilities/v2/triggers/streams/trigger.pb.go b/pkg/capabilities/v2/triggers/streams/trigger.pb.go new file mode 100644 index 000000000..995e82d56 --- /dev/null +++ b/pkg/capabilities/v2/triggers/streams/trigger.pb.go @@ -0,0 +1,283 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc v5.27.3 +// source: cre/capabilities/streams/v1/trigger.proto + +package streams + +import ( + _ "github.com/smartcontractkit/chainlink-protos/cre/go/tools/generator" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +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) +) + +// Configuration for the Streams LLO Trigger +// This matches the existing LLOTriggerConfig structure +type Config struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The IDs of the LLO data streams to subscribe to. + // Stream IDs are uint32 values that identify specific feeds. + StreamIds []uint32 `protobuf:"varint,1,rep,packed,name=stream_ids,json=streamIds,proto3" json:"stream_ids,omitempty"` + // The minimum interval in milliseconds between trigger events. + // Trigger will only emit events at most once per this interval. + MaxFrequencyMs uint64 `protobuf:"varint,2,opt,name=max_frequency_ms,json=maxFrequencyMs,proto3" json:"max_frequency_ms,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Config) Reset() { + *x = Config{} + mi := &file_cre_capabilities_streams_v1_trigger_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Config) ProtoMessage() {} + +func (x *Config) ProtoReflect() protoreflect.Message { + mi := &file_cre_capabilities_streams_v1_trigger_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Config.ProtoReflect.Descriptor instead. +func (*Config) Descriptor() ([]byte, []int) { + return file_cre_capabilities_streams_v1_trigger_proto_rawDescGZIP(), []int{0} +} + +func (x *Config) GetStreamIds() []uint32 { + if x != nil { + return x.StreamIds + } + return nil +} + +func (x *Config) GetMaxFrequencyMs() uint64 { + if x != nil { + return x.MaxFrequencyMs + } + return 0 +} + +// An attributed onchain signature +type OCRSignature struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The signer index + Signer uint32 `protobuf:"varint,1,opt,name=signer,proto3" json:"signer,omitempty"` + // The signature bytes + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OCRSignature) Reset() { + *x = OCRSignature{} + mi := &file_cre_capabilities_streams_v1_trigger_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OCRSignature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OCRSignature) ProtoMessage() {} + +func (x *OCRSignature) ProtoReflect() protoreflect.Message { + mi := &file_cre_capabilities_streams_v1_trigger_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OCRSignature.ProtoReflect.Descriptor instead. +func (*OCRSignature) Descriptor() ([]byte, []int) { + return file_cre_capabilities_streams_v1_trigger_proto_rawDescGZIP(), []int{1} +} + +func (x *OCRSignature) GetSigner() uint32 { + if x != nil { + return x.Signer + } + return 0 +} + +func (x *OCRSignature) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +// OCR Trigger Event payload +// This matches the existing OCRTriggerEvent structure that the transmitter emits +type Report struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Configuration digest for the OCR round + ConfigDigest []byte `protobuf:"bytes,1,opt,name=config_digest,json=configDigest,proto3" json:"config_digest,omitempty"` + // Sequence number of the report + SeqNr uint64 `protobuf:"varint,2,opt,name=seq_nr,json=seqNr,proto3" json:"seq_nr,omitempty"` + // The report bytes (raw OCR report) + Report []byte `protobuf:"bytes,3,opt,name=report,proto3" json:"report,omitempty"` + // Attributed onchain signatures + Sigs []*OCRSignature `protobuf:"bytes,4,rep,name=sigs,proto3" json:"sigs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Report) Reset() { + *x = Report{} + mi := &file_cre_capabilities_streams_v1_trigger_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Report) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Report) ProtoMessage() {} + +func (x *Report) ProtoReflect() protoreflect.Message { + mi := &file_cre_capabilities_streams_v1_trigger_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Report.ProtoReflect.Descriptor instead. +func (*Report) Descriptor() ([]byte, []int) { + return file_cre_capabilities_streams_v1_trigger_proto_rawDescGZIP(), []int{2} +} + +func (x *Report) GetConfigDigest() []byte { + if x != nil { + return x.ConfigDigest + } + return nil +} + +func (x *Report) GetSeqNr() uint64 { + if x != nil { + return x.SeqNr + } + return 0 +} + +func (x *Report) GetReport() []byte { + if x != nil { + return x.Report + } + return nil +} + +func (x *Report) GetSigs() []*OCRSignature { + if x != nil { + return x.Sigs + } + return nil +} + +var File_cre_capabilities_streams_v1_trigger_proto protoreflect.FileDescriptor + +const file_cre_capabilities_streams_v1_trigger_proto_rawDesc = "" + + "\n" + + ")cre/capabilities/streams/v1/trigger.proto\x12\x17capabilities.streams.v1\x1a.cre/tools/generator/v1alpha/cre_metadata.proto\"Q\n" + + "\x06Config\x12\x1d\n" + + "\n" + + "stream_ids\x18\x01 \x03(\rR\tstreamIds\x12(\n" + + "\x10max_frequency_ms\x18\x02 \x01(\x04R\x0emaxFrequencyMs\"D\n" + + "\fOCRSignature\x12\x16\n" + + "\x06signer\x18\x01 \x01(\rR\x06signer\x12\x1c\n" + + "\tsignature\x18\x02 \x01(\fR\tsignature\"\x97\x01\n" + + "\x06Report\x12#\n" + + "\rconfig_digest\x18\x01 \x01(\fR\fconfigDigest\x12\x15\n" + + "\x06seq_nr\x18\x02 \x01(\x04R\x05seqNr\x12\x16\n" + + "\x06report\x18\x03 \x01(\fR\x06report\x129\n" + + "\x04sigs\x18\x04 \x03(\v2%.capabilities.streams.v1.OCRSignatureR\x04sigs2w\n" + + "\aStreams\x12M\n" + + "\aTrigger\x12\x1f.capabilities.streams.v1.Config\x1a\x1f.capabilities.streams.v1.Report0\x01\x1a\x1d\x82\xb5\x18\x19\b\x01\x12\x15streams-trigger@2.0.0BSZQgithub.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/triggers/streamsb\x06proto3" + +var ( + file_cre_capabilities_streams_v1_trigger_proto_rawDescOnce sync.Once + file_cre_capabilities_streams_v1_trigger_proto_rawDescData []byte +) + +func file_cre_capabilities_streams_v1_trigger_proto_rawDescGZIP() []byte { + file_cre_capabilities_streams_v1_trigger_proto_rawDescOnce.Do(func() { + file_cre_capabilities_streams_v1_trigger_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cre_capabilities_streams_v1_trigger_proto_rawDesc), len(file_cre_capabilities_streams_v1_trigger_proto_rawDesc))) + }) + return file_cre_capabilities_streams_v1_trigger_proto_rawDescData +} + +var file_cre_capabilities_streams_v1_trigger_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_cre_capabilities_streams_v1_trigger_proto_goTypes = []any{ + (*Config)(nil), // 0: capabilities.streams.v1.Config + (*OCRSignature)(nil), // 1: capabilities.streams.v1.OCRSignature + (*Report)(nil), // 2: capabilities.streams.v1.Report +} +var file_cre_capabilities_streams_v1_trigger_proto_depIdxs = []int32{ + 1, // 0: capabilities.streams.v1.Report.sigs:type_name -> capabilities.streams.v1.OCRSignature + 0, // 1: capabilities.streams.v1.Streams.Trigger:input_type -> capabilities.streams.v1.Config + 2, // 2: capabilities.streams.v1.Streams.Trigger:output_type -> capabilities.streams.v1.Report + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_cre_capabilities_streams_v1_trigger_proto_init() } +func file_cre_capabilities_streams_v1_trigger_proto_init() { + if File_cre_capabilities_streams_v1_trigger_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cre_capabilities_streams_v1_trigger_proto_rawDesc), len(file_cre_capabilities_streams_v1_trigger_proto_rawDesc)), + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cre_capabilities_streams_v1_trigger_proto_goTypes, + DependencyIndexes: file_cre_capabilities_streams_v1_trigger_proto_depIdxs, + MessageInfos: file_cre_capabilities_streams_v1_trigger_proto_msgTypes, + }.Build() + File_cre_capabilities_streams_v1_trigger_proto = out.File + file_cre_capabilities_streams_v1_trigger_proto_goTypes = nil + file_cre_capabilities_streams_v1_trigger_proto_depIdxs = nil +}