Merge pull request 'extended logging + timeout setting' (#137) from tron-140 into main
Some checks failed
ci/woodpecker/push/chain_gateway Pipeline failed
ci/woodpecker/push/fx_ingestor Pipeline failed
ci/woodpecker/push/frontend Pipeline failed
ci/woodpecker/push/nats Pipeline is pending
ci/woodpecker/push/notification Pipeline is pending
ci/woodpecker/push/payments_orchestrator Pipeline is pending
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline is pending
ci/woodpecker/push/ledger Pipeline is pending
ci/woodpecker/push/mntx_gateway Pipeline is pending
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/db Pipeline was successful

Reviewed-on: #137
This commit was merged in pull request #137.
This commit is contained in:
2025-12-24 01:00:20 +00:00
8 changed files with 31 additions and 4 deletions

View File

@@ -60,3 +60,4 @@ key_management:
cache: cache:
wallet_balance_ttl_seconds: 120 wallet_balance_ttl_seconds: 120
rpc_request_timeout_seconds: 15

View File

@@ -15,6 +15,7 @@ type Deps struct {
Networks *rpcclient.Registry Networks *rpcclient.Registry
Storage storage.Repository Storage storage.Repository
Clock clockpkg.Clock Clock clockpkg.Clock
RPCTimeout time.Duration
EnsureRepository func(context.Context) error EnsureRepository func(context.Context) error
LaunchExecution func(transferRef, sourceWalletRef string, network shared.Network) LaunchExecution func(transferRef, sourceWalletRef string, network shared.Network)
} }

View File

@@ -122,7 +122,11 @@ func estimateNetworkFee(ctx context.Context, logger mlogger.Logger, network shar
} }
defer client.Close() defer client.Close()
timeoutCtx, cancel := context.WithTimeout(ctx, 15*time.Second) timeout := c.deps.RPCTimeout
if timeout <= 0 {
timeout = 15 * time.Second
}
timeoutCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()
tokenABI, err := abi.JSON(strings.NewReader(erc20TransferABI)) tokenABI, err := abi.JSON(strings.NewReader(erc20TransferABI))

View File

@@ -18,6 +18,7 @@ type Deps struct {
Storage storage.Repository Storage storage.Repository
Clock clockpkg.Clock Clock clockpkg.Clock
BalanceCacheTTL time.Duration BalanceCacheTTL time.Duration
RPCTimeout time.Duration
EnsureRepository func(context.Context) error EnsureRepository func(context.Context) error
} }

View File

@@ -64,7 +64,11 @@ func onChainWalletBalance(ctx context.Context, deps Deps, wallet *model.ManagedW
return nil, err return nil, err
} }
timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second) timeout := deps.RPCTimeout
if timeout <= 0 {
timeout = 10 * time.Second
}
timeoutCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()
tokenABI, err := abi.JSON(strings.NewReader(erc20ABIJSON)) tokenABI, err := abi.JSON(strings.NewReader(erc20ABIJSON))

View File

@@ -154,9 +154,10 @@ func (l *loggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, erro
respFields = append(respFields, zap.String("rpc_response", truncate(string(bodyBytes), 2048))) respFields = append(respFields, zap.String("rpc_response", truncate(string(bodyBytes), 2048)))
} }
if resp.StatusCode >= 400 { if resp.StatusCode >= 400 {
l.logger.Warn("rpc response error", respFields...) l.logger.Warn("RPC response error", respFields...)
} else { } else {
l.logger.Debug("rpc response", respFields...) // Log response content so downstream parse failures can be inspected without debug logs.
l.logger.Warn("RPC response", respFields...)
} }
return resp, nil return resp, nil

View File

@@ -140,6 +140,7 @@ func commandsWalletDeps(s *Service) wallet.Deps {
Storage: s.storage, Storage: s.storage,
Clock: s.clock, Clock: s.clock,
BalanceCacheTTL: s.settings.walletBalanceCacheTTL(), BalanceCacheTTL: s.settings.walletBalanceCacheTTL(),
RPCTimeout: s.settings.rpcTimeout(),
EnsureRepository: s.ensureRepository, EnsureRepository: s.ensureRepository,
} }
} }
@@ -150,6 +151,7 @@ func commandsTransferDeps(s *Service) transfer.Deps {
Networks: s.networkRegistry, Networks: s.networkRegistry,
Storage: s.storage, Storage: s.storage,
Clock: s.clock, Clock: s.clock,
RPCTimeout: s.settings.rpcTimeout(),
EnsureRepository: s.ensureRepository, EnsureRepository: s.ensureRepository,
LaunchExecution: s.launchTransferExecution, LaunchExecution: s.launchTransferExecution,
} }

View File

@@ -3,15 +3,18 @@ package gateway
import "time" import "time"
const defaultWalletBalanceCacheTTL = 120 * time.Second const defaultWalletBalanceCacheTTL = 120 * time.Second
const defaultRPCRequestTimeout = 15 * time.Second
// CacheSettings holds tunable gateway behaviour. // CacheSettings holds tunable gateway behaviour.
type CacheSettings struct { type CacheSettings struct {
WalletBalanceCacheTTLSeconds int `yaml:"wallet_balance_ttl_seconds"` WalletBalanceCacheTTLSeconds int `yaml:"wallet_balance_ttl_seconds"`
RPCRequestTimeoutSeconds int `yaml:"rpc_request_timeout_seconds"`
} }
func defaultSettings() CacheSettings { func defaultSettings() CacheSettings {
return CacheSettings{ return CacheSettings{
WalletBalanceCacheTTLSeconds: int(defaultWalletBalanceCacheTTL.Seconds()), WalletBalanceCacheTTLSeconds: int(defaultWalletBalanceCacheTTL.Seconds()),
RPCRequestTimeoutSeconds: int(defaultRPCRequestTimeout.Seconds()),
} }
} }
@@ -19,6 +22,9 @@ func (s CacheSettings) withDefaults() CacheSettings {
if s.WalletBalanceCacheTTLSeconds <= 0 { if s.WalletBalanceCacheTTLSeconds <= 0 {
s.WalletBalanceCacheTTLSeconds = int(defaultWalletBalanceCacheTTL.Seconds()) s.WalletBalanceCacheTTLSeconds = int(defaultWalletBalanceCacheTTL.Seconds())
} }
if s.RPCRequestTimeoutSeconds <= 0 {
s.RPCRequestTimeoutSeconds = int(defaultRPCRequestTimeout.Seconds())
}
return s return s
} }
@@ -28,3 +34,10 @@ func (s CacheSettings) walletBalanceCacheTTL() time.Duration {
} }
return time.Duration(s.WalletBalanceCacheTTLSeconds) * time.Second return time.Duration(s.WalletBalanceCacheTTLSeconds) * time.Second
} }
func (s CacheSettings) rpcTimeout() time.Duration {
if s.RPCRequestTimeoutSeconds <= 0 {
return defaultRPCRequestTimeout
}
return time.Duration(s.RPCRequestTimeoutSeconds) * time.Second
}