Skip to content

Commit

Permalink
Implement new relayer type "dummy"
Browse files Browse the repository at this point in the history
  • Loading branch information
samsondav committed Jun 17, 2024
1 parent b5c25ea commit ce90014
Show file tree
Hide file tree
Showing 21 changed files with 500 additions and 68 deletions.
4 changes: 3 additions & 1 deletion core/chains/evm/logpoller/log_poller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,9 @@ func (lp *logPoller) latestBlocks(ctx context.Context) (*evmtypes.Head, int64, e
if err != nil {
return nil, 0, err
}
// If chain has fewer blocks than finalityDepth, return 0
if latestBlock == nil {
return nil, 0, errors.New("latest block is nil")
}
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
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
9 changes: 9 additions & 0 deletions core/services/chainlink/relayer_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/config/env"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
"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 @@ -38,6 +39,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
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 != types.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 != types.NetworkEVM {
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 != types.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 != types.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 != types.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 != types.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 != types.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
89 changes: 54 additions & 35 deletions core/services/ocr2/plugins/llo/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,11 @@ func setupNode(
})

lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel)
app = cltest.NewApplicationWithConfigV2OnSimulatedBlockchain(t, config, backend, p2pKey, ocr2kb, csaKey, lggr.Named(dbName))
if backend != nil {
app = cltest.NewApplicationWithConfigV2OnSimulatedBlockchain(t, config, backend, p2pKey, ocr2kb, csaKey, lggr.Named(dbName))
} else {
app = cltest.NewApplicationWithConfig(t, config, p2pKey, ocr2kb, csaKey, lggr.Named(dbName))
}
err := app.Start(testutils.Context(t))
require.NoError(t, err)

Expand Down Expand Up @@ -236,74 +240,78 @@ observationSource = """
bridgeName,
))
}
func addBootstrapJob(t *testing.T, bootstrapNode Node, chainID *big.Int, verifierAddress common.Address, name string) {

func addBootstrapJob(t *testing.T, bootstrapNode Node, verifierAddress common.Address, name string, relayType, relayConfig string) {
bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(`
type = "bootstrap"
relay = "evm"
relay = "%s"
schemaVersion = 1
name = "boot-%s"
contractID = "%s"
contractConfigTrackerPollInterval = "1s"
[relayConfig]
chainID = %s
providerType = "llo"
`, name, verifierAddress.Hex(), chainID.String()))
%s`, relayType, name, verifierAddress.Hex(), relayConfig))
}

func addLLOJob(
t *testing.T,
node Node,
verifierAddress,
configStoreAddress common.Address,
verifierAddress common.Address,
bootstrapPeerID string,
bootstrapNodePort int,
serverURL string,
serverPubKey,
clientPubKey ed25519.PublicKey,
jobName string,
chainID *big.Int,
fromBlock int,
pluginConfig,
relayType,
relayConfig string,
) {
node.AddLLOJob(t, fmt.Sprintf(`
type = "offchainreporting2"
schemaVersion = 1
name = "%[1]s"
name = "%s"
forwardingAllowed = false
maxTaskDuration = "1s"
contractID = "%[2]s"
contractID = "%s"
contractConfigTrackerPollInterval = "1s"
ocrKeyBundleID = "%[3]s"
ocrKeyBundleID = "%s"
p2pv2Bootstrappers = [
"%[4]s"
"%s"
]
relay = "evm"
relay = "%s"
pluginType = "llo"
transmitterID = "%[5]x"
transmitterID = "%x"
[pluginConfig]
serverURL = "%[6]s"
serverPubKey = "%[7]x"
channelDefinitionsContractFromBlock = %[8]d
channelDefinitionsContractAddress = "%[9]s"
%s
[relayConfig]
chainID = %[10]s
fromBlock = 1`,
%s`,
jobName,
verifierAddress.Hex(),
node.KeyBundle.ID(),
fmt.Sprintf("%[email protected]:%d", bootstrapPeerID, bootstrapNodePort),
relayType,
clientPubKey,
serverURL,
serverPubKey,
fromBlock,
configStoreAddress.Hex(),
chainID.String(),
pluginConfig,
relayConfig,
))
}

func addOCRJobs(t *testing.T, streams []Stream, serverPubKey ed25519.PublicKey, serverURL string, verifierAddress common.Address, bootstrapPeerID string, bootstrapNodePort int, nodes []Node, configStoreAddress common.Address, clientPubKeys []ed25519.PublicKey, chainID *big.Int, fromBlock int) {
func addOCRJobs(
t *testing.T,
streams []Stream,
serverPubKey ed25519.PublicKey,
serverURL string,
verifierAddress common.Address,
bootstrapPeerID string,
bootstrapNodePort int,
nodes []Node,
configStoreAddress common.Address,
clientPubKeys []ed25519.PublicKey,
pluginConfig,
relayType,
relayConfig string) {
ctx := testutils.Context(t)
createBridge := func(name string, i int, p *big.Int, borm bridges.ORM) (bridgeName string) {
bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
Expand Down Expand Up @@ -343,15 +351,26 @@ func addOCRJobs(t *testing.T, streams []Stream, serverPubKey ed25519.PublicKey,
t,
node,
verifierAddress,
configStoreAddress,
bootstrapPeerID,
bootstrapNodePort,
serverURL,
serverPubKey,
clientPubKeys[i],
"feed-1",
chainID,
fromBlock,
pluginConfig,
relayType,
relayConfig,
)
}
}

func addDummyBootstrapJob(t *testing.T, bootstrapNode Node, name, relayConfig string) {
// TODO: contractID should move into relay config to be honest
bootstrapNode.AddBootstrapJob(t, fmt.Sprintf(`
type = "bootstrap"
relay = "dummy"
schemaVersion = 1
name = "boot-%s"
contractID = "0x"
[relayConfig]
%s`, name, relayConfig))
}
Loading

0 comments on commit ce90014

Please sign in to comment.