Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support "dummy" relayer type #13583

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions .changeset/tender-carpets-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"chainlink": patch
---

Add new relayer type "dummy" for testing.

#added
5 changes: 5 additions & 0 deletions core/chains/evm/logpoller/log_poller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,11 @@ func (lp *logPoller) latestBlocks(ctx context.Context) (*evmtypes.Head, int64, e
if err != nil {
return nil, 0, err
}
if latestBlock == nil {
// Shouldn't happen with a real client, but still better rather to
// return error than panic
return nil, 0, errors.New("latest block is nil")
}
// If chain has fewer blocks than finalityDepth, return 0
return latestBlock, mathutil.Max(latestBlock.Number-lp.finalityDepth, 0), nil
}
Expand Down
2 changes: 1 addition & 1 deletion core/cmd/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G
}
// evm always enabled for backward compatibility
// TODO BCF-2510 this needs to change in order to clear the path for EVM extraction
initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg)}
initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitDummy(ctx, relayerFactory), chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg)}

if cfg.CosmosEnabled() {
cosmosCfg := chainlink.CosmosFactoryConfig{
Expand Down
2 changes: 1 addition & 1 deletion core/internal/cltest/cltest.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn

testCtx := testutils.Context(t)
// evm alway enabled for backward compatibility
initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(testCtx, relayerFactory, evmOpts)}
initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitDummy(testCtx, relayerFactory), chainlink.InitEVM(testCtx, relayerFactory, evmOpts)}

if cfg.CosmosEnabled() {
cosmosCfg := chainlink.CosmosFactoryConfig{
Expand Down
4 changes: 3 additions & 1 deletion core/internal/testutils/testutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,15 +367,17 @@ func RequireLogMessage(t *testing.T, observedLogs *observer.ObservedLogs, msg st
//
// observedZapCore, observedLogs := observer.New(zap.DebugLevel)
// lggr := logger.TestLogger(t, observedZapCore)
func WaitForLogMessage(t *testing.T, observedLogs *observer.ObservedLogs, msg string) {
func WaitForLogMessage(t *testing.T, observedLogs *observer.ObservedLogs, msg string) (le observer.LoggedEntry) {
AssertEventually(t, func() bool {
for _, l := range observedLogs.All() {
if strings.Contains(l.Message, msg) {
le = l
return true
}
}
return false
})
return
}

// WaitForLogMessageCount waits until at least count log message containing the
Expand Down
24 changes: 24 additions & 0 deletions core/services/chainlink/relayer_chain_interoperators.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,19 @@ type ChainsNodesStatuser interface {

var _ RelayerChainInteroperators = &CoreRelayerChainInteroperators{}

type DummyFactory interface {
NewDummy(config DummyFactoryConfig) (loop.Relayer, error)
}

// CoreRelayerChainInteroperators implements [RelayerChainInteroperators]
// as needed for the core [chainlink.Application]
type CoreRelayerChainInteroperators struct {
mu sync.Mutex
loopRelayers map[types.RelayID]loop.Relayer
legacyChains legacyChains

dummyFactory DummyFactory

// we keep an explicit list of services because the legacy implementations have more than
// just the relayer service
srvs []services.ServiceCtx
Expand All @@ -98,6 +104,14 @@ func NewCoreRelayerChainInteroperators(initFuncs ...CoreRelayerChainInitFunc) (*
// CoreRelayerChainInitFunc is a hook in the constructor to create relayers from a factory.
type CoreRelayerChainInitFunc func(op *CoreRelayerChainInteroperators) error

// InitDummy instantiates a dummy relayer
func InitDummy(ctx context.Context, factory RelayerFactory) CoreRelayerChainInitFunc {
return func(op *CoreRelayerChainInteroperators) error {
op.dummyFactory = &factory
return nil
}
}

// InitEVM is a option for instantiating evm relayers
func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfig) CoreRelayerChainInitFunc {
return func(op *CoreRelayerChainInteroperators) (err error) {
Expand Down Expand Up @@ -178,6 +192,16 @@ func (rs *CoreRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, e
defer rs.mu.Unlock()
lr, exist := rs.loopRelayers[id]
if !exist {
// lazily create dummy relayers
if id.Network == "dummy" {
var err error
lr, err = rs.dummyFactory.NewDummy(DummyFactoryConfig{id.ChainID})
if err != nil {
return nil, err
}
rs.loopRelayers[id] = lr
return lr, nil
}
return nil, fmt.Errorf("%w: %s", ErrNoSuchRelayer, id)
}
return lr, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
expectedStarknetNodeCnt int
expectedStarknetRelayerIds []types.RelayID

expectedDummyChainCnt int
expectedDummyNodeCnt int
expectedDummyRelayerIds []types.RelayID

expectedCosmosChainCnt int
expectedCosmosNodeCnt int
expectedCosmosRelayerIds []types.RelayID
Expand Down Expand Up @@ -368,6 +372,8 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
expectedChainCnt, expectedNodeCnt = tt.expectedSolanaChainCnt, tt.expectedSolanaNodeCnt
case relay.NetworkStarkNet:
expectedChainCnt, expectedNodeCnt = tt.expectedStarknetChainCnt, tt.expectedStarknetNodeCnt
case relay.NetworkDummy:
expectedChainCnt, expectedNodeCnt = tt.expectedDummyChainCnt, tt.expectedDummyNodeCnt
case relay.NetworkAptos:
t.Skip("aptos doesn't need a CoreRelayerChainInteroperator")

Expand Down
9 changes: 9 additions & 0 deletions core/services/chainlink/relayer_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
corerelay "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/dummy"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc"
"github.com/smartcontractkit/chainlink/v2/plugins"
Expand All @@ -39,6 +40,14 @@ type RelayerFactory struct {
CapabilitiesRegistry *capabilities.Registry
}

type DummyFactoryConfig struct {
ChainID string
}

func (r *RelayerFactory) NewDummy(config DummyFactoryConfig) (loop.Relayer, error) {
return dummy.NewRelayer(r.Logger, config.ChainID), nil
}

type EVMFactoryConfig struct {
legacyevm.ChainOpts
evmrelay.CSAETHKeystore
Expand Down
6 changes: 2 additions & 4 deletions core/services/llo/bm/dummy_transmitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package bm

import (
"context"
"crypto/ed25519"
"fmt"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
Expand Down Expand Up @@ -37,10 +35,10 @@ type transmitter struct {
fromAccount string
}

func NewTransmitter(lggr logger.Logger, fromAccount ed25519.PublicKey) Transmitter {
func NewTransmitter(lggr logger.Logger, fromAccount string) Transmitter {
return &transmitter{
lggr.Named("DummyTransmitter"),
fmt.Sprintf("%x", fromAccount),
fromAccount,
}
}

Expand Down
3 changes: 1 addition & 2 deletions core/services/llo/bm/dummy_transmitter_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package bm

import (
"crypto/ed25519"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -19,7 +18,7 @@ import (

func Test_DummyTransmitter(t *testing.T) {
lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel)
tr := NewTransmitter(lggr, ed25519.PublicKey("dummy"))
tr := NewTransmitter(lggr, "dummy")

servicetest.Run(t, tr)

Expand Down
4 changes: 4 additions & 0 deletions core/services/llo/data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ func (d *dataSource) Observe(ctx context.Context, streamIDs map[llotypes.StreamI
sv := make(llo.StreamValues)
var mu sync.Mutex

d.lggr.Debugw("Observing streams", "streamIDs", streamIDs)

for streamID := range streamIDs {
go func(streamID llotypes.StreamID) {
defer wg.Done()
Expand Down Expand Up @@ -99,5 +101,7 @@ func (d *dataSource) Observe(ctx context.Context, streamIDs map[llotypes.StreamI

wg.Wait()

d.lggr.Debugw("Observed streams", "streamIDs", streamIDs, "values", sv)

return sv, nil
}
21 changes: 21 additions & 0 deletions core/services/llo/onchain_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package llo

type OnchainConfig struct{}

type OnchainConfigCodec interface {
Encode(OnchainConfig) ([]byte, error)
Decode([]byte) (OnchainConfig, error)
}

var _ OnchainConfigCodec = &JSONOnchainConfigCodec{}

// TODO: Replace this with protobuf, if it is actually used for something
type JSONOnchainConfigCodec struct{}

func (c *JSONOnchainConfigCodec) Encode(OnchainConfig) ([]byte, error) {
return nil, nil
}

func (c *JSONOnchainConfigCodec) Decode([]byte) (OnchainConfig, error) {
return OnchainConfig{}, nil
}
15 changes: 6 additions & 9 deletions core/services/ocr2/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ func (d *Delegate) newServicesMercury(
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "mercury"}
}
if rid.Network != relay.NetworkEVM {
return nil, fmt.Errorf("mercury services: expected EVM relayer got %s", rid.Network)
return nil, fmt.Errorf("mercury services: expected EVM relayer got %q", rid.Network)
}
relayer, err := d.RelayGetter.Get(rid)
if err != nil {
Expand Down Expand Up @@ -895,9 +895,6 @@ func (d *Delegate) newServicesLLO(
if err != nil {
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "streams"}
}
if rid.Network != relay.NetworkEVM {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to double-check, you don't need this log anymore?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a check, not a log if I'm not mistaken, and there isn't really any reason for it to be here. LLO should support any relayer type.

return nil, fmt.Errorf("streams services: expected EVM relayer got %s", rid.Network)
}
relayer, err := d.RelayGetter.Get(rid)
if err != nil {
return nil, ErrRelayNotEnabled{Err: err, Relay: spec.Relay, PluginName: "streams"}
Expand Down Expand Up @@ -1079,7 +1076,7 @@ func (d *Delegate) newServicesDKG(
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "DKG"}
}
if rid.Network != relay.NetworkEVM {
return nil, fmt.Errorf("DKG services: expected EVM relayer got %s", rid.Network)
return nil, fmt.Errorf("DKG services: expected EVM relayer got %q", rid.Network)
}

chain, err2 := d.legacyChains.Get(rid.ChainID)
Expand Down Expand Up @@ -1144,7 +1141,7 @@ func (d *Delegate) newServicesOCR2VRF(
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "VRF"}
}
if rid.Network != relay.NetworkEVM {
return nil, fmt.Errorf("VRF services: expected EVM relayer got %s", rid.Network)
return nil, fmt.Errorf("VRF services: expected EVM relayer got %q", rid.Network)
}
chain, err2 := d.legacyChains.Get(rid.ChainID)
if err2 != nil {
Expand Down Expand Up @@ -1358,7 +1355,7 @@ func (d *Delegate) newServicesOCR2Keepers21(
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "keeper2"}
}
if rid.Network != relay.NetworkEVM {
return nil, fmt.Errorf("keeper2 services: expected EVM relayer got %s", rid.Network)
return nil, fmt.Errorf("keeper2 services: expected EVM relayer got %q", rid.Network)
}

transmitterID := spec.TransmitterID.String
Expand Down Expand Up @@ -1511,7 +1508,7 @@ func (d *Delegate) newServicesOCR2Keepers20(
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "keepers2.0"}
}
if rid.Network != relay.NetworkEVM {
return nil, fmt.Errorf("keepers2.0 services: expected EVM relayer got %s", rid.Network)
return nil, fmt.Errorf("keepers2.0 services: expected EVM relayer got %q", rid.Network)
}
chain, err2 := d.legacyChains.Get(rid.ChainID)
if err2 != nil {
Expand Down Expand Up @@ -1639,7 +1636,7 @@ func (d *Delegate) newServicesOCR2Functions(
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "functions"}
}
if rid.Network != relay.NetworkEVM {
return nil, fmt.Errorf("functions services: expected EVM relayer got %s", rid.Network)
return nil, fmt.Errorf("functions services: expected EVM relayer got %q", rid.Network)
}
chain, err := d.legacyChains.Get(rid.ChainID)
if err != nil {
Expand Down
6 changes: 5 additions & 1 deletion core/services/ocr2/plugins/llo/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type PluginConfig struct {
ChannelDefinitionsContractFromBlock int64 `json:"channelDefinitionsContractFromBlock" toml:"channelDefinitionsContractFromBlock"`

// NOTE: ChannelDefinitions is an override.
// If Channe}lDefinitions is specified, values for
// If ChannelDefinitions is specified, values for
// ChannelDefinitionsContractAddress and
// ChannelDefinitionsContractFromBlock will be ignored
ChannelDefinitions string `json:"channelDefinitions" toml:"channelDefinitions"`
Expand All @@ -41,6 +41,10 @@ type PluginConfig struct {
KeyBundleIDs map[string]string `json:"keyBundleIDs" toml:"keyBundleIDs"`
}

func (p *PluginConfig) Unmarshal(data []byte) error {
return json.Unmarshal(data, p)
}

func (p PluginConfig) Validate() (merr error) {
if p.RawServerURL == "" {
merr = errors.New("llo: ServerURL must be specified")
Expand Down
Loading
Loading