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

Remove legacy Mercury plugin and associated code #16014

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
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
5 changes: 5 additions & 0 deletions .changeset/moody-swans-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": major
---

Remove support for mercury #removed
3 changes: 0 additions & 3 deletions core/services/chainlink/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc"
"github.com/smartcontractkit/chainlink/v2/core/services/standardcapabilities"
"github.com/smartcontractkit/chainlink/v2/core/services/streams"
Expand Down Expand Up @@ -524,7 +523,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
var (
pipelineORM = pipeline.NewORM(opts.DS, globalLogger, cfg.JobPipeline().MaxSuccessfulRuns())
bridgeORM = bridges.NewORM(opts.DS)
mercuryORM = mercury.NewORM(opts.DS)
pipelineRunner = pipeline.NewRunner(pipelineORM, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), legacyEVMChains, keyStore.Eth(), keyStore.VRF(), globalLogger, restrictedHTTPClient, unrestrictedHTTPClient)
jobORM = job.NewORM(opts.DS, pipelineORM, bridgeORM, keyStore, globalLogger)
txmORM = txmgr.NewTxStore(opts.DS, globalLogger)
Expand Down Expand Up @@ -684,7 +682,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
Ds: opts.DS,
JobORM: jobORM,
BridgeORM: bridgeORM,
MercuryORM: mercuryORM,
PipelineRunner: pipelineRunner,
StreamRegistry: streamRegistry,
PeerWrapper: peerWrapper,
Expand Down
85 changes: 1 addition & 84 deletions core/services/job/job_orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,36 +52,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/evm/utils/big"
)

const mercuryOracleTOML = `name = 'LINK / ETH | 0x0000000000000000000000000000000000000000000000000000000000000001 | verifier_proxy 0x0000000000000000000000000000000000000001'
type = 'offchainreporting2'
schemaVersion = 1
externalJobID = '00000000-0000-0000-0000-000000000001'
contractID = '0x0000000000000000000000000000000000000006'
transmitterID = '%s'
feedID = '%s'
relay = 'evm'
pluginType = 'mercury'
observationSource = """
ds [type=http method=GET url="https://chain.link/ETH-USD"];
ds_parse [type=jsonparse path="data.price" separator="."];
ds_multiply [type=multiply times=100];
ds -> ds_parse -> ds_multiply;
"""
[relayConfig]
chainID = 1
fromBlock = 1000
[onchainSigningStrategy]
strategyName = 'single-chain'
[onchainSigningStrategy.config]
publicKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707'
[pluginConfig]
serverURL = 'wss://localhost:8080'
serverPubKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707'
`

func TestORM(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -1185,28 +1155,6 @@ func Test_FindJob(t *testing.T) {

jobOCR2.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource

ocr2WithFeedID1 := "0x0001000000000000000000000000000000000000000000000000000000000001"
ocr2WithFeedID2 := "0x0001000000000000000000000000000000000000000000000000000000000002"
jobOCR2WithFeedID1, err := ocr2validate.ValidatedOracleSpecToml(
testutils.Context(t),
config.OCR2(),
config.Insecure(),
fmt.Sprintf(mercuryOracleTOML, cltest.DefaultCSAKey.PublicKeyString(), ocr2WithFeedID1),
nil,
)
require.NoError(t, err)

jobOCR2WithFeedID2, err := ocr2validate.ValidatedOracleSpecToml(
testutils.Context(t),
config.OCR2(),
config.Insecure(),
fmt.Sprintf(mercuryOracleTOML, cltest.DefaultCSAKey.PublicKeyString(), ocr2WithFeedID2),
nil,
)
jobOCR2WithFeedID2.ExternalJobID = uuid.New()
jobOCR2WithFeedID2.Name = null.StringFrom("new name")
require.NoError(t, err)

err = orm.CreateJob(ctx, &job)
require.NoError(t, err)

Expand All @@ -1216,13 +1164,6 @@ func Test_FindJob(t *testing.T) {
err = orm.CreateJob(ctx, &jobOCR2)
require.NoError(t, err)

err = orm.CreateJob(ctx, &jobOCR2WithFeedID1)
require.NoError(t, err)

// second ocr2 job with same contract id but different feed id
err = orm.CreateJob(ctx, &jobOCR2WithFeedID2)
require.NoError(t, err)

t.Run("by id", func(t *testing.T) {
ctx, cancel := context.WithTimeout(testutils.Context(t), 5*time.Second)
defer cancel()
Expand Down Expand Up @@ -1281,7 +1222,7 @@ func Test_FindJob(t *testing.T) {
assert.Equal(t, job.ID, jbID)
})

t.Run("by contract id without feed id", func(t *testing.T) {
t.Run("by contract id", func(t *testing.T) {
ctx := testutils.Context(t)
contractID := "0x613a38AC1659769640aaE063C651F48E0250454C"

Expand All @@ -1291,30 +1232,6 @@ func Test_FindJob(t *testing.T) {

assert.Equal(t, jobOCR2.ID, jbID)
})

t.Run("by contract id with valid feed id", func(t *testing.T) {
ctx := testutils.Context(t)
contractID := "0x0000000000000000000000000000000000000006"
feedID := common.HexToHash(ocr2WithFeedID1)

// Find job ID for ocr2 job with feed ID
jbID, err2 := orm.FindOCR2JobIDByAddress(ctx, contractID, &feedID)
require.NoError(t, err2)

assert.Equal(t, jobOCR2WithFeedID1.ID, jbID)
})

t.Run("with duplicate contract id but different feed id", func(t *testing.T) {
ctx := testutils.Context(t)
contractID := "0x0000000000000000000000000000000000000006"
feedID := common.HexToHash(ocr2WithFeedID2)

// Find job ID for ocr2 job with feed ID
jbID, err2 := orm.FindOCR2JobIDByAddress(ctx, contractID, &feedID)
require.NoError(t, err2)

assert.Equal(t, jobOCR2WithFeedID2.ID, jbID)
})
}

func Test_FindJobsByPipelineSpecIDs(t *testing.T) {
Expand Down
121 changes: 1 addition & 120 deletions core/services/ocr2/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/generic"
lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/median"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/autotelemetry21"
ocr2keeper21core "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core"
Expand All @@ -69,8 +68,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
functionsRelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions"
evmmercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury"
mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
evmrelaytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/services/streams"
"github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
Expand Down Expand Up @@ -109,7 +106,6 @@ type Delegate struct {
ds sqlutil.DataSource
jobORM job.ORM
bridgeORM bridges.ORM
mercuryORM evmmercury.ORM
pipelineRunner pipeline.Runner
streamRegistry streams.Getter
peerWrapper *ocrcommon.SingletonPeerWrapper
Expand Down Expand Up @@ -218,7 +214,6 @@ type DelegateOpts struct {
Ds sqlutil.DataSource
JobORM job.ORM
BridgeORM bridges.ORM
MercuryORM evmmercury.ORM
PipelineRunner pipeline.Runner
StreamRegistry streams.Getter
PeerWrapper *ocrcommon.SingletonPeerWrapper
Expand All @@ -241,7 +236,6 @@ func NewDelegate(
ds: opts.Ds,
jobORM: opts.JobORM,
bridgeORM: opts.BridgeORM,
mercuryORM: opts.MercuryORM,
pipelineRunner: opts.PipelineRunner,
streamRegistry: opts.StreamRegistry,
peerWrapper: opts.PeerWrapper,
Expand Down Expand Up @@ -497,9 +491,6 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi

ctx = lggrCtx.ContextWithValues(ctx)
switch spec.PluginType {
case types.Mercury:
return d.newServicesMercury(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc)

case types.LLO:
return d.newServicesLLO(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc)

Expand Down Expand Up @@ -534,7 +525,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi

func GetEVMEffectiveTransmitterID(ctx context.Context, jb *job.Job, chain legacyevm.Chain, lggr logger.SugaredLogger) (string, error) {
spec := jb.OCR2OracleSpec
if spec.PluginType == types.Mercury || spec.PluginType == types.LLO {
if spec.PluginType == types.LLO {
return spec.TransmitterID.String, nil
}

Expand All @@ -553,7 +544,6 @@ func GetEVMEffectiveTransmitterID(ctx context.Context, jb *job.Job, chain legacy

// effectiveTransmitterID is the transmitter address registered on the ocr contract. This is by default the EOA account on the node.
// In the case of forwarding, the transmitter address is the forwarder contract deployed onchain between EOA and OCR contract.
// ForwardingAllowed cannot be set with Mercury, so this should always be false for mercury jobs
if jb.ForwardingAllowed {
if chain == nil {
return "", fmt.Errorf("job forwarding requires non-nil chain")
Expand Down Expand Up @@ -828,115 +818,6 @@ func (d *Delegate) newServicesGenericPlugin(
return srvs, nil
}

func (d *Delegate) newServicesMercury(
ctx context.Context,
lggr logger.SugaredLogger,
jb job.Job,
bootstrapPeers []commontypes.BootstrapperLocator,
kb ocr2key.KeyBundle,
ocrDB *db,
lc ocrtypes.LocalConfig,
) ([]job.ServiceCtx, error) {
if jb.OCR2OracleSpec.FeedID == nil || (*jb.OCR2OracleSpec.FeedID == (common.Hash{})) {
return nil, errors.Errorf("ServicesForSpec: mercury job type requires feedID")
}
spec := jb.OCR2OracleSpec
transmitterID := spec.TransmitterID.String
if len(transmitterID) != 64 {
return nil, errors.Errorf("ServicesForSpec: mercury job type requires transmitter ID to be a 32-byte hex string, got: %q", transmitterID)
}
if _, err := hex.DecodeString(transmitterID); err != nil {
return nil, errors.Wrapf(err, "ServicesForSpec: mercury job type requires transmitter ID to be a 32-byte hex string, got: %q", transmitterID)
}

rid, err := spec.RelayID()
if err != nil {
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "mercury"}
}
if rid.Network != relay.NetworkEVM {
return nil, fmt.Errorf("mercury services: expected EVM relayer got %q", rid.Network)
}
relayer, err := d.RelayGetter.Get(rid)
if err != nil {
return nil, ErrRelayNotEnabled{Err: err, Relay: spec.Relay, PluginName: "mercury"}
}

provider, err2 := relayer.NewPluginProvider(ctx,
types.RelayArgs{
ExternalJobID: jb.ExternalJobID,
JobID: jb.ID,
ContractID: spec.ContractID,
New: d.isNewlyCreatedJob,
RelayConfig: spec.RelayConfig.Bytes(),
ProviderType: string(spec.PluginType),
}, types.PluginArgs{
TransmitterID: transmitterID,
PluginConfig: spec.PluginConfig.Bytes(),
})
if err2 != nil {
return nil, err2
}

mercuryProvider, ok := provider.(types.MercuryProvider)
if !ok {
return nil, errors.New("could not coerce PluginProvider to MercuryProvider")
}

lc.ContractConfigTrackerPollInterval = 1 * time.Second // This is the fastest that libocr supports. See: https://github.com/smartcontractkit/offchain-reporting/pull/520

// Disable OCR debug+info logging for legacy mercury jobs unless tracelogging is enabled, because its simply too verbose (150 jobs => ~50k logs per second)
ocrLogger := ocrcommon.NewOCRWrapper(llo.NewSuppressedLogger(lggr, d.cfg.OCR2().TraceLogging()), d.cfg.OCR2().TraceLogging(), func(ctx context.Context, msg string) {
lggr.ErrorIf(d.jobORM.RecordError(ctx, jb.ID, msg), "unable to record error")
})

var relayConfig evmrelaytypes.RelayConfig
err = json.Unmarshal(jb.OCR2OracleSpec.RelayConfig.Bytes(), &relayConfig)
if err != nil {
return nil, fmt.Errorf("error while unmarshalling relay config: %w", err)
}

var telemetryType synchronization.TelemetryType
if relayConfig.EnableTriggerCapability && len(jb.OCR2OracleSpec.PluginConfig) == 0 {
telemetryType = synchronization.OCR3DataFeeds
// First use case for TriggerCapability transmission is Data Feeds, so telemetry should be routed accordingly.
// This is only true if TriggerCapability is the *only* transmission method (PluginConfig is empty).
} else {
telemetryType = synchronization.OCR3Mercury
}

oracleArgsNoPlugin := libocr2.MercuryOracleArgs{
BinaryNetworkEndpointFactory: d.peerWrapper.Peer2,
V2Bootstrappers: bootstrapPeers,
ContractTransmitter: mercuryProvider.ContractTransmitter(),
ContractConfigTracker: mercuryProvider.ContractConfigTracker(),
Database: ocrDB,
LocalConfig: lc,
Logger: ocrLogger,
MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, spec.FeedID.String(), telemetryType),
OffchainConfigDigester: mercuryProvider.OffchainConfigDigester(),
OffchainKeyring: kb,
OnchainKeyring: kb,
MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"job_name": jb.Name.ValueOrZero()}, prometheus.DefaultRegisterer),
}

chEnhancedTelem := make(chan ocrcommon.EnhancedTelemetryMercuryData, 100)

mCfg := mercury.NewMercuryConfig(d.cfg.JobPipeline().MaxSuccessfulRuns(), d.cfg.JobPipeline().ResultWriteQueueDepth(), d.cfg)

mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, lggr, oracleArgsNoPlugin, mCfg, chEnhancedTelem, d.mercuryORM, (mercuryutils.FeedID)(*spec.FeedID), relayConfig.EnableTriggerCapability)

if ocrcommon.ShouldCollectEnhancedTelemetryMercury(jb) {
enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, chEnhancedTelem, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, spec.FeedID.String(), synchronization.EnhancedEAMercury), lggr.Named("EnhancedTelemetryMercury"))
mercuryServices = append(mercuryServices, enhancedTelemService)
} else {
lggr.Infow("Enhanced telemetry is disabled for mercury job", "job", jb.Name)
}

mercuryServices = append(mercuryServices, ocrLogger)

return mercuryServices, err2
}

func (d *Delegate) newServicesLLO(
ctx context.Context,
lggr logger.SugaredLogger,
Expand Down
10 changes: 7 additions & 3 deletions core/services/ocr2/plugins/llo/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ import (
llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo"

"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)

type Server struct {
URL string
PubKey utils.PlainHexBytes
}

type PluginConfig struct {
ChannelDefinitionsContractAddress common.Address `json:"channelDefinitionsContractAddress" toml:"channelDefinitionsContractAddress"`
ChannelDefinitionsContractFromBlock int64 `json:"channelDefinitionsContractFromBlock" toml:"channelDefinitionsContractFromBlock"`
Expand Down Expand Up @@ -49,9 +53,9 @@ func (p *PluginConfig) Unmarshal(data []byte) error {
return json.Unmarshal(data, p)
}

func (p PluginConfig) GetServers() (servers []mercuryconfig.Server) {
func (p PluginConfig) GetServers() (servers []Server) {
for url, pubKey := range p.Servers {
servers = append(servers, mercuryconfig.Server{URL: wssRegexp.ReplaceAllString(url, ""), PubKey: pubKey})
servers = append(servers, Server{URL: wssRegexp.ReplaceAllString(url, ""), PubKey: pubKey})
}
sort.Slice(servers, func(i, j int) bool {
return servers[i].URL < servers[j].URL
Expand Down
Loading
Loading