feat(metrics): add per-IP and DeFi transaction content metrics#440
feat(metrics): add per-IP and DeFi transaction content metrics#440
Conversation
📝 WalkthroughWalkthroughThis pull request refactors the metrics infrastructure and adds transaction content instrumentation. A new 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
1 issue found across 7 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="internal/metrics/metrics.go">
<violation number="1" location="internal/metrics/metrics.go:105">
P1: Using raw client IP as a Prometheus label creates unbounded cardinality and allows metric-series explosion from user-controlled inputs.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| // RecordTxRequest records a submission attempt. result is one of "accepted", | ||
| // "rejected" (node rejected the tx), or "error" (parse or internal error). | ||
| func RecordTxRequest(ip, result string) { | ||
| txSubmitRequestsTotal.WithLabelValues(ip, result).Inc() |
There was a problem hiding this comment.
P1: Using raw client IP as a Prometheus label creates unbounded cardinality and allows metric-series explosion from user-controlled inputs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/metrics/metrics.go, line 105:
<comment>Using raw client IP as a Prometheus label creates unbounded cardinality and allows metric-series explosion from user-controlled inputs.</comment>
<file context>
@@ -0,0 +1,132 @@
+// RecordTxRequest records a submission attempt. result is one of "accepted",
+// "rejected" (node rejected the tx), or "error" (parse or internal error).
+func RecordTxRequest(ip, result string) {
+ txSubmitRequestsTotal.WithLabelValues(ip, result).Inc()
+}
+
</file context>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
submit/txinfo_test.go (1)
49-123: Cover the remaining script-type branches.The parser has explicit
nativeandplutus_v2outputs, but this suite only asserts"none","plutus_v1", and"plutus_v3". A typo or precedence regression in either untested branch would skew the new metrics without failing CI.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@submit/txinfo_test.go` around lines 49 - 123, Add tests covering the missing "native" and "plutus_v2" branches by adding two new parallel test functions (e.g. TestParseTxInfo_NativeScript and TestParseTxInfo_PlutusV2) that call ParseTxInfo with the existing fixture hex blobs (nativeScriptTxHex and plutusV2TxHex via mustDecodeHex), assert info.ScriptType equals "native" and "plutus_v2" respectively, and assert the expected HasMinting and HasReferenceInputs booleans for those fixtures (match the fixtures' expected values, e.g. typically false if they don't include minting/ref inputs); keep the same error handling pattern used in the other tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/api/api.go`:
- Around line 372-380: The tx-content parsing using submit.ParseTxInfo should be
best-effort, not a hard validation gate; change the error branch so that on
parse failure you log the error (include err and context such as clientIP),
increment any relevant metrics for a parse failure if desired, set txInfo to a
nil/empty value or a safe default, and continue the normal submission flow
instead of calling writeJSON(...) and returning; update the same pattern in the
other block around lines where txInfo is parsed (also references to
metrics.IncTxSubmitFailCount and metrics.RecordTxRequest) so parsing failures
only affect the content metric and do not abort the request.
- Around line 344-345: The code currently sets clientIP := realClientIP(r)
trusting X-Real-IP/X-Forwarded-For from any caller; change realClientIP handling
so it only honors forwarded headers when the immediate peer (r.RemoteAddr or
parsed remote IP) is in the configured trusted proxies list, otherwise fall back
to using r.RemoteAddr (or the parsed remote IP) as the client IP; update the
logic used wherever realClientIP is called (including the similar block around
the code handling lines 440-456) to validate the immediate peer against the
trusted proxies set before parsing X-Forwarded-For/X-Real-IP and ensure metrics
use the resulting non-spoofable clientIP variable.
In `@internal/metrics/metrics.go`:
- Around line 17-21: The collectors are currently lazily created in Register()
causing IncTxSubmitCount() and IncTxSubmitFailCount() to panic if called earlier
and Register()/Start() to panic on duplicate calls; fix by eagerly initializing
all prometheus collectors in package init() (so globals used by
IncTxSubmitCount/IncTxSubmitFailCount are always non-nil) and protect the
prometheus.MustRegister(...) path with a sync.Once (e.g., a package-level var
registerOnce sync.Once used inside Register/Start) to make registration
idempotent and safe on repeated Start() calls.
---
Nitpick comments:
In `@submit/txinfo_test.go`:
- Around line 49-123: Add tests covering the missing "native" and "plutus_v2"
branches by adding two new parallel test functions (e.g.
TestParseTxInfo_NativeScript and TestParseTxInfo_PlutusV2) that call ParseTxInfo
with the existing fixture hex blobs (nativeScriptTxHex and plutusV2TxHex via
mustDecodeHex), assert info.ScriptType equals "native" and "plutus_v2"
respectively, and assert the expected HasMinting and HasReferenceInputs booleans
for those fixtures (match the fixtures' expected values, e.g. typically false if
they don't include minting/ref inputs); keep the same error handling pattern
used in the other tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ecd81817-9090-45db-8eb1-feedd0f853d4
📒 Files selected for processing (7)
go.modinternal/api/api.gointernal/api/api_test.gointernal/metrics/metrics.gointernal/metrics/metrics_test.gosubmit/txinfo.gosubmit/txinfo_test.go
474f47a to
75d6c19
Compare
Signed-off-by: Ales Verbic <verbotenj@blinklabs.io>
75d6c19 to
69b3106
Compare
Closes #32
Summary by cubic
Adds per‑IP request and transaction content Prometheus metrics to the tx‑submit API with trusted‑proxy‑aware client IP detection. Legacy gauges remain; new counters track request outcomes and DeFi‑relevant signals.
New Features
tx_submit_requests_total{ip,result}withaccepted/rejected/error. Client IP usesX‑Real‑IP> firstX‑Forwarded‑Foronly when the immediate peer is inapi.trustedProxies/API_TRUSTED_PROXIES; otherwise falls back toRemoteAddr.tx_submit_script_type_total{type},tx_submit_has_minting_total{has_minting},tx_submit_has_reference_inputs_total{has_reference_inputs}. Computed viasubmit.ParseTxInfobefore submission; recorded on accept and reject.tx_submit_countandtx_submit_fail_count. Skips per‑IP metric on bad Content‑Type; recordserroron body read failures.Refactors
internal/metricswithRegister()/RegisterForTesting();Start()now callsmetrics.Register().internal/apiupdated to use the package.Written for commit 69b3106. Summary will update on new commits.
Summary by CodeRabbit
New Features
Tests