From 51a1551d088d0b42f34b3e8af2d5860d9ec74952 Mon Sep 17 00:00:00 2001 From: Tanut Lertwarachai Date: Tue, 24 Dec 2024 21:31:42 +0700 Subject: [PATCH 1/4] add err-logic --- cmd/chains.go | 2 +- cmd/config.go | 2 +- cmd/errors.go | 7 +++ relayer/app.go | 56 +++++++++++----------- relayer/band/client.go | 6 +-- relayer/band/errors.go | 5 ++ relayer/chains/evm/client.go | 19 ++++---- relayer/chains/evm/errors.go | 86 ++++++++++++++++++++++++++++++++++ relayer/chains/evm/provider.go | 38 +++++++-------- relayer/errors.go | 27 +++++++++++ 10 files changed, 186 insertions(+), 62 deletions(-) create mode 100644 cmd/errors.go create mode 100644 relayer/band/errors.go create mode 100644 relayer/chains/evm/errors.go create mode 100644 relayer/errors.go diff --git a/cmd/chains.go b/cmd/chains.go index 6bad572..8fb02ee 100644 --- a/cmd/chains.go +++ b/cmd/chains.go @@ -84,7 +84,7 @@ $ %s chains list $ %s ch l`, appName, appName)), RunE: func(cmd *cobra.Command, args []string) error { if app.Config == nil { - return fmt.Errorf("config does not exist: %s", app.HomePath) + return ErrConfigNotExist(app.HomePath) } i := 1 diff --git a/cmd/config.go b/cmd/config.go index 7df5763..712fb2b 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -37,7 +37,7 @@ $ %s config show --home %s $ %s cfg list`, appName, defaultHome, appName)), RunE: func(cmd *cobra.Command, args []string) error { if app.Config == nil { - return fmt.Errorf("config does not exist: %s", app.HomePath) + return ErrConfigNotExist(app.HomePath) } b, err := toml.Marshal(app.Config) diff --git a/cmd/errors.go b/cmd/errors.go new file mode 100644 index 0000000..24a02d4 --- /dev/null +++ b/cmd/errors.go @@ -0,0 +1,7 @@ +package cmd + +import "fmt" + +func ErrConfigNotExist(homePath string) error { + return fmt.Errorf("config does not exist: %s", homePath) +} diff --git a/relayer/app.go b/relayer/app.go index 5f78b5e..2d2e9c4 100644 --- a/relayer/app.go +++ b/relayer/app.go @@ -182,7 +182,7 @@ func (a *App) InitConfigFile(homePath string, customFilePath string) error { // check if the config file already exists // https://stackoverflow.com/questions/12518876/how-to-check-if-a-file-exists-in-go if _, err := os.Stat(cfgPath); err == nil { - return fmt.Errorf("config already exists: %s", cfgPath) + return ErrConfigExist(cfgPath) } else if !os.IsNotExist(err) { return err } @@ -261,7 +261,7 @@ func (a *App) InitPassphrase() error { // QueryTunnelInfo queries tunnel information by given tunnel ID func (a *App) QueryTunnelInfo(ctx context.Context, tunnelID uint64) (*types.Tunnel, error) { if a.Config == nil { - return nil, fmt.Errorf("config is not initialized") + return nil, ErrConfigNotExist(a.HomePath) } c := a.BandClient @@ -300,7 +300,7 @@ func (a *App) QueryTunnelInfo(ctx context.Context, tunnelID uint64) (*types.Tunn // QueryTunnelPacketInfo queries tunnel packet information by given tunnel ID func (a *App) QueryTunnelPacketInfo(ctx context.Context, tunnelID uint64, sequence uint64) (*bandtypes.Packet, error) { if a.Config == nil { - return nil, fmt.Errorf("config is not initialized") + return nil, ErrConfigNotExist(a.HomePath) } c := a.BandClient @@ -309,11 +309,11 @@ func (a *App) QueryTunnelPacketInfo(ctx context.Context, tunnelID uint64, sequen func (a *App) AddChainConfig(chainName string, filePath string) error { if a.Config == nil { - return fmt.Errorf("config does not exist: %s", a.HomePath) + return ErrConfigNotExist(a.HomePath) } if _, exist := a.Config.TargetChains[chainName]; exist { - return fmt.Errorf("existing chain name : %s", chainName) + return ErrChainNameExist(chainName) } chainProviderConfig, err := LoadChainConfig(filePath) @@ -337,11 +337,11 @@ func (a *App) AddChainConfig(chainName string, filePath string) error { func (a *App) DeleteChainConfig(chainName string) error { if a.Config == nil { - return fmt.Errorf("config does not exist: %s", a.HomePath) + return ErrConfigNotExist(a.HomePath) } if _, exist := a.Config.TargetChains[chainName]; !exist { - return fmt.Errorf("not existing chain name : %s", chainName) + return ErrChainNameNotExist(chainName) } delete(a.Config.TargetChains, chainName) @@ -360,13 +360,13 @@ func (a *App) DeleteChainConfig(chainName string) error { func (a *App) GetChainConfig(chainName string) (chains.ChainProviderConfig, error) { if a.Config == nil { - return nil, fmt.Errorf("config does not exist: %s", a.HomePath) + return nil, ErrConfigNotExist(a.HomePath) } chainProviders := a.Config.TargetChains if _, exist := chainProviders[chainName]; !exist { - return nil, fmt.Errorf("not existing chain name : %s", chainName) + return nil, ErrChainNameNotExist(chainName) } return chainProviders[chainName], nil @@ -382,7 +382,7 @@ func (a *App) AddKey( index uint, ) (*chainstypes.Key, error) { if a.Config == nil { - return nil, fmt.Errorf("config does not exist: %s", a.HomePath) + return nil, ErrConfigNotExist(a.HomePath) } if err := a.validatePassphrase(a.EnvPassphrase); err != nil { @@ -392,11 +392,11 @@ func (a *App) AddKey( cp, exist := a.targetChains[chainName] if !exist { - return nil, fmt.Errorf("chain name does not exist: %s", chainName) + return nil, ErrChainNameNotExist(chainName) } if cp.IsKeyNameExist(keyName) { - return nil, fmt.Errorf("key name already exists: %s", keyName) + return nil, ErrKeyNameExist(keyName) } keyOutput, err := cp.AddKey(keyName, mnemonic, privateKey, a.HomePath, coinType, account, index, a.EnvPassphrase) @@ -409,7 +409,7 @@ func (a *App) AddKey( func (a *App) DeleteKey(chainName string, keyName string) error { if a.Config == nil { - return fmt.Errorf("config does not exist: %s", a.HomePath) + return ErrConfigNotExist(a.HomePath) } if err := a.validatePassphrase(a.EnvPassphrase); err != nil { @@ -419,11 +419,11 @@ func (a *App) DeleteKey(chainName string, keyName string) error { cp, exist := a.targetChains[chainName] if !exist { - return fmt.Errorf("chain name does not exist: %s", chainName) + return ErrChainNameNotExist(chainName) } if !cp.IsKeyNameExist(keyName) { - return fmt.Errorf("key name does not exist: %s", keyName) + return ErrKeyNameNotExist(keyName) } return cp.DeleteKey(a.HomePath, keyName, a.EnvPassphrase) @@ -431,7 +431,7 @@ func (a *App) DeleteKey(chainName string, keyName string) error { func (a *App) ExportKey(chainName string, keyName string) (string, error) { if a.Config == nil { - return "", fmt.Errorf("config does not exist: %s", a.HomePath) + return "", ErrConfigNotExist(a.HomePath) } if err := a.validatePassphrase(a.EnvPassphrase); err != nil { @@ -441,11 +441,11 @@ func (a *App) ExportKey(chainName string, keyName string) (string, error) { cp, exist := a.targetChains[chainName] if !exist { - return "", fmt.Errorf("chain name does not exist: %s", chainName) + return "", ErrChainNameNotExist(chainName) } if !cp.IsKeyNameExist(keyName) { - return "", fmt.Errorf("key name does not exist: %s", chainName) + return "", ErrKeyNameNotExist(keyName) } privateKey, err := cp.ExportPrivateKey(keyName, a.EnvPassphrase) @@ -458,13 +458,13 @@ func (a *App) ExportKey(chainName string, keyName string) (string, error) { func (a *App) ListKeys(chainName string) ([]*chainstypes.Key, error) { if a.Config == nil { - return make([]*chainstypes.Key, 0), fmt.Errorf("config does not exist: %s", a.HomePath) + return make([]*chainstypes.Key, 0), ErrConfigNotExist(a.HomePath) } cp, exist := a.targetChains[chainName] if !exist { - return make([]*chainstypes.Key, 0), fmt.Errorf("chain name does not exist: %s", chainName) + return make([]*chainstypes.Key, 0), ErrChainNameNotExist(chainName) } return cp.Listkeys(), nil @@ -472,16 +472,16 @@ func (a *App) ListKeys(chainName string) ([]*chainstypes.Key, error) { func (a *App) ShowKey(chainName string, keyName string) (string, error) { if a.Config == nil { - return "", fmt.Errorf("config does not exist: %s", a.HomePath) + return "", ErrConfigNotExist(a.HomePath) } cp, exist := a.targetChains[chainName] if !exist { - return "", fmt.Errorf("chain name does not exist: %s", chainName) + return "", ErrChainNameNotExist(chainName) } if !cp.IsKeyNameExist(keyName) { - return "", fmt.Errorf("key name does not exist: %s", keyName) + return "", ErrKeyNameNotExist(keyName) } return cp.ShowKey(keyName), nil @@ -489,17 +489,17 @@ func (a *App) ShowKey(chainName string, keyName string) (string, error) { func (a *App) QueryBalance(ctx context.Context, chainName string, keyName string) (*big.Int, error) { if a.Config == nil { - return nil, fmt.Errorf("config does not exist: %s", a.HomePath) + return nil, ErrConfigNotExist(a.HomePath) } cp, exist := a.targetChains[chainName] if !exist { - return nil, fmt.Errorf("chain name does not exist: %s", chainName) + return nil, ErrChainNameNotExist(chainName) } if !cp.IsKeyNameExist(keyName) { - return nil, fmt.Errorf("key name does not exist: %s", chainName) + return nil, ErrKeyNameNotExist(keyName) } return cp.QueryBalance(ctx, keyName) @@ -604,7 +604,7 @@ func (a *App) Start(ctx context.Context, tunnelIDs []uint64) error { for _, tunnel := range tunnels { chainProvider, ok := a.targetChains[tunnel.TargetChainID] if !ok { - return fmt.Errorf("target chain provider not found: %s", tunnel.TargetChainID) + return ErrChainNameNotExist(tunnel.TargetChainID) } tr := NewTunnelRelayer( @@ -648,7 +648,7 @@ func (a *App) Relay(ctx context.Context, tunnelID uint64) error { chainProvider, ok := a.targetChains[tunnel.TargetChainID] if !ok { - return fmt.Errorf("target chain provider not found: %s", tunnel.TargetChainID) + return ErrChainNameNotExist(tunnel.TargetChainID) } if err := chainProvider.LoadFreeSenders(a.HomePath, a.EnvPassphrase); err != nil { diff --git a/relayer/band/client.go b/relayer/band/client.go index bfe5400..9d79d01 100644 --- a/relayer/band/client.go +++ b/relayer/band/client.go @@ -106,7 +106,7 @@ func (c *client) Connect(timeout uint) error { func (c *client) GetTunnel(ctx context.Context, tunnelID uint64) (*types.Tunnel, error) { // check connection to bandchain if c.QueryClient == nil { - return nil, fmt.Errorf("cannot connect to bandchain") + return nil, ErrBandChainNotConnect } res, err := c.QueryClient.TunnelQueryClient.Tunnel(ctx, &tunneltypes.QueryTunnelRequest{ @@ -141,7 +141,7 @@ func (c *client) GetTunnel(ctx context.Context, tunnelID uint64) (*types.Tunnel, func (c *client) GetTunnelPacket(ctx context.Context, tunnelID uint64, sequence uint64) (*types.Packet, error) { // check connection to bandchain if c.QueryClient == nil { - return nil, fmt.Errorf("cannot connect to bandchain") + return nil, ErrBandChainNotConnect } // Get packet information by given tunnel ID and sequence @@ -199,7 +199,7 @@ func (c *client) GetTunnelPacket(ctx context.Context, tunnelID uint64, sequence func (c *client) GetTunnels(ctx context.Context) ([]types.Tunnel, error) { // check connection to bandchain if c.QueryClient == nil { - return nil, fmt.Errorf("cannot connect to bandchain") + return nil, ErrBandChainNotConnect } tunnels := make([]types.Tunnel, 0) diff --git a/relayer/band/errors.go b/relayer/band/errors.go new file mode 100644 index 0000000..b55f568 --- /dev/null +++ b/relayer/band/errors.go @@ -0,0 +1,5 @@ +package band + +import "fmt" + +var ErrBandChainNotConnect = fmt.Errorf("cannot connect to bandchain") diff --git a/relayer/chains/evm/client.go b/relayer/chains/evm/client.go index 26f92cf..f7a2f14 100644 --- a/relayer/chains/evm/client.go +++ b/relayer/chains/evm/client.go @@ -2,7 +2,6 @@ package evm import ( "context" - "fmt" "math/big" "time" @@ -104,7 +103,7 @@ func (c *client) PendingNonceAt(ctx context.Context, address gethcommon.Address) zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", address.Hex()), ) - return 0, fmt.Errorf("[EVMClient] failed to get nonce: %w", err) + return 0, ErrGetNonce(err) } return nonce, nil @@ -118,7 +117,7 @@ func (c *client) GetBlockHeight(ctx context.Context) (uint64, error) { blockHeight, err := c.client.BlockNumber(newCtx) if err != nil { 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 0, ErrGetBlockHeight(err) } return blockHeight, nil @@ -138,7 +137,7 @@ func (c *client) GetTxReceipt(ctx context.Context, txHash string) (*gethtypes.Re zap.String("endpoint", c.selectedEndpoint), zap.String("tx_hash", txHash), ) - return nil, fmt.Errorf("[EVMClient] failed to get tx receipt: %w", err) + return nil, ErrGetTxReceipt(err) } return receipt, nil @@ -157,7 +156,7 @@ func (c *client) GetTxByHash(ctx context.Context, txHash string) (*gethtypes.Tra zap.String("endpoint", c.selectedEndpoint), zap.String("tx_hash", txHash), ) - return nil, false, fmt.Errorf("[EVMClient] failed to get tx by hash: %w", err) + return nil, false, ErrGetTxByHash(err) } return tx, isPending, nil @@ -181,7 +180,7 @@ func (c *client) Query(ctx context.Context, gethAddr gethcommon.Address, data [] zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", gethAddr.Hex()), ) - return nil, fmt.Errorf("[EVMClient] failed to query: %w", err) + return nil, ErrQuery(err) } return res, nil @@ -200,7 +199,7 @@ func (c *client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", msg.To.Hex()), ) - return 0, fmt.Errorf("[EVMClient] failed to estimate gas: %w", err) + return 0, ErrEstimateGas(err, true) } // NOTE: Add 20% buffer to the estimated gas. @@ -282,7 +281,7 @@ func (c *client) BroadcastTx(ctx context.Context, tx *gethtypes.Transaction) (st zap.String("tx_hash", tx.Hash().Hex()), ) - return "", fmt.Errorf("[EVMClient] failed to broadcast tx with error %s", err.Error()) + return "", ErrBroadcastTx(err.Error()) } return tx.Hash().Hex(), nil @@ -346,7 +345,7 @@ func (c *client) getClientWithMaxHeight(ctx context.Context) (ClientConnectionRe } if result.Client == nil { - return ClientConnectionResult{}, fmt.Errorf("[EVMClient] failed to connect to EVM chain") + return ClientConnectionResult{}, ErrConnectEVMChain } return result, nil @@ -374,7 +373,7 @@ func (c *client) GetBalance(ctx context.Context, gethAddr gethcommon.Address) (* zap.String("endpoint", c.selectedEndpoint), zap.String("evm_address", gethAddr.Hex()), ) - return nil, fmt.Errorf("[EVMClient] failed to query balance: %w", err) + return nil, ErrQueryBalance(err) } return res, nil diff --git a/relayer/chains/evm/errors.go b/relayer/chains/evm/errors.go new file mode 100644 index 0000000..f9ef194 --- /dev/null +++ b/relayer/chains/evm/errors.go @@ -0,0 +1,86 @@ +package evm + +import "fmt" + +var ( + evmProviderErr = func(err error) error { + return fmt.Errorf("[EVMProvider] %w", err) + } + evmClientErr = func(err error) error { + return fmt.Errorf("[EVMClient] %w", err) + } +) + +var ( + // Common error + ErrEstimateGas = func(err error, isClient bool) error { + if !isClient { + return evmClientErr(fmt.Errorf("failed to estimate gas: %s", err)) + } + return evmProviderErr(fmt.Errorf("failed to estimate gas: %s", err)) + } + + // EVMProvider errors + ErrLoadAbi = func(err error) error { + return evmProviderErr(fmt.Errorf("failed to load abi: %w", err)) + } + + ErrUnsupportedGasType = func(gasType GasType) error { + return evmProviderErr(fmt.Errorf("unsupported gas type: %v", gasType)) + } + + ErrPackCalldata = func(err error) error { + return evmProviderErr(fmt.Errorf("failed to pack calldata: %s", err)) + } + + ErrQueryData = func(err error) error { + return evmProviderErr(fmt.Errorf("failed to query data: %w", err)) + } + + ErrUnpackData = func(err error) error { + return evmProviderErr(fmt.Errorf("failed to unpack data: %w", err)) + } + + ErrInvalidAddress = func(err error) error { + return evmProviderErr(fmt.Errorf("invalid address: %w", err)) + } + + ErrClientConnection = func(err error) error { + return evmProviderErr(fmt.Errorf("failed to query contract: %w", err)) + } + + ErrRelayPacketRetries = func(retries int) error { + return evmProviderErr(fmt.Errorf("failed to relay packet after %d retries", retries)) + } + + // EVMClient errors + ErrGetNonce = func(err error) error { + return evmClientErr(fmt.Errorf("failed to get nonce: %w", err)) + } + + ErrGetBlockHeight = func(err error) error { + return evmClientErr(fmt.Errorf("failed to get block height: %w", err)) + } + + ErrGetTxReceipt = func(err error) error { + return evmClientErr(fmt.Errorf("failed to get tx receipt: %w", err)) + } + + ErrGetTxByHash = func(err error) error { + return evmClientErr(fmt.Errorf("failed to get tx by hash: %w", err)) + } + + ErrQuery = func(err error) error { + return evmClientErr(fmt.Errorf("failed to query: %w", err)) + } + + ErrBroadcastTx = func(s string) error { + return evmClientErr(fmt.Errorf("failed to broadcast tx with error: %s", s)) + } + + ErrConnectEVMChain = evmClientErr(fmt.Errorf("failed to connect to EVM chain")) + + ErrQueryBalance = func(err error) error { + return evmClientErr(fmt.Errorf("failed to query balance: %w", err)) + } +) diff --git a/relayer/chains/evm/provider.go b/relayer/chains/evm/provider.go index 4442d8c..ec6255e 100644 --- a/relayer/chains/evm/provider.go +++ b/relayer/chains/evm/provider.go @@ -57,7 +57,7 @@ func NewEVMChainProvider( zap.Error(err), zap.String("chain_name", chainName), ) - return nil, fmt.Errorf("[EVMProvider] failed to load abi: %w", err) + return nil, ErrLoadAbi(err) } addr, err := HexToAddress(cfg.TunnelRouterAddress) @@ -66,7 +66,7 @@ func NewEVMChainProvider( zap.Error(err), zap.String("chain_name", chainName), ) - return nil, fmt.Errorf("[EVMProvider] incorrect address: %w", err) + return nil, ErrInvalidAddress(err) } keyStoreDir := path.Join(homePath, keyDir, chainName, privateKeyDir) @@ -109,13 +109,13 @@ func (cp *EVMChainProvider) QueryTunnelInfo( ) (*chainstypes.Tunnel, error) { if err := cp.Client.CheckAndConnect(ctx); err != nil { cp.Log.Error("Connect client error", zap.Error(err)) - return nil, fmt.Errorf("[EVMProvider] failed to connect client: %w", err) + return nil, ErrClientConnection(err) } addr, err := HexToAddress(tunnelDestinationAddr) if err != nil { cp.Log.Error("Invalid address", zap.Error(err), zap.String("address", tunnelDestinationAddr)) - return nil, fmt.Errorf("[EVMProvider] invalid address: %w", err) + return nil, ErrInvalidAddress(err) } info, err := cp.queryTunnelInfo(ctx, tunnelID, addr) @@ -127,7 +127,7 @@ func (cp *EVMChainProvider) QueryTunnelInfo( zap.String("address", tunnelDestinationAddr), ) - return nil, fmt.Errorf("[EVMProvider] failed to query contract: %w", err) + return nil, ErrQueryData(err) } return &chainstypes.Tunnel{ @@ -146,13 +146,13 @@ func (cp *EVMChainProvider) RelayPacket( ) error { if err := cp.Client.CheckAndConnect(ctx); err != nil { cp.Log.Error("Connect client error", zap.Error(err)) - return fmt.Errorf("[EVMProvider] failed to connect client: %w", err) + return ErrClientConnection(err) } gasInfo, err := cp.EstimateGas(ctx) if err != nil { cp.Log.Error("Failed to estimate gas", zap.Error(err)) - return fmt.Errorf("failed to estimate gas: %w", err) + return ErrEstimateGas(err, false) } // get a free sender @@ -246,7 +246,7 @@ func (cp *EVMChainProvider) RelayPacket( retryCount += 1 } - return fmt.Errorf("[EVMProvider] failed to relay packet after %d retries", cp.Config.MaxRetry) + return ErrRelayPacketRetries(cp.Config.MaxRetry) } // handleRelay handles the relay message from the source chain to the destination chain. @@ -338,7 +338,7 @@ func (cp *EVMChainProvider) EstimateGas(ctx context.Context) (GasInfo, error) { return cp.BumpAndBoundGas(ctx, NewGasEIP1559Info(priorityFee, baseFee), 1.0) default: - return GasInfo{}, fmt.Errorf("unsupported gas type: %v", cp.GasType) + return GasInfo{}, ErrUnsupportedGasType(cp.GasType) } } @@ -392,7 +392,7 @@ func (cp *EVMChainProvider) BumpAndBoundGas( return NewGasEIP1559Info(newPriorityFee, newBaseFee), nil default: - return GasInfo{}, fmt.Errorf("unsupported gas type: %v", cp.GasType) + return GasInfo{}, ErrUnsupportedGasType(cp.GasType) } } @@ -404,17 +404,17 @@ func (cp *EVMChainProvider) queryTunnelInfo( ) (*TunnelInfoOutput, error) { calldata, err := cp.TunnelRouterABI.Pack("tunnelInfo", tunnelID, addr) if err != nil { - return nil, fmt.Errorf("failed to pack calldata: %w", err) + return nil, ErrPackCalldata(err) } b, err := cp.Client.Query(ctx, cp.TunnelRouterAddress, calldata) if err != nil { - return nil, fmt.Errorf("failed to query data: %w", err) + return nil, ErrQueryData(err) } var output TunnelInfoOutputRaw if err := cp.TunnelRouterABI.UnpackIntoInterface(&output, "tunnelInfo", b); err != nil { - return nil, fmt.Errorf("failed to unpack data: %w", err) + return nil, ErrUnpackData(err) } return &output.Info, nil @@ -475,7 +475,7 @@ func (cp *EVMChainProvider) newRelayTx( }) default: - return nil, fmt.Errorf("unsupported gas type: %v", cp.GasType) + return nil, ErrUnsupportedGasType(cp.GasType) } return tx, nil @@ -520,7 +520,7 @@ func (cp *EVMChainProvider) signTx( case GasTypeEIP1559: signer = gethtypes.NewLondonSigner(big.NewInt(int64(cp.Config.ChainID))) default: - return nil, fmt.Errorf("unsupported gas type: %v", cp.GasType) + return nil, ErrUnsupportedGasType(cp.GasType) } return gethtypes.SignTx(tx, signer, sender.PrivateKey) @@ -537,7 +537,7 @@ func (cp *EVMChainProvider) QueryBalance( zap.Error(err), zap.String("chain_name", cp.ChainName), ) - return nil, fmt.Errorf("[EVMProvider] failed to connect client: %w", err) + return nil, ErrClientConnection(err) } address, err := HexToAddress(cp.KeyInfo[keyName]) @@ -552,17 +552,17 @@ func (cp *EVMChainProvider) QueryBalance( func (cp *EVMChainProvider) queryRelayerGasFee(ctx context.Context) (*big.Int, error) { calldata, err := cp.TunnelRouterABI.Pack("gasFee") if err != nil { - return nil, fmt.Errorf("failed to pack calldata: %w", err) + return nil, ErrPackCalldata(err) } b, err := cp.Client.Query(ctx, cp.TunnelRouterAddress, calldata) if err != nil { - return nil, fmt.Errorf("failed to query data: %w", err) + return nil, ErrQueryData(err) } var output *big.Int if err := cp.TunnelRouterABI.UnpackIntoInterface(&output, "gasFee", b); err != nil { - return nil, fmt.Errorf("failed to unpack data: %w", err) + return nil, ErrUnpackData(err) } return output, nil diff --git a/relayer/errors.go b/relayer/errors.go new file mode 100644 index 0000000..311c536 --- /dev/null +++ b/relayer/errors.go @@ -0,0 +1,27 @@ +package relayer + +import "fmt" + +func ErrConfigNotExist(homePath string) error { + return fmt.Errorf("config does not exist: %s", homePath) +} + +func ErrConfigExist(cfgPath string) error { + return fmt.Errorf("config already exists: %s", cfgPath) +} + +func ErrChainNameExist(chainName string) error { + return fmt.Errorf("chain name already exists: %s", chainName) +} + +func ErrChainNameNotExist(chainName string) error { + return fmt.Errorf("chain name does not exist: %s", chainName) +} + +func ErrKeyNameExist(keyName string) error { + return fmt.Errorf("key name already exists: %s", keyName) +} + +func ErrKeyNameNotExist(keyName string) error { + return fmt.Errorf("key name does not exist: %s", keyName) +} From 7efe5e656d1caf32c33335d5b40e82136613282b Mon Sep 17 00:00:00 2001 From: Tanut Lertwarachai Date: Tue, 24 Dec 2024 21:55:23 +0700 Subject: [PATCH 2/4] add err in test --- cmd/config_test.go | 3 ++- relayer/app_test.go | 2 +- relayer/config.go | 2 +- relayer/config_test.go | 6 +++--- relayer/errors.go | 4 ++++ 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cmd/config_test.go b/cmd/config_test.go index d2db276..057bb7a 100644 --- a/cmd/config_test.go +++ b/cmd/config_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/bandprotocol/falcon/cmd" "github.com/bandprotocol/falcon/internal/relayertest" ) @@ -133,5 +134,5 @@ func TestInitCmdAlreadyExist(t *testing.T) { require.FileExists(t, cfgPath) res = sys.RunWithInput(t, "config", "init") - require.ErrorContains(t, res.Err, "config already exists") + require.Error(t, res.Err, cmd.ErrConfigNotExist(sys.HomeDir)) } diff --git a/relayer/app_test.go b/relayer/app_test.go index ec21785..c3ed11b 100644 --- a/relayer/app_test.go +++ b/relayer/app_test.go @@ -104,7 +104,7 @@ func (s *AppTestSuite) TestInitExistingConfig() { // second time should fail err = s.app.InitConfigFile(s.app.HomePath, customCfgPath) - s.Require().ErrorContains(err, "config already exists:") + s.Require().Error(err, relayer.ErrConfigExist(s.app.HomePath)) } func (s *AppTestSuite) TestInitCustomConfig() { diff --git a/relayer/config.go b/relayer/config.go index 484028c..2cf90fc 100644 --- a/relayer/config.go +++ b/relayer/config.go @@ -73,7 +73,7 @@ func ParseChainProviderConfig(w ChainProviderConfigWrapper) (chains.ChainProvide cfg = &newCfg default: - return cfg, fmt.Errorf("unsupported chain type: %s", typeName) + return cfg, ErrUnsupportedChainType(typeName) } return cfg, nil diff --git a/relayer/config_test.go b/relayer/config_test.go index 04f1acb..3ab173e 100644 --- a/relayer/config_test.go +++ b/relayer/config_test.go @@ -53,7 +53,7 @@ chain_type = 'evms' require.NoError(t, err) _, err = relayer.LoadConfig(cfgPath) - require.ErrorContains(t, err, "unsupported chain type: evms") + require.Error(t, err, relayer.ErrUnsupportedChainType("evms")) } func TestParseChainProviderConfigTypeEVM(t *testing.T) { @@ -81,7 +81,7 @@ func TestParseChainProviderConfigTypeNotFound(t *testing.T) { } _, err := relayer.ParseChainProviderConfig(w) - require.ErrorContains(t, err, "unsupported chain type: evms") + require.Error(t, err, relayer.ErrUnsupportedChainType("evms")) } func TestParseChainProviderConfigNoChainType(t *testing.T) { @@ -108,7 +108,7 @@ func TestParseConfigInvalidChainProviderConfig(t *testing.T) { } _, err := relayer.ParseConfig(w) - require.ErrorContains(t, err, "unsupported chain type: evms") + require.Error(t, err, relayer.ErrUnsupportedChainType("evms")) } func TestUnmarshalConfig(t *testing.T) { diff --git a/relayer/errors.go b/relayer/errors.go index 311c536..17736b7 100644 --- a/relayer/errors.go +++ b/relayer/errors.go @@ -25,3 +25,7 @@ func ErrKeyNameExist(keyName string) error { func ErrKeyNameNotExist(keyName string) error { return fmt.Errorf("key name does not exist: %s", keyName) } + +func ErrUnsupportedChainType(typeName string) error { + return fmt.Errorf("unsupported chain type: %s", typeName) +} From b21cca9eeb638817175b55e29c4d23a212b2d97a Mon Sep 17 00:00:00 2001 From: Tanut Lertwarachai Date: Tue, 28 Jan 2025 18:59:42 +0700 Subject: [PATCH 3/4] fix bug --- relayer/chains/evm/keys_test.go | 2 +- relayer/chains/evm/provider_eip1559_test.go | 4 ++-- relayer/chains/evm/provider_test.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/relayer/chains/evm/keys_test.go b/relayer/chains/evm/keys_test.go index a514c23..81207d8 100644 --- a/relayer/chains/evm/keys_test.go +++ b/relayer/chains/evm/keys_test.go @@ -235,7 +235,7 @@ func (s *KeysTestSuite) TestDeleteKey() { // Delete the key again should return error err = s.chainProvider.DeleteKey(s.homePath, keyName, "") - s.Require().ErrorContains(err, "key name does not exist") + s.Require().ErrorContains(err, evm.ErrKeyNameNotExist(keyName).Error()) } func (s *KeysTestSuite) TestExportPrivateKey() { diff --git a/relayer/chains/evm/provider_eip1559_test.go b/relayer/chains/evm/provider_eip1559_test.go index 7abf9de..5126058 100644 --- a/relayer/chains/evm/provider_eip1559_test.go +++ b/relayer/chains/evm/provider_eip1559_test.go @@ -168,7 +168,7 @@ func (s *EIP1559ProviderTestSuite) TestRelayPacketFailedBroadcastTx() { s.MockDefaultResponses() err := s.chainProvider.RelayPacket(context.Background(), &s.relayingPacket) - s.Require().ErrorContains(err, "failed to relay packet after") + s.Require().ErrorContains(err, evm.ErrRelayPacketRetries(s.chainProvider.Config.MaxRetry).Error()) } func (s *EIP1559ProviderTestSuite) TestRelayPacketFailedTxReceiptStatus() { @@ -198,7 +198,7 @@ func (s *EIP1559ProviderTestSuite) TestRelayPacketFailedTxReceiptStatus() { s.MockDefaultResponses() err := s.chainProvider.RelayPacket(context.Background(), &s.relayingPacket) - s.Require().ErrorContains(err, "failed to relay packet after") + s.Require().ErrorContains(err, evm.ErrRelayPacketRetries(s.chainProvider.Config.MaxRetry).Error()) } func (s *EIP1559ProviderTestSuite) TestBumpAndBoundGas() { diff --git a/relayer/chains/evm/provider_test.go b/relayer/chains/evm/provider_test.go index 0ad145f..085802c 100644 --- a/relayer/chains/evm/provider_test.go +++ b/relayer/chains/evm/provider_test.go @@ -188,7 +188,7 @@ func (s *ProviderTestSuite) TestQueryTunnelInfo() { Query(gomock.Any(), s.chainProvider.TunnelRouterAddress, queryTunnelCalldata). Return([]uint8{0, 124}, nil) }, - err: fmt.Errorf("failed to unpack data"), + err: evm.ErrUnpackData(fmt.Errorf("")), }, } @@ -217,7 +217,7 @@ func (s *ProviderTestSuite) TestQueryTunnelInfo() { func (s *ProviderTestSuite) TestEstimateGasUnsupportedGas() { _, err := s.chainProvider.EstimateGasFee(context.Background()) - s.Require().ErrorContains(err, "unsupported gas type:") + s.Require().ErrorContains(err, evm.ErrUnsupportedGasType(s.chainProvider.GasType).Error()) } func (s *ProviderTestSuite) TestCheckConfirmedTx() { From f595c7b7cc8ac6b67cb27a9e587bfc0273c69e19 Mon Sep 17 00:00:00 2001 From: Tanut Lertwarachai Date: Wed, 29 Jan 2025 01:52:04 +0700 Subject: [PATCH 4/4] add client test --- relayer/band/client.go | 6 +++--- relayer/band/client_test.go | 4 ++-- relayer/band/errors.go | 18 ++++++++++++++++-- relayer/config_test.go | 2 +- relayer/errors.go | 32 +++++++++++++++++--------------- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/relayer/band/client.go b/relayer/band/client.go index dc44f2c..1a72f7f 100644 --- a/relayer/band/client.go +++ b/relayer/band/client.go @@ -141,7 +141,7 @@ func (c *client) GetTunnel(ctx context.Context, tunnelID uint64) (*types.Tunnel, } if res.Tunnel.Route.TypeUrl != "/band.tunnel.v1beta1.TSSRoute" { - return nil, fmt.Errorf("unsupported route type: %s", res.Tunnel.Route.TypeUrl) + return nil, ErrUnsupportedRouteType(res.Tunnel.Route.TypeUrl) } // Extract route information @@ -153,7 +153,7 @@ func (c *client) GetTunnel(ctx context.Context, tunnelID uint64) (*types.Tunnel, tssRoute, ok := route.(*tunneltypes.TSSRoute) if !ok { - return nil, fmt.Errorf("unsupported route type: %T", route) + return nil, ErrUnsupportedRouteType(route.String()) } return types.NewTunnel( @@ -199,7 +199,7 @@ func (c *client) GetTunnelPacket(ctx context.Context, tunnelID uint64, sequence tssPacketReceipt, ok := packetReceipt.(*tunneltypes.TSSPacketReceipt) if !ok { - return nil, fmt.Errorf("unsupported packet content type: %T", packetReceipt) + return nil, ErrUnsupportedPacketContentType(packetReceipt) } signingID := uint64(tssPacketReceipt.SigningID) diff --git a/relayer/band/client_test.go b/relayer/band/client_test.go index 0af6f1f..bf34093 100644 --- a/relayer/band/client_test.go +++ b/relayer/band/client_test.go @@ -141,7 +141,7 @@ func (s *ClientTestSuite) TestGetTunnel() { { name: "unsupported route type", in: 2, - err: fmt.Errorf("unsupported route type"), + err: band.ErrUnsupportedRouteType(""), preprocess: func(c context.Context) { s.bandQueryClient.EXPECT().Tunnel(s.ctx, &tunneltypes.QueryTunnelRequest{ TunnelId: uint64(2), @@ -286,7 +286,7 @@ func (s *ClientTestSuite) TestGetOtherTunnelPacket() { // actual result _, err = s.client.GetTunnelPacket(s.ctx, uint64(1), uint64(100)) - s.Require().ErrorContains(err, "unsupported packet content type") + s.Require().ErrorContains(err, band.ErrUnsupportedPacketContentType(msg).Error()) } func (s *ClientTestSuite) TestGetTunnels() { diff --git a/relayer/band/errors.go b/relayer/band/errors.go index b55f568..00ae5c0 100644 --- a/relayer/band/errors.go +++ b/relayer/band/errors.go @@ -1,5 +1,19 @@ package band -import "fmt" +import ( + "fmt" -var ErrBandChainNotConnect = fmt.Errorf("cannot connect to bandchain") + tunneltypes "github.com/bandprotocol/falcon/internal/bandchain/tunnel" +) + +var ( + ErrBandChainNotConnect = fmt.Errorf("cannot connect to Bandchain") + + ErrUnsupportedRouteType = func(route string) error { + return fmt.Errorf("unsupported route type: %s", route) + } + + ErrUnsupportedPacketContentType = func(packetReceipt tunneltypes.PacketReceiptI) error { + return fmt.Errorf("unsupported packet content type: %T", packetReceipt) + } +) diff --git a/relayer/config_test.go b/relayer/config_test.go index 33fcc93..13f2e28 100644 --- a/relayer/config_test.go +++ b/relayer/config_test.go @@ -110,7 +110,7 @@ func TestParseChainProviderConfig(t *testing.T) { "chain_type": "evms", "endpoints": []string{"http://localhost:8545"}, }, - err: fmt.Errorf("unsupported chain type: evms"), + err: relayer.ErrUnsupportedChainType("evms"), }, { name: "missing chain type", diff --git a/relayer/errors.go b/relayer/errors.go index 4b46684..b180623 100644 --- a/relayer/errors.go +++ b/relayer/errors.go @@ -2,22 +2,24 @@ package relayer import "fmt" -func ErrConfigNotExist(homePath string) error { - return fmt.Errorf("config does not exist: %s", homePath) -} +var ( + ErrConfigNotExist = func(homePath string) error { + return fmt.Errorf("config does not exist: %s", homePath) + } -func ErrConfigExist(cfgPath string) error { - return fmt.Errorf("config already exists: %s", cfgPath) -} + ErrConfigExist = func(cfgPath string) error { + return fmt.Errorf("config already exists: %s", cfgPath) + } -func ErrChainNameExist(chainName string) error { - return fmt.Errorf("chain name already exists: %s", chainName) -} + ErrChainNameExist = func(chainName string) error { + return fmt.Errorf("chain name already exists: %s", chainName) + } -func ErrChainNameNotExist(chainName string) error { - return fmt.Errorf("chain name does not exist: %s", chainName) -} + ErrChainNameNotExist = func(chainName string) error { + return fmt.Errorf("chain name does not exist: %s", chainName) + } -func ErrUnsupportedChainType(typeName string) error { - return fmt.Errorf("unsupported chain type: %s", typeName) -} + ErrUnsupportedChainType = func(typeName string) error { + return fmt.Errorf("unsupported chain type: %s", typeName) + } +)