Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cyan-ears-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

#change Add keystore service to standardcapabilities, refactor integration_tests/framework to use a p2p key in the test node
6 changes: 3 additions & 3 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ jobs:
if: github.event_name == 'pull_request' && needs.changes.outputs.should-run-cre-tests == 'true'
uses: smartcontractkit/chainlink/.github/workflows/cre-system-tests.yaml@53e6348b792989514a6b7b53745bfcc389f706d9 # 27th June 2025
with:
chainlink_version: test-${{ inputs.evm-ref || inputs.cl_ref || github.sha }}
chainlink_version: ${{ inputs.evm-ref || inputs.cl_ref || github.sha }}
chainlink_image_tag: test-${{ inputs.evm-ref && format('{0}-plugins', inputs.evm-ref) || inputs.cl_ref && format('{0}-plugins', inputs.cl_ref) || format('{0}-plugins', github.sha) }}
secrets: inherit

Expand Down Expand Up @@ -307,7 +307,7 @@ jobs:
if: github.event_name == 'push' && needs.changes.outputs.should-run-cre-tests == 'true'
uses: smartcontractkit/chainlink/.github/workflows/cre-system-tests.yaml@53e6348b792989514a6b7b53745bfcc389f706d9 # 27th June 2025
with:
chainlink_version: test-${{ inputs.evm-ref || inputs.cl_ref || github.sha }}
chainlink_version: ${{ inputs.evm-ref || inputs.cl_ref || github.sha }}
chainlink_image_tag: test-${{ inputs.evm-ref && format('{0}-plugins', inputs.evm-ref) || inputs.cl_ref && format('{0}-plugins', inputs.cl_ref) || format('{0}-plugins', github.sha) }}
secrets:
inherit
Expand All @@ -324,7 +324,7 @@ jobs:
if: github.event_name == 'workflow_dispatch'
uses: smartcontractkit/chainlink/.github/workflows/cre-system-tests.yaml@53e6348b792989514a6b7b53745bfcc389f706d9 # 27th June 2025
with:
chainlink_version: test-${{ inputs.evm-ref || inputs.cl_ref || github.sha }}
chainlink_version: ${{ inputs.evm-ref || inputs.cl_ref || github.sha }}
chainlink_image_tag: test-${{ inputs.evm-ref && format('{0}-plugins', inputs.evm-ref) || inputs.cl_ref && format('{0}-plugins', inputs.cl_ref) || format('{0}-plugins', github.sha) }}
secrets:
inherit
Expand Down
3 changes: 2 additions & 1 deletion core/capabilities/fakes/consensus_nodag.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func (fc *fakeConsensusNoDAG) Initialise(
_ core.PipelineRunnerService,
_ core.RelayerSet,
_ core.OracleFactory,
_ core.GatewayConnector) error {
_ core.GatewayConnector,
_ core.Keystore) error {
return nil
}
3 changes: 2 additions & 1 deletion core/capabilities/fakes/evm_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ func (fc *FakeEVMChain) Initialise(ctx context.Context, config string, _ core.Te
_ core.PipelineRunnerService,
_ core.RelayerSet,
_ core.OracleFactory,
_ core.GatewayConnector) error {
_ core.GatewayConnector,
_ core.Keystore) error {
// TODO: do validation of config here

err := fc.Start(ctx)
Expand Down
3 changes: 2 additions & 1 deletion core/capabilities/fakes/http_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ func (fh *DirectHTTPAction) Initialise(ctx context.Context, config string, _ cor
_ core.PipelineRunnerService,
_ core.RelayerSet,
_ core.OracleFactory,
_ core.GatewayConnector) error {
_ core.GatewayConnector,
_ core.Keystore) error {
// TODO: do validation of config here

err := fh.Start(ctx)
Expand Down
3 changes: 2 additions & 1 deletion core/capabilities/fakes/manual_cron_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ func (f *ManualCronTriggerService) Initialise(ctx context.Context, config string
_ core.PipelineRunnerService,
_ core.RelayerSet,
_ core.OracleFactory,
_ core.GatewayConnector) error {
_ core.GatewayConnector,
_ core.Keystore) error {
f.lggr.Debugf("Initialising %s", ServiceName)

var cronConfig ManualCronConfig
Expand Down
3 changes: 2 additions & 1 deletion core/capabilities/fakes/manual_http_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ func (f *ManualHTTPTriggerService) Initialise(ctx context.Context, config string
_ core.PipelineRunnerService,
_ core.RelayerSet,
_ core.OracleFactory,
_ core.GatewayConnector) error {
_ core.GatewayConnector,
_ core.Keystore) error {
f.lggr.Debugf("Initialising %s", HTTPTriggerServiceName)
return f.Start(ctx)
}
Expand Down
9 changes: 9 additions & 0 deletions core/capabilities/fakes/standard_capabilities_mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ func (k *KVStoreMock) Get(ctx context.Context, key string) ([]byte, error) {
return nil, nil
}

type KeystoreMock struct{}

func (k *KeystoreMock) Accounts(ctx context.Context) (accounts []string, err error) {
return nil, nil
}
func (k *KeystoreMock) Sign(ctx context.Context, account string, data []byte) (signed []byte, err error) {
return nil, nil
}

type ErrorLogMock struct{}

func (e *ErrorLogMock) SaveError(ctx context.Context, msg string) error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
"github.com/smartcontractkit/chainlink-common/pkg/values"
kcr "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"

"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -88,9 +89,14 @@ func (r *CapabilitiesRegistry) setupDON(donInfo DonConfiguration, capabilities [

r.backend.Commit()

peerIDs := make([][32]byte, 0, len(donInfo.p2pKeys))
nodes := []kcr.CapabilitiesRegistryNodeParams{}
for _, peerID := range donInfo.peerIDs {
n, innerErr := peerToNode(r.nodeOperatorID, peerID)
for i, p2pkey := range donInfo.p2pKeys {
signer, innerErr := getSignerStringFromOCRKeyBundle(donInfo.KeyBundles[i])
require.NoError(r.t, innerErr)
peer := peerIDAndOCRSigner{PeerID: p2ptypes.PeerID(p2pkey.PeerID()), Signer: signer}
peerIDs = append(peerIDs, p2pkey.PeerID())
n, innerErr := peerToNode(r.nodeOperatorID, peer)
require.NoError(r.t, innerErr)

n.HashedCapabilityIds = hashedCapabilityIDs
Expand All @@ -101,9 +107,6 @@ func (r *CapabilitiesRegistry) setupDON(donInfo DonConfiguration, capabilities [
require.NoError(r.t, err)
r.backend.Commit()

ps, err := peers(donInfo.peerIDs)
require.NoError(r.t, err)

var capabilityConfigurations []kcr.CapabilitiesRegistryCapabilityConfiguration
for i, c := range capabilities {
configBinary, err2 := proto.Marshal(c.donCapabilityConfig)
Expand All @@ -115,7 +118,7 @@ func (r *CapabilitiesRegistry) setupDON(donInfo DonConfiguration, capabilities [
})
}

_, err = r.contract.AddDON(r.backend.transactionOpts, ps, capabilityConfigurations, true, donInfo.AcceptsWorkflows, donInfo.F)
_, err = r.contract.AddDON(r.backend.transactionOpts, peerIDs, capabilityConfigurations, true, donInfo.AcceptsWorkflows, donInfo.F)
require.NoError(r.t, err)
r.backend.Commit()

Expand Down
22 changes: 12 additions & 10 deletions core/capabilities/integration_tests/framework/don.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ type capabilityNode struct {
registry *capabilities.Registry
key ethkey.KeyV2
KeyBundle ocr2key.KeyBundle
peerID peer
peer peerIDAndOCRSigner
start func()
}

Expand Down Expand Up @@ -164,11 +164,13 @@ func NewDON(ctx context.Context, t *testing.T, lggr logger.Logger, donConfig Don
CapabilityDONs: dependentDONs,
}

signer, err := getSignerStringFromOCRKeyBundle(donConfig.KeyBundles[i])
require.NoError(t, err)
cn := &capabilityNode{
registry: capabilityRegistry,
key: donConfig.keys[i],
KeyBundle: donConfig.KeyBundles[i],
peerID: donConfig.peerIDs[i],
peer: peerIDAndOCRSigner{PeerID: member, Signer: signer},
}
don.nodes = append(don.nodes, cn)

Expand All @@ -187,7 +189,7 @@ func NewDON(ctx context.Context, t *testing.T, lggr logger.Logger, donConfig Don
modifier(c, cn)
}
}, donContext.syncerFetcherFunc, donContext.computeFetcherFactory)

require.NoError(t, node.KeyStore.P2P().Add(ctx, donConfig.p2pKeys[i]))
require.NoError(t, node.Start(testutils.Context(t)))
cn.TestApplication = node
}
Expand Down Expand Up @@ -231,12 +233,8 @@ func (d *DON) GetExternalCapabilities() (map[CapabilityRegistration]bool, error)
}

for _, node := range d.nodes {
peerIDBytes, err := peerIDToBytes(node.peerID.PeerID)
if err != nil {
return nil, fmt.Errorf("failed to convert peer ID to bytes: %w", err)
}
result[CapabilityRegistration{
nodePeerID: hex.EncodeToString(peerIDBytes[:]),
nodePeerID: hex.EncodeToString(node.peer.PeerID[:]),
capabilityID: publishedCapability.registryConfig.LabelledName + "@" + publishedCapability.registryConfig.Version,
capabilityDonID: d.GetID(),
}] = true
Expand All @@ -254,8 +252,12 @@ func (d *DON) GetF() uint8 {
return d.config.F
}

func (d *DON) GetPeerIDs() []peer {
return d.config.peerIDs
func (d *DON) GetPeerIDsAndOCRSigners() []peerIDAndOCRSigner {
peers := make([]peerIDAndOCRSigner, 0, len(d.nodes))
for _, node := range d.nodes {
peers = append(peers, node.peer)
}
return peers
}

func (d *DON) Start(ctx context.Context) error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
)

Expand All @@ -15,7 +16,7 @@ type DonConfiguration struct {
name string
keys []ethkey.KeyV2
KeyBundles []ocr2key.KeyBundle
peerIDs []peer
p2pKeys []p2pkey.KeyV2
}

// NewDonConfigurationParams exists purely to make it obvious in the test code what DON configuration is being used
Expand All @@ -31,20 +32,15 @@ func NewDonConfiguration(don NewDonConfigurationParams) (DonConfiguration, error
return DonConfiguration{}, errors.New("invalid configuration, number of nodes must be at least 3*F+1")
}

keyBundles, peerIDs, err := getKeyBundlesAndPeerIDs(don.Name, don.NumNodes)
keyBundles, p2pKeys, err := getKeyBundlesAndP2PKeys(don.Name, don.NumNodes)
if err != nil {
return DonConfiguration{}, fmt.Errorf("failed to get key bundles and peer IDs: %w", err)
return DonConfiguration{}, fmt.Errorf("failed to get key bundles and p2p keys: %w", err)
}

donPeers := make([]p2ptypes.PeerID, len(peerIDs))
donPeers := make([]p2ptypes.PeerID, len(p2pKeys))
var donKeys []ethkey.KeyV2
for i := 0; i < len(peerIDs); i++ {
peerID := p2ptypes.PeerID{}
err = peerID.UnmarshalText([]byte(peerIDs[i].PeerID))
if err != nil {
return DonConfiguration{}, fmt.Errorf("failed to unmarshal peer ID: %w", err)
}
donPeers[i] = peerID
for i := 0; i < len(p2pKeys); i++ {
donPeers[i] = p2ptypes.PeerID(p2pKeys[i].PeerID())
newKey, err := ethkey.NewV2()
if err != nil {
return DonConfiguration{}, fmt.Errorf("failed to create key: %w", err)
Expand All @@ -60,7 +56,7 @@ func NewDonConfiguration(don NewDonConfigurationParams) (DonConfiguration, error
AcceptsWorkflows: don.AcceptsWorkflows,
},
name: don.Name,
peerIDs: peerIDs,
p2pKeys: p2pKeys,
keys: donKeys,
KeyBundles: keyBundles,
}
Expand Down
69 changes: 22 additions & 47 deletions core/capabilities/integration_tests/framework/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,26 @@ import (
"context"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"strings"

"github.com/mr-tron/base58"

ragetypes "github.com/smartcontractkit/libocr/ragep2p/types"

kcr "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
)

type peer struct {
PeerID string
type peerIDAndOCRSigner struct {
PeerID p2ptypes.PeerID
Signer string
}

func peerIDToBytes(peerID string) ([32]byte, error) {
var peerIDB ragetypes.PeerID
err := peerIDB.UnmarshalText([]byte(peerID))
if err != nil {
return [32]byte{}, err
}

return peerIDB, nil
}

func peers(ps []peer) ([][32]byte, error) {
out := [][32]byte{}
for _, p := range ps {
b, err := peerIDToBytes(p.PeerID)
if err != nil {
return nil, err
}

out = append(out, b)
}

return out, nil
}

func peerToNode(nopID uint32, p peer) (kcr.CapabilitiesRegistryNodeParams, error) {
peerIDB, err := peerIDToBytes(p.PeerID)
if err != nil {
return kcr.CapabilitiesRegistryNodeParams{}, fmt.Errorf("failed to convert peerID: %w", err)
}

func peerToNode(nopID uint32, p peerIDAndOCRSigner) (kcr.CapabilitiesRegistryNodeParams, error) {
sig := strings.TrimPrefix(p.Signer, "0x")
signerB, err := hex.DecodeString(sig)
if err != nil {
Expand All @@ -64,17 +35,20 @@ func peerToNode(nopID uint32, p peer) (kcr.CapabilitiesRegistryNodeParams, error

return kcr.CapabilitiesRegistryNodeParams{
NodeOperatorId: nopID,
P2pId: peerIDB,
P2pId: p.PeerID,
Signer: sigb,
EncryptionPublicKey: testutils.Random32Byte(),
}, nil
}

func getKeyBundlesAndPeerIDs(donName string, numNodes int) ([]ocr2key.KeyBundle, []peer, error) {
func getKeyBundlesAndP2PKeys(donName string, numNodes int) ([]ocr2key.KeyBundle, []p2pkey.KeyV2, error) {
var keyBundles []ocr2key.KeyBundle
var donPeerIDs []peer
var donPeerKeys []p2pkey.KeyV2
for i := 0; i < numNodes; i++ {
peerID := NewPeerID(donName, i)
key, err := p2pkey.NewV2()
if err != nil {
return nil, nil, fmt.Errorf("failed to create p2p key: %w", err)
}

keyBundle, err := ocr2key.New(chaintype.EVM)
if err != nil {
Expand All @@ -83,16 +57,9 @@ func getKeyBundlesAndPeerIDs(donName string, numNodes int) ([]ocr2key.KeyBundle,

keyBundles = append(keyBundles, keyBundle)

pk := keyBundle.PublicKey()

p := peer{
PeerID: peerID,
Signer: fmt.Sprintf("0x%x", pk),
}

donPeerIDs = append(donPeerIDs, p)
donPeerKeys = append(donPeerKeys, key)
}
return keyBundles, donPeerIDs, nil
return keyBundles, donPeerKeys, nil
}

type peerWrapper struct {
Expand Down Expand Up @@ -167,6 +134,14 @@ func (t p2pPeer) IsBootstrap() bool {
return false
}

func getSignerStringFromOCRKeyBundle(keyBundle ocr2key.KeyBundle) (string, error) {
if keyBundle == nil {
return "", errors.New("keyBundle is nil")
}

return fmt.Sprintf("0x%x", keyBundle.PublicKey()), nil
}

func NewPeerID(donName string, nodeOrdinal int) string {
privKeyString := fmt.Sprintf("privatekey:%s:%d", donName, nodeOrdinal)
privKey := sha256.Sum256([]byte(privKeyString))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ func SetupForwarderContract(t *testing.T, reportCreator *framework.DON,
require.NoError(t, err)
backend.Commit()

signers := make([]common.Address, 0, len(reportCreator.GetPeerIDs()))
for _, p := range reportCreator.GetPeerIDs() {
signers := make([]common.Address, 0, len(reportCreator.GetPeerIDsAndOCRSigners()))
for _, p := range reportCreator.GetPeerIDsAndOCRSigners() {
signers = append(signers, common.HexToAddress(p.Signer))
}

Expand Down
2 changes: 1 addition & 1 deletion core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ require (
github.com/smartcontractkit/chain-selectors v1.0.62-0.20250630182638-8bd9c28cf772
github.com/smartcontractkit/chainlink-automation v0.8.1
github.com/smartcontractkit/chainlink-ccip v0.0.0-20250627133416-1d85eec09097
github.com/smartcontractkit/chainlink-common v0.7.1-0.20250702201310-07178aa95345
github.com/smartcontractkit/chainlink-common v0.7.1-0.20250703124621-c798a00616be
github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20250702175503-91331140edc3
github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20250604171706-a98fa6515eae
github.com/smartcontractkit/chainlink-deployments-framework v0.16.0
Expand Down
Loading
Loading