extended logging

This commit is contained in:
Stephan D
2025-12-25 21:49:44 +01:00
parent af7abbb095
commit 6151e3d3a5
4 changed files with 40 additions and 31 deletions

View File

@@ -95,7 +95,7 @@ func (d *Driver) NativeBalance(ctx context.Context, deps driver.Deps, network sh
} }
func (d *Driver) EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, destination string, amount *moneyv1.Money) (*moneyv1.Money, error) { func (d *Driver) EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, destination string, amount *moneyv1.Money) (*moneyv1.Money, error) {
d.logger.Debug("estimate fee request", d.logger.Debug("Estimate fee request",
zap.String("wallet_ref", wallet.WalletRef), zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.String("destination", destination), zap.String("destination", destination),
@@ -104,13 +104,13 @@ func (d *Driver) EstimateFee(ctx context.Context, deps driver.Deps, network shar
driverDeps.Logger = d.logger driverDeps.Logger = d.logger
result, err := evm.EstimateFee(ctx, driverDeps, network, wallet, wallet.DepositAddress, destination, amount) result, err := evm.EstimateFee(ctx, driverDeps, network, wallet, wallet.DepositAddress, destination, amount)
if err != nil { if err != nil {
d.logger.Warn("estimate fee failed", d.logger.Warn("Estimate fee failed",
zap.String("wallet_ref", wallet.WalletRef), zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.Error(err), zap.Error(err),
) )
} else if result != nil { } else if result != nil {
d.logger.Debug("estimate fee result", d.logger.Debug("Estimate fee result",
zap.String("wallet_ref", wallet.WalletRef), zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.String("amount", result.Amount), zap.String("amount", result.Amount),

View File

@@ -95,7 +95,7 @@ func (d *Driver) NativeBalance(ctx context.Context, deps driver.Deps, network sh
} }
func (d *Driver) EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, destination string, amount *moneyv1.Money) (*moneyv1.Money, error) { func (d *Driver) EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, destination string, amount *moneyv1.Money) (*moneyv1.Money, error) {
d.logger.Debug("estimate fee request", d.logger.Debug("Estimate fee request",
zap.String("wallet_ref", wallet.WalletRef), zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.String("destination", destination), zap.String("destination", destination),
@@ -104,13 +104,13 @@ func (d *Driver) EstimateFee(ctx context.Context, deps driver.Deps, network shar
driverDeps.Logger = d.logger driverDeps.Logger = d.logger
result, err := evm.EstimateFee(ctx, driverDeps, network, wallet, wallet.DepositAddress, destination, amount) result, err := evm.EstimateFee(ctx, driverDeps, network, wallet, wallet.DepositAddress, destination, amount)
if err != nil { if err != nil {
d.logger.Warn("estimate fee failed", d.logger.Warn("Estimate fee failed",
zap.String("wallet_ref", wallet.WalletRef), zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.Error(err), zap.Error(err),
) )
} else if result != nil { } else if result != nil {
d.logger.Debug("estimate fee result", d.logger.Debug("Estimate fee result",
zap.String("wallet_ref", wallet.WalletRef), zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.String("amount", result.Amount), zap.String("amount", result.Amount),

View File

@@ -95,7 +95,7 @@ func parseBaseUnitAmount(amount string) (*big.Int, error) {
// Balance fetches ERC20 token balance for the provided address. // Balance fetches ERC20 token balance for the provided address.
func Balance(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, address string) (*moneyv1.Money, error) { func Balance(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, address string) (*moneyv1.Money, error) {
logger := deps.Logger logger := deps.Logger.Named("evm")
registry := deps.Registry registry := deps.Registry
if registry == nil { if registry == nil {
@@ -175,7 +175,7 @@ func Balance(ctx context.Context, deps driver.Deps, network shared.Network, wall
// NativeBalance fetches native token balance for the provided address. // NativeBalance fetches native token balance for the provided address.
func NativeBalance(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, address string) (*moneyv1.Money, error) { func NativeBalance(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, address string) (*moneyv1.Money, error) {
logger := deps.Logger logger := deps.Logger.Named("evm")
registry := deps.Registry registry := deps.Registry
if registry == nil { if registry == nil {
@@ -233,7 +233,7 @@ func NativeBalance(ctx context.Context, deps driver.Deps, network shared.Network
// EstimateFee estimates ERC20 transfer fees for the given parameters. // EstimateFee estimates ERC20 transfer fees for the given parameters.
func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, fromAddress, destination string, amount *moneyv1.Money) (*moneyv1.Money, error) { func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, fromAddress, destination string, amount *moneyv1.Money) (*moneyv1.Money, error) {
logger := deps.Logger logger := deps.Logger.Named("evm")
registry := deps.Registry registry := deps.Registry
if registry == nil { if registry == nil {
@@ -259,10 +259,12 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
client, err := registry.Client(network.Name) client, err := registry.Client(network.Name)
if err != nil { if err != nil {
logger.Warn("Failed to resolve client", zap.Error(err), zap.String("network_name", network.Name))
return nil, err return nil, err
} }
rpcClient, err := registry.RPCClient(network.Name) rpcClient, err := registry.RPCClient(network.Name)
if err != nil { if err != nil {
logger.Warn("Failed to resolve RPC client", zap.Error(err), zap.String("network_name", network.Name))
return nil, err return nil, err
} }
@@ -280,10 +282,12 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
if contract == "" { if contract == "" {
amountBase, err := parseBaseUnitAmount(amount.GetAmount()) amountBase, err := parseBaseUnitAmount(amount.GetAmount())
if err != nil { if err != nil {
logger.Warn("Failed to parse base unit amount", zap.Error(err), zap.String("amount", amount.GetAmount()))
return nil, err return nil, err
} }
gasPrice, err := client.SuggestGasPrice(timeoutCtx) gasPrice, err := client.SuggestGasPrice(timeoutCtx)
if err != nil { if err != nil {
logger.Warn("Failed to suggest gas price", zap.Error(err))
return nil, merrors.Internal("failed to suggest gas price: " + err.Error()) return nil, merrors.Internal("failed to suggest gas price: " + err.Error())
} }
callMsg := ethereum.CallMsg{ callMsg := ethereum.CallMsg{
@@ -294,6 +298,7 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
} }
gasLimit, err := client.EstimateGas(timeoutCtx, callMsg) gasLimit, err := client.EstimateGas(timeoutCtx, callMsg)
if err != nil { if err != nil {
logger.Warn("Failed to estimate gas", zap.Error(err), zap.Any("call_mesasge", callMsg))
return nil, merrors.Internal("failed to estimate gas: " + err.Error()) return nil, merrors.Internal("failed to estimate gas: " + err.Error())
} }
fee := new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gasLimit)) fee := new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gasLimit))
@@ -304,6 +309,7 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
}, nil }, nil
} }
if !common.IsHexAddress(contract) { if !common.IsHexAddress(contract) {
logger.Warn("Failed to validate contract", zap.String("contract", contract))
return nil, merrors.InvalidArgument("invalid token contract address") return nil, merrors.InvalidArgument("invalid token contract address")
} }
@@ -322,11 +328,13 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
input, err := erc20ABI.Pack("transfer", toAddr, amountBase) input, err := erc20ABI.Pack("transfer", toAddr, amountBase)
if err != nil { if err != nil {
logger.Warn("Failed to encode transfer call", zap.Error(err))
return nil, merrors.Internal("failed to encode transfer call: " + err.Error()) return nil, merrors.Internal("failed to encode transfer call: " + err.Error())
} }
gasPrice, err := client.SuggestGasPrice(timeoutCtx) gasPrice, err := client.SuggestGasPrice(timeoutCtx)
if err != nil { if err != nil {
logger.Warn("Failed to suggest gas price", zap.Error(err))
return nil, merrors.Internal("failed to suggest gas price: " + err.Error()) return nil, merrors.Internal("failed to suggest gas price: " + err.Error())
} }
@@ -338,6 +346,7 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
} }
gasLimit, err := client.EstimateGas(timeoutCtx, callMsg) gasLimit, err := client.EstimateGas(timeoutCtx, callMsg)
if err != nil { if err != nil {
logger.Warn("Failed to estimate gas", zap.Error(err), zap.Error(err), zap.Any("call_message", callMsg))
return nil, merrors.Internal("failed to estimate gas: " + err.Error()) return nil, merrors.Internal("failed to estimate gas: " + err.Error())
} }
@@ -352,7 +361,7 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
// SubmitTransfer submits an ERC20 transfer on an EVM-compatible chain. // SubmitTransfer submits an ERC20 transfer on an EVM-compatible chain.
func SubmitTransfer(ctx context.Context, deps driver.Deps, network shared.Network, transfer *model.Transfer, source *model.ManagedWallet, fromAddress, destination string) (string, error) { func SubmitTransfer(ctx context.Context, deps driver.Deps, network shared.Network, transfer *model.Transfer, source *model.ManagedWallet, fromAddress, destination string) (string, error) {
logger := deps.Logger logger := deps.Logger.Named("evm")
registry := deps.Registry registry := deps.Registry
if deps.KeyManager == nil { if deps.KeyManager == nil {
@@ -384,7 +393,7 @@ func SubmitTransfer(ctx context.Context, deps driver.Deps, network shared.Networ
return "", executorInvalid("invalid destination address " + destination) return "", executorInvalid("invalid destination address " + destination)
} }
logger.Info("submitting transfer", logger.Info("Submitting transfer",
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("source_wallet_ref", source.WalletRef), zap.String("source_wallet_ref", source.WalletRef),
zap.String("network", network.Name), zap.String("network", network.Name),
@@ -537,7 +546,7 @@ func SubmitTransfer(ctx context.Context, deps driver.Deps, network shared.Networ
// AwaitConfirmation waits for the transaction receipt. // AwaitConfirmation waits for the transaction receipt.
func AwaitConfirmation(ctx context.Context, deps driver.Deps, network shared.Network, txHash string) (*types.Receipt, error) { func AwaitConfirmation(ctx context.Context, deps driver.Deps, network shared.Network, txHash string) (*types.Receipt, error) {
logger := deps.Logger logger := deps.Logger.Named("evm")
registry := deps.Registry registry := deps.Registry
if strings.TrimSpace(txHash) == "" { if strings.TrimSpace(txHash) == "" {

View File

@@ -81,12 +81,12 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
client, err := o.clients.Client(network.Name) client, err := o.clients.Client(network.Name)
if err != nil { if err != nil {
o.logger.Warn("failed to initialise rpc client", zap.Error(err), zap.String("network", network.Name)) o.logger.Warn("Failed to initialise RPC client", zap.Error(err), zap.String("network", network.Name))
return "", err return "", err
} }
rpcClient, err := o.clients.RPCClient(network.Name) rpcClient, err := o.clients.RPCClient(network.Name)
if err != nil { if err != nil {
o.logger.Warn("failed to initialise rpc client", o.logger.Warn("Failed to initialise RPC client",
zap.String("network", network.Name), zap.String("network", network.Name),
zap.Error(err), zap.Error(err),
) )
@@ -101,7 +101,7 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
nonce, err := client.PendingNonceAt(ctx, sourceAddress) nonce, err := client.PendingNonceAt(ctx, sourceAddress)
if err != nil { if err != nil {
o.logger.Warn("failed to fetch nonce", zap.Error(err), o.logger.Warn("Failed to fetch nonce", zap.Error(err),
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("wallet_ref", source.WalletRef), zap.String("wallet_ref", source.WalletRef),
) )
@@ -110,7 +110,7 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
gasPrice, err := client.SuggestGasPrice(ctx) gasPrice, err := client.SuggestGasPrice(ctx)
if err != nil { if err != nil {
o.logger.Warn("failed to suggest gas price", o.logger.Warn("Failed to suggest gas price",
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.Error(err), zap.Error(err),
@@ -124,12 +124,12 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
chainID := new(big.Int).SetUint64(network.ChainID) chainID := new(big.Int).SetUint64(network.ChainID)
if strings.TrimSpace(transfer.ContractAddress) == "" { if strings.TrimSpace(transfer.ContractAddress) == "" {
o.logger.Warn("native token transfer requested but not supported", zap.String("transfer_ref", transfer.TransferRef)) o.logger.Warn("Native token transfer requested but not supported", zap.String("transfer_ref", transfer.TransferRef))
return "", merrors.NotImplemented("executor: native token transfers not yet supported") return "", merrors.NotImplemented("executor: native token transfers not yet supported")
} }
if !common.IsHexAddress(transfer.ContractAddress) { if !common.IsHexAddress(transfer.ContractAddress) {
o.logger.Warn("invalid token contract address", o.logger.Warn("Invalid token contract address",
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("contract", transfer.ContractAddress), zap.String("contract", transfer.ContractAddress),
) )
@@ -139,7 +139,7 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
decimals, err := erc20Decimals(ctx, rpcClient, tokenAddress) decimals, err := erc20Decimals(ctx, rpcClient, tokenAddress)
if err != nil { if err != nil {
o.logger.Warn("failed to read token decimals", zap.Error(err), o.logger.Warn("Failed to read token decimals", zap.Error(err),
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("contract", transfer.ContractAddress), zap.String("contract", transfer.ContractAddress),
) )
@@ -148,12 +148,12 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
amount := transfer.NetAmount amount := transfer.NetAmount
if amount == nil || strings.TrimSpace(amount.Amount) == "" { if amount == nil || strings.TrimSpace(amount.Amount) == "" {
o.logger.Warn("transfer missing net amount", zap.String("transfer_ref", transfer.TransferRef)) o.logger.Warn("Transfer missing net amount", zap.String("transfer_ref", transfer.TransferRef))
return "", executorInvalid("transfer missing net amount") return "", executorInvalid("transfer missing net amount")
} }
amountInt, err := toBaseUnits(amount.Amount, decimals) amountInt, err := toBaseUnits(amount.Amount, decimals)
if err != nil { if err != nil {
o.logger.Warn("failed to convert amount to base units", zap.Error(err), o.logger.Warn("Failed to convert amount to base units", zap.Error(err),
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("amount", amount.Amount), zap.String("amount", amount.Amount),
) )
@@ -177,7 +177,7 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
} }
gasLimit, err := client.EstimateGas(ctx, callMsg) gasLimit, err := client.EstimateGas(ctx, callMsg)
if err != nil { if err != nil {
o.logger.Warn("failed to estimate gas", o.logger.Warn("Failed to estimate gas",
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.Error(err), zap.Error(err),
) )
@@ -188,7 +188,7 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
signedTx, err := o.keyManager.SignTransaction(ctx, source.KeyReference, tx, chainID) signedTx, err := o.keyManager.SignTransaction(ctx, source.KeyReference, tx, chainID)
if err != nil { if err != nil {
o.logger.Warn("failed to sign transaction", zap.Error(err), o.logger.Warn("Failed to sign transaction", zap.Error(err),
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("wallet_ref", source.WalletRef), zap.String("wallet_ref", source.WalletRef),
) )
@@ -196,14 +196,14 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
} }
if err := client.SendTransaction(ctx, signedTx); err != nil { if err := client.SendTransaction(ctx, signedTx); err != nil {
o.logger.Warn("failed to send transaction", zap.Error(err), o.logger.Warn("Failed to send transaction", zap.Error(err),
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
) )
return "", executorInternal("failed to send transaction", err) return "", executorInternal("failed to send transaction", err)
} }
txHash = signedTx.Hash().Hex() txHash = signedTx.Hash().Hex()
o.logger.Info("transaction submitted", o.logger.Info("Transaction submitted",
zap.String("transfer_ref", transfer.TransferRef), zap.String("transfer_ref", transfer.TransferRef),
zap.String("tx_hash", txHash), zap.String("tx_hash", txHash),
zap.String("network", network.Name), zap.String("network", network.Name),
@@ -214,12 +214,12 @@ func (o *onChainExecutor) SubmitTransfer(ctx context.Context, transfer *model.Tr
func (o *onChainExecutor) AwaitConfirmation(ctx context.Context, network shared.Network, txHash string) (*types.Receipt, error) { func (o *onChainExecutor) AwaitConfirmation(ctx context.Context, network shared.Network, txHash string) (*types.Receipt, error) {
if strings.TrimSpace(txHash) == "" { if strings.TrimSpace(txHash) == "" {
o.logger.Warn("missing transaction hash for confirmation", zap.String("network", network.Name)) o.logger.Warn("Missing transaction hash for confirmation", zap.String("network", network.Name))
return nil, executorInvalid("tx hash is required") return nil, executorInvalid("tx hash is required")
} }
rpcURL := strings.TrimSpace(network.RPCURL) rpcURL := strings.TrimSpace(network.RPCURL)
if rpcURL == "" { if rpcURL == "" {
o.logger.Warn("network rpc url missing while awaiting confirmation", zap.String("tx_hash", txHash)) o.logger.Warn("Network RPC url missing while awaiting confirmation", zap.String("tx_hash", txHash))
return nil, executorInvalid("network rpc url is not configured") return nil, executorInvalid("network rpc url is not configured")
} }
@@ -238,27 +238,27 @@ func (o *onChainExecutor) AwaitConfirmation(ctx context.Context, network shared.
if errors.Is(err, ethereum.NotFound) { if errors.Is(err, ethereum.NotFound) {
select { select {
case <-ticker.C: case <-ticker.C:
o.logger.Debug("transaction not yet mined", o.logger.Debug("Transaction not yet mined",
zap.String("tx_hash", txHash), zap.String("tx_hash", txHash),
zap.String("network", network.Name), zap.String("network", network.Name),
) )
continue continue
case <-ctx.Done(): case <-ctx.Done():
o.logger.Warn("context cancelled while awaiting confirmation", o.logger.Warn("Context cancelled while awaiting confirmation",
zap.String("tx_hash", txHash), zap.String("tx_hash", txHash),
zap.String("network", network.Name), zap.String("network", network.Name),
) )
return nil, ctx.Err() return nil, ctx.Err()
} }
} }
o.logger.Warn("failed to fetch transaction receipt", o.logger.Warn("Failed to fetch transaction receipt",
zap.String("tx_hash", txHash), zap.String("tx_hash", txHash),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.Error(err), zap.Error(err),
) )
return nil, executorInternal("failed to fetch transaction receipt", err) return nil, executorInternal("failed to fetch transaction receipt", err)
} }
o.logger.Info("transaction confirmed", o.logger.Info("Transaction confirmed",
zap.String("tx_hash", txHash), zap.String("tx_hash", txHash),
zap.String("network", network.Name), zap.String("network", network.Name),
zap.Uint64("block_number", receipt.BlockNumber.Uint64()), zap.Uint64("block_number", receipt.BlockNumber.Uint64()),