rpc: fix inconsistent logging levels (#265)

* rpc: fix incosistent logging levels

* minor changes
This commit is contained in:
Federico Kunze Küllmer 2021-07-12 14:39:35 -04:00 committed by GitHub
parent 1a48e09e78
commit 74b7eaf431
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 248 additions and 285 deletions

View File

@ -4,6 +4,8 @@ package rpc
import ( import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/server"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/tharsis/ethermint/ethereum/rpc/backend" "github.com/tharsis/ethermint/ethereum/rpc/backend"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth" "github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth"
@ -29,10 +31,10 @@ const (
) )
// GetRPCAPIs returns the list of all APIs // GetRPCAPIs returns the list of all APIs
func GetRPCAPIs(clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.API { func GetRPCAPIs(ctx *server.Context, clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.API {
nonceLock := new(types.AddrLocker) nonceLock := new(types.AddrLocker)
backend := backend.NewEVMBackend(clientCtx) backend := backend.NewEVMBackend(ctx.Logger, clientCtx)
ethAPI := eth.NewPublicAPI(clientCtx, backend, nonceLock) ethAPI := eth.NewPublicAPI(ctx.Logger, clientCtx, backend, nonceLock)
return []rpc.API{ return []rpc.API{
{ {
@ -50,7 +52,7 @@ func GetRPCAPIs(clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.
{ {
Namespace: EthNamespace, Namespace: EthNamespace,
Version: apiVersion, Version: apiVersion,
Service: filters.NewPublicAPI(tmWSClient, backend), Service: filters.NewPublicAPI(ctx.Logger, tmWSClient, backend),
Public: true, Public: true,
}, },
{ {
@ -62,13 +64,13 @@ func GetRPCAPIs(clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.
{ {
Namespace: PersonalNamespace, Namespace: PersonalNamespace,
Version: apiVersion, Version: apiVersion,
Service: personal.NewAPI(ethAPI), Service: personal.NewAPI(ctx.Logger, ethAPI),
Public: true, Public: true,
}, },
{ {
Namespace: TxPoolNamespace, Namespace: TxPoolNamespace,
Version: apiVersion, Version: apiVersion,
Service: txpool.NewPublicAPI(), Service: txpool.NewPublicAPI(ctx.Logger),
Public: true, Public: true,
}, },
} }

View File

@ -9,8 +9,8 @@ import (
"github.com/tharsis/ethermint/ethereum/rpc/types" "github.com/tharsis/ethermint/ethereum/rpc/types"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
log "github.com/xlab/suplog"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
@ -58,7 +58,7 @@ type EVMBackend struct {
} }
// NewEVMBackend creates a new EVMBackend instance // NewEVMBackend creates a new EVMBackend instance
func NewEVMBackend(clientCtx client.Context) *EVMBackend { func NewEVMBackend(logger log.Logger, clientCtx client.Context) *EVMBackend {
chainID, err := ethermint.ParseChainID(clientCtx.ChainID) chainID, err := ethermint.ParseChainID(clientCtx.ChainID)
if err != nil { if err != nil {
panic(err) panic(err)
@ -67,7 +67,7 @@ func NewEVMBackend(clientCtx client.Context) *EVMBackend {
ctx: context.Background(), ctx: context.Background(),
clientCtx: clientCtx, clientCtx: clientCtx,
queryClient: types.NewQueryClient(clientCtx), queryClient: types.NewQueryClient(clientCtx),
logger: log.WithField("module", "evm-backend"), logger: logger.With("module", "evm-backend"),
chainID: chainID, chainID: chainID,
} }
} }
@ -110,21 +110,21 @@ func (e *EVMBackend) GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (
resBlock, err := e.clientCtx.Client.Block(e.ctx, &height) resBlock, err := e.clientCtx.Client.Block(e.ctx, &height)
if err != nil { if err != nil {
// e.logger.Debugf("GetBlockByNumber safely bumping down from %d to latest", height) // e.logger.Debug("GetBlockByNumber safely bumping down from %d to latest", height)
if resBlock, err = e.clientCtx.Client.Block(e.ctx, nil); err != nil { if resBlock, err = e.clientCtx.Client.Block(e.ctx, nil); err != nil {
e.logger.WithError(err).Debugln("GetBlockByNumber failed to get latest block") e.logger.Debug("GetBlockByNumber failed to get latest block", "error", err.Error())
return nil, nil return nil, nil
} }
} }
if resBlock.Block == nil { if resBlock.Block == nil {
e.logger.Debugln("GetBlockByNumber block not found", "height", height) e.logger.Debug("GetBlockByNumber block not found", "height", height)
return nil, nil return nil, nil
} }
res, err := e.EthBlockFromTendermint(e.clientCtx, e.queryClient, resBlock.Block, fullTx) res, err := e.EthBlockFromTendermint(e.clientCtx, e.queryClient, resBlock.Block, fullTx)
if err != nil { if err != nil {
e.logger.WithError(err).Debugf("EthBlockFromTendermint failed with block %s", resBlock.Block.String()) e.logger.Debug("EthBlockFromTendermint failed", "height", height, "error", err.Error())
} }
return res, err return res, err
@ -134,12 +134,12 @@ func (e *EVMBackend) GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (
func (e *EVMBackend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) { func (e *EVMBackend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) {
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes()) resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes())
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("BlockByHash block not found", "hash", hash.Hex()) e.logger.Debug("BlockByHash block not found", "hash", hash.Hex(), "error", err.Error())
return nil, err return nil, err
} }
if resBlock.Block == nil { if resBlock.Block == nil {
e.logger.Debugln("BlockByHash block not found", "hash", hash.Hex()) e.logger.Debug("BlockByHash block not found", "hash", hash.Hex())
return nil, nil return nil, nil
} }
@ -161,7 +161,7 @@ func (e *EVMBackend) EthBlockFromTendermint(
for i, txBz := range block.Txs { for i, txBz := range block.Txs {
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz) tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil { if err != nil {
e.logger.WithError(err).Warningln("failed to decode transaction in block at height ", block.Height) e.logger.Debug("failed to decode transaction in block", "height", block.Height, "error", err.Error())
continue continue
} }
@ -183,13 +183,13 @@ func (e *EVMBackend) EthBlockFromTendermint(
// get full transaction from message data // get full transaction from message data
from, err := ethMsg.GetSender(e.chainID) from, err := ethMsg.GetSender(e.chainID)
if err != nil { if err != nil {
e.logger.WithError(err).Warningln("failed to get sender from already included transaction ", hash) e.logger.Debug("failed to get sender from already included transaction", "hash", hash.Hex(), "error", err.Error())
from = common.HexToAddress(ethMsg.From) from = common.HexToAddress(ethMsg.From)
} }
txData, err := evmtypes.UnpackTxData(ethMsg.Data) txData, err := evmtypes.UnpackTxData(ethMsg.Data)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("decoding failed") e.logger.Debug("decoding failed", "error", err.Error())
return nil, fmt.Errorf("failed to unpack tx data: %w", err) return nil, fmt.Errorf("failed to unpack tx data: %w", err)
} }
@ -202,7 +202,7 @@ func (e *EVMBackend) EthBlockFromTendermint(
uint64(i), uint64(i),
) )
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("NewTransactionFromData for receipt failed", "hash", hash.Hex) e.logger.Debug("NewTransactionFromData for receipt failed", "hash", hash.Hex(), "error", err.Error())
continue continue
} }
ethRPCTxs = append(ethRPCTxs, ethTx) ethRPCTxs = append(ethRPCTxs, ethTx)
@ -211,15 +211,13 @@ func (e *EVMBackend) EthBlockFromTendermint(
blockBloomResp, err := queryClient.BlockBloom(types.ContextWithHeight(block.Height), &evmtypes.QueryBlockBloomRequest{}) blockBloomResp, err := queryClient.BlockBloom(types.ContextWithHeight(block.Height), &evmtypes.QueryBlockBloomRequest{})
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("failed to query BlockBloom", "height", block.Height) e.logger.Debug("failed to query BlockBloom", "height", block.Height, "error", err.Error())
blockBloomResp = &evmtypes.QueryBlockBloomResponse{Bloom: ethtypes.Bloom{}.Bytes()} blockBloomResp = &evmtypes.QueryBlockBloomResponse{Bloom: ethtypes.Bloom{}.Bytes()}
} }
bloom := ethtypes.BytesToBloom(blockBloomResp.Bloom) bloom := ethtypes.BytesToBloom(blockBloomResp.Bloom)
formattedBlock := types.FormatBlock(block.Header, block.Size(), ethermint.DefaultRPCGasLimit, new(big.Int).SetUint64(gasUsed), ethRPCTxs, bloom) formattedBlock := types.FormatBlock(block.Header, block.Size(), ethermint.DefaultRPCGasLimit, new(big.Int).SetUint64(gasUsed), ethRPCTxs, bloom)
e.logger.Infoln(formattedBlock)
return formattedBlock, nil return formattedBlock, nil
} }
@ -241,14 +239,13 @@ func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Heade
height = 1 height = 1
default: default:
if blockNum < 0 { if blockNum < 0 {
err := errors.Errorf("incorrect block height: %d", height) return nil, errors.Errorf("incorrect block height: %d", height)
return nil, err
} }
} }
resBlock, err := e.clientCtx.Client.Block(e.ctx, &height) resBlock, err := e.clientCtx.Client.Block(e.ctx, &height)
if err != nil { if err != nil {
e.logger.Warningf("HeaderByNumber failed") e.logger.Debug("HeaderByNumber failed")
return nil, err return nil, err
} }
@ -256,7 +253,7 @@ func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Heade
res, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req) res, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req)
if err != nil { if err != nil {
e.logger.Warningf("HeaderByNumber BlockBloom fail %d", resBlock.Block.Height) e.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height)
return nil, err return nil, err
} }
@ -269,7 +266,7 @@ func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Heade
func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) { func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) {
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, blockHash.Bytes()) resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, blockHash.Bytes())
if err != nil { if err != nil {
e.logger.Warningf("HeaderByHash fail") e.logger.Debug("HeaderByHash failed", "hash", blockHash.Hex())
return nil, err return nil, err
} }
@ -277,7 +274,7 @@ func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, erro
res, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req) res, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req)
if err != nil { if err != nil {
e.logger.Warningf("HeaderByHash BlockBloom fail %d", resBlock.Block.Height) e.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height)
return nil, err return nil, err
} }
@ -296,7 +293,7 @@ func (e *EVMBackend) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, er
res, err := e.queryClient.TxLogs(e.ctx, req) res, err := e.queryClient.TxLogs(e.ctx, req)
if err != nil { if err != nil {
e.logger.Warningf("TxLogs fail") e.logger.Debug("TxLogs failed", "tx-hash", req.Hash)
return nil, err return nil, err
} }
@ -332,7 +329,7 @@ func (e *EVMBackend) GetLogs(blockHash common.Hash) ([][]*ethtypes.Log, error) {
res, err := e.queryClient.BlockLogs(e.ctx, req) res, err := e.queryClient.BlockLogs(e.ctx, req)
if err != nil { if err != nil {
e.logger.Warningf("BlockLogs fail") e.logger.Debug("BlockLogs failed", "hash", req.Hash)
return nil, err return nil, err
} }
@ -364,8 +361,7 @@ func (e *EVMBackend) GetLogsByNumber(blockNum types.BlockNumber) ([][]*ethtypes.
height = 1 height = 1
default: default:
if blockNum < 0 { if blockNum < 0 {
err := errors.Errorf("incorrect block height: %d", height) return nil, errors.Errorf("incorrect block height: %d", height)
return nil, err
} }
} }
@ -375,7 +371,7 @@ func (e *EVMBackend) GetLogsByNumber(blockNum types.BlockNumber) ([][]*ethtypes.
return [][]*ethtypes.Log{}, nil return [][]*ethtypes.Log{}, nil
} }
e.logger.Warningf("failed to query block at %d", height) e.logger.Debug("failed to query block", "height", height)
return nil, err return nil, err
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/viper" "github.com/spf13/viper"
log "github.com/xlab/suplog" "github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
@ -48,6 +48,7 @@ type PublicAPI struct {
// NewPublicAPI creates an instance of the public ETH Web3 API. // NewPublicAPI creates an instance of the public ETH Web3 API.
func NewPublicAPI( func NewPublicAPI(
logger log.Logger,
clientCtx client.Context, clientCtx client.Context,
backend backend.Backend, backend backend.Backend,
nonceLock *rpctypes.AddrLocker, nonceLock *rpctypes.AddrLocker,
@ -80,7 +81,7 @@ func NewPublicAPI(
clientCtx: clientCtx, clientCtx: clientCtx,
queryClient: rpctypes.NewQueryClient(clientCtx), queryClient: rpctypes.NewQueryClient(clientCtx),
chainIDEpoch: epoch, chainIDEpoch: epoch,
logger: log.WithField("module", "json-rpc"), logger: logger.With("client", "json-rpc"),
backend: backend, backend: backend,
nonceLock: nonceLock, nonceLock: nonceLock,
} }
@ -95,20 +96,20 @@ func (e *PublicAPI) ClientCtx() client.Context {
// ProtocolVersion returns the supported Ethereum protocol version. // ProtocolVersion returns the supported Ethereum protocol version.
func (e *PublicAPI) ProtocolVersion() hexutil.Uint { func (e *PublicAPI) ProtocolVersion() hexutil.Uint {
e.logger.Debugln("eth_protocolVersion") e.logger.Debug("eth_protocolVersion")
return hexutil.Uint(ethermint.ProtocolVersion) return hexutil.Uint(ethermint.ProtocolVersion)
} }
// ChainId returns the chain's identifier in hex format // ChainId returns the chain's identifier in hex format
func (e *PublicAPI) ChainId() (hexutil.Uint, error) { // nolint func (e *PublicAPI) ChainId() (hexutil.Uint, error) { // nolint
e.logger.Debugln("eth_chainId") e.logger.Debug("eth_chainId")
return hexutil.Uint(uint(e.chainIDEpoch.Uint64())), nil return hexutil.Uint(uint(e.chainIDEpoch.Uint64())), nil
} }
// Syncing returns whether or not the current node is syncing with other peers. Returns false if not, or a struct // Syncing returns whether or not the current node is syncing with other peers. Returns false if not, or a struct
// outlining the state of the sync if it is. // outlining the state of the sync if it is.
func (e *PublicAPI) Syncing() (interface{}, error) { func (e *PublicAPI) Syncing() (interface{}, error) {
e.logger.Debugln("eth_syncing") e.logger.Debug("eth_syncing")
status, err := e.clientCtx.Client.Status(e.ctx) status, err := e.clientCtx.Client.Status(e.ctx)
if err != nil { if err != nil {
@ -130,7 +131,7 @@ func (e *PublicAPI) Syncing() (interface{}, error) {
// Coinbase is the address that staking rewards will be send to (alias for Etherbase). // Coinbase is the address that staking rewards will be send to (alias for Etherbase).
func (e *PublicAPI) Coinbase() (string, error) { func (e *PublicAPI) Coinbase() (string, error) {
e.logger.Debugln("eth_coinbase") e.logger.Debug("eth_coinbase")
node, err := e.clientCtx.GetNode() node, err := e.clientCtx.GetNode()
if err != nil { if err != nil {
@ -158,19 +159,19 @@ func (e *PublicAPI) Coinbase() (string, error) {
// Mining returns whether or not this node is currently mining. Always false. // Mining returns whether or not this node is currently mining. Always false.
func (e *PublicAPI) Mining() bool { func (e *PublicAPI) Mining() bool {
e.logger.Debugln("eth_mining") e.logger.Debug("eth_mining")
return false return false
} }
// Hashrate returns the current node's hashrate. Always 0. // Hashrate returns the current node's hashrate. Always 0.
func (e *PublicAPI) Hashrate() hexutil.Uint64 { func (e *PublicAPI) Hashrate() hexutil.Uint64 {
e.logger.Debugln("eth_hashrate") e.logger.Debug("eth_hashrate")
return 0 return 0
} }
// GasPrice returns the current gas price based on Ethermint's gas price oracle. // GasPrice returns the current gas price based on Ethermint's gas price oracle.
func (e *PublicAPI) GasPrice() *hexutil.Big { func (e *PublicAPI) GasPrice() *hexutil.Big {
e.logger.Debugln("eth_gasPrice") e.logger.Debug("eth_gasPrice")
// TODO: use minimum value defined in config instead of default or implement oracle // TODO: use minimum value defined in config instead of default or implement oracle
out := big.NewInt(ethermint.DefaultGasPrice) out := big.NewInt(ethermint.DefaultGasPrice)
return (*hexutil.Big)(out) return (*hexutil.Big)(out)
@ -178,7 +179,7 @@ func (e *PublicAPI) GasPrice() *hexutil.Big {
// Accounts returns the list of accounts available to this node. // Accounts returns the list of accounts available to this node.
func (e *PublicAPI) Accounts() ([]common.Address, error) { func (e *PublicAPI) Accounts() ([]common.Address, error) {
e.logger.Debugln("eth_accounts") e.logger.Debug("eth_accounts")
addresses := make([]common.Address, 0) // return [] instead of nil if empty addresses := make([]common.Address, 0) // return [] instead of nil if empty
@ -197,13 +198,13 @@ func (e *PublicAPI) Accounts() ([]common.Address, error) {
// BlockNumber returns the current block number. // BlockNumber returns the current block number.
func (e *PublicAPI) BlockNumber() (hexutil.Uint64, error) { func (e *PublicAPI) BlockNumber() (hexutil.Uint64, error) {
// e.logger.Debugln("eth_blockNumber") e.logger.Debug("eth_blockNumber")
return e.backend.BlockNumber() return e.backend.BlockNumber()
} }
// GetBalance returns the provided account's balance up to the provided block number. // GetBalance returns the provided account's balance up to the provided block number.
func (e *PublicAPI) GetBalance(address common.Address, blockNum rpctypes.BlockNumber) (*hexutil.Big, error) { // nolint: interfacer func (e *PublicAPI) GetBalance(address common.Address, blockNum rpctypes.BlockNumber) (*hexutil.Big, error) { // nolint: interfacer
e.logger.Debugln("eth_getBalance", "address", address.String(), "block number", blockNum) e.logger.Debug("eth_getBalance", "address", address.String(), "block number", blockNum)
req := &evmtypes.QueryBalanceRequest{ req := &evmtypes.QueryBalanceRequest{
Address: address.String(), Address: address.String(),
@ -224,7 +225,7 @@ func (e *PublicAPI) GetBalance(address common.Address, blockNum rpctypes.BlockNu
// GetStorageAt returns the contract storage at the given address, block number, and key. // GetStorageAt returns the contract storage at the given address, block number, and key.
func (e *PublicAPI) GetStorageAt(address common.Address, key string, blockNum rpctypes.BlockNumber) (hexutil.Bytes, error) { // nolint: interfacer func (e *PublicAPI) GetStorageAt(address common.Address, key string, blockNum rpctypes.BlockNumber) (hexutil.Bytes, error) { // nolint: interfacer
e.logger.Debugln("eth_getStorageAt", "address", address.Hex(), "key", key, "block number", blockNum) e.logger.Debug("eth_getStorageAt", "address", address.Hex(), "key", key, "block number", blockNum)
req := &evmtypes.QueryStorageRequest{ req := &evmtypes.QueryStorageRequest{
Address: address.String(), Address: address.String(),
@ -242,7 +243,7 @@ func (e *PublicAPI) GetStorageAt(address common.Address, key string, blockNum rp
// GetTransactionCount returns the number of transactions at the given address up to the given block number. // GetTransactionCount returns the number of transactions at the given address up to the given block number.
func (e *PublicAPI) GetTransactionCount(address common.Address, blockNum rpctypes.BlockNumber) (*hexutil.Uint64, error) { func (e *PublicAPI) GetTransactionCount(address common.Address, blockNum rpctypes.BlockNumber) (*hexutil.Uint64, error) {
e.logger.Debugln("eth_getTransactionCount", "address", address.Hex(), "block number", blockNum) e.logger.Debug("eth_getTransactionCount", "address", address.Hex(), "block number", blockNum)
// Get nonce (sequence) from account // Get nonce (sequence) from account
from := sdk.AccAddress(address.Bytes()) from := sdk.AccAddress(address.Bytes())
@ -267,7 +268,7 @@ func (e *PublicAPI) GetTransactionCount(address common.Address, blockNum rpctype
// GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash. // GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash.
func (e *PublicAPI) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint { func (e *PublicAPI) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint {
e.logger.Debugln("eth_getBlockTransactionCountByHash", "hash", hash.Hex()) e.logger.Debug("eth_getBlockTransactionCountByHash", "hash", hash.Hex())
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes()) resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes())
if err != nil { if err != nil {
@ -280,7 +281,7 @@ func (e *PublicAPI) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Ui
// GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number. // GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number.
func (e *PublicAPI) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint { func (e *PublicAPI) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint {
e.logger.Debugln("eth_getBlockTransactionCountByNumber", "block number", blockNum) e.logger.Debug("eth_getBlockTransactionCountByNumber", "block number", blockNum)
resBlock, err := e.clientCtx.Client.Block(e.ctx, blockNum.TmHeight()) resBlock, err := e.clientCtx.Client.Block(e.ctx, blockNum.TmHeight())
if err != nil { if err != nil {
return nil return nil
@ -302,7 +303,7 @@ func (e *PublicAPI) GetUncleCountByBlockNumber(blockNum rpctypes.BlockNumber) he
// GetCode returns the contract code at the given address and block number. // GetCode returns the contract code at the given address and block number.
func (e *PublicAPI) GetCode(address common.Address, blockNumber rpctypes.BlockNumber) (hexutil.Bytes, error) { // nolint: interfacer func (e *PublicAPI) GetCode(address common.Address, blockNumber rpctypes.BlockNumber) (hexutil.Bytes, error) { // nolint: interfacer
e.logger.Debugln("eth_getCode", "address", address.Hex(), "block number", blockNumber) e.logger.Debug("eth_getCode", "address", address.Hex(), "block number", blockNumber)
req := &evmtypes.QueryCodeRequest{ req := &evmtypes.QueryCodeRequest{
Address: address.String(), Address: address.String(),
@ -318,26 +319,26 @@ func (e *PublicAPI) GetCode(address common.Address, blockNumber rpctypes.BlockNu
// GetTransactionLogs returns the logs given a transaction hash. // GetTransactionLogs returns the logs given a transaction hash.
func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) { func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) {
e.logger.Debugln("eth_getTransactionLogs", "hash", txHash) e.logger.Debug("eth_getTransactionLogs", "hash", txHash)
return e.backend.GetTransactionLogs(txHash) return e.backend.GetTransactionLogs(txHash)
} }
// Sign signs the provided data using the private key of address via Geth's signature standard. // Sign signs the provided data using the private key of address via Geth's signature standard.
func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) {
e.logger.Debugln("eth_sign", "address", address.Hex(), "data", common.Bytes2Hex(data)) e.logger.Debug("eth_sign", "address", address.Hex(), "data", common.Bytes2Hex(data))
from := sdk.AccAddress(address.Bytes()) from := sdk.AccAddress(address.Bytes())
_, err := e.clientCtx.Keyring.KeyByAddress(from) _, err := e.clientCtx.Keyring.KeyByAddress(from)
if err != nil { if err != nil {
e.logger.Errorln("failed to find key in keyring", "address", address.String()) e.logger.Error("failed to find key in keyring", "address", address.String())
return nil, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error()) return nil, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
} }
// Sign the requested hash with the wallet // Sign the requested hash with the wallet
signature, _, err := e.clientCtx.Keyring.SignByAddress(from, data) signature, _, err := e.clientCtx.Keyring.SignByAddress(from, data)
if err != nil { if err != nil {
e.logger.Panicln("keyring.SignByAddress failed") e.logger.Error("keyring.SignByAddress failed", "address", address.Hex())
return nil, err return nil, err
} }
@ -347,12 +348,12 @@ func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.By
// SendTransaction sends an Ethereum transaction. // SendTransaction sends an Ethereum transaction.
func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, error) { func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, error) {
e.logger.Debugln("eth_sendTransaction", "args", args.String()) e.logger.Debug("eth_sendTransaction", "args", args.String())
// Look up the wallet containing the requested signer // Look up the wallet containing the requested signer
_, err := e.clientCtx.Keyring.KeyByAddress(sdk.AccAddress(args.From.Bytes())) _, err := e.clientCtx.Keyring.KeyByAddress(sdk.AccAddress(args.From.Bytes()))
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to find key in keyring", "address", args.From) e.logger.Error("failed to find key in keyring", "address", args.From, "error", err.Error())
return common.Hash{}, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error()) return common.Hash{}, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
} }
@ -364,7 +365,7 @@ func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, erro
msg := args.ToTransaction() msg := args.ToTransaction()
if err := msg.ValidateBasic(); err != nil { if err := msg.ValidateBasic(); err != nil {
e.logger.WithError(err).Debugln("tx failed basic validation") e.logger.Debug("tx failed basic validation", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
@ -373,38 +374,38 @@ func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, erro
// Sign transaction // Sign transaction
if err := msg.Sign(signer, e.clientCtx.Keyring); err != nil { if err := msg.Sign(signer, e.clientCtx.Keyring); err != nil {
e.logger.Debugln("failed to sign tx", "error", err) e.logger.Debug("failed to sign tx", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
// Assemble transaction from fields // Assemble transaction from fields
builder, ok := e.clientCtx.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder) builder, ok := e.clientCtx.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder)
if !ok { if !ok {
e.logger.WithError(err).Panicln("clientCtx.TxConfig.NewTxBuilder returns unsupported builder") e.logger.Error("clientCtx.TxConfig.NewTxBuilder returns unsupported builder", "error", err.Error())
} }
option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{}) option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
if err != nil { if err != nil {
e.logger.WithError(err).Panicln("codectypes.NewAnyWithValue failed to pack an obvious value") e.logger.Error("codectypes.NewAnyWithValue failed to pack an obvious value", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
builder.SetExtensionOptions(option) builder.SetExtensionOptions(option)
err = builder.SetMsgs(msg) err = builder.SetMsgs(msg)
if err != nil { if err != nil {
e.logger.WithError(err).Panicln("builder.SetMsgs failed") e.logger.Error("builder.SetMsgs failed", "error", err.Error())
} }
// Query params to use the EVM denomination // Query params to use the EVM denomination
res, err := e.queryClient.QueryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{}) res, err := e.queryClient.QueryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{})
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to query evm params") e.logger.Error("failed to query evm params", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
txData, err := evmtypes.UnpackTxData(msg.Data) txData, err := evmtypes.UnpackTxData(msg.Data)
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to unpack tx data") e.logger.Error("failed to unpack tx data", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
@ -416,7 +417,7 @@ func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, erro
txEncoder := e.clientCtx.TxConfig.TxEncoder() txEncoder := e.clientCtx.TxConfig.TxEncoder()
txBytes, err := txEncoder(builder.GetTx()) txBytes, err := txEncoder(builder.GetTx())
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to encode eth tx using default encoder") e.logger.Error("failed to encode eth tx using default encoder", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
@ -430,7 +431,7 @@ func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, erro
if err == nil { if err == nil {
err = errors.New(rsp.RawLog) err = errors.New(rsp.RawLog)
} }
e.logger.WithError(err).Errorln("failed to broadcast tx") e.logger.Error("failed to broadcast tx", "error", err.Error())
return txHash, err return txHash, err
} }
@ -440,53 +441,53 @@ func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, erro
// SendRawTransaction send a raw Ethereum transaction. // SendRawTransaction send a raw Ethereum transaction.
func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
e.logger.Debugln("eth_sendRawTransaction", "data_len", len(data)) e.logger.Debug("eth_sendRawTransaction", "length", len(data))
// RLP decode raw transaction bytes // RLP decode raw transaction bytes
tx, err := e.clientCtx.TxConfig.TxDecoder()(data) tx, err := e.clientCtx.TxConfig.TxDecoder()(data)
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("transaction decoding failed") e.logger.Error("transaction decoding failed", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
ethereumTx, isEthTx := tx.(*evmtypes.MsgEthereumTx) ethereumTx, isEthTx := tx.(*evmtypes.MsgEthereumTx)
if !isEthTx { if !isEthTx {
e.logger.Debugln("invalid transaction type", "type", fmt.Sprintf("%T", tx)) e.logger.Debug("invalid transaction type", "type", fmt.Sprintf("%T", tx))
return common.Hash{}, fmt.Errorf("invalid transaction type %T", tx) return common.Hash{}, fmt.Errorf("invalid transaction type %T", tx)
} }
if err := ethereumTx.ValidateBasic(); err != nil { if err := ethereumTx.ValidateBasic(); err != nil {
e.logger.WithError(err).Debugln("tx failed basic validation") e.logger.Debug("tx failed basic validation", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
builder, ok := e.clientCtx.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder) builder, ok := e.clientCtx.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder)
if !ok { if !ok {
e.logger.Panicln("clientCtx.TxConfig.NewTxBuilder returns unsupported builder") e.logger.Error("clientCtx.TxConfig.NewTxBuilder returns unsupported builder")
} }
option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{}) option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
if err != nil { if err != nil {
e.logger.WithError(err).Panicln("codectypes.NewAnyWithValue failed to pack an obvious value") e.logger.Error("codectypes.NewAnyWithValue failed to pack an obvious value", "error", err.Error())
} }
builder.SetExtensionOptions(option) builder.SetExtensionOptions(option)
err = builder.SetMsgs(tx.GetMsgs()...) err = builder.SetMsgs(tx.GetMsgs()...)
if err != nil { if err != nil {
e.logger.WithError(err).Panicln("builder.SetMsgs failed") e.logger.Error("builder.SetMsgs failed", "error", err.Error())
} }
// Query params to use the EVM denomination // Query params to use the EVM denomination
res, err := e.queryClient.QueryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{}) res, err := e.queryClient.QueryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{})
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to query evm params") e.logger.Error("failed to query evm params", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
txData, err := evmtypes.UnpackTxData(ethereumTx.Data) txData, err := evmtypes.UnpackTxData(ethereumTx.Data)
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to unpack tx data") e.logger.Error("failed to unpack tx data", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
@ -497,7 +498,7 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
// Encode transaction by default Tx encoder // Encode transaction by default Tx encoder
txBytes, err := e.clientCtx.TxConfig.TxEncoder()(builder.GetTx()) txBytes, err := e.clientCtx.TxConfig.TxEncoder()(builder.GetTx())
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to encode eth tx using default encoder") e.logger.Error("failed to encode eth tx using default encoder", "error", err.Error())
return common.Hash{}, err return common.Hash{}, err
} }
@ -509,7 +510,7 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
if err == nil { if err == nil {
err = errors.New(rsp.RawLog) err = errors.New(rsp.RawLog)
} }
e.logger.WithError(err).Errorln("failed to broadcast tx") e.logger.Error("failed to broadcast tx", "error", err.Error())
return txHash, err return txHash, err
} }
@ -518,7 +519,7 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
// Call performs a raw contract call. // Call performs a raw contract call.
func (e *PublicAPI) Call(args evmtypes.CallArgs, blockNr rpctypes.BlockNumber, _ *rpctypes.StateOverride) (hexutil.Bytes, error) { func (e *PublicAPI) Call(args evmtypes.CallArgs, blockNr rpctypes.BlockNumber, _ *rpctypes.StateOverride) (hexutil.Bytes, error) {
e.logger.Debugln("eth_call", "args", args.String(), "block number", blockNr) e.logger.Debug("eth_call", "args", args.String(), "block number", blockNr)
data, err := e.doCall(args, blockNr) data, err := e.doCall(args, blockNr)
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
@ -550,10 +551,8 @@ func (e *PublicAPI) doCall(
} }
// EstimateGas returns an estimate of gas usage for the given smart contract call. // EstimateGas returns an estimate of gas usage for the given smart contract call.
// It adds 1,000 gas to the returned value instead of using the gas adjustment
// param from the SDK.
func (e *PublicAPI) EstimateGas(args evmtypes.CallArgs) (hexutil.Uint64, error) { func (e *PublicAPI) EstimateGas(args evmtypes.CallArgs) (hexutil.Uint64, error) {
e.logger.Debugln("eth_estimateGas") e.logger.Debug("eth_estimateGas")
// From ContextWithHeight: if the provided height is 0, // From ContextWithHeight: if the provided height is 0,
// it will return an empty context and the gRPC query will use // it will return an empty context and the gRPC query will use
@ -572,13 +571,13 @@ func (e *PublicAPI) EstimateGas(args evmtypes.CallArgs) (hexutil.Uint64, error)
// GetBlockByHash returns the block identified by hash. // GetBlockByHash returns the block identified by hash.
func (e *PublicAPI) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) { func (e *PublicAPI) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) {
e.logger.Debugln("eth_getBlockByHash", "hash", hash.Hex(), "full", fullTx) e.logger.Debug("eth_getBlockByHash", "hash", hash.Hex(), "full", fullTx)
return e.backend.GetBlockByHash(hash, fullTx) return e.backend.GetBlockByHash(hash, fullTx)
} }
// GetBlockByNumber returns the block identified by number. // GetBlockByNumber returns the block identified by number.
func (e *PublicAPI) GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) { func (e *PublicAPI) GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) {
e.logger.Debugln("eth_getBlockByNumber", "number", ethBlockNum, "full", fullTx) e.logger.Debug("eth_getBlockByNumber", "number", ethBlockNum, "full", fullTx)
return e.backend.GetBlockByNumber(ethBlockNum, fullTx) return e.backend.GetBlockByNumber(ethBlockNum, fullTx)
} }
@ -599,11 +598,11 @@ func (e *PublicAPI) GetTxByEthHash(hash common.Hash) (*tmrpctypes.ResultTx, erro
// GetTransactionByHash returns the transaction identified by hash. // GetTransactionByHash returns the transaction identified by hash.
func (e *PublicAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error) { func (e *PublicAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error) {
e.logger.Debugln("eth_getTransactionByHash", "hash", hash.Hex()) e.logger.Debug("eth_getTransactionByHash", "hash", hash.Hex())
res, err := e.GetTxByEthHash(hash) res, err := e.GetTxByEthHash(hash)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("tx not found", "hash", hash.Hex()) e.logger.Debug("tx not found", "hash", hash.Hex(), "error", err.Error())
// try to find tx in mempool // try to find tx in mempool
txs, err := e.backend.PendingTransactions() txs, err := e.backend.PendingTransactions()
@ -634,19 +633,19 @@ func (e *PublicAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransac
resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height) resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("block not found", "height", res.Height) e.logger.Debug("block not found", "height", res.Height, "error", err.Error())
return nil, nil return nil, nil
} }
tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx) tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("decoding failed") e.logger.Debug("decoding failed", "error", err.Error())
return nil, fmt.Errorf("failed to decode tx: %w", err) return nil, fmt.Errorf("failed to decode tx: %w", err)
} }
msg, err := evmtypes.UnwrapEthereumMsg(&tx) msg, err := evmtypes.UnwrapEthereumMsg(&tx)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("invalid tx") e.logger.Debug("invalid tx", "error", err.Error())
return nil, err return nil, err
} }
@ -661,30 +660,30 @@ func (e *PublicAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransac
// GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index. // GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index.
func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
e.logger.Debugln("eth_getTransactionByBlockHashAndIndex", "hash", hash.Hex(), "index", idx) e.logger.Debug("eth_getTransactionByBlockHashAndIndex", "hash", hash.Hex(), "index", idx)
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes()) resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes())
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("block not found", "hash", hash.Hex()) e.logger.Debug("block not found", "hash", hash.Hex(), "error", err.Error())
return nil, nil return nil, nil
} }
i := int(idx) i := int(idx)
if i >= len(resBlock.Block.Txs) { if i >= len(resBlock.Block.Txs) {
e.logger.Debugln("block txs index out of bound", "index", i) e.logger.Debug("block txs index out of bound", "index", i)
return nil, nil return nil, nil
} }
txBz := resBlock.Block.Txs[i] txBz := resBlock.Block.Txs[i]
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz) tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("decoding failed") e.logger.Debug("decoding failed", "error", err.Error())
return nil, fmt.Errorf("failed to decode tx: %w", err) return nil, fmt.Errorf("failed to decode tx: %w", err)
} }
msg, err := evmtypes.UnwrapEthereumMsg(&tx) msg, err := evmtypes.UnwrapEthereumMsg(&tx)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("invalid tx") e.logger.Debug("invalid tx", "error", err.Error())
return nil, err return nil, err
} }
@ -699,30 +698,30 @@ func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexu
// GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index. // GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index.
func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
e.logger.Debugln("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx) e.logger.Debug("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx)
resBlock, err := e.clientCtx.Client.Block(e.ctx, blockNum.TmHeight()) resBlock, err := e.clientCtx.Client.Block(e.ctx, blockNum.TmHeight())
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("block not found", "height", blockNum.Int64()) e.logger.Debug("block not found", "height", blockNum.Int64(), "error", err.Error())
return nil, nil return nil, nil
} }
i := int(idx) i := int(idx)
if i >= len(resBlock.Block.Txs) { if i >= len(resBlock.Block.Txs) {
e.logger.Debugln("block txs index out of bound", "index", i) e.logger.Debug("block txs index out of bound", "index", i)
return nil, nil return nil, nil
} }
txBz := resBlock.Block.Txs[i] txBz := resBlock.Block.Txs[i]
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz) tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("decoding failed") e.logger.Debug("decoding failed", "error", err.Error())
return nil, fmt.Errorf("failed to decode tx: %w", err) return nil, fmt.Errorf("failed to decode tx: %w", err)
} }
msg, err := evmtypes.UnwrapEthereumMsg(&tx) msg, err := evmtypes.UnwrapEthereumMsg(&tx)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("invalid tx") e.logger.Debug("invalid tx", "error", err.Error())
return nil, err return nil, err
} }
@ -737,42 +736,42 @@ func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockN
// GetTransactionReceipt returns the transaction receipt identified by hash. // GetTransactionReceipt returns the transaction receipt identified by hash.
func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) { func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) {
e.logger.Debugln("eth_getTransactionReceipt", "hash", hash.Hex()) e.logger.Debug("eth_getTransactionReceipt", "hash", hash.Hex())
res, err := e.GetTxByEthHash(hash) res, err := e.GetTxByEthHash(hash)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("tx not found", "hash", hash.Hex()) e.logger.Debug("tx not found", "hash", hash.Hex(), "error", err.Error())
return nil, nil return nil, nil
} }
resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height) resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("block not found", "height", res.Height) e.logger.Debug("block not found", "height", res.Height, "error", err.Error())
return nil, nil return nil, nil
} }
tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx) tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("decoding failed") e.logger.Debug("decoding failed", "error", err.Error())
return nil, fmt.Errorf("failed to decode tx: %w", err) return nil, fmt.Errorf("failed to decode tx: %w", err)
} }
msg, err := evmtypes.UnwrapEthereumMsg(&tx) msg, err := evmtypes.UnwrapEthereumMsg(&tx)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("invalid tx") e.logger.Debug("invalid tx", "error", err.Error())
return nil, err return nil, err
} }
txData, err := evmtypes.UnpackTxData(msg.Data) txData, err := evmtypes.UnpackTxData(msg.Data)
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to unpack tx data") e.logger.Error("failed to unpack tx data", "error", err.Error())
return nil, err return nil, err
} }
cumulativeGasUsed := uint64(0) cumulativeGasUsed := uint64(0)
blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, &res.Height) blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, &res.Height)
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("failed to retrieve block results", "height", res.Height) e.logger.Debug("failed to retrieve block results", "height", res.Height, "error", err.Error())
return nil, nil return nil, nil
} }
@ -795,7 +794,7 @@ func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interfac
resLogs, err := e.queryClient.TxLogs(e.ctx, &evmtypes.QueryTxLogsRequest{Hash: hash.Hex()}) resLogs, err := e.queryClient.TxLogs(e.ctx, &evmtypes.QueryTxLogsRequest{Hash: hash.Hex()})
if err != nil { if err != nil {
e.logger.WithError(err).Debugln("logs not found", "hash", hash.Hex()) e.logger.Debug("logs not found", "hash", hash.Hex(), "error", err.Error())
resLogs = &evmtypes.QueryTxLogsResponse{Logs: []*evmtypes.Log{}} resLogs = &evmtypes.QueryTxLogsResponse{Logs: []*evmtypes.Log{}}
} }
@ -841,7 +840,7 @@ func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interfac
// PendingTransactions returns the transactions that are in the transaction pool // PendingTransactions returns the transactions that are in the transaction pool
// and have a from address that is one of the accounts this node manages. // and have a from address that is one of the accounts this node manages.
func (e *PublicAPI) PendingTransactions() ([]*rpctypes.RPCTransaction, error) { func (e *PublicAPI) PendingTransactions() ([]*rpctypes.RPCTransaction, error) {
e.logger.Debugln("eth_getPendingTransactions") e.logger.Debug("eth_getPendingTransactions")
txs, err := e.backend.PendingTransactions() txs, err := e.backend.PendingTransactions()
if err != nil { if err != nil {
@ -886,7 +885,7 @@ func (e *PublicAPI) GetUncleByBlockNumberAndIndex(number hexutil.Uint, idx hexut
// GetProof returns an account object with proof and any storage proofs // GetProof returns an account object with proof and any storage proofs
func (e *PublicAPI) GetProof(address common.Address, storageKeys []string, blockNumber rpctypes.BlockNumber) (*rpctypes.AccountResult, error) { func (e *PublicAPI) GetProof(address common.Address, storageKeys []string, blockNumber rpctypes.BlockNumber) (*rpctypes.AccountResult, error) {
height := blockNumber.Int64() height := blockNumber.Int64()
e.logger.Debugln("eth_getProof", "address", address.Hex(), "keys", storageKeys, "number", height) e.logger.Debug("eth_getProof", "address", address.Hex(), "keys", storageKeys, "number", height)
ctx := rpctypes.ContextWithHeight(height) ctx := rpctypes.ContextWithHeight(height)
clientCtx := e.clientCtx.WithHeight(height) clientCtx := e.clientCtx.WithHeight(height)
@ -1011,7 +1010,7 @@ func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs
return args, err return args, err
} }
args.Gas = &estimated args.Gas = &estimated
e.logger.Debugln("estimate gas usage automatically", "gas", args.Gas) e.logger.Debug("estimate gas usage automatically", "gas", args.Gas)
} }
if args.ChainID == nil { if args.ChainID == nil {
@ -1046,7 +1045,7 @@ func (e *PublicAPI) getAccountNonce(accAddr common.Address, pending bool, height
// to manually add them. // to manually add them.
pendingTxs, err := e.backend.PendingTransactions() pendingTxs, err := e.backend.PendingTransactions()
if err != nil { if err != nil {
logger.WithError(err).Errorln("fails to fetch pending transactions") logger.Error("failed to fetch pending transactions", "error", err.Error())
return nonce, nil return nonce, nil
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/tharsis/ethermint/ethereum/rpc/types" "github.com/tharsis/ethermint/ethereum/rpc/types"
log "github.com/xlab/suplog" "github.com/tendermint/tendermint/libs/log"
coretypes "github.com/tendermint/tendermint/rpc/core/types" coretypes "github.com/tendermint/tendermint/rpc/core/types"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
@ -51,6 +51,7 @@ type filter struct {
// PublicFilterAPI offers support to create and manage filters. This will allow external clients to retrieve various // PublicFilterAPI offers support to create and manage filters. This will allow external clients to retrieve various
// information related to the Ethereum protocol such as blocks, transactions and logs. // information related to the Ethereum protocol such as blocks, transactions and logs.
type PublicFilterAPI struct { type PublicFilterAPI struct {
logger log.Logger
backend Backend backend Backend
events *EventSystem events *EventSystem
filtersMu sync.Mutex filtersMu sync.Mutex
@ -58,11 +59,13 @@ type PublicFilterAPI struct {
} }
// NewPublicAPI returns a new PublicFilterAPI instance. // NewPublicAPI returns a new PublicFilterAPI instance.
func NewPublicAPI(tmWSClient *rpcclient.WSClient, backend Backend) *PublicFilterAPI { func NewPublicAPI(logger log.Logger, tmWSClient *rpcclient.WSClient, backend Backend) *PublicFilterAPI {
logger = logger.With("api", "filter")
api := &PublicFilterAPI{ api := &PublicFilterAPI{
logger: logger,
backend: backend, backend: backend,
filters: make(map[rpc.ID]*filter), filters: make(map[rpc.ID]*filter),
events: NewEventSystem(tmWSClient), events: NewEventSystem(logger, tmWSClient),
} }
go api.timeoutLoop() go api.timeoutLoop()
@ -125,10 +128,7 @@ func (api *PublicFilterAPI) NewPendingTransactionFilter() rpc.ID {
data, ok := ev.Data.(tmtypes.EventDataTx) data, ok := ev.Data.(tmtypes.EventDataTx)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", ev.Data))
"expected": "tmtypes.EventDataTx",
"actual": fmt.Sprintf("%T", ev.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
@ -185,10 +185,7 @@ func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Su
data, ok := ev.Data.(tmtypes.EventDataTx) data, ok := ev.Data.(tmtypes.EventDataTx)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", ev.Data))
"expected": "tmtypes.EventDataTx",
"actual": fmt.Sprintf("%T", ev.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
@ -243,10 +240,7 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
data, ok := ev.Data.(tmtypes.EventDataNewBlockHeader) data, ok := ev.Data.(tmtypes.EventDataNewBlockHeader)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", ev.Data))
"expected": "tmtypes.EventDataNewBlockHeader",
"actual": fmt.Sprintf("%T", ev.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
@ -296,10 +290,7 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
data, ok := ev.Data.(tmtypes.EventDataNewBlockHeader) data, ok := ev.Data.(tmtypes.EventDataNewBlockHeader)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", ev.Data))
"expected": "tmtypes.EventDataNewBlockHeader",
"actual": fmt.Sprintf("%T", ev.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
@ -359,10 +350,7 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit filters.FilterCriteri
// get transaction result data // get transaction result data
dataTx, ok := ev.Data.(tmtypes.EventDataTx) dataTx, ok := ev.Data.(tmtypes.EventDataTx)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", ev.Data))
"expected": "tmtypes.EventDataTx",
"actual": fmt.Sprintf("%T", ev.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
@ -436,10 +424,7 @@ func (api *PublicFilterAPI) NewFilter(criteria filters.FilterCriteria) (rpc.ID,
} }
dataTx, ok := ev.Data.(tmtypes.EventDataTx) dataTx, ok := ev.Data.(tmtypes.EventDataTx)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", ev.Data))
"expected": "tmtypes.EventDataTx",
"actual": fmt.Sprintf("%T", ev.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
@ -474,7 +459,7 @@ func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit filters.FilterCrit
var filter *Filter var filter *Filter
if crit.BlockHash != nil { if crit.BlockHash != nil {
// Block filter requested, construct a single-shot filter // Block filter requested, construct a single-shot filter
filter = NewBlockFilter(api.backend, crit) filter = NewBlockFilter(api.logger, api.backend, crit)
} else { } else {
// Convert the RPC block numbers into internal representations // Convert the RPC block numbers into internal representations
begin := rpc.LatestBlockNumber.Int64() begin := rpc.LatestBlockNumber.Int64()
@ -486,7 +471,7 @@ func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit filters.FilterCrit
end = crit.ToBlock.Int64() end = crit.ToBlock.Int64()
} }
// Construct the range filter // Construct the range filter
filter = NewRangeFilter(api.backend, begin, end, crit.Addresses, crit.Topics) filter = NewRangeFilter(api.logger, api.backend, begin, end, crit.Addresses, crit.Topics)
} }
// Run the filter and return all the logs // Run the filter and return all the logs
@ -536,7 +521,7 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*et
var filter *Filter var filter *Filter
if f.crit.BlockHash != nil { if f.crit.BlockHash != nil {
// Block filter requested, construct a single-shot filter // Block filter requested, construct a single-shot filter
filter = NewBlockFilter(api.backend, f.crit) filter = NewBlockFilter(api.logger, api.backend, f.crit)
} else { } else {
// Convert the RPC block numbers into internal representations // Convert the RPC block numbers into internal representations
begin := rpc.LatestBlockNumber.Int64() begin := rpc.LatestBlockNumber.Int64()
@ -548,7 +533,7 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*et
end = f.crit.ToBlock.Int64() end = f.crit.ToBlock.Int64()
} }
// Construct the range filter // Construct the range filter
filter = NewRangeFilter(api.backend, begin, end, f.crit.Addresses, f.crit.Topics) filter = NewRangeFilter(api.logger, api.backend, begin, end, f.crit.Addresses, f.crit.Topics)
} }
// Run the filter and return all the logs // Run the filter and return all the logs
logs, err := filter.Logs(ctx) logs, err := filter.Logs(ctx)

View File

@ -7,9 +7,9 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
log "github.com/xlab/suplog"
tmjson "github.com/tendermint/tendermint/libs/json" tmjson "github.com/tendermint/tendermint/libs/json"
"github.com/tendermint/tendermint/libs/log"
tmquery "github.com/tendermint/tendermint/libs/pubsub/query" tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
coretypes "github.com/tendermint/tendermint/rpc/core/types" coretypes "github.com/tendermint/tendermint/rpc/core/types"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
@ -35,6 +35,7 @@ var (
// EventSystem creates subscriptions, processes events and broadcasts them to the // EventSystem creates subscriptions, processes events and broadcasts them to the
// subscription which match the subscription criteria using the Tendermint's RPC client. // subscription which match the subscription criteria using the Tendermint's RPC client.
type EventSystem struct { type EventSystem struct {
logger log.Logger
ctx context.Context ctx context.Context
tmWSClient *rpcclient.WSClient tmWSClient *rpcclient.WSClient
@ -57,13 +58,14 @@ type EventSystem struct {
// //
// The returned manager has a loop that needs to be stopped with the Stop function // The returned manager has a loop that needs to be stopped with the Stop function
// or by stopping the given mux. // or by stopping the given mux.
func NewEventSystem(tmWSClient *rpcclient.WSClient) *EventSystem { func NewEventSystem(logger log.Logger, tmWSClient *rpcclient.WSClient) *EventSystem {
index := make(filterIndex) index := make(filterIndex)
for i := filters.UnknownSubscription; i < filters.LastIndexSubscription; i++ { for i := filters.UnknownSubscription; i < filters.LastIndexSubscription; i++ {
index[i] = make(map[rpc.ID]*Subscription) index[i] = make(map[rpc.ID]*Subscription)
} }
es := &EventSystem{ es := &EventSystem{
logger: logger,
ctx: context.Background(), ctx: context.Background(),
tmWSClient: tmWSClient, tmWSClient: tmWSClient,
lightMode: false, lightMode: false,
@ -222,7 +224,7 @@ func (es *EventSystem) eventLoop() {
ch := make(chan coretypes.ResultEvent) ch := make(chan coretypes.ResultEvent)
es.topicChans[f.event] = ch es.topicChans[f.event] = ch
if err := es.eventBus.AddTopic(f.event, ch); err != nil { if err := es.eventBus.AddTopic(f.event, ch); err != nil {
log.WithField("topic", f.event).WithError(err).Errorln("failed to add event topic to event bus") es.logger.Error("failed to add event topic to event bus", "topic", f.event, "error", err.Error())
} }
es.indexMux.Unlock() es.indexMux.Unlock()
close(f.installed) close(f.installed)
@ -241,7 +243,7 @@ func (es *EventSystem) eventLoop() {
// remove topic only when channel is not used by other subscriptions // remove topic only when channel is not used by other subscriptions
if !channelInUse { if !channelInUse {
if err := es.tmWSClient.Unsubscribe(es.ctx, f.event); err != nil { if err := es.tmWSClient.Unsubscribe(es.ctx, f.event); err != nil {
log.WithError(err).WithField("query", f.event).Errorln("failed to unsubscribe from query") es.logger.Error("failed to unsubscribe from query", "query", f.event, "error", err.Error())
} }
ch, ok := es.topicChans[f.event] ch, ok := es.topicChans[f.event]
@ -267,7 +269,7 @@ func (es *EventSystem) consumeEvents() {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
continue continue
} else if err := tmjson.Unmarshal(rpcResp.Result, &ev); err != nil { } else if err := tmjson.Unmarshal(rpcResp.Result, &ev); err != nil {
log.WithError(err).Warningln("failed to JSON unmarshal ResponsesCh result event") es.logger.Error("failed to JSON unmarshal ResponsesCh result event", "error", err.Error())
continue continue
} }
@ -280,8 +282,8 @@ func (es *EventSystem) consumeEvents() {
ch, ok := es.topicChans[ev.Query] ch, ok := es.topicChans[ev.Query]
es.indexMux.RUnlock() es.indexMux.RUnlock()
if !ok { if !ok {
log.WithField("topic", ev.Query).Warningln("channel for subscription not found, lol") es.logger.Debug("channel for subscription not found", "topic", ev.Query)
log.Infoln("available channels:", es.eventBus.Topics()) es.logger.Debug("list of available channels", "channels", es.eventBus.Topics())
continue continue
} }
@ -289,7 +291,7 @@ func (es *EventSystem) consumeEvents() {
t := time.NewTimer(time.Second) t := time.NewTimer(time.Second)
select { select {
case <-t.C: case <-t.C:
log.WithField("topic", ev.Query).Warningln("dropped event during lagging subscription") es.logger.Debug("dropped event during lagging subscription", "topic", ev.Query)
case ch <- ev: case ch <- ev:
} }
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/tharsis/ethermint/ethereum/rpc/types" "github.com/tharsis/ethermint/ethereum/rpc/types"
"github.com/pkg/errors" "github.com/pkg/errors"
log "github.com/xlab/suplog" "github.com/tendermint/tendermint/libs/log"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
@ -18,6 +18,7 @@ import (
// Filter can be used to retrieve and filter logs. // Filter can be used to retrieve and filter logs.
type Filter struct { type Filter struct {
logger log.Logger
backend Backend backend Backend
criteria filters.FilterCriteria criteria filters.FilterCriteria
matcher *bloombits.Matcher matcher *bloombits.Matcher
@ -25,14 +26,14 @@ type Filter struct {
// NewBlockFilter creates a new filter which directly inspects the contents of // NewBlockFilter creates a new filter which directly inspects the contents of
// a block to figure out whether it is interesting or not. // a block to figure out whether it is interesting or not.
func NewBlockFilter(backend Backend, criteria filters.FilterCriteria) *Filter { func NewBlockFilter(logger log.Logger, backend Backend, criteria filters.FilterCriteria) *Filter {
// Create a generic filter and convert it into a block filter // Create a generic filter and convert it into a block filter
return newFilter(backend, criteria, nil) return newFilter(logger, backend, criteria, nil)
} }
// NewRangeFilter creates a new filter which uses a bloom filter on blocks to // NewRangeFilter creates a new filter which uses a bloom filter on blocks to
// figure out whether a particular block is interesting or not. // figure out whether a particular block is interesting or not.
func NewRangeFilter(backend Backend, begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter { func NewRangeFilter(logger log.Logger, backend Backend, begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter {
// Flatten the address and topic filter clauses into a single bloombits filter // Flatten the address and topic filter clauses into a single bloombits filter
// system. Since the bloombits are not positional, nil topics are permitted, // system. Since the bloombits are not positional, nil topics are permitted,
// which get flattened into a nil byte slice. // which get flattened into a nil byte slice.
@ -63,12 +64,13 @@ func NewRangeFilter(backend Backend, begin, end int64, addresses []common.Addres
Topics: topics, Topics: topics,
} }
return newFilter(backend, criteria, bloombits.NewMatcher(size, filtersBz)) return newFilter(logger, backend, criteria, bloombits.NewMatcher(size, filtersBz))
} }
// newFilter returns a new Filter // newFilter returns a new Filter
func newFilter(backend Backend, criteria filters.FilterCriteria, matcher *bloombits.Matcher) *Filter { func newFilter(logger log.Logger, backend Backend, criteria filters.FilterCriteria, matcher *bloombits.Matcher) *Filter {
return &Filter{ return &Filter{
logger: logger,
backend: backend, backend: backend,
criteria: criteria, criteria: criteria,
matcher: matcher, matcher: matcher,
@ -90,13 +92,11 @@ func (f *Filter) Logs(_ context.Context) ([]*ethtypes.Log, error) {
if f.criteria.BlockHash != nil && *f.criteria.BlockHash != (common.Hash{}) { if f.criteria.BlockHash != nil && *f.criteria.BlockHash != (common.Hash{}) {
header, err := f.backend.HeaderByHash(*f.criteria.BlockHash) header, err := f.backend.HeaderByHash(*f.criteria.BlockHash)
if err != nil { if err != nil {
err = errors.Wrap(err, "failed to fetch header by hash") return nil, errors.Wrap(err, "failed to fetch header by hash")
return nil, err
} }
if header == nil { if header == nil {
err := errors.Errorf("unknown block header %s", f.criteria.BlockHash.String()) return nil, errors.Errorf("unknown block header %s", f.criteria.BlockHash.String())
return nil, err
} }
return f.blockLogs(header) return f.blockLogs(header)
@ -105,12 +105,11 @@ func (f *Filter) Logs(_ context.Context) ([]*ethtypes.Log, error) {
// Figure out the limits of the filter range // Figure out the limits of the filter range
header, err := f.backend.HeaderByNumber(types.EthLatestBlockNumber) header, err := f.backend.HeaderByNumber(types.EthLatestBlockNumber)
if err != nil { if err != nil {
err = errors.Wrap(err, "failed to fetch header by number (latest)") return nil, errors.Wrap(err, "failed to fetch header by number (latest)")
return nil, err
} }
if header == nil || header.Number == nil { if header == nil || header.Number == nil {
log.Warningln("header not found or has no number") f.logger.Debug("header not found or has no number")
return nil, nil return nil, nil
} }
@ -123,8 +122,7 @@ func (f *Filter) Logs(_ context.Context) ([]*ethtypes.Log, error) {
} }
if f.criteria.ToBlock.Int64()-f.criteria.FromBlock.Int64() > maxFilterBlocks { if f.criteria.ToBlock.Int64()-f.criteria.FromBlock.Int64() > maxFilterBlocks {
err := errors.Errorf("maximum [from, to] blocks distance: %d", maxFilterBlocks) return nil, errors.Errorf("maximum [from, to] blocks distance: %d", maxFilterBlocks)
return nil, err
} }
// check bounds // check bounds
@ -137,9 +135,10 @@ func (f *Filter) Logs(_ context.Context) ([]*ethtypes.Log, error) {
for i := f.criteria.FromBlock.Int64(); i <= f.criteria.ToBlock.Int64(); i++ { for i := f.criteria.FromBlock.Int64(); i <= f.criteria.ToBlock.Int64(); i++ {
block, err := f.backend.GetBlockByNumber(types.BlockNumber(i), false) block, err := f.backend.GetBlockByNumber(types.BlockNumber(i), false)
if err != nil { if err != nil {
err = errors.Wrapf(err, "failed to fetch block by number %d", i) return logs, errors.Wrapf(err, "failed to fetch block by number %d", i)
return logs, err }
} else if block["transactions"] == nil {
if block["transactions"] == nil {
continue continue
} }
@ -147,28 +146,32 @@ func (f *Filter) Logs(_ context.Context) ([]*ethtypes.Log, error) {
txs, ok := block["transactions"].([]interface{}) txs, ok := block["transactions"].([]interface{})
if !ok { if !ok {
txHashes, ok = block["transactions"].([]common.Hash) _, ok = block["transactions"].([]common.Hash)
if !ok { if !ok {
log.WithField( f.logger.Error(
"transactions", "reading transactions from block data failed",
fmt.Sprintf("%T", block["transactions"]), "type", fmt.Sprintf("%T", block["transactions"]),
).Errorln("reading transactions from block data: bad field type") )
}
continue continue
} }
} else if len(txs) == 0 && len(txHashes) == 0 {
if len(txs) == 0 {
continue continue
} }
for _, tx := range txs { for _, tx := range txs {
txHash, ok := tx.(common.Hash) txHash, ok := tx.(common.Hash)
if !ok { if !ok {
log.WithField( f.logger.Error(
"tx", "transactions list contains non-hash element",
fmt.Sprintf("%T", tx), "type", fmt.Sprintf("%T", tx),
).Errorln("transactions list contains non-hash element") )
} else { continue
txHashes = append(txHashes, txHash)
} }
txHashes = append(txHashes, txHash)
} }
logsMatched := f.checkMatches(txHashes) logsMatched := f.checkMatches(txHashes)
@ -188,9 +191,7 @@ func (f *Filter) blockLogs(header *ethtypes.Header) ([]*ethtypes.Log, error) {
// eth header's hash doesn't match tm block hash // eth header's hash doesn't match tm block hash
logsList, err := f.backend.GetLogsByNumber(types.BlockNumber(header.Number.Int64())) logsList, err := f.backend.GetLogsByNumber(types.BlockNumber(header.Number.Int64()))
if err != nil { if err != nil {
err = errors.Wrapf(err, "failed to fetch logs block number %d", header.Number.Int64()) return []*ethtypes.Log{}, errors.Wrapf(err, "failed to fetch logs block number %d", header.Number.Int64())
return []*ethtypes.Log{}, err
} }
var unfiltered []*ethtypes.Log // nolint: prealloc var unfiltered []*ethtypes.Log // nolint: prealloc

View File

@ -9,7 +9,7 @@ import (
"github.com/tharsis/ethermint/crypto/hd" "github.com/tharsis/ethermint/crypto/hd"
ethermint "github.com/tharsis/ethermint/types" ethermint "github.com/tharsis/ethermint/types"
log "github.com/xlab/suplog" "github.com/tendermint/tendermint/libs/log"
sdkcrypto "github.com/cosmos/cosmos-sdk/crypto" sdkcrypto "github.com/cosmos/cosmos-sdk/crypto"
"github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keyring"
@ -32,10 +32,10 @@ type PrivateAccountAPI struct {
} }
// NewAPI creates an instance of the public Personal Eth API. // NewAPI creates an instance of the public Personal Eth API.
func NewAPI(ethAPI *eth.PublicAPI) *PrivateAccountAPI { func NewAPI(logger log.Logger, ethAPI *eth.PublicAPI) *PrivateAccountAPI {
return &PrivateAccountAPI{ return &PrivateAccountAPI{
ethAPI: ethAPI, ethAPI: ethAPI,
logger: log.WithField("module", "personal"), logger: logger.With("api", "personal"),
} }
} }
@ -96,7 +96,7 @@ func (api *PrivateAccountAPI) ListAccounts() ([]common.Address, error) {
// LockAccount will lock the account associated with the given address when it's unlocked. // LockAccount will lock the account associated with the given address when it's unlocked.
// It removes the key corresponding to the given address from the API's local keys. // It removes the key corresponding to the given address from the API's local keys.
func (api *PrivateAccountAPI) LockAccount(address common.Address) bool { // nolint: interfacer func (api *PrivateAccountAPI) LockAccount(address common.Address) bool { // nolint: interfacer
api.logger.Debugln("personal_lockAccount", "address", address.String()) api.logger.Debug("personal_lockAccount", "address", address.String())
api.logger.Info("personal_lockAccount not supported") api.logger.Info("personal_lockAccount not supported")
// TODO: Not supported. See underlying issue https://github.com/99designs/keyring/issues/85 // TODO: Not supported. See underlying issue https://github.com/99designs/keyring/issues/85
return false return false
@ -115,9 +115,9 @@ func (api *PrivateAccountAPI) NewAccount(password string) (common.Address, error
} }
addr := common.BytesToAddress(info.GetPubKey().Address().Bytes()) addr := common.BytesToAddress(info.GetPubKey().Address().Bytes())
api.logger.Infoln("Your new key was generated", "address", addr.String()) api.logger.Info("Your new key was generated", "address", addr.String())
api.logger.Infoln("Please backup your key file!", "path", os.Getenv("HOME")+"/.ethermint/"+name) api.logger.Info("Please backup your key file!", "path", os.Getenv("HOME")+"/.ethermint/"+name)
api.logger.Infoln("Please remember your password!") api.logger.Info("Please remember your password!")
return addr, nil return addr, nil
} }
@ -125,7 +125,7 @@ func (api *PrivateAccountAPI) NewAccount(password string) (common.Address, error
// the given password for duration seconds. If duration is nil it will use a // the given password for duration seconds. If duration is nil it will use a
// default of 300 seconds. It returns an indication if the account was unlocked. // default of 300 seconds. It returns an indication if the account was unlocked.
func (api *PrivateAccountAPI) UnlockAccount(_ context.Context, addr common.Address, _ string, _ *uint64) (bool, error) { // nolint: interfacer func (api *PrivateAccountAPI) UnlockAccount(_ context.Context, addr common.Address, _ string, _ *uint64) (bool, error) { // nolint: interfacer
api.logger.Debugln("personal_unlockAccount", "address", addr.String()) api.logger.Debug("personal_unlockAccount", "address", addr.String())
// TODO: Not supported. See underlying issue https://github.com/99designs/keyring/issues/85 // TODO: Not supported. See underlying issue https://github.com/99designs/keyring/issues/85
return false, nil return false, nil
} }
@ -154,7 +154,7 @@ func (api *PrivateAccountAPI) Sign(_ context.Context, data hexutil.Bytes, addr c
sig, _, err := api.ethAPI.ClientCtx().Keyring.SignByAddress(cosmosAddr, accounts.TextHash(data)) sig, _, err := api.ethAPI.ClientCtx().Keyring.SignByAddress(cosmosAddr, accounts.TextHash(data))
if err != nil { if err != nil {
api.logger.WithError(err).Debugln("failed to sign with key", "data", data, "address", addr.String()) api.logger.Error("failed to sign with key", "data", data, "address", addr.String(), "error", err.Error())
return nil, err return nil, err
} }

View File

@ -1,9 +1,11 @@
package txpool package txpool
import ( import (
"github.com/tendermint/tendermint/libs/log"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/tharsis/ethermint/ethereum/rpc/types" "github.com/tharsis/ethermint/ethereum/rpc/types"
log "github.com/xlab/suplog"
) )
// PublicAPI offers and API for the transaction pool. It only operates on data that is non-confidential. // PublicAPI offers and API for the transaction pool. It only operates on data that is non-confidential.
@ -13,9 +15,9 @@ type PublicAPI struct {
} }
// NewPublicAPI creates a new tx pool service that gives information about the transaction pool. // NewPublicAPI creates a new tx pool service that gives information about the transaction pool.
func NewPublicAPI() *PublicAPI { func NewPublicAPI(logger log.Logger) *PublicAPI {
return &PublicAPI{ return &PublicAPI{
logger: log.WithField("module", "txpool"), logger: logger.With("module", "txpool"),
} }
} }

View File

@ -9,22 +9,20 @@ import (
"net/http" "net/http"
"sync" "sync"
"github.com/ethereum/go-ethereum/eth/filters"
rpcfilters "github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth/filters"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/pkg/errors" "github.com/pkg/errors"
log "github.com/xlab/suplog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/rpc"
"github.com/tendermint/tendermint/libs/log"
coretypes "github.com/tendermint/tendermint/rpc/core/types" coretypes "github.com/tendermint/tendermint/rpc/core/types"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
"github.com/ethereum/go-ethereum/common" rpcfilters "github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth/filters"
"github.com/ethereum/go-ethereum/rpc"
"github.com/tharsis/ethermint/ethereum/rpc/types" "github.com/tharsis/ethermint/ethereum/rpc/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types" evmtypes "github.com/tharsis/ethermint/x/evm/types"
) )
@ -68,12 +66,13 @@ type websocketsServer struct {
logger log.Logger logger log.Logger
} }
func NewWebsocketsServer(tmWSClient *rpcclient.WSClient, rpcAddr, wsAddr string) WebsocketsServer { func NewWebsocketsServer(logger log.Logger, tmWSClient *rpcclient.WSClient, rpcAddr, wsAddr string) WebsocketsServer {
logger = logger.With("module", "websocket-server")
return &websocketsServer{ return &websocketsServer{
rpcAddr: rpcAddr, rpcAddr: rpcAddr,
wsAddr: wsAddr, wsAddr: wsAddr,
api: newPubSubAPI(tmWSClient), api: newPubSubAPI(logger, tmWSClient),
logger: log.WithField("module", "websocket-server"), logger: logger,
} }
} }
@ -88,7 +87,7 @@ func (s *websocketsServer) Start() {
return return
} }
s.logger.WithError(err).Errorln("failed to start HTTP server for WS") s.logger.Error("failed to start HTTP server for WS", "error", err.Error())
} }
}() }()
} }
@ -102,7 +101,7 @@ func (s *websocketsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil) conn, err := upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {
s.logger.WithError(err).Warningln("websocket upgrade failed") s.logger.Debug("websocket upgrade failed", "error", err.Error())
return return
} }
@ -280,12 +279,13 @@ type pubSubAPI struct {
} }
// newPubSubAPI creates an instance of the ethereum PubSub API. // newPubSubAPI creates an instance of the ethereum PubSub API.
func newPubSubAPI(tmWSClient *rpcclient.WSClient) *pubSubAPI { func newPubSubAPI(logger log.Logger, tmWSClient *rpcclient.WSClient) *pubSubAPI {
logger = logger.With("module", "websocket-client")
return &pubSubAPI{ return &pubSubAPI{
events: rpcfilters.NewEventSystem(tmWSClient), events: rpcfilters.NewEventSystem(logger, tmWSClient),
filtersMu: new(sync.RWMutex), filtersMu: new(sync.RWMutex),
filters: make(map[rpc.ID]*wsSubscription), filters: make(map[rpc.ID]*wsSubscription),
logger: log.WithField("module", "websocket-client"), logger: logger,
} }
} }
@ -358,10 +358,7 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
data, ok := event.Data.(tmtypes.EventDataNewBlockHeader) data, ok := event.Data.(tmtypes.EventDataNewBlockHeader)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", event.Data))
"expected": "tmtypes.EventDataNewBlockHeader",
"actual": fmt.Sprintf("%T", event.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
@ -386,7 +383,7 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
err = wsSub.wsConn.WriteJSON(res) err = wsSub.wsConn.WriteJSON(res)
if err != nil { if err != nil {
api.logger.WithError(err).Error("error writing header, will drop peer") api.logger.Error("error writing header, will drop peer", "error", err.Error())
try(func() { try(func() {
api.filtersMu.RUnlock() api.filtersMu.RUnlock()
@ -411,7 +408,7 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
api.unsubscribe(subID) api.unsubscribe(subID)
return return
} }
log.WithError(err).Debugln("dropping NewHeads WebSocket subscription", subID) api.logger.Debug("dropping NewHeads WebSocket subscription", "subscription-id", subID, "error", err.Error())
api.unsubscribe(subID) api.unsubscribe(subID)
case <-unsubscribed: case <-unsubscribed:
return return
@ -423,20 +420,15 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
} }
func try(fn func(), l log.Logger, desc string) { func try(fn func(), l log.Logger, desc string) {
if l == nil {
l = log.DefaultLogger
}
defer func() { defer func() {
if x := recover(); x != nil { if x := recover(); x != nil {
if err, ok := x.(error); ok { if err, ok := x.(error); ok {
// debug.PrintStack() // debug.PrintStack()
l.WithError(err).Debugln("panic during", desc) l.Debug("panic during "+desc, "error", err.Error())
return return
} }
// debug.PrintStack() l.Debug(fmt.Sprintf("panic during %s: %+v", desc, x))
l.Debugf("panic during %s: %+v", desc, x)
return return
} }
}() }()
@ -451,9 +443,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
params, ok := extra.(map[string]interface{}) params, ok := extra.(map[string]interface{})
if !ok { if !ok {
err := errors.New("invalid criteria") err := errors.New("invalid criteria")
log.WithFields(log.Fields{ api.logger.Debug("invalid criteria", "type", fmt.Sprintf("%T", extra))
"criteria": fmt.Sprintf("expected: map[string]interface{}, got %T", extra),
}).Errorln(err)
return "", err return "", err
} }
@ -461,12 +451,8 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
address, ok := params["address"].(string) address, ok := params["address"].(string)
addresses, sok := params["address"].([]interface{}) addresses, sok := params["address"].([]interface{})
if !ok && !sok { if !ok && !sok {
err := errors.New("invalid address; must be address or array of addresses") err := errors.New("invalid addresses; must be address or array of addresses")
log.WithFields(log.Fields{ api.logger.Debug("invalid addresses", "type", fmt.Sprintf("%T", params["address"]))
"address": ok,
"addresses": sok,
"type": fmt.Sprintf("%T", params["address"]),
}).Errorln(err)
return "", err return "", err
} }
@ -480,7 +466,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
address, ok := addr.(string) address, ok := addr.(string)
if !ok { if !ok {
err := errors.New("invalid address") err := errors.New("invalid address")
log.WithField("type", fmt.Sprintf("%T", addr)).Errorln(err) api.logger.Debug("invalid address", "type", fmt.Sprintf("%T", addr))
return "", err return "", err
} }
@ -492,12 +478,8 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
if params["topics"] != nil { if params["topics"] != nil {
topics, ok := params["topics"].([]interface{}) topics, ok := params["topics"].([]interface{})
if !ok { if !ok {
err := errors.New("invalid topics") err := errors.Errorf("invalid topics: %s", topics)
api.logger.Error("invalid topics", "type", fmt.Sprintf("%T", topics))
log.WithFields(log.Fields{
"type": fmt.Sprintf("expected []interface{}, got %T", params["topics"]),
}).Errorln(err)
return "", err return "", err
} }
@ -507,7 +489,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
tstr, ok := topic.(string) tstr, ok := topic.(string)
if !ok { if !ok {
err := errors.Errorf("invalid topic: %s", topic) err := errors.Errorf("invalid topic: %s", topic)
log.WithField("type", fmt.Sprintf("expected string, got %T", topic)).Errorln(err) api.logger.Error("invalid topic", "type", fmt.Sprintf("%T", topic))
return err return err
} }
@ -533,11 +515,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
subtopicsList, ok := subtopics.([]interface{}) subtopicsList, ok := subtopics.([]interface{})
if !ok { if !ok {
err := errors.New("invalid subtopics") err := errors.New("invalid subtopics")
api.logger.Error("invalid subtopic", "type", fmt.Sprintf("%T", subtopics))
log.WithFields(log.Fields{
"type": fmt.Sprintf("expected []interface{}, got %T", subtopics),
}).Errorln(err)
return "", err return "", err
} }
@ -546,7 +524,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
tstr, ok := subtopic.(string) tstr, ok := subtopic.(string)
if !ok { if !ok {
err := errors.Errorf("invalid subtopic: %s", subtopic) err := errors.Errorf("invalid subtopic: %s", subtopic)
log.WithField("type", fmt.Sprintf("expected string, got %T", subtopic)).Errorln(err) api.logger.Error("invalid subtopic", "type", fmt.Sprintf("%T", subtopic))
return "", err return "", err
} }
@ -560,7 +538,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
critBz, err := json.Marshal(crit) critBz, err := json.Marshal(crit)
if err != nil { if err != nil {
log.WithError(err).Errorln("failed to JSON marshal criteria") api.logger.Error("failed to JSON marshal criteria", "error", err.Error())
return rpc.ID(""), err return rpc.ID(""), err
} }
@ -569,7 +547,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
sub, _, err := api.events.SubscribeLogs(crit) sub, _, err := api.events.SubscribeLogs(crit)
if err != nil { if err != nil {
log.WithError(err).Errorln("failed to subscribe logs") api.logger.Error("failed to subscribe logs", "error", err.Error())
return rpc.ID(""), err return rpc.ID(""), err
} }
@ -594,16 +572,13 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
dataTx, ok := event.Data.(tmtypes.EventDataTx) dataTx, ok := event.Data.(tmtypes.EventDataTx)
if !ok { if !ok {
log.WithFields(log.Fields{ api.logger.Debug("event data type mismatch", "type", fmt.Sprintf("%T", event.Data))
"expected": "tmtypes.EventDataTx",
"actual": fmt.Sprintf("%T", event.Data),
}).Warningln("event Data type mismatch")
continue continue
} }
txResponse, err := evmtypes.DecodeTxResponse(dataTx.TxResult.Result.Data) txResponse, err := evmtypes.DecodeTxResponse(dataTx.TxResult.Result.Data)
if err != nil { if err != nil {
log.WithError(err).Errorln("failed to decode tx response") api.logger.Error("failed to decode tx response", "error", err.Error())
return return
} }
@ -615,7 +590,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
api.filtersMu.RLock() api.filtersMu.RLock()
wsSub, ok := api.filters[subID] wsSub, ok := api.filters[subID]
if !ok { if !ok {
log.Warningln("subID not in filters", subID) api.logger.Debug("subID not in filters", subID)
return return
} }
api.filtersMu.RUnlock() api.filtersMu.RUnlock()
@ -650,7 +625,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
api.unsubscribe(subID) api.unsubscribe(subID)
return return
} }
log.WithError(err).Warningln("dropping Logs WebSocket subscription", subID) api.logger.Debug("dropping Logs WebSocket subscription", "subscription-id", subID, "error", err.Error())
api.unsubscribe(subID) api.unsubscribe(subID)
case <-unsubscribed: case <-unsubscribed:
return return
@ -706,7 +681,7 @@ func (api *pubSubAPI) subscribePendingTransactions(wsConn *wsConn) (rpc.ID, erro
err = wsSub.wsConn.WriteJSON(res) err = wsSub.wsConn.WriteJSON(res)
if err != nil { if err != nil {
api.logger.WithError(err).Warningln("error writing header, will drop peer") api.logger.Debug("error writing header, will drop peer", "error", err.Error())
try(func() { try(func() {
api.filtersMu.Lock() api.filtersMu.Lock()
@ -727,7 +702,7 @@ func (api *pubSubAPI) subscribePendingTransactions(wsConn *wsConn) (rpc.ID, erro
api.unsubscribe(subID) api.unsubscribe(subID)
return return
} }
log.WithError(err).Warningln("dropping PendingTransactions WebSocket subscription", subID) api.logger.Debug("dropping PendingTransactions WebSocket subscription", subID, "error", err.Error())
api.unsubscribe(subID) api.unsubscribe(subID)
case <-unsubscribed: case <-unsubscribed:
return return

View File

@ -15,7 +15,6 @@ import (
"github.com/rs/cors" "github.com/rs/cors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/xlab/closer" "github.com/xlab/closer"
log "github.com/xlab/suplog"
"google.golang.org/grpc" "google.golang.org/grpc"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
@ -168,17 +167,18 @@ which accepts a path for the resulting pprof file.
func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator types.AppCreator) error { func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator types.AppCreator) error {
cfg := ctx.Config cfg := ctx.Config
home := cfg.RootDir home := cfg.RootDir
logger := ctx.Logger
traceWriterFile := ctx.Viper.GetString(flagTraceStore) traceWriterFile := ctx.Viper.GetString(flagTraceStore)
db, err := openDB(home) db, err := openDB(home)
if err != nil { if err != nil {
log.WithError(err).Errorln("failed to open DB") logger.Error("failed to open DB", "error", err.Error())
return err return err
} }
traceWriter, err := openTraceWriter(traceWriterFile) traceWriter, err := openTraceWriter(traceWriterFile)
if err != nil { if err != nil {
log.WithError(err).Errorln("failed to open trace writer") logger.Error("failed to open trace writer", "error", err.Error())
return err return err
} }
@ -186,7 +186,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
if err != nil { if err != nil {
log.WithError(err).Errorln("failed load or gen node key") logger.Error("failed load or gen node key", "error", err.Error())
return err return err
} }
@ -202,12 +202,12 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
ctx.Logger.With("module", "node"), ctx.Logger.With("module", "node"),
) )
if err != nil { if err != nil {
log.WithError(err).Errorln("failed init node") logger.Error("failed init node", "error", err.Error())
return err return err
} }
if err := tmNode.Start(); err != nil { if err := tmNode.Start(); err != nil {
log.WithError(err).Errorln("failed start tendermint server") logger.Error("failed start tendermint server", "error", err.Error())
return err return err
} }
@ -228,7 +228,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
if config.GRPC.Enable { if config.GRPC.Enable {
grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC.Address) grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC.Address)
if err != nil { if err != nil {
log.WithError(err).Errorln("failed to boot GRPC server") logger.Error("failed to boot GRPC server", "error", err.Error())
return err return err
} }
} }
@ -241,18 +241,19 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
if config.EVMRPC.Enable { if config.EVMRPC.Enable {
tmEndpoint := "/websocket" tmEndpoint := "/websocket"
tmRPCAddr := cfg.RPC.ListenAddress tmRPCAddr := cfg.RPC.ListenAddress
log.Infoln("EVM RPC Connecting to Tendermint WebSocket at", tmRPCAddr+tmEndpoint) logger.Info("EVM RPC Connecting to Tendermint WebSocket at", tmRPCAddr+tmEndpoint)
tmWsClient := ConnectTmWS(tmRPCAddr, tmEndpoint) tmWsClient := ConnectTmWS(tmRPCAddr, tmEndpoint)
rpcServer := ethrpc.NewServer() rpcServer := ethrpc.NewServer()
apis := rpc.GetRPCAPIs(clientCtx, tmWsClient) apis := rpc.GetRPCAPIs(ctx, clientCtx, tmWsClient)
for _, api := range apis { for _, api := range apis {
if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil { if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil {
log.WithFields(log.Fields{ logger.Error(
"namespace": api.Namespace, "failed to register service in EVM RPC namespace",
"service": api.Service, "namespace", api.Namespace,
}).WithError(err).Fatalln("failed to register service in EVM RPC namespace") "service", api.Service,
)
return err return err
} }
} }
@ -286,31 +287,31 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
errCh := make(chan error) errCh := make(chan error)
go func() { go func() {
log.Infoln("Starting EVM RPC server on", config.EVMRPC.RPCAddress) logger.Info("Starting EVM RPC server", "address", config.EVMRPC.RPCAddress)
if err := httpSrv.ListenAndServe(); err != nil { if err := httpSrv.ListenAndServe(); err != nil {
if err == http.ErrServerClosed { if err == http.ErrServerClosed {
close(httpSrvDone) close(httpSrvDone)
return return
} }
log.WithError(err).Errorln("failed to start EVM RPC server") logger.Error("failed to start EVM RPC server", "error", err.Error())
errCh <- err errCh <- err
} }
}() }()
select { select {
case err := <-errCh: case err := <-errCh:
log.WithError(err).Errorln("failed to boot EVM RPC server") logger.Error("failed to boot EVM RPC server", "error", err.Error())
return err return err
case <-time.After(1 * time.Second): // assume EVM RPC server started successfully case <-time.After(1 * time.Second): // assume EVM RPC server started successfully
} }
log.Infoln("Starting EVM WebSocket server on", config.EVMRPC.WsAddress) logger.Info("Starting EVM WebSocket server", "address", config.EVMRPC.WsAddress)
_, port, _ := net.SplitHostPort(config.EVMRPC.RPCAddress) _, port, _ := net.SplitHostPort(config.EVMRPC.RPCAddress)
// allocate separate WS connection to Tendermint // allocate separate WS connection to Tendermint
tmWsClient = ConnectTmWS(tmRPCAddr, tmEndpoint) tmWsClient = ConnectTmWS(tmRPCAddr, tmEndpoint)
wsSrv = rpc.NewWebsocketsServer(tmWsClient, "localhost:"+port, config.EVMRPC.WsAddress) wsSrv = rpc.NewWebsocketsServer(logger, tmWsClient, "localhost:"+port, config.EVMRPC.WsAddress)
go wsSrv.Start() go wsSrv.Start()
} }
@ -329,7 +330,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
select { select {
case err := <-errCh: case err := <-errCh:
log.WithError(err).Errorln("failed to boot API server") logger.Error("failed to boot API server", "error", err.Error())
return err return err
case <-time.After(5 * time.Second): // assume server started successfully case <-time.After(5 * time.Second): // assume server started successfully
} }
@ -340,17 +341,17 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
if cpuProfile := ctx.Viper.GetString(flagCPUProfile); cpuProfile != "" { if cpuProfile := ctx.Viper.GetString(flagCPUProfile); cpuProfile != "" {
f, err := os.Create(cpuProfile) f, err := os.Create(cpuProfile)
if err != nil { if err != nil {
log.WithError(err).Errorln("failed to create CP profile") logger.Error("failed to create CP profile", "error", err.Error())
return err return err
} }
log.WithField("profile", cpuProfile).Infoln("starting CPU profiler") logger.Info("starting CPU profiler", "profile", cpuProfile)
if err := pprof.StartCPUProfile(f); err != nil { if err := pprof.StartCPUProfile(f); err != nil {
return err return err
} }
cpuProfileCleanup = func() { cpuProfileCleanup = func() {
log.WithField("profile", cpuProfile).Infoln("stopping CPU profiler") logger.Info("stopping CPU profiler", "profile", cpuProfile)
pprof.StopCPUProfile() pprof.StopCPUProfile()
f.Close() f.Close()
} }
@ -370,9 +371,9 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
defer cancelFn() defer cancelFn()
if err := httpSrv.Shutdown(shutdownCtx); err != nil { if err := httpSrv.Shutdown(shutdownCtx); err != nil {
log.WithError(err).Warningln("HTTP server shutdown produced a warning") logger.Error("HTTP server shutdown produced a warning", "error", err.Error())
} else { } else {
log.Infoln("HTTP server shut down, waiting 5 sec") logger.Info("HTTP server shut down, waiting 5 sec")
select { select {
case <-time.Tick(5 * time.Second): case <-time.Tick(5 * time.Second):
case <-httpSrvDone: case <-httpSrvDone:
@ -384,7 +385,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
grpcSrv.Stop() grpcSrv.Stop()
} }
log.Infoln("Bye!") logger.Info("Bye!")
}) })
closer.Hold() closer.Hold()

View File

@ -40,4 +40,4 @@ ethermintd collect-gentxs
ethermintd validate-genesis ethermintd validate-genesis
# Start the node (remove the --pruning=nothing flag if historical queries are not needed) # Start the node (remove the --pruning=nothing flag if historical queries are not needed)
ethermintd start --pruning=nothing --rpc.unsafe --keyring-backend test --trace --log_level "info" ethermintd start --pruning=nothing --rpc.unsafe --keyring-backend test --trace --log_level info

View File

@ -121,7 +121,7 @@ func startInProcess(cfg Config, val *Validator) error {
val.jsonRPC = jsonrpc.NewServer() val.jsonRPC = jsonrpc.NewServer()
apis := rpc.GetRPCAPIs(val.ClientCtx, tmWsClient) apis := rpc.GetRPCAPIs(val.Ctx, val.ClientCtx, tmWsClient)
for _, api := range apis { for _, api := range apis {
if err := val.jsonRPC.RegisterName(api.Namespace, api.Service); err != nil { if err := val.jsonRPC.RegisterName(api.Namespace, api.Service); err != nil {
return fmt.Errorf("failed to register JSON-RPC namespace %s: %w", api.Namespace, err) return fmt.Errorf("failed to register JSON-RPC namespace %s: %w", api.Namespace, err)