diff --git a/Makefile b/Makefile index f0d409d..15d7663 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,11 @@ empty = $(whitespace) $(whitespace) comma := , build_tags_comma_sep := $(subst $(empty),$(comma),$(build_tags)) -ldflags = -X github.com/bandprotocol/falcon/version.Name=falcon \ - -X github.com/bandprotocol/falcon/version.AppName=falcon \ - -X github.com/bandprotocol/falcon/version.Commit=$(COMMIT) \ - -X github.com/bandprotocol/falcon/version.Version=$(VERSION) \ - -X "github.com/bandprotocol/falcon/version.BuildTags=$(build_tags_comma_sep)" +ldflags = -X github.com/bandprotocol/falcon/main.Name=falcon \ + -X github.com/bandprotocol/falcon/cmd.AppName=falcon \ + -X github.com/bandprotocol/falcon/cmd.Commit=$(COMMIT) \ + -X github.com/bandprotocol/falcon/cmd.Version=$(VERSION) \ + -X "github.com/bandprotocol/falcon/cmd.BuildTags=$(build_tags_comma_sep)" ifeq ($(LINK_STATICALLY),true) ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static" diff --git a/cmd/config.go b/cmd/config.go index 63cdba3..7df5763 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -52,7 +52,7 @@ $ %s cfg list`, appName, defaultHome, appName)), return cmd } -// configInitCmd returns the commands that for initializing an empty config at the --home location +// configInitCmd returns the commands that initializes an empty config at the --home location func configInitCmd(app *relayer.App) *cobra.Command { cmd := &cobra.Command{ Use: "init", diff --git a/cmd/root.go b/cmd/root.go index 9218d52..0233a8e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -20,8 +20,7 @@ import ( ) const ( - appName = "falcon" - + appName = "falcon" defaultCoinType = 60 ) @@ -69,6 +68,7 @@ func NewRootCmd(log *zap.Logger) *cobra.Command { panic(err) } + // Register --log-format flag rootCmd.PersistentFlags().String("log-format", "auto", "log output format (auto, logfmt, json, or console)") if err := app.Viper.BindPFlag("log-format", rootCmd.PersistentFlags().Lookup("log-format")); err != nil { panic(err) @@ -90,7 +90,9 @@ func NewRootCmd(log *zap.Logger) *cobra.Command { transactionCmd(app), queryCmd(app), startCmd(app), + lineBreakCommand(), + versionCmd(app), ) return rootCmd diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 0000000..bbc2428 --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,59 @@ +package cmd + +import ( + "fmt" + "runtime" + "strings" + + "github.com/pelletier/go-toml/v2" + "github.com/spf13/cobra" + + "github.com/bandprotocol/falcon/relayer" +) + +var ( + // Version defines the application version (defined at compile time) + Version = "" + Commit = "" + Dirty = "" +) + +type versionInfo struct { + Version string `json:"version" yaml:"version"` + Commit string `json:"commit" yaml:"commit"` + Go string `json:"go" yaml:"go"` +} + +// versionCmd returns a command that prints the falcon version information. +func versionCmd(_ *relayer.App) *cobra.Command { + versionCmd := &cobra.Command{ + Use: "version", + Aliases: []string{"v"}, + Short: "Print the falcon version info", + Args: withUsage(cobra.NoArgs), + Example: strings.TrimSpace(fmt.Sprintf(` +$ %s version +$ %s v`, + appName, appName, + )), + RunE: func(cmd *cobra.Command, args []string) error { + commit := Commit + if Dirty != "0" { + commit += " (dirty)" + } + + verInfo := versionInfo{ + Version: Version, + Commit: commit, + Go: fmt.Sprintf("%s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH), + } + + bz, err := toml.Marshal(&verInfo) + + fmt.Fprintln(cmd.OutOrStdout(), string(bz)) + return err + }, + } + + return versionCmd +} diff --git a/relayer/app.go b/relayer/app.go index 7bd8fd4..ab2eace 100644 --- a/relayer/app.go +++ b/relayer/app.go @@ -129,14 +129,14 @@ func (a *App) initLogger(configLogLevel string) error { func (a *App) initTargetChains(ctx context.Context) error { a.targetChains = make(chains.ChainProviders) if a.Config == nil || a.Config.TargetChains == nil { - a.Log.Error("target chains not found in config") + a.Log.Error("Target chains not found in config") return nil } for chainName, chainConfig := range a.Config.TargetChains { cp, err := chainConfig.NewChainProvider(chainName, a.Log, a.HomePath, a.Debug) if err != nil { - a.Log.Error("cannot create chain provider", + a.Log.Error("Cannot create chain provider", zap.Error(err), zap.String("chain_name", chainName), ) @@ -144,7 +144,7 @@ func (a *App) initTargetChains(ctx context.Context) error { } if err := cp.Init(ctx); err != nil { - a.Log.Error("cannot initialize chain provider", + a.Log.Error("Cannot initialize chain provider", zap.Error(err), zap.String("chain_name", chainName), ) @@ -554,7 +554,7 @@ func (a *App) validatePassphrase(envPassphrase string) error { // Start starts the tunnel relayer program. func (a *App) Start(ctx context.Context, tunnelIDs []uint64) error { - a.Log.Info("starting tunnel relayer") + a.Log.Info("Starting tunnel relayer") isSyncTunnelsAllowed := false @@ -579,7 +579,7 @@ func (a *App) Start(ctx context.Context, tunnelIDs []uint64) error { } if len(tunnels) == 0 { - a.Log.Error("no tunnel ID provided") + a.Log.Error("No tunnel ID provided") return fmt.Errorf("no tunnel ID provided") } @@ -628,7 +628,7 @@ func (a *App) Start(ctx context.Context, tunnelIDs []uint64) error { // Relay relays the packet from the source chain to the destination chain. func (a *App) Relay(ctx context.Context, tunnelID uint64) error { - a.Log.Debug("query tunnel info on band chain", zap.Uint64("tunnel_id", tunnelID)) + a.Log.Debug("Query tunnel info on band chain", zap.Uint64("tunnel_id", tunnelID)) tunnel, err := a.BandClient.GetTunnel(ctx, tunnelID) if err != nil { return err diff --git a/relayer/chains/evm/client.go b/relayer/chains/evm/client.go index 02e72df..45e2d05 100644 --- a/relayer/chains/evm/client.go +++ b/relayer/chains/evm/client.go @@ -10,7 +10,6 @@ import ( gethcommon "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" - "github.com/shopspring/decimal" "go.uber.org/zap" ) @@ -21,17 +20,9 @@ type Client interface { Connect(ctx context.Context) error CheckAndConnect(ctx context.Context) error StartLivelinessCheck(ctx context.Context, interval time.Duration) - GetNonce(ctx context.Context, address gethcommon.Address) (uint64, error) + PendingNonceAt(ctx context.Context, address gethcommon.Address) (uint64, error) GetBlockHeight(ctx context.Context) (uint64, error) GetTxReceipt(ctx context.Context, txHash string) (*gethtypes.Receipt, error) - GetEffectiveGasPrice( - ctx context.Context, - receipt *gethtypes.Receipt, - ) (decimal.NullDecimal, error) - GetEffectiveGasTipValue( - ctx context.Context, - receipt *gethtypes.Receipt, - ) (decimal.NullDecimal, error) Query(ctx context.Context, gethAddr gethcommon.Address, data []byte) ([]byte, error) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) EstimateGasPrice(ctx context.Context) (*big.Int, error) @@ -61,7 +52,7 @@ func NewClient(chainName string, cfg *EVMChainProviderConfig, log *zap.Logger) * Endpoints: cfg.Endpoints, QueryTimeout: cfg.QueryTimeout, ExecuteTimeout: cfg.ExecuteTimeout, - Log: log, + Log: log.With(zap.String("chain_name", chainName)), } } @@ -69,21 +60,13 @@ func NewClient(chainName string, cfg *EVMChainProviderConfig, log *zap.Logger) * func (c *client) Connect(ctx context.Context) error { res, err := c.getClientWithMaxHeight(ctx) if err != nil { - c.Log.Error( - "failed to connect to EVM chain", - zap.Error(err), - zap.String("chain_name", c.ChainName), - ) + c.Log.Error("Failed to connect to EVM chain", zap.Error(err)) return err } c.selectedEndpoint = res.Endpoint c.client = res.Client - c.Log.Info( - "Connected to EVM chain", - zap.String("chain_name", c.ChainName), - zap.String("endpoint", c.selectedEndpoint), - ) + c.Log.Info("Connected to EVM chain", zap.String("endpoint", c.selectedEndpoint)) return nil } @@ -94,10 +77,7 @@ func (c *client) StartLivelinessCheck(ctx context.Context, interval time.Duratio for { select { case <-ctx.Done(): - c.Log.Info( - "Stopping liveliness check", - zap.String("chain_name", c.ChainName), - ) + c.Log.Info("Stopping liveliness check") ticker.Stop() @@ -105,26 +85,22 @@ func (c *client) StartLivelinessCheck(ctx context.Context, interval time.Duratio case <-ticker.C: err := c.Connect(ctx) if err != nil { - c.Log.Error( - "liveliness check: unable to reconnect to any endpoints", - zap.Error(err), - ) + c.Log.Error("Liveliness check: unable to reconnect to any endpoints", zap.Error(err)) } } } } -// GetNonce returns the current nonce of the given address. -func (c *client) GetNonce(ctx context.Context, address gethcommon.Address) (uint64, error) { +// PendingNonceAt returns the current pending nonce of the given address. +func (c *client) PendingNonceAt(ctx context.Context, address gethcommon.Address) (uint64, error) { newCtx, cancel := context.WithTimeout(ctx, c.QueryTimeout) defer cancel() - nonce, err := c.client.NonceAt(newCtx, address, nil) + nonce, err := c.client.PendingNonceAt(newCtx, address) if err != nil { c.Log.Error( - "Failed to get nonce", + "Failed to get pending nonce", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", address.Hex()), ) @@ -139,37 +115,13 @@ func (c *client) GetBlockHeight(ctx context.Context) (uint64, error) { newCtx, cancel := context.WithTimeout(ctx, c.QueryTimeout) defer cancel() - block, err := c.client.BlockByNumber(newCtx, nil) + blockHeight, err := c.client.BlockNumber(newCtx) if err != nil { - c.Log.Error( - "Failed to get block height", - zap.Error(err), - zap.String("chain_name", c.ChainName), - zap.String("endpoint", c.selectedEndpoint), - ) + c.Log.Error("Failed to get block height", zap.Error(err), zap.String("endpoint", c.selectedEndpoint)) return 0, fmt.Errorf("[EVMClient] failed to get block height: %w", err) } - return block.NumberU64(), nil -} - -// GetBlock returns the block information of the given height. -func (c *client) GetBlock(ctx context.Context, height uint64) (*gethtypes.Block, error) { - newCtx, cancel := context.WithTimeout(ctx, c.QueryTimeout) - defer cancel() - - block, err := c.client.BlockByNumber(newCtx, new(big.Int).SetUint64(height)) - if err != nil { - c.Log.Error( - "Failed to get block information", - zap.Error(err), - zap.String("chain_name", c.ChainName), - zap.String("endpoint", c.selectedEndpoint), - ) - return nil, fmt.Errorf("[EVMClient] failed to get block information: %w", err) - } - - return block, nil + return blockHeight, nil } // GetTxReceipt returns the transaction receipt of the given transaction hash. @@ -183,7 +135,6 @@ func (c *client) GetTxReceipt(ctx context.Context, txHash string) (*gethtypes.Re c.Log.Debug( "Failed to get tx receipt", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("tx_hash", txHash), ) @@ -203,7 +154,6 @@ func (c *client) GetTxByHash(ctx context.Context, txHash string) (*gethtypes.Tra c.Log.Error( "Failed to get tx by hash", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("tx_hash", txHash), ) @@ -213,66 +163,6 @@ func (c *client) GetTxByHash(ctx context.Context, txHash string) (*gethtypes.Tra return tx, isPending, nil } -// GetEffectiveGasTipValue returns the effective gas tip of the given transaction receipt. -func (c *client) GetEffectiveGasTipValue( - ctx context.Context, - receipt *gethtypes.Receipt, -) (decimal.NullDecimal, error) { - tx, isPending, err := c.GetTxByHash(ctx, receipt.TxHash.String()) - if err != nil { - return decimal.NullDecimal{}, err - } - - if isPending { - c.Log.Debug( - "tx is pending", - zap.String("chain_name", c.ChainName), - zap.String("endpoint", c.selectedEndpoint), - zap.String("tx_hash", receipt.TxHash.String()), - ) - return decimal.NullDecimal{}, fmt.Errorf("[EVMClient] tx is pending") - } - - newCtx, cancel := context.WithTimeout(ctx, c.QueryTimeout) - defer cancel() - - header, err := c.GetBlock(newCtx, receipt.BlockNumber.Uint64()) - if err != nil { - return decimal.NullDecimal{}, err - } - - baseFee := header.BaseFee() - priorityFee := tx.EffectiveGasTipValue(baseFee) - return decimal.NewNullDecimal( - decimal.New(new(big.Int).Add(baseFee, priorityFee).Int64(), 0), - ), nil -} - -// GetEffectiveGasPrice returns the effective gas price of the given transaction receipt. -func (c *client) GetEffectiveGasPrice( - ctx context.Context, - receipt *gethtypes.Receipt, -) (decimal.NullDecimal, error) { - tx, isPending, err := c.GetTxByHash(ctx, receipt.TxHash.String()) - if err != nil { - return decimal.NullDecimal{}, err - } - - if isPending { - c.Log.Debug( - "tx is pending", - zap.String("chain_name", c.ChainName), - zap.String("endpoint", c.selectedEndpoint), - zap.String("tx_hash", receipt.TxHash.String()), - ) - return decimal.NullDecimal{}, fmt.Errorf("[EVMClient] tx is pending") - } - - return decimal.NewNullDecimal( - decimal.New(int64(tx.GasPrice().Uint64()), 0), - ), nil -} - // Query queries the EVM chain, if never connected before, it will try to connect to the available one. func (c *client) Query(ctx context.Context, gethAddr gethcommon.Address, data []byte) ([]byte, error) { callMsg := ethereum.CallMsg{ @@ -288,7 +178,6 @@ func (c *client) Query(ctx context.Context, gethAddr gethcommon.Address, data [] c.Log.Error( "Failed to query contract", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", gethAddr.Hex()), ) @@ -308,7 +197,6 @@ func (c *client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, c.Log.Error( "Failed to estimate gas", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", msg.To.Hex()), ) @@ -328,7 +216,6 @@ func (c *client) EstimateGasPrice(ctx context.Context) (*big.Int, error) { c.Log.Error( "Failed to estimate gas price", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), ) return nil, err @@ -360,7 +247,6 @@ func (c *client) EstimateGasTipCap(ctx context.Context) (*big.Int, error) { c.Log.Error( "Failed to estimate gas tip cap", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), ) return nil, err @@ -373,7 +259,6 @@ func (c *client) EstimateGasTipCap(ctx context.Context) (*big.Int, error) { func (c *client) BroadcastTx(ctx context.Context, tx *gethtypes.Transaction) (string, error) { c.Log.Debug( "Broadcasting tx", - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("tx_hash", tx.Hash().Hex()), zap.String("to", tx.To().Hex()), @@ -390,7 +275,6 @@ func (c *client) BroadcastTx(ctx context.Context, tx *gethtypes.Transaction) (st c.Log.Error( "Failed to broadcast tx", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("tx_hash", tx.Hash().Hex()), ) @@ -413,7 +297,6 @@ func (c *client) getClientWithMaxHeight(ctx context.Context) (ClientConnectionRe "Failed to connect to EVM chain", zap.Error(err), zap.String("endpoint", endpoint), - zap.String("chain_name", c.ChainName), ) ch <- ClientConnectionResult{endpoint, nil, 0} return @@ -422,19 +305,25 @@ func (c *client) getClientWithMaxHeight(ctx context.Context) (ClientConnectionRe newCtx, cancel := context.WithTimeout(ctx, c.QueryTimeout) defer cancel() - block, err := client.BlockByNumber(newCtx, nil) + blockHeight, err := client.BlockNumber(newCtx) if err != nil { c.Log.Debug( "Failed to get block height", zap.Error(err), zap.String("endpoint", endpoint), - zap.String("chain_name", c.ChainName), ) ch <- ClientConnectionResult{endpoint, client, 0} return } - ch <- ClientConnectionResult{endpoint, client, block.NumberU64()} + c.Log.Debug( + "Get height of the given client", + zap.Error(err), + zap.String("endpoint", endpoint), + zap.Uint64("block_number", blockHeight), + ) + + ch <- ClientConnectionResult{endpoint, client, blockHeight} }(endpoint) } @@ -442,7 +331,7 @@ func (c *client) getClientWithMaxHeight(ctx context.Context) (ClientConnectionRe for i := 0; i < len(c.Endpoints); i++ { r := <-ch if r.Client != nil { - if r.BlockHeight >= result.BlockHeight { + if r.BlockHeight > result.BlockHeight { if result.Client != nil { result.Client.Close() } @@ -479,7 +368,6 @@ func (c *client) GetBalance(ctx context.Context, gethAddr gethcommon.Address) (* c.Log.Error( "Failed to query balance", zap.Error(err), - zap.String("chain_name", c.ChainName), zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", gethAddr.Hex()), ) diff --git a/relayer/chains/evm/provider.go b/relayer/chains/evm/provider.go index de8cad2..4397b1e 100644 --- a/relayer/chains/evm/provider.go +++ b/relayer/chains/evm/provider.go @@ -85,15 +85,13 @@ func NewEVMChainProvider( KeyInfo: keyInfo, TunnelRouterAddress: addr, TunnelRouterABI: abi, - Log: log, + Log: log.With(zap.String("chain_name", chainName)), KeyStore: keyStore, }, nil } // Connect connects to the EVM chain. func (cp *EVMChainProvider) Init(ctx context.Context) error { - // TODO: implement loading private key from store - go cp.Client.StartLivelinessCheck(ctx, cp.Config.LivelinessCheckingInterval) return nil @@ -106,31 +104,21 @@ func (cp *EVMChainProvider) QueryTunnelInfo( tunnelDestinationAddr string, ) (*chainstypes.Tunnel, error) { if err := cp.Client.CheckAndConnect(ctx); err != nil { - cp.Log.Error( - "connect client error", - zap.Error(err), - zap.String("chain_name", cp.ChainName), - ) + cp.Log.Error("Connect client error", zap.Error(err)) return nil, fmt.Errorf("[EVMProvider] failed to connect client: %w", err) } addr, err := HexToAddress(tunnelDestinationAddr) if err != nil { - cp.Log.Error( - "invalid address", - zap.Error(err), - zap.String("chain_name", cp.ChainName), - zap.String("address", tunnelDestinationAddr), - ) + cp.Log.Error("Invalid address", zap.Error(err), zap.String("address", tunnelDestinationAddr)) return nil, fmt.Errorf("[EVMProvider] invalid address: %w", err) } info, err := cp.queryTunnelInfo(ctx, tunnelID, addr) if err != nil { cp.Log.Error( - "query contract error", + "Query contract error", zap.Error(err), - zap.String("chain_name", cp.ChainName), zap.Uint64("tunnel_id", tunnelID), zap.String("address", tunnelDestinationAddr), ) @@ -153,67 +141,42 @@ func (cp *EVMChainProvider) RelayPacket( packet *bandtypes.Packet, ) error { if err := cp.Client.CheckAndConnect(ctx); err != nil { - cp.Log.Error( - "connect client error", - zap.Error(err), - zap.String("chain_name", cp.ChainName), - ) + cp.Log.Error("Connect client error", zap.Error(err)) return fmt.Errorf("[EVMProvider] failed to connect client: %w", err) } gasInfo, err := cp.EstimateGas(ctx) if err != nil { - cp.Log.Error( - "failed to estimate gas", - zap.Error(err), - zap.String("chain_name", cp.ChainName), - ) + cp.Log.Error("Failed to estimate gas", zap.Error(err)) return fmt.Errorf("failed to estimate gas: %w", err) } // get a free sender + cp.Log.Debug("Waiting for a free sender...") sender := <-cp.FreeSenders defer func() { cp.FreeSenders <- sender }() - cp.Log.Debug( - fmt.Sprintf("Relaying packet using address: %v", sender.Address), - zap.String("evm_sender_address", sender.Address.String()), - zap.String("chain_name", cp.ChainName), + log := cp.Log.With( zap.Uint64("tunnel_id", packet.TunnelID), zap.Uint64("sequence", packet.Sequence), + zap.String("sender_address", sender.Address.String()), ) - retryCount := 0 - for retryCount < cp.Config.MaxRetry { - cp.Log.Info( - "relaying a message", - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), - zap.Int("retry_count", retryCount), - ) + retryCount := 1 + for retryCount <= cp.Config.MaxRetry { + log.Info("Relaying a message", zap.Int("retry_count", retryCount)) // create and submit a transaction; if failed, retry, no need to bump gas. txHash, err := cp.handleRelay(ctx, packet, sender, gasInfo) if err != nil { - cp.Log.Error( - "HandleRelay error", - zap.Error(err), - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), - zap.Int("retry_count", retryCount), - ) + log.Error("HandleRelay error", zap.Error(err), zap.Int("retry_count", retryCount)) retryCount += 1 continue } createdAt := time.Now() - cp.Log.Info( - "submitted a message; checking transaction status", - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), + log.Info( + "Submitted a message; checking transaction status", zap.String("tx_hash", txHash), zap.Int("retry_count", retryCount), ) @@ -224,12 +187,9 @@ func (cp *EVMChainProvider) RelayPacket( for time.Since(createdAt) < cp.Config.WaitingTxDuration { result, err := cp.checkConfirmedTx(ctx, txHash) if err != nil { - cp.Log.Debug( + log.Debug( "Failed to check tx status", zap.Error(err), - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), zap.String("tx_hash", txHash), zap.Int("retry_count", retryCount), ) @@ -244,11 +204,8 @@ func (cp *EVMChainProvider) RelayPacket( txStatus = result.Status switch result.Status { case TX_STATUS_SUCCESS: - cp.Log.Info( + log.Info( "Packet is successfully relayed", - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), zap.String("tx_hash", txHash), zap.Int("retry_count", retryCount), ) @@ -257,12 +214,9 @@ func (cp *EVMChainProvider) RelayPacket( retryCount += 1 break checkTxLogic case TX_STATUS_UNMINED: - cp.Log.Debug( + log.Debug( "Waiting for tx to be mined", zap.Error(err), - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), zap.String("tx_hash", txHash), zap.Int("retry_count", retryCount), ) @@ -271,13 +225,10 @@ func (cp *EVMChainProvider) RelayPacket( } } - cp.Log.Error( + log.Error( "Failed to relaying a packet with status and error", zap.Error(checkTxErr), zap.String("status", txStatus.String()), - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), zap.String("tx_hash", txHash), zap.Int("retry_count", retryCount), ) @@ -285,14 +236,7 @@ func (cp *EVMChainProvider) RelayPacket( // bump gas and retry gasInfo, err = cp.BumpAndBoundGas(ctx, gasInfo, cp.Config.GasMultiplier) if err != nil { - cp.Log.Error( - "cannot bump gas", - zap.Error(err), - zap.String("chain_name", cp.ChainName), - zap.Uint64("tunnel_id", packet.TunnelID), - zap.Uint64("sequence", packet.Sequence), - zap.Int("retry_count", retryCount), - ) + log.Error("Cannot bump gas", zap.Error(err), zap.Int("retry_count", retryCount)) } retryCount += 1 @@ -341,7 +285,6 @@ func (cp *EVMChainProvider) checkConfirmedTx( TX_STATUS_UNMINED, decimal.NullDecimal{}, cp.GasType, - decimal.NullDecimal{}, ) receipt, err := cp.Client.GetTxReceipt(ctx, txHash) @@ -365,27 +308,7 @@ func (cp *EVMChainProvider) checkConfirmedTx( // calculate gas used and effective gas price gasUsed := decimal.NewNullDecimal(decimal.New(int64(receipt.GasUsed), 0)) - - effectiveGas, err := cp.GetEffectiveGas(ctx, receipt) - if err != nil { - return nil, fmt.Errorf("failed to get effective gas price: %w", err) - } - - return NewConfirmTxResult(txHash, TX_STATUS_SUCCESS, gasUsed, cp.GasType, effectiveGas), nil -} - -func (cp *EVMChainProvider) GetEffectiveGas( - ctx context.Context, - receipt *gethtypes.Receipt, -) (decimal.NullDecimal, error) { - switch cp.GasType { - case GasTypeLegacy: - return cp.Client.GetEffectiveGasPrice(ctx, receipt) - case GasTypeEIP1559: - return cp.Client.GetEffectiveGasTipValue(ctx, receipt) - default: - return decimal.NullDecimal{}, fmt.Errorf("unsupported gas type: %v", cp.GasType) - } + return NewConfirmTxResult(txHash, TX_STATUS_SUCCESS, gasUsed, cp.GasType), nil } // EstimateGas estimates the gas for the transaction. @@ -500,7 +423,7 @@ func (cp *EVMChainProvider) newRelayTx( sender gethcommon.Address, gasInfo GasInfo, ) (*gethtypes.Transaction, error) { - nonce, err := cp.Client.GetNonce(ctx, sender) + nonce, err := cp.Client.PendingNonceAt(ctx, sender) if err != nil { return nil, err } @@ -606,7 +529,7 @@ func (cp *EVMChainProvider) QueryBalance( ) (*big.Int, error) { if err := cp.Client.CheckAndConnect(ctx); err != nil { cp.Log.Error( - "connect client error", + "Connect client error", zap.Error(err), zap.String("chain_name", cp.ChainName), ) diff --git a/relayer/chains/evm/types.go b/relayer/chains/evm/types.go index 3e07928..f363122 100644 --- a/relayer/chains/evm/types.go +++ b/relayer/chains/evm/types.go @@ -35,11 +35,10 @@ func (t TxStatus) String() string { // ConfirmTxResult is the result of confirming a transaction type ConfirmTxResult struct { - TxHash string - Status TxStatus - GasUsed decimal.NullDecimal - GasType GasType - EffectiveGas decimal.NullDecimal + TxHash string + Status TxStatus + GasUsed decimal.NullDecimal + GasType GasType } func NewConfirmTxResult( @@ -47,14 +46,12 @@ func NewConfirmTxResult( status TxStatus, gasUsed decimal.NullDecimal, gasType GasType, - effectiveGas decimal.NullDecimal, ) *ConfirmTxResult { return &ConfirmTxResult{ - TxHash: txHash, - Status: status, - GasUsed: gasUsed, - GasType: gasType, - EffectiveGas: effectiveGas, + TxHash: txHash, + Status: status, + GasUsed: gasUsed, + GasType: gasType, } } diff --git a/relayer/scheduler.go b/relayer/scheduler.go index fdbe468..92f93cb 100644 --- a/relayer/scheduler.go +++ b/relayer/scheduler.go @@ -95,7 +95,7 @@ func (s *Scheduler) Execute(ctx context.Context) { // Execute the task for each tunnel relayer for i, tr := range s.TunnelRelayers { if s.isErrorOnHolds[i] { - s.Log.Info( + s.Log.Debug( "Skipping this tunnel: the operation is on hold due to error on last round.", zap.Uint64("tunnel_id", tr.TunnelID), zap.Int("relayer_id", i), @@ -113,18 +113,18 @@ func (s *Scheduler) Execute(ctx context.Context) { // TriggerTunnelRelayer triggers the tunnel relayer to check and relay the packet func (s *Scheduler) TriggerTunnelRelayer(ctx context.Context, task Task) { tr := s.TunnelRelayers[task.RelayerID] - s.Log.Info("Executing task", zap.Uint64("tunnel_id", tr.TunnelID)) // if the tunnel relayer is executing, skip the round if tr.IsExecuting() { - s.Log.Info( + s.Log.Debug( "Skipping this tunnel: tunnel relayer is executing on another process", zap.Uint64("tunnel_id", tr.TunnelID), ) - return } + s.Log.Info("Executing task", zap.Uint64("tunnel_id", tr.TunnelID)) + // Check and relay the packet, if error occurs, set the error flag. if err := tr.CheckAndRelay(ctx); err != nil { s.isErrorOnHolds[task.RelayerID] = true @@ -156,7 +156,7 @@ func (s *Scheduler) SyncTunnels(ctx context.Context) { return } - s.Log.Info("starting sync tunnels") + s.Log.Info("Starting sync tunnels") tunnels, err := s.BandClient.GetTunnels(ctx) if err != nil { s.Log.Error("Failed to fetch tunnels from Band Chain", zap.Error(err)) diff --git a/relayer/tunnel_relayer.go b/relayer/tunnel_relayer.go index 61df995..4d6fc88 100644 --- a/relayer/tunnel_relayer.go +++ b/relayer/tunnel_relayer.go @@ -35,7 +35,7 @@ func NewTunnelRelayer( targetChainProvider chains.ChainProvider, ) TunnelRelayer { return TunnelRelayer{ - Log: log, + Log: log.With(zap.Uint64("tunnel_id", tunnelID)), TunnelID: tunnelID, ContractAddress: contractAddress, CheckingPacketInterval: checkingPacketInterval, @@ -64,11 +64,7 @@ func (t *TunnelRelayer) CheckAndRelay(ctx context.Context) (err error) { // Query tunnel info from BandChain tunnelBandInfo, err := t.BandClient.GetTunnel(ctx, t.TunnelID) if err != nil { - t.Log.Error( - "failed to get tunnel", - zap.Error(err), - zap.Uint64("tunnel_id", t.TunnelID), - ) + t.Log.Error("Failed to get tunnel", zap.Error(err)) return err } @@ -78,37 +74,24 @@ func (t *TunnelRelayer) CheckAndRelay(ctx context.Context) (err error) { return err } if !tunnelChainInfo.IsActive { - t.Log.Error("tunnel is not active on target chain", zap.Uint64("tunnel_id", t.TunnelID)) + t.Log.Error("Tunnel is not active on target chain") return fmt.Errorf("tunnel is not active on target chain") } // end process if current packet is already relayed nextSeq := tunnelChainInfo.LatestSequence + 1 if tunnelBandInfo.LatestSequence < nextSeq { - t.Log.Info( - "no new packet to relay", - zap.Uint64("tunnel_id", t.TunnelID), - zap.Uint64("sequence", tunnelChainInfo.LatestSequence), - ) + t.Log.Info("No new packet to relay", zap.Uint64("sequence", tunnelChainInfo.LatestSequence)) return nil } // Relay packets for seq := nextSeq; seq <= tunnelBandInfo.LatestSequence; seq++ { - t.Log.Info( - "relaying packet", - zap.Uint64("tunnel_id", t.TunnelID), - zap.Uint64("sequence", seq), - ) + t.Log.Info("Relaying packet", zap.Uint64("sequence", seq)) packet, err := t.BandClient.GetTunnelPacket(ctx, t.TunnelID, seq) if err != nil { - t.Log.Error( - "failed to get packet", - zap.Error(err), - zap.Uint64("tunnel_id", t.TunnelID), - zap.Uint64("sequence", seq), - ) + t.Log.Error("Failed to get packet", zap.Error(err), zap.Uint64("sequence", seq)) return err } @@ -119,38 +102,24 @@ func (t *TunnelRelayer) CheckAndRelay(ctx context.Context) (err error) { switch tsstypes.SigningStatus(tsstypes.SigningStatus_value[signing.Status]) { case tsstypes.SIGNING_STATUS_FALLEN: - t.Log.Error( - "Failed to relay packet", - zap.Error(fmt.Errorf("signing status is fallen")), - zap.Uint64("tunnel_id", t.TunnelID), - zap.Uint64("sequence", seq), - ) + err := fmt.Errorf("signing status is fallen") + t.Log.Error("Failed to relay packet", zap.Error(err), zap.Uint64("sequence", seq)) return err case tsstypes.SIGNING_STATUS_WAITING: t.Log.Info( "The current packet must wait for the completion of the EVM signature", - zap.Uint64("tunnel_id", t.TunnelID), zap.Uint64("sequence", seq), ) return nil } if err := t.TargetChainProvider.RelayPacket(ctx, packet); err != nil { - t.Log.Error( - "failed to relay packet", - zap.Error(err), - zap.Uint64("tunnel_id", t.TunnelID), - zap.Uint64("sequence", seq), - ) + t.Log.Error("Failed to relay packet", zap.Error(err), zap.Uint64("sequence", seq)) return err } - t.Log.Info( - "successfully relayed packet", - zap.Uint64("tunnel_id", t.TunnelID), - zap.Uint64("sequence", seq), - ) + t.Log.Info("Successfully relayed packet", zap.Uint64("sequence", seq)) } return nil