From 4ff2b45eb300db66b3cb527d996dbfdfbda8df8d Mon Sep 17 00:00:00 2001 From: satyakwok Date: Tue, 26 May 2026 10:05:41 +0200 Subject: [PATCH] chore: restore testnet compose files + lock in gRPC localhost fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `compose.testnet.env` and `docker-compose.testnet.yml` were deleted at some point during the May 22 testnet stack reshuffles. The running testnet container survived but was orphaned from its compose context: `docker compose down/up` would no longer reach it, and a `docker rm` would have lost the env config entirely (with no way to recreate without re-doing the manual `docker run` from scratch). Today (2026-05-26) the missing files surfaced via a different bug: the indexer's gRPC tail subscription was failing every ~130s on `https://grpc-testnet.sentrixchain.com:443`. Cloudflare's HTTP/2 stream timeout was resetting the long-running subscription. Indexer sits on the same host as the testnet fullnode-1 gRPC server (`127.0.0.1:50055`) under `network_mode: host`, so the public URL was doing a pointless hop through CF + Caddy. Fix already applied via manual `docker run` with `GRPC_URL=http://127.0.0.1:50055` — 0 h2 errors confirmed across the 130s failure cycle after the swap. This commit locks in: * `compose.testnet.env.example` — template with the local GRPC_URL and the why-not-public-URL rationale in comments. `compose.testnet.env` itself stays gitignored (carries real Postgres password). * `docker-compose.testnet.yml` — testnet port overrides (:5437 pg, :8089 api) plus the `network_mode: host` declaration the manual `docker run` was carrying. * `.gitignore` — `compose.testnet.env` added alongside `compose.env`. Next clean compose-driven testnet recreate: docker compose -f docker-compose.yml -f docker-compose.testnet.yml \ --env-file compose.testnet.env \ --project-name indexer-rs-testnet \ up -d --force-recreate The running container survives any docker daemon or host restart via its `unless-stopped` policy. Only a `docker rm` would force a recreate, and now there are committed files for that recreate. --- .gitignore | 1 + compose.testnet.env.example | 40 +++++++++++++++++++++++++++++++++++++ docker-compose.testnet.yml | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 compose.testnet.env.example create mode 100644 docker-compose.testnet.yml diff --git a/.gitignore b/.gitignore index 4ef2785..bb25190 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,5 @@ Cargo.lock.bak* .DS_Store Thumbs.db compose.env +compose.testnet.env docker-compose.override.yml diff --git a/compose.testnet.env.example b/compose.testnet.env.example new file mode 100644 index 0000000..51d5f6f --- /dev/null +++ b/compose.testnet.env.example @@ -0,0 +1,40 @@ +# indexer-rs dual-run config TEMPLATE — testnet, on the build/deploy host. +# Copy to `compose.testnet.env` (gitignored) and fill in real values. +# +# Used together with: +# docker compose -f docker-compose.yml -f docker-compose.testnet.yml \ +# --env-file compose.testnet.env \ +# --project-name indexer-rs-testnet \ +# up -d +# +# Postgres on :5437 (avoids :5432 used by TS indexer's pg and :5436 +# used by the mainnet indexer-rs override). API on :8089. +# +# GRPC_URL — keep this as the local loopback URL on the same host as +# the testnet fullnode-1 gRPC server. The public Cloudflare-proxied +# `grpc-testnet.sentrixchain.com` URL gets its long-running tail +# subscription reset every ~130s by Cloudflare's HTTP/2 stream +# timeout; loopback bypasses Cloudflare entirely. +# Verified 2026-05-26: 0 h2 errors after switch, was 4-5/min before. + +DATABASE_URL=postgres://indexer:CHANGE_ME@127.0.0.1:5437/indexer + +RPC_URL=http://127.0.0.1:9545/rpc +REST_URL=http://127.0.0.1:9545 +INDEXER_NETWORK=testnet +INDEXER_BACKFILL_LOOP_SECS=5 +INDEXER_BACKFILL_CONCURRENCY=100 +INDEXER_BACKFILL_BATCH=100 + +# Local loopback — testnet fullnode-1's gRPC bind. Caddy reverse-proxies +# the public `grpc-testnet.sentrixchain.com` to this same port for +# external dApps; same-host services skip the proxy hop. +GRPC_URL=http://127.0.0.1:50055 + +INDEXER_API_BIND=127.0.0.1:8089 +INDEXER_API_METRICS_BIND=127.0.0.1:9081 + +RUST_LOG=indexer=debug,indexer_sync=debug,sqlx=warn,hyper=warn,tower_http=info +POSTGRES_PASSWORD=CHANGE_ME +POSTGRES_USER=indexer +POSTGRES_DB=indexer diff --git a/docker-compose.testnet.yml b/docker-compose.testnet.yml new file mode 100644 index 0000000..f7a662f --- /dev/null +++ b/docker-compose.testnet.yml @@ -0,0 +1,39 @@ +# Testnet override for indexer-rs. +# +# Usage: +# docker compose -f docker-compose.yml -f docker-compose.testnet.yml \ +# --env-file compose.testnet.env \ +# --project-name indexer-rs-testnet \ +# up -d +# +# Postgres on :5437 (avoids :5432 used by TS indexer's pg, and :5436 +# used by the mainnet indexer-rs override). API on :8089 (avoids :8080 +# from mainnet override + code-server on :8080). +# +# Restored 2026-05-26 after the gRPC tail reconnect-loop incident. +# Original file was deleted at some point during the 2026-05-22 testnet +# stack reshuffles; the running testnet container was orphaned from its +# compose context until this restore. compose.testnet.env carries the +# canonical GRPC_URL fix (`http://127.0.0.1:50055` instead of the public +# Cloudflare-proxied URL — see that file for the why). + +services: + postgres: + ports: !override + - "127.0.0.1:5437:5432" + + indexer: + image: indexer-rs:erc20-handler + # network_mode: host so 127.0.0.1:50055 (testnet fullnode-1 gRPC) + # resolves to the host's loopback instead of the container's own. + # Same reason GRPC_URL is the local URL in compose.testnet.env. + network_mode: host + env_file: + - ./compose.testnet.env + + api: + image: indexer-rs:erc20-handler + ports: !override + - "127.0.0.1:8089:8080" + env_file: + - ./compose.testnet.env