fixed tron ip connection
All checks were successful
ci/woodpecker/push/gateway_tron Pipeline was successful

This commit is contained in:
Stephan D
2026-03-03 18:32:26 +01:00
parent 7cac494509
commit 3f578353da
7 changed files with 33 additions and 14 deletions

View File

@@ -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") 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 := make([]grpc.DialOption, 0, len(opts)+1)
dialOpts = append(dialOpts, opts...) 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{}))) 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 { if err != nil {
return nil, merrors.Internal(fmt.Sprintf("chain-gateway: dial %s: %s", cfg.Address, err.Error())) return nil, merrors.Internal(fmt.Sprintf("chain-gateway: dial %s: %s", cfg.Address, err.Error()))
} }

View File

@@ -40,8 +40,10 @@ chains:
chain_id: 3448148188 # Nile testnet chain_id: 3448148188 # Nile testnet
native_token: TRX native_token: TRX
rpc_url_env: TRON_GATEWAY_RPC_URL rpc_url_env: TRON_GATEWAY_RPC_URL
grpc_url_env: TRON_GATEWAY_GRPC_URL grpc:
grpc_token_env: TRON_GATEWAY_GRPC_TOKEN url_env: TRON_GATEWAY_GRPC_URL
token_env: TRON_GATEWAY_GRPC_TOKEN
force_ipv4: false
gas_topup_policy: gas_topup_policy:
buffer_percent: 0.10 buffer_percent: 0.10
min_native_balance_trx: 10 min_native_balance_trx: 10

View File

@@ -40,8 +40,10 @@ chains:
chain_id: 728126428 # 0x2b6653dc chain_id: 728126428 # 0x2b6653dc
native_token: TRX native_token: TRX
rpc_url_env: TRON_GATEWAY_RPC_URL rpc_url_env: TRON_GATEWAY_RPC_URL
grpc_url_env: TRON_GATEWAY_GRPC_URL grpc:
grpc_token_env: TRON_GATEWAY_GRPC_TOKEN url_env: TRON_GATEWAY_GRPC_URL
token_env: TRON_GATEWAY_GRPC_TOKEN
force_ipv4: true
gas_topup_policy: gas_topup_policy:
buffer_percent: 0.10 buffer_percent: 0.10
min_native_balance_trx: 10 min_native_balance_trx: 10

View File

@@ -53,14 +53,19 @@ type config struct {
type chainConfig struct { type chainConfig struct {
Name string `yaml:"name"` Name string `yaml:"name"`
RPCURLEnv string `yaml:"rpc_url_env"` RPCURLEnv string `yaml:"rpc_url_env"`
GRPCURLEnv string `yaml:"grpc_url_env"` // Native TRON gRPC endpoint GRPC chainGRPCConfig `yaml:"grpc"`
GRPCTokenEnv string `yaml:"grpc_token_env"`
ChainID uint64 `yaml:"chain_id"` ChainID uint64 `yaml:"chain_id"`
NativeToken string `yaml:"native_token"` NativeToken string `yaml:"native_token"`
Tokens []tokenConfig `yaml:"tokens"` Tokens []tokenConfig `yaml:"tokens"`
GasTopUpPolicy *gasTopUpPolicyConfig `yaml:"gas_topup_policy"` 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 { type serviceWalletConfig struct {
Chain string `yaml:"chain"` Chain string `yaml:"chain"`
Address string `yaml:"address"` Address string `yaml:"address"`
@@ -282,14 +287,14 @@ func resolveNetworkConfigs(logger mlogger.Logger, chains []chainConfig) ([]gatew
// Resolve optional TRON gRPC URL // Resolve optional TRON gRPC URL
grpcURL := "" grpcURL := ""
if grpcEnv := strings.TrimSpace(chain.GRPCURLEnv); grpcEnv != "" { if grpcEnv := strings.TrimSpace(chain.GRPC.URLEnv); grpcEnv != "" {
grpcURL = strings.TrimSpace(os.Getenv(grpcEnv)) grpcURL = strings.TrimSpace(os.Getenv(grpcEnv))
if grpcURL != "" { if grpcURL != "" {
logger.Info("TRON gRPC URL configured", zap.String("chain", network.String()), zap.String("env", grpcEnv)) logger.Info("TRON gRPC URL configured", zap.String("chain", network.String()), zap.String("env", grpcEnv))
} }
} }
grpcToken := "" grpcToken := ""
if grpcTokenEnv := strings.TrimSpace(chain.GRPCTokenEnv); grpcTokenEnv != "" { if grpcTokenEnv := strings.TrimSpace(chain.GRPC.TokenEnv); grpcTokenEnv != "" {
grpcToken = strings.TrimSpace(os.Getenv(grpcTokenEnv)) grpcToken = strings.TrimSpace(os.Getenv(grpcTokenEnv))
if grpcToken != "" { if grpcToken != "" {
logger.Info("TRON gRPC token configured", zap.String("chain", network.String()), zap.String("env", grpcTokenEnv)) 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, RPCURL: rpcURL,
GRPCUrl: grpcURL, GRPCUrl: grpcURL,
GRPCToken: grpcToken, GRPCToken: grpcToken,
GRPCForceIPv4: chain.GRPC.ForceIPv4,
ChainID: chain.ChainID, ChainID: chain.ChainID,
NativeToken: chain.NativeToken, NativeToken: chain.NativeToken,
TokenConfigs: contracts, TokenConfigs: contracts,

View File

@@ -6,6 +6,7 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"math/big" "math/big"
"net"
"net/url" "net/url"
"strings" "strings"
"time" "time"
@@ -27,7 +28,7 @@ type Client struct {
} }
// NewClient creates a new TRON gRPC client connected to the given endpoint. // 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 == "" { if grpcURL == "" {
return nil, merrors.InvalidArgument("tronclient: grpc url is required") 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} opts := []grpc.DialOption{transportCreds}
if forceIPv4 {
opts = append(opts, grpc.WithContextDialer(grpcForceIPv4Dialer))
}
if token := strings.TrimSpace(authToken); token != "" { if token := strings.TrimSpace(authToken); token != "" {
opts = append(opts, opts = append(opts,
grpc.WithUnaryInterceptor(grpcTokenUnaryInterceptor(token)), grpc.WithUnaryInterceptor(grpcTokenUnaryInterceptor(token)),
@@ -67,6 +71,11 @@ func NewClient(grpcURL string, timeout time.Duration, authToken string) (*Client
}, nil }, 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) { func normalizeGRPCAddress(grpcURL string) (string, bool, error) {
target := strings.TrimSpace(grpcURL) target := strings.TrimSpace(grpcURL)
useTLS := false useTLS := false

View File

@@ -40,6 +40,7 @@ func Prepare(ctx context.Context, logger mlogger.Logger, networks []shared.Netwo
name := network.Name.String() name := network.Name.String()
grpcURL := strings.TrimSpace(network.GRPCUrl) grpcURL := strings.TrimSpace(network.GRPCUrl)
grpcToken := strings.TrimSpace(network.GRPCToken) grpcToken := strings.TrimSpace(network.GRPCToken)
forceIPv4 := network.GRPCForceIPv4
if !network.Name.IsValid() { if !network.Name.IsValid() {
continue continue
@@ -56,9 +57,10 @@ func Prepare(ctx context.Context, logger mlogger.Logger, networks []shared.Netwo
registry.logger.Info("Initializing TRON gRPC client", registry.logger.Info("Initializing TRON gRPC client",
zap.String("network", name), zap.String("network", name),
zap.String("grpc_url", grpcURL), 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 { if err != nil {
registry.Close() registry.Close()
registry.logger.Error("Failed to initialize TRON gRPC client", registry.logger.Error("Failed to initialize TRON gRPC client",

View File

@@ -170,6 +170,7 @@ type Network struct {
RPCURL string RPCURL string
GRPCUrl string // Native TRON gRPC endpoint (for transactions) GRPCUrl string // Native TRON gRPC endpoint (for transactions)
GRPCToken string // Optional auth token for TRON gRPC (x-token header) GRPCToken string // Optional auth token for TRON gRPC (x-token header)
GRPCForceIPv4 bool // Force IPv4 sockets when dialing TRON gRPC endpoint.
ChainID uint64 ChainID uint64
NativeToken string NativeToken string
TokenConfigs []TokenContract TokenConfigs []TokenContract