Skip to content

Commit

Permalink
Remove legacy Mercury plugin and associated code
Browse files Browse the repository at this point in the history
  • Loading branch information
samsondav committed Jan 23, 2025
1 parent c682bd7 commit 32cf4d5
Show file tree
Hide file tree
Showing 58 changed files with 72 additions and 11,164 deletions.
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": minor
---

Remove support for mercury
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 @@ -523,7 +522,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 @@ -683,7 +681,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/core/utils/testutils/heavyweight"
)

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

0 comments on commit 32cf4d5

Please sign in to comment.