44 "context"
55 "fmt"
66 "math/big"
7+ "net/http"
78 "net/url"
89 "strings"
910 "sync"
@@ -17,6 +18,19 @@ import (
1718 "github.com/sirupsen/logrus"
1819)
1920
21+ // sharedHTTPClient is reused across all RPC clients to enable TCP connection
22+ // pooling. Go's default MaxIdleConnsPerHost is 2, which forces a new TCP
23+ // connection for nearly every request under any concurrency. This transport
24+ // raises the per-host pool to 100, letting high-throughput callers (like
25+ // transaction spammers) reuse connections instead of churning them.
26+ var sharedHTTPClient = & http.Client {
27+ Transport : & http.Transport {
28+ MaxIdleConns : 100 ,
29+ MaxIdleConnsPerHost : 100 ,
30+ IdleConnTimeout : 90 * time .Second ,
31+ },
32+ }
33+
2034// ClientType represents the type of Ethereum client
2135type ClientType string
2236
@@ -156,7 +170,13 @@ func NewClient(options *ClientOptions) (*Client, error) {
156170 }
157171
158172 ctx := context .Background ()
159- rpcClient , err := rpc .DialOptions (ctx , rpchost , rpc .WithWebsocketMessageSizeLimit (0 ))
173+
174+ dialOpts := []rpc.ClientOption {rpc .WithWebsocketMessageSizeLimit (0 )}
175+ if strings .HasPrefix (rpchost , "http://" ) || strings .HasPrefix (rpchost , "https://" ) {
176+ dialOpts = append (dialOpts , rpc .WithHTTPClient (sharedHTTPClient ))
177+ }
178+
179+ rpcClient , err := rpc .DialOptions (ctx , rpchost , dialOpts ... )
160180 if err != nil {
161181 return nil , err
162182 }
0 commit comments