Skip to content

OEV-1414 Add feedAddress to meta metrics#502

Open
cll-gg wants to merge 13 commits into
developfrom
OEV-1414-add-feed-label-to-meta-metrics
Open

OEV-1414 Add feedAddress to meta metrics#502
cll-gg wants to merge 13 commits into
developfrom
OEV-1414-add-feed-label-to-meta-metrics

Conversation

@cll-gg

@cll-gg cll-gg commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What

Add feedAddress to meta client related metrics

Why

To improve observability

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

⚠️ API Diff Results - github.com/smartcontractkit/chainlink-evm

⚠️ Breaking Changes (6)

pkg/txm/clientwrappers/dualbroadcast.(*MetaClient) (1)
  • SendRequest — Type changed:
func(
  context.Context, 
  *github.com/smartcontractkit/chainlink-evm/pkg/txm/types.Transaction, 
  *github.com/smartcontractkit/chainlink-evm/pkg/txm/types.Attempt, 
  string, 
  + github.com/ethereum/go-ethereum/common.Address, 
  github.com/ethereum/go-ethereum/common.Address
)
(*MetacalldataResponse, error)
pkg/txm/clientwrappers/dualbroadcast.(*MetaMetrics) (5)
  • RecordBidsReceived — Type changed:
func(
  context.Context, 
  int, 
  + github.com/ethereum/go-ethereum/common.Address
)
  • RecordLatency — Type changed:
func(
  context.Context, 
  time.Duration, 
  + github.com/ethereum/go-ethereum/common.Address
)
  • RecordSendOperationError — Type changed:
func(
  context.Context, 
  + github.com/ethereum/go-ethereum/common.Address
)
  • RecordSendRequestError — Type changed:
func(
  context.Context, 
  + github.com/ethereum/go-ethereum/common.Address
)
  • RecordStatusCode — Type changed:
func(
  context.Context, 
  int, 
  + github.com/ethereum/go-ethereum/common.Address
)

📄 View full apidiff report

@cll-gg
cll-gg marked this pull request as ready for review July 14, 2026 16:32
@cll-gg
cll-gg requested review from a team and dimriou as code owners July 14, 2026 16:32
Copilot AI review requested due to automatic review settings July 14, 2026 16:32
@cll-gg
cll-gg requested a review from a team as a code owner July 14, 2026 16:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Meta client OTEL metrics to include a per-feed/per-contract address dimension, improving observability by allowing status/latency/errors/bid counts to be segmented by destination.

Changes:

  • Added a new feedAddress parameter to MetaMetrics recording methods and propagated it through MetaClient call sites.
  • Attached an address attribute to Meta-related metrics (status code, latency, bids received, and error counters).
  • Updated unit tests to cover the new method signatures.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.

File Description
pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go Adds an address attribute to Meta metrics and updates metric recording method signatures.
pkg/txm/clientwrappers/dualbroadcast/meta_metrics_test.go Updates tests to call the updated MetaMetrics methods with a feed address argument.
pkg/txm/clientwrappers/dualbroadcast/meta_client.go Passes an address through when recording Meta metrics during request/operation lifecycle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_client.go Outdated
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_client.go Outdated
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_client.go
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go
cll-gg and others added 5 commits July 15, 2026 09:08
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_client.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_client.go Outdated
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_client.go Outdated
Comment on lines +72 to +77
func (m *MetaMetrics) RecordStatusCode(ctx context.Context, statusCode int, feedAddress string) {
m.statusCodeCounter.Add(ctx, 1,
metric.WithAttributes(
attribute.String("chainID", m.chainID),
attribute.String("statusCode", strconv.Itoa(statusCode)),
attribute.String("feedAddress", strings.ToLower(feedAddress)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can pass feedAddress as a common.Address param and avoid spamming txMeta.FwdrDestAddress.Hex() in the caller and also avoid strings.ToLower(feedAddress) since all callers will be consistent with .Hex() call

Suggested change
func (m *MetaMetrics) RecordStatusCode(ctx context.Context, statusCode int, feedAddress string) {
m.statusCodeCounter.Add(ctx, 1,
metric.WithAttributes(
attribute.String("chainID", m.chainID),
attribute.String("statusCode", strconv.Itoa(statusCode)),
attribute.String("feedAddress", strings.ToLower(feedAddress)),
func (m *MetaMetrics) RecordStatusCode(ctx context.Context, statusCode int, feedAddress common.Address) {
m.statusCodeCounter.Add(ctx, 1,
metric.WithAttributes(
attribute.String("chainID", m.chainID),
attribute.String("statusCode", strconv.Itoa(statusCode)),
attribute.String("feedAddress", feedAddress.Hex()),

@cll-gg cll-gg Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah yes, passing address is a lot nicer 👍
Will update.

also avoid strings.ToLower(feedAddress) since all callers will be consistent with .Hex() call

WDYM with this?
The toLower call is to prevent mixed-case addresses from being labels in PromQL, because PromQL doesn't have a lowercase function, making it impossible to match a mixed-case address with a lowercased address.

Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go Outdated
Comment thread pkg/txm/clientwrappers/dualbroadcast/meta_metrics.go Outdated
@cll-gg
cll-gg requested a review from dimriou July 15, 2026 09:49
tx.AttemptCount == 1 && !tx.IsPurgeable {
// Auction & Validate
meta, err := a.SendRequest(ctx, tx, attempt, *meta.DualBroadcastParams, tx.ToAddress)
meta, err := a.SendRequest(ctx, tx, attempt, txMeta, tx.ToAddress)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SendRequest only has one caller. It would be better if we explode the params and separate the DualBroadcastParams from the feedAddress. We can pass both independently keep the DualBroadcastParams as is and just pass feeAddress to the underlying callers. This avoid spamming *txMeta.FwdrDestAddress .

Suggested change
meta, err := a.SendRequest(ctx, tx, attempt, txMeta, tx.ToAddress)
meta, err := a.SendRequest(ctx, tx, attempt, *meta.DualBroadcastParams, tx.ToAddress, feedAddress)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense, updated

Comment on lines +334 to +336
if txMeta == nil || txMeta.FwdrDestAddress == nil || txMeta.DualBroadcastParams == nil {
return nil, errors.New("missing tx meta fields for dual broadcast request")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would consider this redundant as we make the same check right before we call SendRequest.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

And there's only one caller, fair

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Comment on lines +196 to +203
txMeta, err := tx.GetMeta()
if err != nil {
return err
}

// #1
if meta != nil &&
meta.DualBroadcast != nil && *meta.DualBroadcast && meta.DualBroadcastParams != nil && meta.FwdrDestAddress != nil &&
if txMeta != nil &&
txMeta.DualBroadcast != nil && *txMeta.DualBroadcast && txMeta.DualBroadcastParams != nil && txMeta.FwdrDestAddress != nil &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No need to rename this local variable, meta seems clear enough.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree on its own, but consider line 207, there we reassign/shadow meta to a different variable, so it changes from TxMeta struct to a MetacalldataResponse struct.
This makes it impossible to call meta.FwdrDestAddress after line 207.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ok makes sense. We could also rename the returned value of SendRequest since meta is now used inside here, whatever feels best.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, I've opted for renaming the returned value from SendRequest instead

m.latencyHistogram.Record(ctx, duration.Milliseconds(),
metric.WithAttributes(
attribute.String("chainID", m.chainID),
attribute.String("feedAddress", strings.ToLower(feedAddress.Hex())),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would consider not using strings.ToLower as this forces other callers to ensure they call it in other places to stay consistent. If they miss it, then some attributes will be upper case and other lower case. Just by calling .Hex() , which is required by the attribute param, we ensure everyone does the same.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The toLower call is to prevent mixed-case addresses from being labels in PromQL, because PromQL doesn't have a lowercase function, making it impossible to match a mixed-case address with a lowercased address.

We encountered this already in matching SDS metrics (lowercased addresses) with RDDPE metrics (checksummed addresses), see https://github.com/smartcontractkit/rdd-prometheus-exporter/pull/139.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But Hex() doesn't return a random mixed case, it returns the EIP55-compliant hex string. Can't we use that standard for querying?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

True, that's likely better and more consistent. I'll have to update SDS for that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the lowercase here

@cll-gg
cll-gg requested a review from dimriou July 15, 2026 10:28

@dimriou dimriou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice, looks pretty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants