From 3f578353da9345588be99f48a51dda30523df848 Mon Sep 17 00:00:00 2001 From: Stephan D Date: Tue, 3 Mar 2026 18:32:26 +0100 Subject: [PATCH] fixed tron ip connection --- api/gateway/tron/client/client.go | 5 +---- api/gateway/tron/config.dev.yml | 6 ++++-- api/gateway/tron/config.yml | 6 ++++-- .../tron/internal/server/internal/serverimp.go | 14 ++++++++++---- .../internal/service/gateway/tronclient/client.go | 11 ++++++++++- .../service/gateway/tronclient/registry.go | 4 +++- api/gateway/tron/shared/helpers.go | 1 + 7 files changed, 33 insertions(+), 14 deletions(-) diff --git a/api/gateway/tron/client/client.go b/api/gateway/tron/client/client.go index a54b3b46..6131ace6 100644 --- a/api/gateway/tron/client/client.go +++ b/api/gateway/tron/client/client.go @@ -63,9 +63,6 @@ func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, erro return nil, merrors.InvalidArgument("chain-gateway: address is required") } - dialCtx, cancel := context.WithTimeout(ctx, cfg.DialTimeout) - defer cancel() - dialOpts := make([]grpc.DialOption, 0, len(opts)+1) dialOpts = append(dialOpts, opts...) @@ -75,7 +72,7 @@ func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, erro dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) } - conn, err := grpc.DialContext(dialCtx, cfg.Address, dialOpts...) + conn, err := grpc.NewClient(cfg.Address, dialOpts...) if err != nil { return nil, merrors.Internal(fmt.Sprintf("chain-gateway: dial %s: %s", cfg.Address, err.Error())) } diff --git a/api/gateway/tron/config.dev.yml b/api/gateway/tron/config.dev.yml index cc3e5022..7cfbfc38 100644 --- a/api/gateway/tron/config.dev.yml +++ b/api/gateway/tron/config.dev.yml @@ -40,8 +40,10 @@ chains: chain_id: 3448148188 # Nile testnet native_token: TRX rpc_url_env: TRON_GATEWAY_RPC_URL - grpc_url_env: TRON_GATEWAY_GRPC_URL - grpc_token_env: TRON_GATEWAY_GRPC_TOKEN + grpc: + url_env: TRON_GATEWAY_GRPC_URL + token_env: TRON_GATEWAY_GRPC_TOKEN + force_ipv4: false gas_topup_policy: buffer_percent: 0.10 min_native_balance_trx: 10 diff --git a/api/gateway/tron/config.yml b/api/gateway/tron/config.yml index 8c572774..cbf73c2e 100644 --- a/api/gateway/tron/config.yml +++ b/api/gateway/tron/config.yml @@ -40,8 +40,10 @@ chains: chain_id: 728126428 # 0x2b6653dc native_token: TRX rpc_url_env: TRON_GATEWAY_RPC_URL - grpc_url_env: TRON_GATEWAY_GRPC_URL - grpc_token_env: TRON_GATEWAY_GRPC_TOKEN + grpc: + url_env: TRON_GATEWAY_GRPC_URL + token_env: TRON_GATEWAY_GRPC_TOKEN + force_ipv4: true gas_topup_policy: buffer_percent: 0.10 min_native_balance_trx: 10 diff --git a/api/gateway/tron/internal/server/internal/serverimp.go b/api/gateway/tron/internal/server/internal/serverimp.go index a4de7253..6dc55905 100644 --- a/api/gateway/tron/internal/server/internal/serverimp.go +++ b/api/gateway/tron/internal/server/internal/serverimp.go @@ -53,14 +53,19 @@ type config struct { type chainConfig struct { Name string `yaml:"name"` RPCURLEnv string `yaml:"rpc_url_env"` - GRPCURLEnv string `yaml:"grpc_url_env"` // Native TRON gRPC endpoint - GRPCTokenEnv string `yaml:"grpc_token_env"` + GRPC chainGRPCConfig `yaml:"grpc"` ChainID uint64 `yaml:"chain_id"` NativeToken string `yaml:"native_token"` Tokens []tokenConfig `yaml:"tokens"` GasTopUpPolicy *gasTopUpPolicyConfig `yaml:"gas_topup_policy"` } +type chainGRPCConfig struct { + URLEnv string `yaml:"url_env"` // Native TRON gRPC endpoint env var + TokenEnv string `yaml:"token_env"` // Optional auth token env var for x-token header + ForceIPv4 bool `yaml:"force_ipv4"` // Force IPv4 sockets when dialing TRON gRPC. +} + type serviceWalletConfig struct { Chain string `yaml:"chain"` Address string `yaml:"address"` @@ -282,14 +287,14 @@ func resolveNetworkConfigs(logger mlogger.Logger, chains []chainConfig) ([]gatew // Resolve optional TRON gRPC URL grpcURL := "" - if grpcEnv := strings.TrimSpace(chain.GRPCURLEnv); grpcEnv != "" { + if grpcEnv := strings.TrimSpace(chain.GRPC.URLEnv); grpcEnv != "" { grpcURL = strings.TrimSpace(os.Getenv(grpcEnv)) if grpcURL != "" { logger.Info("TRON gRPC URL configured", zap.String("chain", network.String()), zap.String("env", grpcEnv)) } } grpcToken := "" - if grpcTokenEnv := strings.TrimSpace(chain.GRPCTokenEnv); grpcTokenEnv != "" { + if grpcTokenEnv := strings.TrimSpace(chain.GRPC.TokenEnv); grpcTokenEnv != "" { grpcToken = strings.TrimSpace(os.Getenv(grpcTokenEnv)) if grpcToken != "" { logger.Info("TRON gRPC token configured", zap.String("chain", network.String()), zap.String("env", grpcTokenEnv)) @@ -301,6 +306,7 @@ func resolveNetworkConfigs(logger mlogger.Logger, chains []chainConfig) ([]gatew RPCURL: rpcURL, GRPCUrl: grpcURL, GRPCToken: grpcToken, + GRPCForceIPv4: chain.GRPC.ForceIPv4, ChainID: chain.ChainID, NativeToken: chain.NativeToken, TokenConfigs: contracts, diff --git a/api/gateway/tron/internal/service/gateway/tronclient/client.go b/api/gateway/tron/internal/service/gateway/tronclient/client.go index 5cb9131a..576a7be5 100644 --- a/api/gateway/tron/internal/service/gateway/tronclient/client.go +++ b/api/gateway/tron/internal/service/gateway/tronclient/client.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" "math/big" + "net" "net/url" "strings" "time" @@ -27,7 +28,7 @@ type Client struct { } // NewClient creates a new TRON gRPC client connected to the given endpoint. -func NewClient(grpcURL string, timeout time.Duration, authToken string) (*Client, error) { +func NewClient(grpcURL string, timeout time.Duration, authToken string, forceIPv4 bool) (*Client, error) { if grpcURL == "" { return nil, merrors.InvalidArgument("tronclient: grpc url is required") } @@ -50,6 +51,9 @@ func NewClient(grpcURL string, timeout time.Duration, authToken string) (*Client } opts := []grpc.DialOption{transportCreds} + if forceIPv4 { + opts = append(opts, grpc.WithContextDialer(grpcForceIPv4Dialer)) + } if token := strings.TrimSpace(authToken); token != "" { opts = append(opts, grpc.WithUnaryInterceptor(grpcTokenUnaryInterceptor(token)), @@ -67,6 +71,11 @@ func NewClient(grpcURL string, timeout time.Duration, authToken string) (*Client }, nil } +func grpcForceIPv4Dialer(ctx context.Context, address string) (net.Conn, error) { + var dialer net.Dialer + return dialer.DialContext(ctx, "tcp4", address) +} + func normalizeGRPCAddress(grpcURL string) (string, bool, error) { target := strings.TrimSpace(grpcURL) useTLS := false diff --git a/api/gateway/tron/internal/service/gateway/tronclient/registry.go b/api/gateway/tron/internal/service/gateway/tronclient/registry.go index 04da5a4b..db084c81 100644 --- a/api/gateway/tron/internal/service/gateway/tronclient/registry.go +++ b/api/gateway/tron/internal/service/gateway/tronclient/registry.go @@ -40,6 +40,7 @@ func Prepare(ctx context.Context, logger mlogger.Logger, networks []shared.Netwo name := network.Name.String() grpcURL := strings.TrimSpace(network.GRPCUrl) grpcToken := strings.TrimSpace(network.GRPCToken) + forceIPv4 := network.GRPCForceIPv4 if !network.Name.IsValid() { continue @@ -56,9 +57,10 @@ func Prepare(ctx context.Context, logger mlogger.Logger, networks []shared.Netwo registry.logger.Info("Initializing TRON gRPC client", zap.String("network", name), zap.String("grpc_url", grpcURL), + zap.Bool("force_ipv4", forceIPv4), ) - client, err := NewClient(grpcURL, timeout, grpcToken) + client, err := NewClient(grpcURL, timeout, grpcToken, forceIPv4) if err != nil { registry.Close() registry.logger.Error("Failed to initialize TRON gRPC client", diff --git a/api/gateway/tron/shared/helpers.go b/api/gateway/tron/shared/helpers.go index e834e9d3..5131609e 100644 --- a/api/gateway/tron/shared/helpers.go +++ b/api/gateway/tron/shared/helpers.go @@ -170,6 +170,7 @@ type Network struct { RPCURL string GRPCUrl string // Native TRON gRPC endpoint (for transactions) GRPCToken string // Optional auth token for TRON gRPC (x-token header) + GRPCForceIPv4 bool // Force IPv4 sockets when dialing TRON gRPC endpoint. ChainID uint64 NativeToken string TokenConfigs []TokenContract