Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

EVM proxy forwards through a 2-connection pool and exhausts the validator's ephemeral ports

オープン
#4,196 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
55/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
go

調査の方向性

Start at sei-tendermint/internal/p2p/giga_router_common.go:281 and compare its EVM RPC dialing with the long-lived client in giga/evmonly/rpc/server.go:55. Trace how EvmProxy(sender) selects forwarded requests, then validate the tuned client under forwarded transaction load by checking connection failures, TIME_WAIT sockets, throughput, and CPU usage.

索引モデルが issue の本文から書いたものです。

説明

The validator-to-validator EVM proxy dials with no HTTP client, so it inherits http.DefaultTransport and its MaxIdleConnsPerHost of 2. Under load each validator opens and closes a socket for nearly every forwarded transaction and runs out of ephemeral ports.

Where

sei-tendermint/internal/p2p/giga_router_common.go:281:

client, err := ethrpc.DialContext(ctx, addr.EVMRPC.String())

No rpc.WithHTTPClient(...), so go-ethereum falls back to client = new(http.Client) (rpc/http.go:153-156). A zero-value http.Client has a nil Transport and therefore uses http.DefaultTransport, where DefaultMaxIdleConnsPerHost = 2 (Go net/http/transport.go:60).

The forward itself is giga/evmonly/rpc/server.go:55, taken whenever EvmProxy(sender) returns a client — that is, whenever the receiving validator does not own the sender.

Measured

4-validator EVM-only Autobahn chain, blockInterval: 400ms, ~15k tx/s offered, clients routing by address modulo so ~75% of transactions were forwarded. Ephemeral range 32768–60999 (28,232 ports), tcp_tw_reuse=2.

/proc/net/sockstat on each validator:

v0: tw 79789    v1: tw 79685    v2: tw 84468    v3: tw 80069

Each validator held ~80,000 sockets in TIME_WAIT against 28,232 ports, and roughly 40% of forwarded sends failed with connect: cannot assign requested address. Those errors surface at the client as a eth_sendRawTransaction failure naming a validator pod FQDN the client never dialed, which makes them easy to misattribute to the load generator.

Removing the proxy traffic — by having the client send to the owning validator instead — dropped TIME_WAIT to 23–156 per validator and raised throughput from 15,246 to 37,929 tx/s while validator CPU halved, from 23.8–27.4 of 31.85 cores to 13.3–14.1. So the forward was costing roughly half of each validator's CPU.

Suggested fix

Pass a tuned client, as runEvmProxy maintains one long-lived client per committee member:

ethrpc.DialOptions(ctx, addr.EVMRPC.String(), ethrpc.WithHTTPClient(&http.Client{
    Transport: &http.Transport{
        MaxIdleConns:        <peers * perHost>,
        MaxIdleConnsPerHost: <perHost>,
        IdleConnTimeout:     90 * time.Second,
    },
}))

Sizing it to the expected concurrent forwards per peer is enough; anything above the default of 2 removes the port churn.

Two related notes:

  • The forward is untimed, so there is no metric attributing this latency to the proxy. Adding one would have made the diagnosis immediate rather than by subtraction.
  • enable_evm_proxy defaults to true and is not reachable from the SeiNetwork CRD, so a chain cannot opt out without correct client-side shard routing.
主要言語
Go
スター
2.8k
フォーク
888
平均マージ
23時間 48分
マージ済み PR(30日)
227

環境構築

  • Dockerfile または Docker Compose ファイルあり
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。