Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion x/evm/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func CmdQueryAccount() *cobra.Command {
offline, _ := cmd.Flags().GetBool("offline")

if offline {
var addrEth = eth.NibiruAddrToEthAddr(addrBech32)
addrEth := eth.NibiruAddrToEthAddr(addrBech32)
resp := new(evm.QueryEthAccountResponse)
resp.EthAddress = addrEth.Hex()
resp.Bech32Address = addrBech32.String()
Expand Down
44 changes: 29 additions & 15 deletions x/evm/evmstate/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,29 +690,43 @@ 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()
result.TxHash = ethTx.Hash()
txConfig.TxHash = result.TxHash
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