Skip to content

Commit

Permalink
[Keystone] Merge version field with ID
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryNguyen5 committed May 8, 2024
1 parent c503b3c commit 1ec01be
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 48 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ require (
go.uber.org/goleak v1.2.1
go.uber.org/zap v1.26.0
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/mod v0.14.0
google.golang.org/grpc v1.58.3
google.golang.org/protobuf v1.31.0
)
Expand Down
30 changes: 19 additions & 11 deletions pkg/capabilities/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"errors"
"fmt"
"regexp"
"strings"
"time"

p2ptypes "github.com/smartcontractkit/libocr/ragep2p/types"
"golang.org/x/mod/semver"

"github.com/smartcontractkit/chainlink-common/pkg/values"
)
Expand Down Expand Up @@ -176,16 +176,31 @@ type CapabilityInfo struct {
ID string
CapabilityType CapabilityType
Description string
Version string
DON *DON
}

// Parse out the version from the ID.
func (c CapabilityInfo) Version() string {
return c.ID[strings.Index(c.ID, "@")+1:]
}

// Info returns the info of the capability.
func (c CapabilityInfo) Info(ctx context.Context) (CapabilityInfo, error) {
return c, nil
}

var idRegex = regexp.MustCompile(`[a-z0-9_\-:]`)
// This regex allows for the following format:
//
// {name}:{label1_key}_{labe1_value}:{label2_key}_{label2_value}@{version}
//
// The version regex is taken from https://semver.org/, but has been modified to support only major versions.
//
// It is also validated when a workflow is being ingested. See the following link for more details:
// https://github.com/smartcontractkit/chainlink/blob/a0d1ce5e9cddc540bba8eb193865646cf0ebc0a8/core/services/workflows/models_yaml.go#L309
//
// The difference between the regex within the link above and this one is that we do not use double backslashes, since
// we only needed those for JSON schema regex validation.
var idRegex = regexp.MustCompile(`^[a-z0-9_\-:]+@(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`)

const (
// TODO: this length was largely picked arbitrarily.
Expand All @@ -199,7 +214,6 @@ func NewCapabilityInfo(
id string,
capabilityType CapabilityType,
description string,
version string,
don *DON,
) (CapabilityInfo, error) {
if len(id) > idMaxLength {
Expand All @@ -209,10 +223,6 @@ func NewCapabilityInfo(
return CapabilityInfo{}, fmt.Errorf("invalid id: %s. Allowed: %s", id, idRegex)
}

if ok := semver.IsValid(version); !ok {
return CapabilityInfo{}, fmt.Errorf("invalid version: %+v", version)
}

if err := capabilityType.IsValid(); err != nil {
return CapabilityInfo{}, err
}
Expand All @@ -221,7 +231,6 @@ func NewCapabilityInfo(
ID: id,
CapabilityType: capabilityType,
Description: description,
Version: version,
DON: don,
}, nil
}
Expand All @@ -232,10 +241,9 @@ func MustNewCapabilityInfo(
id string,
capabilityType CapabilityType,
description string,
version string,
don *DON,
) CapabilityInfo {
c, err := NewCapabilityInfo(id, capabilityType, description, version, don)
c, err := NewCapabilityInfo(id, capabilityType, description, don)
if err != nil {
panic(err)
}
Expand Down
59 changes: 49 additions & 10 deletions pkg/capabilities/capabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,52 @@ import (

func Test_CapabilityInfo(t *testing.T) {
ci, err := NewCapabilityInfo(
"capability-id",
"capability-id@1",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
"v1.0.0",
nil,
)
require.NoError(t, err)

gotCi, err := ci.Info(tests.Context(t))
require.NoError(t, err)
require.Equal(t, ci.Version(), "1")
assert.Equal(t, ci, gotCi)

ci, err = NewCapabilityInfo(
// add build metadata and sha
"capability-id@1+build.1234.sha-5678",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
nil,
)
require.NoError(t, err)

gotCi, err = ci.Info(tests.Context(t))
require.NoError(t, err)
require.Equal(t, ci.Version(), "1+build.1234.sha-5678")
assert.Equal(t, ci, gotCi)

// prerelease
ci, err = NewCapabilityInfo(
"capability-id@1-beta",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
nil,
)
require.NoError(t, err)

gotCi, err = ci.Info(tests.Context(t))
require.NoError(t, err)
require.Equal(t, ci.Version(), "1-beta")
assert.Equal(t, ci, gotCi)
}

func Test_CapabilityInfo_Invalid(t *testing.T) {
_, err := NewCapabilityInfo(
"capability-id",
"capability-id@2",
CapabilityType(5),
"This is a mock capability that doesn't do anything.",
"v1.0.0",
nil,
)
assert.ErrorContains(t, err, "invalid capability type")
Expand All @@ -42,25 +69,38 @@ func Test_CapabilityInfo_Invalid(t *testing.T) {
"&!!!",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
"v1.0.0",
nil,
)
assert.ErrorContains(t, err, "invalid id")

_, err = NewCapabilityInfo(
"mock-capability",
"mock-capability@v1",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
nil,
)
assert.ErrorContains(t, err, "invalid id")

_, err = NewCapabilityInfo(
"mock-capability@1.0",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
nil,
)
assert.ErrorContains(t, err, "invalid id")

_, err = NewCapabilityInfo(
"mock-capability@1.0.1",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
"hello",
nil,
)
assert.ErrorContains(t, err, "invalid version")

assert.ErrorContains(t, err, "invalid id")
_, err = NewCapabilityInfo(
strings.Repeat("n", 256),
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
"hello",
nil,
)
assert.ErrorContains(t, err, "exceeds max length 128")
Expand Down Expand Up @@ -192,7 +232,6 @@ func Test_MustNewCapabilityInfo(t *testing.T) {
"capability-id",
CapabilityTypeAction,
"This is a mock capability that doesn't do anything.",
"should-panic",
nil,
)
})
Expand Down
3 changes: 1 addition & 2 deletions pkg/capabilities/consensus/ocr3/capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ import (
)

const (
ocrCapabilityID = "offchain_reporting"
ocrCapabilityID = "offchain_reporting@1"
)

var info = capabilities.MustNewCapabilityInfo(
ocrCapabilityID,
capabilities.CapabilityTypeConsensus,
"OCR3 consensus exposed as a capability.",
"v1.0.0",
nil,
)

Expand Down
4 changes: 2 additions & 2 deletions pkg/capabilities/testdata/fixtures/validator/schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/smartcontractkit/chainlink/capabilities/test/root",
"$id": "https://github.com/smartcontractkit/chainlink/capabilities/test@1/root",
"properties": {
"config": {
"properties": {
Expand Down Expand Up @@ -84,4 +84,4 @@
"outputs"
],
"description": "test description"
}
}
3 changes: 1 addition & 2 deletions pkg/capabilities/triggers/mercury_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ import (
)

var mercuryInfo = capabilities.MustNewCapabilityInfo(
"mercury-trigger",
"mercury-trigger@1",
capabilities.CapabilityTypeTrigger,
"An example mercury trigger.",
"v1.0.0",
nil,
)

Expand Down
3 changes: 1 addition & 2 deletions pkg/capabilities/triggers/on_demand_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import (
)

var info = capabilities.MustNewCapabilityInfo(
"on-demand-trigger",
"on-demand-trigger@1",
capabilities.CapabilityTypeTrigger,
"An example on-demand trigger.",
"v1.0.0",
nil,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/smartcontractkit/chainlink/capabilities/on-demand-trigger/root",
"$id": "https://github.com/smartcontractkit/chainlink/capabilities/on-demand-trigger@1/root",
"properties": {
"config": {
"properties": {},
Expand Down
3 changes: 1 addition & 2 deletions pkg/capabilities/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,9 @@ func TestValidator_ValidateOutputs(t *testing.T) {

func TestValidator_GenerateSchema(t *testing.T) {
capInfo := CapabilityInfo{
ID: "test",
ID: "test@1",
CapabilityType: CapabilityTypeTrigger,
Description: "test description",
Version: "1.0.0",
}
v := NewValidator[TestConfig, TestInputs, TestOutputs](ValidatorArgs{Info: capInfo})
schema, err := v.Schema()
Expand Down
2 changes: 0 additions & 2 deletions pkg/loop/internal/core/services/capability/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ func (c *baseCapabilityServer) Info(ctx context.Context, request *emptypb.Empty)
Id: info.ID,
CapabilityType: ct,
Description: info.Description,
Version: info.Version,
}, nil
}

Expand Down Expand Up @@ -173,7 +172,6 @@ func (c *baseCapabilityClient) Info(ctx context.Context) (capabilities.Capabilit
ID: resp.Id,
CapabilityType: ct,
Description: resp.Description,
Version: resp.Version,
}, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,9 @@ func TestCapabilitiesRegistry(t *testing.T) {

// Add capability Trigger
triggerInfo := capabilities.CapabilityInfo{
ID: "trigger-1",
ID: "trigger-1@1",
CapabilityType: capabilities.CapabilityTypeTrigger,
Description: "trigger-1-description",
Version: "trigger-1-version",
}
testTrigger := mockTriggerCapability{
mockBaseCapability: &mockBaseCapability{info: triggerInfo},
Expand Down Expand Up @@ -217,10 +216,9 @@ func TestCapabilitiesRegistry(t *testing.T) {

// Add capability Trigger
actionInfo := capabilities.CapabilityInfo{
ID: "action-1",
ID: "action-1@2",
CapabilityType: capabilities.CapabilityTypeAction,
Description: "action-1-description",
Version: "action-1-version",
}

actionCallbackChan := make(chan capabilities.CapabilityResponse, 10)
Expand Down Expand Up @@ -254,10 +252,9 @@ func TestCapabilitiesRegistry(t *testing.T) {

// Add capability Consensus
consensusInfo := capabilities.CapabilityInfo{
ID: "consensus-1",
ID: "consensus-1@3",
CapabilityType: capabilities.CapabilityTypeConsensus,
Description: "consensus-1-description",
Version: "consensus-1-version",
}
testConsensus := mockConsensusCapability{
mockBaseCapability: &mockBaseCapability{info: consensusInfo},
Expand All @@ -271,10 +268,9 @@ func TestCapabilitiesRegistry(t *testing.T) {

// Add capability Target
targetInfo := capabilities.CapabilityInfo{
ID: "target-1",
ID: "target-1@1",
CapabilityType: capabilities.CapabilityTypeTarget,
Description: "target-1-description",
Version: "target-1-version",
}
testTarget := mockTargetCapability{
mockBaseCapability: &mockBaseCapability{info: targetInfo},
Expand All @@ -293,5 +289,5 @@ func testCapabilityInfo(t *testing.T, expectedInfo capabilities.CapabilityInfo,
require.Equal(t, expectedInfo.ID, gotInfo.ID)
require.Equal(t, expectedInfo.CapabilityType, gotInfo.CapabilityType)
require.Equal(t, expectedInfo.Description, gotInfo.Description)
require.Equal(t, expectedInfo.Version, gotInfo.Version)
require.Equal(t, expectedInfo.Version(), gotInfo.Version())
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (m *mockTrigger) Stop() {

func mustMockTrigger(t *testing.T) *mockTrigger {
return &mockTrigger{
BaseCapability: capabilities.MustNewCapabilityInfo("trigger", capabilities.CapabilityTypeTrigger, "a mock trigger", "v0.0.1", nil),
BaseCapability: capabilities.MustNewCapabilityInfo("trigger@1", capabilities.CapabilityTypeTrigger, "a mock trigger", nil),
callback: make(chan capabilities.CapabilityResponse, 10),
unregisterCalls: make(chan bool, 10),
registerCalls: make(chan bool, 10),
Expand Down Expand Up @@ -99,7 +99,7 @@ func (m *mockCallback) Execute(ctx context.Context, request capabilities.Capabil

func mustMockCallback(t *testing.T, _type capabilities.CapabilityType) *mockCallback {
return &mockCallback{
BaseCapability: capabilities.MustNewCapabilityInfo(fmt.Sprintf("callback %s", _type), _type, fmt.Sprintf("a mock %s", _type), "v0.0.1", nil),
BaseCapability: capabilities.MustNewCapabilityInfo(fmt.Sprintf("callback-%s@1", _type), _type, fmt.Sprintf("a mock %s", _type), nil),
callback: make(chan capabilities.CapabilityResponse),
}
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/loop/internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ var (
GetConsensusID = "get-consensus-id"
GetTargetID = "get-target-id"
CapabilityInfo = capabilities.CapabilityInfo{
ID: "capability-info-id",
ID: "capability-info-id@1",
CapabilityType: 2,
Description: "capability-info-description",
Version: "capability-info-version",
}
)

Expand Down

0 comments on commit 1ec01be

Please sign in to comment.