Skip to content

Commit

Permalink
reject authz Exec message in checkTx mode
Browse files Browse the repository at this point in the history
support cpu profiling abci handshake

json-rpc(filters) fix block hash on newBlock filter (evmos#1503)

* tests(filters) add block hash check on newBlock filter

* tests(filters) fix linting errors

* fix(filters): fix newBlock filter response

* fix(filters): add changes on CHANGELOG file
  • Loading branch information
yihuang committed Feb 22, 2023
1 parent 3316bdc commit 6b8b7b1
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [#1392](https://github.com/evmos/ethermint/pull/1392) Allow fill the proposer address in json-rpc through tendermint api, and pass explicitly to grpc query handler.
* (rpc) [#1405](https://github.com/evmos/ethermint/pull/1405) Pass chain-id to grpc query through request, otherwise it's not initialized if abci event don't happens.
* (rpc) [#1431](https://github.com/evmos/ethermint/pull/1431) Align hex-strings proof fields in `eth_getProof` as Ethereum.
* (rpc) [#1503](https://github.com/evmos/ethermint/pull/1503) Fix block hashes returned on JSON-RPC filter `eth_newBlockFilter`.

## [v0.19.3] - 2022-10-14

Expand Down
4 changes: 4 additions & 0 deletions app/ante/fee_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ func NewDynamicFeeChecker(k DynamicFeeEVMKeeper) authante.TxFeeChecker {
}
}

if ctx.IsCheckTx() && maxPriorityPrice.Sign() == -1 {
return nil, 0, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "priority fee is negative")
}

gas := feeTx.GetGas()
feeCoins := feeTx.GetFee()
fee := feeCoins.AmountOfNoDenomValidation(denom)
Expand Down
10 changes: 10 additions & 0 deletions app/ante/reject_msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ante
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz"
evmtypes "github.com/evmos/ethermint/x/evm/types"
)

Expand All @@ -20,6 +21,15 @@ func (rmd RejectMessagesDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
"MsgEthereumTx needs to be contained within a tx with 'ExtensionOptionsEthereumTx' option",
)
}

if ctx.IsCheckTx() {
if _, ok := msg.(*authz.MsgExec); ok {
return ctx, sdkerrors.Wrapf(
sdkerrors.ErrInvalidType,
"authz Exec message is disabled",
)
}
}
}
return next(ctx, tx, simulate)
}
5 changes: 1 addition & 4 deletions rpc/namespaces/ethereum/eth/filters/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,9 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
continue
}

baseFee := types.BaseFeeFromEvents(data.ResultBeginBlock.Events)

header := types.EthHeaderFromTendermint(data.Header, ethtypes.Bloom{}, baseFee)
api.filtersMu.Lock()
if f, found := api.filters[headerSub.ID()]; found {
f.hashes = append(f.hashes, header.Hash())
f.hashes = append(f.hashes, common.BytesToHash(data.Header.Hash()))
}
api.filtersMu.Unlock()
case <-errCh:
Expand Down
74 changes: 48 additions & 26 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ which accepts a path for the resulting pprof file.
withTM, _ := cmd.Flags().GetBool(srvflags.WithTendermint)
if !withTM {
serverCtx.Logger.Info("starting ABCI without Tendermint")
return startStandAlone(serverCtx, opts)
return wrapCPUProfile(serverCtx, func() error {
return startStandAlone(serverCtx, opts)
})
}

serverCtx.Logger.Info("Unlocking keyring")
Expand All @@ -138,7 +140,9 @@ which accepts a path for the resulting pprof file.
serverCtx.Logger.Info("starting ABCI with Tendermint")

// amino is needed here for backwards compatibility of REST routes
err = startInProcess(serverCtx, clientCtx, opts)
err = wrapCPUProfile(serverCtx, func() error {
return startInProcess(serverCtx, clientCtx, opts)
})
errCode, ok := err.(server.ErrorCode)
if !ok {
return err
Expand Down Expand Up @@ -268,30 +272,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, opts StartOpt
cfg := ctx.Config
home := cfg.RootDir
logger := ctx.Logger
if cpuProfile := ctx.Viper.GetString(srvflags.CPUProfile); cpuProfile != "" {
fp, err := ethdebug.ExpandHome(cpuProfile)
if err != nil {
ctx.Logger.Debug("failed to get filepath for the CPU profile file", "error", err.Error())
return err
}
f, err := os.Create(fp)
if err != nil {
return err
}

ctx.Logger.Info("starting CPU profiler", "profile", cpuProfile)
if err := pprof.StartCPUProfile(f); err != nil {
return err
}

defer func() {
ctx.Logger.Info("stopping CPU profiler", "profile", cpuProfile)
pprof.StopCPUProfile()
if err := f.Close(); err != nil {
logger.Error("failed to close CPU profiler file", "error", err.Error())
}
}()
}

traceWriterFile := ctx.Viper.GetString(srvflags.TraceStore)
db, err := opts.DBOpener(home, server.GetAppDBBackend(ctx.Viper))
Expand Down Expand Up @@ -627,3 +607,45 @@ func startTelemetry(cfg config.Config) (*telemetry.Metrics, error) {
}
return telemetry.New(cfg.Telemetry)
}

// wrapCPUProfile runs callback in a goroutine, then wait for quit signals.
func wrapCPUProfile(ctx *server.Context, callback func() error) error {
if cpuProfile := ctx.Viper.GetString(srvflags.CPUProfile); cpuProfile != "" {
fp, err := ethdebug.ExpandHome(cpuProfile)
if err != nil {
ctx.Logger.Debug("failed to get filepath for the CPU profile file", "error", err.Error())
return err
}
f, err := os.Create(fp)
if err != nil {
return err
}

ctx.Logger.Info("starting CPU profiler", "profile", cpuProfile)
if err := pprof.StartCPUProfile(f); err != nil {
return err
}

defer func() {
ctx.Logger.Info("stopping CPU profiler", "profile", cpuProfile)
pprof.StopCPUProfile()
if err := f.Close(); err != nil {
ctx.Logger.Info("failed to close cpu-profile file", "profile", cpuProfile, "err", err.Error())
}
}()
}

errCh := make(chan error)
go func() {
errCh <- callback()
}()

select {
case err := <-errCh:
return err

case <-time.After(types.ServerStartTime):
}

return server.WaitForQuitSignals()
}
14 changes: 12 additions & 2 deletions tests/integration_tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ def test_pending_transaction_filter(cluster):
txhash = send_successful_transaction(w3)
assert txhash in flt.get_new_entries()

# check if tx_hash is valid
tx = w3.eth.get_transaction(txhash)
assert tx.hash == txhash

# without new txs since last call
assert flt.get_new_entries() == []

Expand All @@ -34,8 +38,14 @@ def test_block_filter(cluster):

# with tx
send_successful_transaction(w3)
blocks = flt.get_new_entries()
assert len(blocks) >= 1
block_hashes = flt.get_new_entries()
assert len(block_hashes) >= 1

# check if the returned block hash is correct
# getBlockByHash
block = w3.eth.get_block(block_hashes[0])
# block should exist
assert block.hash == block_hashes[0]

# without new txs since last call
assert flt.get_new_entries() == []
Expand Down
21 changes: 16 additions & 5 deletions tests/integration_tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from eth_account import Account
from hexbytes import HexBytes
from web3._utils.transactions import fill_nonce, fill_transaction_defaults
from web3.exceptions import TimeExhausted

load_dotenv(Path(__file__).parent.parent.parent / "scripts/.env")
Account.enable_unaudited_hdwallet_features()
Expand Down Expand Up @@ -147,17 +148,27 @@ def sign_transaction(w3, tx, key=KEYS["validator"]):
return acct.sign_transaction(tx)


def send_transaction(w3, tx, key=KEYS["validator"]):
def send_transaction(w3, tx, key=KEYS["validator"], i=0):
if i > 3:
raise TimeExhausted
signed = sign_transaction(w3, tx, key)
txhash = w3.eth.send_raw_transaction(signed.rawTransaction)
return w3.eth.wait_for_transaction_receipt(txhash)
try:
return w3.eth.wait_for_transaction_receipt(txhash, timeout=20)
except TimeExhausted:
return send_transaction(w3, tx, key, i + 1)


def send_successful_transaction(w3):
def send_successful_transaction(w3, i=0):
if i > 3:
raise TimeExhausted
signed = sign_transaction(w3, {"to": ADDRS["community"], "value": 1000})
txhash = w3.eth.send_raw_transaction(signed.rawTransaction)
receipt = w3.eth.wait_for_transaction_receipt(txhash)
assert receipt.status == 1
try:
receipt = w3.eth.wait_for_transaction_receipt(txhash, timeout=20)
assert receipt.status == 1
except TimeExhausted:
return send_successful_transaction(w3, i + 1)
return txhash


Expand Down

0 comments on commit 6b8b7b1

Please sign in to comment.