Add LOOP-compatible Head Reporter#17580
Conversation
c7cba34 to
0a6f1f5
Compare
4f9eb45 to
0959d71
Compare
0959d71 to
127520e
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR extends the telemetry reporting functionality by renaming the legacy EVM telemetry reporter and adding a new Solana telemetry reporter implementation. Key changes include:
- Renaming the EVM telemetry reporter to EVMTelemetryReporter and updating related tests.
- Introducing the SolanaTelemetryReporter, along with associated report functions and tests.
- Updating wiring in the application to accommodate multiple telemetry reporters for different chain types.
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| core/utils/safe_math.go & safe_math_test.go | Added helper function and tests for safely converting int64 to uint64. |
| core/services/headreporter/telemetry_reporter.go | Renamed telemetry reporter for EVM, and added Solana telemetry reporter implementation. |
| core/services/headreporter/telemetry_reporter_test.go | Updated tests to reflect the renaming and added tests for Solana telemetry reporting. |
| core/services/chainlink/relayer_chain_interoperators.go | Updated inline documentation to reflect the correct filtering function. |
| core/services/chainlink/application.go | Integrated both EVM and Solana telemetry reporters into the application wiring. |
Comments suppressed due to low confidence (1)
core/services/chainlink/application.go:480
- [nitpick] Consider renaming 'legacyEVMTelemReporter' to 'legacyEVMTelemetryReporter' to improve clarity and maintain consistent naming conventions.
legacyEVMTelemReporter := headreporter.NewEVMTelemetryReporter(telemetryManager, globalLogger, evmChainIDs...)
| } | ||
| telemReporter := headreporter.NewTelemetryReporter(telemetryManager, globalLogger, chainIDs...) | ||
| headReporter := headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) | ||
| solanaRelayers, _ := relayChainInterops.List(FilterRelayersByType("Solana")).GetIDToRelayerMap() |
There was a problem hiding this comment.
Ignoring the error returned from GetIDToRelayerMap may lead to unhandled failure cases; consider checking and handling the error appropriately.
| solanaRelayers, _ := relayChainInterops.List(FilterRelayersByType("Solana")).GetIDToRelayerMap() | |
| solanaRelayers, err := relayChainInterops.List(FilterRelayersByType("Solana")).GetIDToRelayerMap() | |
| if err != nil { | |
| return nil, errors.Wrap(err, "failed to get Solana relayers map") | |
| } |
There was a problem hiding this comment.
Yeah we should probably handle this error here
There was a problem hiding this comment.
It seemed a bit silly to handle it when the function always returns nil. I guess I'll just update the signature so that it doesn't look like it can return an error.
| } | ||
|
|
||
| // ReportNewHead is unimplemented on Solana because there is no Headtracker to subscribe to | ||
| func (t *solanaTelemetryReporter) ReportNewHead(_ context.Context, _ *evmtypes.Head) error { |
There was a problem hiding this comment.
Don't like the fact that this method still needs an evmtypes.Head, even though this is part of the interface for Solana.
Seems easy to change to a generic head, but perhaps lets do it in a separate PR later.
There was a problem hiding this comment.
Yeah, I considered making that change, but I think this ReportNewHead method will need to be removed soon anyway. The only reason EVM is able to use ReportNewHead (registered callback) rather than PeriodicReport (polling) is because it's not running in LOOP. I don'tt hink non-evm chains would ever be able to use it unless we changed the way our LOOP arch is set up so that relayers could make callbacks to the core node.
| return nil | ||
| } | ||
|
|
||
| type solanaTelemetryReporter struct { |
There was a problem hiding this comment.
nice work!
I see there's literally nothing solana specific here.
What do you think about renaming it to genericTelemReporter, and enable it for all chain families, perhaps except EVM, or maybe don't even need to filter out EVM.
This will just add more telem reporting of EVM Heads at periodic intervals too. I already checked, in EVM relayer's LatestHead(), we return a cached version of head, so no extra RPCs are made.
No other non-evm is launched on CCIP yet, so this change would be no-op in production till they launch.
I only see Aptos and Tron DF being live that would start reporting these Heads, but not a bad thing.
What do you think?
There was a problem hiding this comment.
Yeah, I guess we could do that.
I was mostly thinking that the amount of QA testing needed might be a lot less if we know the change only affects Solana. But you have a good point, I don't think LatestHead is implemented for any families but EVM & Solana so the other chains shouldn't matter. And if it's cached on EVM it shouldn't make much of a difference there and can be tested simultaneously with Solana on staging.
| if i < 0 { | ||
| i = 0 | ||
| } | ||
| return uint64(i) //nolint:gosec |
There was a problem hiding this comment.
Did you get any benefit by creating this, then, if you still get this lint warning?
I would say, since we know we are converting from a positive number, lets just ignore this warning
There was a problem hiding this comment.
The benefit was that, there were at least 6 different lines where I had to add //nolint:gosec to get CI to pass... now it's contained to just a single location. Several times I thought I'd gotten all of them and then the CI would fail again.
There was a problem hiding this comment.
Next time I'm making an update to chainlink-common I'd like to move it there, and re-use it also in LogPoller since that is also filled with a lot of the same //nolint:gosec's
There was a problem hiding this comment.
Also, it seems slightly safer in that... if somehow there were a situation where a negative block number were passed it wouldn't accidentally get converted into a positive number. And if there were a clock that was set prior to 1970 it would cause less unpredictable behavior.
Renames: - NewEVMTelemetry -> NewLegacyEVMTelemetry - NewPrometheusReporter -> NewLegacyEVMPrometheusReporter - evmTelemetryReporter -> legacyEVMTelemetryReporter - NewSolanaTelemetryReporter -> NewTelemetryReporter - solanaTelemetryReporter -> loopTelemetryReporter Now, NewTelemetryReporter handles all relayers in the same way (including EVM). The legacy EVM Telemetry Reporter is left operational so we still receive metrics about finalized heads. This can be removed once we extend the relayer interface to be able to fetch finalized heads from there.
08872b1 to
1200f29
Compare
1200f29 to
6040248
Compare
6040248 to
04b7ccb
Compare
|
* Add Solana Head Reporter * Add explanation to //golint:nosec * Address PR comments Renames: - NewEVMTelemetry -> NewLegacyEVMTelemetry - NewPrometheusReporter -> NewLegacyEVMPrometheusReporter - evmTelemetryReporter -> legacyEVMTelemetryReporter - NewSolanaTelemetryReporter -> NewTelemetryReporter - solanaTelemetryReporter -> loopTelemetryReporter Now, NewTelemetryReporter handles all relayers in the same way (including EVM). The legacy EVM Telemetry Reporter is left operational so we still receive metrics about finalized heads. This can be removed once we extend the relayer interface to be able to fetch finalized heads from there. * Remove unused error output from GetIDToRelayerMap()




Description
Presently, we only have an evm implementation (
headreporter.telemetryReporter) ofHeadReporterbased on the legacy EVM chains.This re-names
headreporter.telemetryReportertoheadreporter.evmTelemetryReporterand addsheadreporter.loopTelemetryReporter, a chain-agnostic implementation ofHeadReporter.This should work for any chains that fully implement the Relayer interface (specifically LatestHead) since they are all required to satisfy the same interface. We don't want to replace the legacy EVM implementation yet with it for EVM, because that would remove reporting on finalized heads.
Adding support for finalized heads later will require extending the relayer interface. To avoid removing any functionality from EVM, this will run side-by-side the legacy EVM implementation, which can be removed once we add LatestFinalizedHead (or similar) to the relayer interface. There will be some extra reporting on latest heads for evm now, but these are cached in memory so it shouldn't add any overhead.