Skip to content

Commit ec9f9bf

Browse files
tac0turtleMarko Baricevicrandygrokdependabot[bot]julienrbrt
authored
feat: add key rotation (#3282)
* add key rotation * remove need for pubkey and add some tests * comments and amendments * commen changes * redo the design * revert header change * deps * fix docker and proto * ammendments from commnets * linting * test: cover unexpected DA proposer rejection * fix: resolve key rotation conflicts with main (#3313) * 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> * fix merge * fix: classify invalid external blocks safely * chore: update EVM module tidy output * ci: retry Docker image pulls in E2E tests * fix: preserve DA data until block acceptance * fix: selectively evict header or data from cache on block validation failure Classify block validation errors as FaultHeader or FaultData so the syncer can drop only the offending side of the (header, data) pair from the DA cache. Previously a single mismatch removed both, discarding a potentially legitimate counterpart. * feat: handle execution proposer rotation * test: require proposer-control image for rotation e2e * feat: support promotable proposer rotation * ci: remove Docker image pre-pull retries * chore: remove unused markdown link config * refactor: make execute result structural * refactor: remove proposer from execution info * fix: resolve CI lint and benchmark failures * fix: reject unexpected DA proposers early * refactor: simplify sync validation faults * refactor: remove unused header verifier * docs: remove stale execution info proposer field * fix: replace pending DA header with expected proposer * ci: configure markdown link checker * fix: address key rotation review comments * fix: stabilize kv HTTP shutdown test * docs: use relative markdown links * fix: update CI tidy and markdown checks --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Marko Baricevic <markobaricevic@MarkosMacStudio.localdomain> Co-authored-by: Randy Grok <randygrok@gmail.com> Co-authored-by: Randy Grok <98407738+randygrok@users.noreply.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: Cian Hatton <github.qpeyb@simplelogin.fr> Co-authored-by: criciss <cricis@msn.com>
1 parent 79b5b4f commit ec9f9bf

101 files changed

Lines changed: 2858 additions & 433 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/proto.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,17 @@ jobs:
1515
- uses: bufbuild/buf-action@v1
1616
with:
1717
format: false
18+
breaking: false
19+
- name: Check protobuf breaking changes
20+
env:
21+
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }}
22+
run: |
23+
if [ -z "$BASE_SHA" ] || [[ "$BASE_SHA" =~ ^0+$ ]]; then
24+
echo "No base SHA available for buf breaking check"
25+
exit 0
26+
fi
27+
28+
buf breaking proto \
29+
--limit-to-input-files \
30+
--error-format github-actions \
31+
--against "https://github.com/${{ github.repository }}.git#format=git,commit=${BASE_SHA}"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Check out our tutorials on our [website][docs].
5858

5959
## Onboarding with Claude Code
6060

61-
Use [Claude Code](https://claude.ai/code) to explore the codebase:
61+
Use [Claude Code](https://code.claude.com/docs/en/overview) to explore the codebase:
6262

6363
```bash
6464
cd ev-node && claude

apps/evm/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.25.8
44

55
replace (
66
github.com/evstack/ev-node => ../../
7+
github.com/evstack/ev-node/core => ../../core
78
github.com/evstack/ev-node/execution/evm => ../../execution/evm
89
)
910

apps/evm/go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,6 @@ github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJ
228228
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8=
229229
github.com/ethereum/go-ethereum v1.17.3 h1:Ev/sQHH+UdKZHWjuVzhu2pxhi/sXaPZl23Q+Q5LDd4Q=
230230
github.com/ethereum/go-ethereum v1.17.3/go.mod h1:f2EhRwqewIZkGoQekywI2Y2RZAMTSavLNkD9qItFy1A=
231-
github.com/evstack/ev-node/core v1.0.0 h1:s0Tx0uWHme7SJn/ZNEtee4qNM8UO6PIxXnHhPbbKTz8=
232-
github.com/evstack/ev-node/core v1.0.0/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
233231
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
234232
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
235233
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=

apps/grpc/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.25.8
44

55
replace (
66
github.com/evstack/ev-node => ../../
7+
github.com/evstack/ev-node/core => ../../core
78
github.com/evstack/ev-node/execution/grpc => ../../execution/grpc
89
)
910

apps/grpc/go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,6 @@ github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQ
188188
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
189189
github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
190190
github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
191-
github.com/evstack/ev-node/core v1.0.0 h1:s0Tx0uWHme7SJn/ZNEtee4qNM8UO6PIxXnHhPbbKTz8=
192-
github.com/evstack/ev-node/core v1.0.0/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
193191
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
194192
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
195193
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=

apps/testapp/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ WORKDIR /ev-node
2121
# Dependencies are only re-downloaded when go.mod or go.sum change.
2222
COPY go.mod go.sum ./
2323
COPY apps/testapp/go.mod apps/testapp/go.sum ./apps/testapp/
24+
COPY core/go.mod core/go.sum ./core/
2425
RUN go mod download && (cd apps/testapp && go mod download)
2526

2627
# Copy the rest of the source and build.

apps/testapp/go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ module github.com/evstack/ev-node/apps/testapp
22

33
go 1.25.8
44

5-
replace github.com/evstack/ev-node => ../../.
5+
replace (
6+
github.com/evstack/ev-node => ../../.
7+
github.com/evstack/ev-node/core => ../../core
8+
)
69

710
require (
811
github.com/evstack/ev-node v1.1.3

apps/testapp/go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,6 @@ github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQ
188188
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
189189
github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
190190
github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
191-
github.com/evstack/ev-node/core v1.0.0 h1:s0Tx0uWHme7SJn/ZNEtee4qNM8UO6PIxXnHhPbbKTz8=
192-
github.com/evstack/ev-node/core v1.0.0/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
193191
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
194192
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
195193
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=

apps/testapp/kv/http_server_test.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package executor
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"net"
87
"net/http"
@@ -241,8 +240,14 @@ func TestHTTPServerContextCancellation(t *testing.T) {
241240
errCh <- server.Start(ctx)
242241
}()
243242

244-
// Give it time to start
245-
time.Sleep(100 * time.Millisecond)
243+
select {
244+
case err := <-errCh:
245+
if err != nil {
246+
t.Fatalf("Server start error: %v", err)
247+
}
248+
case <-time.After(2 * time.Second):
249+
t.Fatal("Server start timed out")
250+
}
246251

247252
// Send a request to confirm it's running
248253
client := &http.Client{Timeout: 1 * time.Second}
@@ -260,21 +265,33 @@ func TestHTTPServerContextCancellation(t *testing.T) {
260265

261266
// Cancel the context to shut down the server
262267
cancel()
268+
client.CloseIdleConnections()
263269

264-
// Wait for shutdown to complete with timeout
265-
select {
266-
case err := <-errCh:
267-
if err != nil && errors.Is(err, http.ErrServerClosed) {
268-
t.Fatalf("Server shutdown error: %v", err)
269-
}
270-
case <-time.After(2 * time.Second):
271-
t.Fatal("Server shutdown timed out")
270+
// Verify server is actually shutdown by waiting until new connections fail.
271+
shutdownClient := &http.Client{
272+
Timeout: 100 * time.Millisecond,
273+
Transport: &http.Transport{
274+
DisableKeepAlives: true,
275+
},
272276
}
273-
274-
// Verify server is actually shutdown by attempting a new connection
275-
_, err = client.Get(fmt.Sprintf("http://%s/store", serverAddr))
276-
if err == nil {
277-
t.Fatal("Expected connection error after shutdown, but got none")
277+
defer shutdownClient.CloseIdleConnections()
278+
279+
deadline := time.After(2 * time.Second)
280+
ticker := time.NewTicker(10 * time.Millisecond)
281+
defer ticker.Stop()
282+
for {
283+
select {
284+
case <-deadline:
285+
t.Fatal("Expected connection error after shutdown, but server kept accepting requests")
286+
case <-ticker.C:
287+
resp, err := shutdownClient.Get(fmt.Sprintf("http://%s/store", serverAddr))
288+
if err != nil {
289+
return
290+
}
291+
if err := resp.Body.Close(); err != nil {
292+
t.Fatalf("Failed to close response body: %v", err)
293+
}
294+
}
278295
}
279296
}
280297

0 commit comments

Comments
 (0)