feat(execution/grpc): adding support for grpc otlp#3300
Conversation
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 WalkthroughWalkthroughAdds OpenTelemetry propagation via inbound and outbound Connect interceptors; the client and handler now apply these interceptors, OTEL modules are added to go.mod, and tests verify traceparent and baggage propagation plus end-to-end trace identity preservation. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant OutIC as Outbound\nInterceptor
participant Prop as OTEL\nPropagator
participant GRPCClient as Connect\nClient
participant InIC as Inbound\nInterceptor
participant Server as Server\nHandler
Client->>OutIC: Call with context (may have baggage/trace)
OutIC->>Prop: Retrieve global text-map propagator
Prop-->>OutIC: Propagator
OutIC->>OutIC: Inject headers into request
OutIC->>GRPCClient: Send request with headers
GRPCClient->>InIC: Deliver request + headers
InIC->>Prop: Retrieve global text-map propagator
Prop-->>InIC: Propagator
InIC->>InIC: Extract headers into context
InIC->>Server: Forward request with extracted context
Server-->>InIC: Response
InIC-->>GRPCClient: Return response
GRPCClient-->>OutIC: Response
OutIC-->>Client: Final response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ 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. Review rate limit: 0/1 reviews remaining, refill in 57 minutes and 11 seconds.Comment |
|
The latest Buf updates on your PR. Results from workflow CI / buf-check (pull_request).
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3300 +/- ##
==========================================
+ Coverage 60.52% 60.72% +0.20%
==========================================
Files 126 127 +1
Lines 13721 13735 +14
==========================================
+ Hits 8304 8340 +36
+ Misses 4513 4491 -22
Partials 904 904
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@execution/grpc/otel_propagation_test.go`:
- Around line 156-157: The test currently writes to shared variable midSpan from
the handler goroutine and reads it from the test goroutine with a time.Sleep,
causing a race; change this to a channel-based handoff: create a chan trace.Span
or chan trace.SpanContext (or chan string for traceID) in the test, have the
handler (the goroutine that currently assigns midSpan) send the span (or
span.Context()/TraceID) on that channel, and have the test goroutine receive
from the channel before asserting (replace uses of midSpan with the received
value); update references to midSpan in the handler and assertions to use the
received value to eliminate the race and remove the timing-dependent sleep.
- Around line 83-89: The test has data races because gotTraceparent, gotBaggage,
and midSpan are written from interceptor/handler goroutines and read from the
test goroutine; replace the unsynchronized string/bool accesses with a sync
primitive (e.g., a single sync.Mutex protecting gotTraceparent and gotBaggage
and a channel or sync.Cond to signal midSpan readiness) so writes in
captureHeader (UnaryInterceptorFunc) and the handler acquire the mutex before
setting values and signal the channel after setting midSpan, and the test
goroutine waits on that channel (or locks the mutex) instead of sleeping; update
all locations referencing gotTraceparent, gotBaggage, and midSpan to use the
chosen synchronization to eliminate race detector warnings.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: acca9aea-2543-4f34-861a-aff1dae1335d
⛔ Files ignored due to path filters (1)
execution/grpc/go.sumis excluded by!**/*.sum
📒 Files selected for processing (5)
execution/grpc/client.goexecution/grpc/go.modexecution/grpc/handler.goexecution/grpc/otel_propagation.goexecution/grpc/otel_propagation_test.go
| gotTraceparent := "" | ||
| captureHeader := connect.UnaryInterceptorFunc(func(next connect.UnaryFunc) connect.UnaryFunc { | ||
| return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { | ||
| gotTraceparent = req.Header().Get("traceparent") | ||
| return next(ctx, req) | ||
| } | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd -t f -i "otel_propagation_test.go" | head -20Repository: evstack/ev-node
Length of output: 99
🏁 Script executed:
cat -n execution/grpc/otel_propagation_test.go | head -200Repository: evstack/ev-node
Length of output: 7290
🏁 Script executed:
# Verify no explicit sync primitives protect these variables
rg -A 10 "var (gotTraceparent|gotBaggage|midSpan)" execution/grpc/otel_propagation_test.goRepository: evstack/ev-node
Length of output: 1021
🏁 Script executed:
# Check if there are any sync primitives used elsewhere in the test file
rg "(sync\.|Mutex|WaitGroup|Channel)" execution/grpc/otel_propagation_test.goRepository: evstack/ev-node
Length of output: 41
🏁 Script executed:
# Confirm that GetTxs and GetExecutionInfo are blocking calls that wait for completion
grep -A 5 "func.*GetTxs\|func.*GetExecutionInfo" execution/grpc/otel_propagation_test.go | head -20Repository: evstack/ev-node
Length of output: 41
🏁 Script executed:
# Check if httptest.Server spawns goroutines (standard library behavior verification)
rg "httptest.NewServer" -B 2 -A 2 execution/grpc/otel_propagation_test.goRepository: evstack/ev-node
Length of output: 865
🏁 Script executed:
# Check how client.GetTxs() is defined to confirm it's a blocking call
fd -t f "client.go" execution/grpc/ | head -5Repository: evstack/ev-node
Length of output: 84
🏁 Script executed:
# Look for the client implementation
rg "func.*NewClient" -A 10 execution/grpc/ | head -30Repository: evstack/ev-node
Length of output: 730
🏁 Script executed:
# Verify the blocking behavior by checking the generated client code signature
cat -n execution/grpc/client.go | grep -A 20 "func.*GetTxs"Repository: evstack/ev-node
Length of output: 1082
🏁 Script executed:
# Confirm the blocking nature - check if there's an error return that would indicate completion
rg "client.GetTxs|client.GetExecutionInfo" execution/grpc/otel_propagation_test.go | grep -v "downstreamClient\|upstreamClient"Repository: evstack/ev-node
Length of output: 240
Synchronize header capture and span access to avoid test data races.
gotTraceparent, gotBaggage, and midSpan are written in handler/interceptor goroutines and read in the test goroutine without synchronization. Although the blocking RPC calls provide implicit ordering, the Go race detector requires explicit synchronization primitives (mutex or channels) to recognize the happens-before relationship. Additionally, the fixed 10ms sleep at line 189 violates the determinism guideline; use explicit synchronization instead of timing-based waits.
Suggested fix (mutex-guarded capture)
import (
"context"
"net/http/httptest"
+ "sync"
"testing"
"time"
@@
- gotTraceparent := ""
+ var mu sync.Mutex
+ gotTraceparent := ""
captureHeader := connect.UnaryInterceptorFunc(func(next connect.UnaryFunc) connect.UnaryFunc {
return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
+ mu.Lock()
gotTraceparent = req.Header().Get("traceparent")
+ mu.Unlock()
return next(ctx, req)
}
})
@@
- if gotTraceparent == "" {
+ mu.Lock()
+ traceparent := gotTraceparent
+ mu.Unlock()
+ if traceparent == "" {
t.Fatalf("expected traceparent metadata to be propagated")
}Apply the same pattern to gotBaggage (lines 123-131) and midSpan (lines 156-193). For the end-to-end test, use a channel or sync primitive to wait for the handler to populate midSpan instead of the fixed sleep.
Also applies to: 97-103, 123-131, 139-148, 156-193
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@execution/grpc/otel_propagation_test.go` around lines 83 - 89, The test has
data races because gotTraceparent, gotBaggage, and midSpan are written from
interceptor/handler goroutines and read from the test goroutine; replace the
unsynchronized string/bool accesses with a sync primitive (e.g., a single
sync.Mutex protecting gotTraceparent and gotBaggage and a channel or sync.Cond
to signal midSpan readiness) so writes in captureHeader (UnaryInterceptorFunc)
and the handler acquire the mutex before setting values and signal the channel
after setting midSpan, and the test goroutine waits on that channel (or locks
the mutex) instead of sleeping; update all locations referencing gotTraceparent,
gotBaggage, and midSpan to use the chosen synchronization to eliminate race
detector warnings.
| var midSpan trace.Span | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n execution/grpc/otel_propagation_test.go | head -200Repository: evstack/ev-node
Length of output: 7290
🏁 Script executed:
tail -n +195 execution/grpc/otel_propagation_test.go | head -50Repository: evstack/ev-node
Length of output: 332
Fix concurrent access to midSpan without race condition or timing-dependent waits.
midSpan is written in the handler goroutine (line 170) and read in the test goroutine (line 192) without synchronization. The time.Sleep(10ms) is brittle and timing-dependent, violating the determinism requirement for tests. Use channel-based synchronization to pass the trace ID explicitly instead.
Suggested fix (channel-based synchronization)
- var midSpan trace.Span
+ midTraceIDCh := make(chan trace.TraceID, 1)
@@
upstreamExec := &mockExecutor{getTxsFunc: func(ctx context.Context) ([][]byte, error) {
ctx, span := tracer.Start(ctx, "upstream-mid")
- midSpan = span
+ midTraceIDCh <- span.SpanContext().TraceID()
defer span.End()
@@
- time.Sleep(10 * time.Millisecond)
-
rootTraceID := root.SpanContext().TraceID()
- if midSpan.SpanContext().TraceID() != rootTraceID {
+ var midTraceID trace.TraceID
+ select {
+ case midTraceID = <-midTraceIDCh:
+ case <-time.After(time.Second):
+ t.Fatalf("timeout waiting for upstream-mid span")
+ }
+ if midTraceID != rootTraceID {
t.Fatalf("mid span trace id mismatch")
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@execution/grpc/otel_propagation_test.go` around lines 156 - 157, The test
currently writes to shared variable midSpan from the handler goroutine and reads
it from the test goroutine with a time.Sleep, causing a race; change this to a
channel-based handoff: create a chan trace.Span or chan trace.SpanContext (or
chan string for traceID) in the test, have the handler (the goroutine that
currently assigns midSpan) send the span (or span.Context()/TraceID) on that
channel, and have the test goroutine receive from the channel before asserting
(replace uses of midSpan with the received value); update references to midSpan
in the handler and assertions to use the received value to eliminate the race
and remove the timing-dependent sleep.
# Conflicts: # execution/grpc/client.go
* build(deps): Bump the all-go group across 8 directories with 7 updates (#3291) * build(deps): Bump the all-go group across 8 directories with 7 updates Bumps the all-go group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [github.com/aws/aws-sdk-go-v2/service/kms](https://github.com/aws/aws-sdk-go-v2) | `1.50.5` | `1.51.0` | | [github.com/aws/smithy-go](https://github.com/aws/smithy-go) | `1.25.0` | `1.25.1` | | [github.com/libp2p/go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub) | `0.15.0` | `0.16.0` | | [github.com/rs/zerolog](https://github.com/rs/zerolog) | `1.35.0` | `1.35.1` | | [google.golang.org/api](https://github.com/googleapis/google-api-go-client) | `0.274.0` | `0.276.0` | Bumps the all-go group with 1 update in the /apps/evm directory: [github.com/rs/zerolog](https://github.com/rs/zerolog). Bumps the all-go group with 1 update in the /apps/grpc directory: [github.com/rs/zerolog](https://github.com/rs/zerolog). Bumps the all-go group with 1 update in the /apps/testapp directory: [github.com/rs/zerolog](https://github.com/rs/zerolog). Bumps the all-go group with 2 updates in the /execution/evm directory: [github.com/rs/zerolog](https://github.com/rs/zerolog) and [github.com/evstack/ev-node](https://github.com/evstack/ev-node). Bumps the all-go group with 1 update in the /execution/grpc directory: [github.com/evstack/ev-node](https://github.com/evstack/ev-node). Bumps the all-go group with 1 update in the /test/docker-e2e directory: [github.com/celestiaorg/tastora](https://github.com/celestiaorg/tastora). Bumps the all-go group with 2 updates in the /test/e2e directory: [github.com/rs/zerolog](https://github.com/rs/zerolog) and [github.com/celestiaorg/tastora](https://github.com/celestiaorg/tastora). Updates `github.com/aws/aws-sdk-go-v2/service/kms` from 1.50.5 to 1.51.0 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](aws/aws-sdk-go-v2@service/ssm/v1.50.5...service/s3/v1.51.0) Updates `github.com/aws/smithy-go` from 1.25.0 to 1.25.1 - [Release notes](https://github.com/aws/smithy-go/releases) - [Changelog](https://github.com/aws/smithy-go/blob/main/CHANGELOG.md) - [Commits](aws/smithy-go@v1.25.0...v1.25.1) Updates `github.com/libp2p/go-libp2p-pubsub` from 0.15.0 to 0.16.0 - [Release notes](https://github.com/libp2p/go-libp2p-pubsub/releases) - [Commits](libp2p/go-libp2p-pubsub@v0.15.0...v0.16.0) Updates `github.com/rs/zerolog` from 1.35.0 to 1.35.1 - [Commits](rs/zerolog@v1.35.0...v1.35.1) Updates `google.golang.org/api` from 0.274.0 to 0.276.0 - [Release notes](https://github.com/googleapis/google-api-go-client/releases) - [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md) - [Commits](googleapis/google-api-go-client@v0.274.0...v0.276.0) Updates `github.com/rs/zerolog` from 1.35.0 to 1.35.1 - [Commits](rs/zerolog@v1.35.0...v1.35.1) Updates `github.com/rs/zerolog` from 1.35.0 to 1.35.1 - [Commits](rs/zerolog@v1.35.0...v1.35.1) Updates `github.com/rs/zerolog` from 1.35.0 to 1.35.1 - [Commits](rs/zerolog@v1.35.0...v1.35.1) Updates `github.com/rs/zerolog` from 1.35.0 to 1.35.1 - [Commits](rs/zerolog@v1.35.0...v1.35.1) Updates `github.com/evstack/ev-node` from 1.1.0 to 1.1.1 - [Release notes](https://github.com/evstack/ev-node/releases) - [Changelog](https://github.com/evstack/ev-node/blob/main/CHANGELOG.md) - [Commits](v1.1.0...v1.1.1) Updates `github.com/evstack/ev-node` from 1.1.0 to 1.1.1 - [Release notes](https://github.com/evstack/ev-node/releases) - [Changelog](https://github.com/evstack/ev-node/blob/main/CHANGELOG.md) - [Commits](v1.1.0...v1.1.1) Updates `github.com/celestiaorg/tastora` from 0.17.0 to 0.19.0 - [Release notes](https://github.com/celestiaorg/tastora/releases) - [Commits](celestiaorg/tastora@v0.17.0...v0.19.0) Updates `github.com/rs/zerolog` from 1.35.0 to 1.35.1 - [Commits](rs/zerolog@v1.35.0...v1.35.1) Updates `github.com/celestiaorg/tastora` from 0.16.1-0.20260312082036-2ee1b0a2ac4e to 0.19.0 - [Release notes](https://github.com/celestiaorg/tastora/releases) - [Commits](celestiaorg/tastora@v0.17.0...v0.19.0) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/service/kms dependency-version: 1.51.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-go - dependency-name: github.com/aws/smithy-go dependency-version: 1.25.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/libp2p/go-libp2p-pubsub dependency-version: 0.16.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-go - dependency-name: github.com/rs/zerolog dependency-version: 1.35.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: google.golang.org/api dependency-version: 0.276.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-go - dependency-name: github.com/rs/zerolog dependency-version: 1.35.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/rs/zerolog dependency-version: 1.35.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/rs/zerolog dependency-version: 1.35.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/rs/zerolog dependency-version: 1.35.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/evstack/ev-node dependency-version: 1.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/evstack/ev-node dependency-version: 1.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/celestiaorg/tastora dependency-version: 0.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-go - dependency-name: github.com/rs/zerolog dependency-version: 1.35.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-go - dependency-name: github.com/celestiaorg/tastora dependency-version: 0.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-go ... Signed-off-by: dependabot[bot] <support@github.com> * tidy --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Julien Robert <julien@rbrt.fr> * build(deps): Bump postcss from 8.5.8 to 8.5.12 in /docs in the npm_and_yarn group across 1 directory (#3292) build(deps): Bump postcss Bumps the npm_and_yarn group with 1 update in the /docs directory: [postcss](https://github.com/postcss/postcss). Updates `postcss` from 8.5.8 to 8.5.12 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](postcss/postcss@8.5.8...8.5.12) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.12 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci: skip code jobs on docs-only changes (#3295) Add a `changes` job using dorny/paths-filter to detect whether any non-documentation files were modified. All heavy jobs (lint, docker, test, docker-tests, proto) are gated behind this check and skipped when the PR only touches docs/** or markdown files. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: brand-aligned syntax theme for code blocks (#3294) * docs: better code readability * chore: restore yarn.lock to main Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(style): address PR review feedback - Add `"type": "dark"` to ev-dark.json theme manifest - Raise punctuation token contrast from #505050 to #767676 (WCAG AA) - Align --vp-code-block-color CSS var with ev-dark default text (#dbd7ca) - Use ThemeRegistration type instead of `as any` in config.ts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(cache): reduce tx cache retention (#3299) * docs: high availability sequencer guide (#3293) * docs: ev-node high availability * docs: node placement * docs(ha): address PR review feedback Critical fixes: - Fix snapshot_threshold math: 5000 ÷ 10 = 500s ≈ 8.3 min (not 83s) - Fix trailing_logs math: 18000 ÷ 10 = 1800s = 30 min (not 5 min) Medium fixes: - Fix heartbeat_timeout description: it is a follower-side election trigger, not the interval at which the leader sends heartbeats - Add explicit restart instruction after Step 5 data copy in single-to-ha.md so the chain keeps producing blocks during preparation (Steps 6-8) - Replace priv_validator_key.json with signer.json in single-to-ha.md to match cluster-setup.md and the E2E tests Minor fixes: - Exclude self from raft.peers in all examples (cluster-setup.md node-1 yaml/CLI/systemd, single-to-ha.md node-1 and node-2) - Add "exclude local node" note to raft.peers description in overview.md - Fix P2P port in overview.md Interaction with P2P section (7676 → 26656) - Add text language tag to all bare fenced blocks (MD040): multiaddr example, RTT equations, and all log snippets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(ha): absorb raft_production.md into ha/overview.md raft_production.md had no sidebar entry and its content was fully superseded by the new ha/ guides. Extract the three pieces that were unique to it — bootstrap flag docs, auto-detection startup mode explanation, and static-membership limitation note — into ha/overview.md, then delete the file. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(ha): use EnvironmentFile for signer passphrase Passing --evnode.signer.passphrase inline exposes the secret in ps aux, journalctl, and shell history. - Add EnvironmentFile=/etc/ev-node/env (chmod 600) to the systemd unit in cluster-setup.md with setup instructions - Replace all inline <YOUR_PASSPHRASE> occurrences with $EV_SIGNER_PASSPHRASE sourced from /etc/ev-node/env in every evm start / evm init snippet across both guides Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(ha): explicit node-2 peers and action-based rolling restart - Replace "peers list is identical" stub in node-2 config with an explicit peers list that excludes node-2 itself, and add a note that each node must omit itself from raft.peers - Replace "Wait ~30 seconds" in rolling restart with journalctl one-liners that exit as soon as the node logs follower/leader state, giving a deterministic signal instead of an arbitrary timeout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(ha): fix raft.peers self-inclusion startup bug The abbreviated node-2 snippet with "# peers list is identical" caused a startup failure: with raft_addr=0.0.0.0:5001 the bootstrap code's literal address comparison does not recognise node-2@10.0.0.2:5001 as self, so node-2 is appended twice and deduplicateServers returns "duplicate peers found in config". - Fix intro text: "only raft.node_id and raft_addr differ" → "raft.node_id is unique; raft.peers and p2p.peers must exclude self" - Expand node-2 snippet to a full evnode.yaml with the correct peers list (node-1, node-3, node-4, node-5 — no node-2) and an inline explanation of the wildcard address pitfall - Align overview.md trailing_logs example to 1 block/s (matching block_time: "1s" used throughout) and note the 10 block/s rate too Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(ha): fix passphrase flag and failover kill cardinality check Replace non-existent --evnode.signer.passphrase with the actual --evnode.signer.passphrase_file flag throughout cluster-setup and single-to-ha guides. Update passphrase setup to create a chmod 600 file at /etc/ev-node/passphrase referenced directly by the flag. Add mapfile-based cardinality check in the failover test fallback kill command to guard against killing the wrong process. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(ha): fix RPC endpoints, init ordering, and snap_count CLI flag Replace incorrect CometBFT RPC calls (port 26657/status) with the actual ev-node HTTP API (port 7331 /health/ready, /raft/node) and EVM execution layer (cast block latest) throughout both guides. Align single-to-ha Step 2 init ordering with cluster-setup: create passphrase file before evm init so the signer key is encrypted from the start, and pass --evnode.node.aggregator and passphrase_file flags. Fix Step 9a fallback kill in single-to-ha to use mapfile cardinality check, matching the pattern already applied in cluster-setup. Add --evnode.raft.snap_count=3 to the CLI start example to match the YAML config block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * perf(store): save metadata async (#3298) * perf(store): save metadata async * cl * Optimize metadata writes with batching * feedback * De-duplicate batched writes by key in cached store * fix * updates * chore(deps): security (#3296) * fix security deps * fix helpers * feat: add grpc socket and flattn tx batches to allow for lower allocations (#3297) * add grpc socket and flattn tx batches to allow for lower allocations * redo proto * docs: update changelog for grpc execution transport * remove extra txs * refactor(execution/grpc): move execution service where it belongs (#3302) * refactor(execution/grpc): move execution service where it belongs * reduce diff * fix lint * feat(execution/grpc): adding support for grpc otlp (#3300) * feat: adding support for grpc oltp * chore: fix linting * cl --------- Co-authored-by: Julien Robert <julien@rbrt.fr> * chore: fix some minor issues in comments (#3304) * build(deps): Bump dorny/paths-filter from 3 to 4 (#3308) Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 3 to 4. - [Release notes](https://github.com/dorny/paths-filter/releases) - [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) - [Commits](dorny/paths-filter@v3...v4) --- updated-dependencies: - dependency-name: dorny/paths-filter dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(pkg/sequencers): add queue limit in solo sequencer (#3312) * feat(pkg/sequencers): add queue limit in solo sequencer * use option * cl * move test files * fix: address key rotation CI failures * fix: repair markdown link checks * test: stabilize sync loop persistence test --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Julien Robert <julien@rbrt.fr> Co-authored-by: auricom <27022259+auricom@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Marko <marko@baricevic.me> Co-authored-by: Cian Hatton <github.qpeyb@simplelogin.fr> Co-authored-by: criciss <cricis@msn.com>

Overview
When OLTP wiring was set up, it was only wired for HTTP, this adds the grpc interceptor
Summary by CodeRabbit
New Features
Tests
Chores