Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ See https://github.com/dangoslen/changelog-enforcer.
- [#2405](https://github.com/NibiruChain/nibiru/pull/2405) - chore: additional coin logos which could be used externally
- [#2406](https://github.com/NibiruChain/nibiru/pull/2406) - chore: added monad logo svg
- [#2407](https://github.com/NibiruChain/nibiru/pull/2407) - feat(sudo-ante): implement zero gas actors for invoking whitelisted contract
- [#2409](https://github.com/NibiruChain/nibiru/pull/2409) - fix(evm-trace-block): handle native tracer errors JSON-RPC errors for "debug_traceBlockByNumber". Fixes [Nibiru#2400 bug](https://github.com/NibiruChain/nibiru/issues/2400)
- [#2410](https://github.com/NibiruChain/nibiru/pull/2410) -
feat(evm/grpc-query): Update the "/eth.evm.v1.Query/Balance" query to work with
"0x" Ethereum hex and "nibi"-prefixed Bech32 address formats. Return no Eth
Expand Down
2 changes: 1 addition & 1 deletion app/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewAnteHandlerNonEVM(
ante.AnteDecPreventEthereumTxMsgs{}, // reject MsgEthereumTxs
ante.AnteDecAuthzGuard{}, // disable certain messages in authz grant "generic"
authante.NewSetUpContextDecorator(),
ante.AnteDecSaiOracle{PublicKeepers: pk},
ante.AnteDecZeroGasActors{PublicKeepers: pk},
wasmkeeper.NewLimitSimulationGasDecorator(opts.WasmConfig.SimulationGasLimit),
wasmkeeper.NewCountTXDecorator(opts.TxCounterStoreKey),
// TODO: bug(security): Authz is unsafe. Let's include a guard to make
Expand Down
16 changes: 7 additions & 9 deletions app/ante/fixed_gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const (

var (
_ sdk.AnteDecorator = AnteDecEnsureSinglePostPriceMessage{}
_ sdk.AnteDecorator = AnteDecSaiOracle{}
_ sdk.AnteDecorator = AnteDecZeroGasActors{}
)

// AnteDecEnsureSinglePostPriceMessage ensures that there is only one
Expand Down Expand Up @@ -61,22 +61,20 @@ func (anteDec AnteDecEnsureSinglePostPriceMessage) AnteHandle(
return next(ctx, tx, simulate)
}

// AnteDecSaiOracle checks for Wasm execute contract calls from a set of
// known senders to the Sai oracle contract(s) and lowers gas costs using a fixed
// gas meter.
type AnteDecSaiOracle struct {
// AnteDecZeroGasActors checks for Wasm execute contract calls from a set of
// known senders to the whitelisted contract(s), giving those transactions zero
// gas costs using a fixed gas meter.
type AnteDecZeroGasActors struct {
keepers.PublicKeepers
}

func (anteDec AnteDecSaiOracle) AnteHandle(
func (anteDec AnteDecZeroGasActors) AnteHandle(
ctx sdk.Context,
tx sdk.Tx,
simulate bool,
next sdk.AnteHandler,
) (newCtx sdk.Context, err error) {
goCtx := sdk.WrapSDKContext(ctx)
resp, _ := anteDec.SudoKeeper.QueryZeroGasActors(goCtx, nil)
zeroGasActors := resp.Actors
zeroGasActors := anteDec.SudoKeeper.GetZeroGasActors(ctx)
if len(zeroGasActors.Senders) == 0 || len(zeroGasActors.Contracts) == 0 {
return next(ctx, tx, simulate)
}
Expand Down
3 changes: 2 additions & 1 deletion eth/rpc/rpcapi/api_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ func (a *DebugAPI) TraceBlockByNumber(height rpc.BlockNumber, config *evm.TraceC
// Get Tendermint Block
resBlock, err := a.backend.TendermintBlockByNumber(height)
if err != nil {
a.logger.Debug("get block failed", "height", height, "error", err.Error())
err = fmt.Errorf("%s { blockHeight: %d }", err, height)
a.logger.Debug("get block failed", "error", err.Error())
return nil, err
}

Expand Down
10 changes: 5 additions & 5 deletions eth/rpc/rpcapi/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ func (b *Backend) TraceBlock(height rpc.BlockNumber,
config *evm.TraceConfig,
block *tmrpctypes.ResultBlock,
) ([]*evm.TxTraceResult, error) {
txs := block.Block.Txs
txsLength := len(txs)
blockTxs := block.Block.Txs
txsLength := len(blockTxs)

if txsLength == 0 {
// If there are no transactions return empty array
Expand All @@ -153,10 +153,10 @@ func (b *Backend) TraceBlock(height rpc.BlockNumber,
txDecoder := b.clientCtx.TxConfig.TxDecoder()

var txsMessages []*evm.MsgEthereumTx
for i, tx := range txs {
decodedTx, err := txDecoder(tx)
for i, blockTx := range blockTxs {
decodedTx, err := txDecoder(blockTx)
if err != nil {
b.logger.Error("failed to decode transaction", "hash", txs[i].Hash(), "error", err.Error())
b.logger.Error("failed to decode transaction", "hash", blockTxs[i].Hash(), "error", err.Error())
continue
}

Expand Down
23 changes: 22 additions & 1 deletion eth/rpc/rpcapi/tracing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func (s *BackendSuite) TestTraceBlock() {
tmBlock *tmrpctypes.ResultBlock
txCount int
traceConfig *evm.TraceConfig
wantErr bool
}{
{
name: "happy: TraceBlock, no txs, tracer: default",
Expand Down Expand Up @@ -124,6 +125,18 @@ func (s *BackendSuite) TestTraceBlock() {
txCount: 1,
traceConfig: traceConfigDefaultTracer(),
},
{
name: "sad: TraceBlock with ultra small timeout, causing tracer to stop too early",
blockNumber: *s.SuccessfulTxTransfer().BlockNumberRpc,
tmBlock: tmBlockWithTx,
txCount: 1,
traceConfig: func() *evm.TraceConfig {
cfg := traceConfigCallTracer()
cfg.Timeout = "1ns" // Force immediate timeout
return cfg
}(),
wantErr: true,
},
}

for _, tc := range testCases {
Expand All @@ -135,6 +148,10 @@ func (s *BackendSuite) TestTraceBlock() {
tc.traceConfig,
tc.tmBlock,
)
if tc.wantErr {
s.Require().Error(err, tc.wantErr)
return
}
s.Require().NoError(err)
resRes = append(resRes, txTraceResults)
}
Expand All @@ -146,7 +163,11 @@ func (s *BackendSuite) TestTraceBlock() {
rpc.BlockNumber(tc.tmBlock.Block.Height),
tc.traceConfig,
)
s.NoError(err)
if tc.wantErr {
s.Require().Error(err)
return
}
s.Require().NoError(err)

var txTraceResults []*evm.TxTraceResult
err = json.Unmarshal(resJson, &txTraceResults)
Expand Down
41 changes: 27 additions & 14 deletions x/evm/evmstate/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,29 +690,42 @@ func (k Keeper) TraceBlock(
big.NewInt(ctx.BlockHeight()),
evm.ParseBlockTimeUnixU64(ctx),
)
txsLength := len(req.Txs)
results := make([]*evm.TxTraceResult, 0, txsLength)

txConfig := NewEmptyTxConfig(gethcommon.BytesToHash(ctx.HeaderHash().Bytes()))

// NOTE: Nibiru EVM uses exclusively native tracers and considers JS tracers
// out of scope.
//
// Geth differentiates between native tracers and JS tracers.
// Native tracers are the defaults like the "callTracer" and others have low
// overhead and return errors if any of the txs fail tracing.
//
// JS tracers (geth only) have high overhead. Tracing for them runs a
// parallel process that generates statesin one thread and traces txs in
// separate worker threads. JS tracers store tracing errors for each tx as
// fields of the returned trace result instead of failing the query.
var (
results = make([]evm.TxTraceResult, len(req.Txs))
txConfig = NewEmptyTxConfig(gethcommon.BytesToHash(ctx.HeaderHash().Bytes()))
// Transaction data as an EVM message to be traced.
msg *core.Message
)
for i, tx := range req.Txs {
result := evm.TxTraceResult{}
ethTx := tx.AsTransaction()
txConfig.TxHash = ethTx.Hash()
txConfig.TxIndex = uint(i)
msg, err := core.TransactionToMessage(ethTx, signer, evmCfg.BaseFeeWei)
if err != nil {
result.Error = err.Error()
continue
}
// Here in "core.TransactionToMessage", the resulting msg is guaranteed
// not to be nil, and potential signer errors are not relevant for
// tracing, as this is only a query.
msg, _ = core.TransactionToMessage(ethTx, signer, evmCfg.BaseFeeWei)
traceResult, logIndex, err := k.TraceEthTxMsg(ctx, evmCfg, txConfig, *msg, req.TraceConfig, tracerConfig)
if err != nil {
result.Error = err.Error()
} else {
txConfig.LogIndex = logIndex
result.Result = traceResult
// Since Nibiru uses native tracers from geth, failure to trace any
// tx means block tracing fails too.
return nil, fmt.Errorf("trace tx error { txhash: %s, blockHeight: %d }: %w", ethTx.Hash().Hex(), ctx.BlockHeight(), err)
}
results = append(results, &result)
txConfig.LogIndex = logIndex
result.Result = traceResult
results[i] = result
}

resultData, err := json.Marshal(results)
Expand Down
Loading
Loading