Skip to content

Commit 4763011

Browse files
committed
Porting EVM tracer + Firehose to seiv2
1 parent 4025070 commit 4763011

File tree

21 files changed

+7097
-22
lines changed

21 files changed

+7097
-22
lines changed

app/app.go

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@ import (
77
"encoding/json"
88
"fmt"
99
"io"
10+
"math/big"
1011
"os"
1112
"path/filepath"
1213
"strings"
1314
"sync"
1415
"time"
1516

17+
ethcommon "github.com/ethereum/go-ethereum/common"
18+
ethhexutil "github.com/ethereum/go-ethereum/common/hexutil"
19+
ethtypes "github.com/ethereum/go-ethereum/core/types"
1620
"github.com/ethereum/go-ethereum/ethclient"
1721
ethrpc "github.com/ethereum/go-ethereum/rpc"
22+
1823
"github.com/sei-protocol/sei-chain/app/antedecorators"
1924
"github.com/sei-protocol/sei-chain/evmrpc"
2025
"github.com/sei-protocol/sei-chain/precompiles"
@@ -126,6 +131,8 @@ import (
126131
evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper"
127132
"github.com/sei-protocol/sei-chain/x/evm/querier"
128133
"github.com/sei-protocol/sei-chain/x/evm/replay"
134+
evmtracers "github.com/sei-protocol/sei-chain/x/evm/tracers"
135+
"github.com/sei-protocol/sei-chain/x/evm/tracing"
129136
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
130137
"github.com/spf13/cast"
131138
abci "github.com/tendermint/tendermint/abci/types"
@@ -375,6 +382,7 @@ type App struct {
375382

376383
encodingConfig appparams.EncodingConfig
377384
evmRPCConfig evmrpc.Config
385+
evmTracer *tracing.Hooks
378386
}
379387

380388
// New returns a reference to an initialized blockchain app
@@ -622,6 +630,15 @@ func New(
622630
app.EvmKeeper.EthClient = ethclient.NewClient(rpcclient)
623631
}
624632

633+
if app.evmRPCConfig.LiveEVMTracer != "" {
634+
chainConfig := evmtypes.DefaultChainConfig().EthereumConfig(app.EvmKeeper.ChainID())
635+
evmTracer, err := evmtracers.NewBlockchainTracer(evmtracers.GlobalLiveTracerRegistry, app.evmRPCConfig.LiveEVMTracer, chainConfig)
636+
if err != nil {
637+
panic(fmt.Sprintf("error creating EVM tracer due to %s", err))
638+
}
639+
app.evmTracer = evmTracer
640+
}
641+
625642
customDependencyGenerators := aclmapping.NewCustomDependencyGenerator()
626643
aclOpts = append(aclOpts, aclkeeper.WithResourceTypeToStoreKeyMap(aclutils.ResourceTypeToStoreKeyMap))
627644
aclOpts = append(aclOpts, aclkeeper.WithDependencyGeneratorMappings(customDependencyGenerators.GetCustomDependencyGenerators(app.EvmKeeper)))
@@ -1416,12 +1433,23 @@ func (app *App) ProcessTXsWithOCC(ctx sdk.Context, txs [][]byte, typedTxs []sdk.
14161433
wg.Add(1)
14171434
go func(txIndex int, tx []byte) {
14181435
defer wg.Done()
1436+
1437+
var txTracer sdk.TxTracer
1438+
if app.evmTracer != nil {
1439+
txTracer = app.evmTracer
1440+
if app.evmTracer.GetTxTracer != nil {
1441+
txTracer = app.evmTracer.GetTxTracer(absoluteTxIndices[txIndex])
1442+
}
1443+
}
1444+
14191445
deliverTxEntry := &sdk.DeliverTxEntry{
14201446
Request: abci.RequestDeliverTx{Tx: tx},
14211447
SdkTx: typedTxs[txIndex],
14221448
Checksum: sha256.Sum256(tx),
14231449
AbsoluteIndex: absoluteTxIndices[txIndex],
1450+
TxTracer: txTracer,
14241451
}
1452+
14251453
// get prefill estimate
14261454
estimatedWritesets, err := app.AccessControlKeeper.GenerateEstimatedWritesets(ctx, app.GetAnteDepGenerator(), txIndex, typedTxs[txIndex])
14271455
// if no error, then we assign the mapped writesets for prefill estimate
@@ -1482,12 +1510,17 @@ func (app *App) BuildDependenciesAndRunTxs(ctx sdk.Context, txs [][]byte, typedT
14821510
return app.ProcessBlockSynchronous(ctx, txs, typedTxs, absoluteTxIndices), ctx
14831511
}
14841512

1485-
func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequest, lastCommit abci.CommitInfo) ([]abci.Event, []*abci.ExecTxResult, abci.ResponseEndBlock, error) {
1513+
func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequest, lastCommit abci.CommitInfo) (events []abci.Event, txResults []*abci.ExecTxResult, endBlockResp abci.ResponseEndBlock, err error) {
14861514
ctx = ctx.WithIsOCCEnabled(app.OccEnabled())
1515+
14871516
goCtx := app.decorateContextWithDexMemState(ctx.Context())
14881517
ctx = ctx.WithContext(goCtx)
14891518

1490-
events := []abci.Event{}
1519+
if app.evmTracer != nil {
1520+
ctx = evmtracers.SetCtxBlockchainTracer(ctx, app.evmTracer)
1521+
}
1522+
1523+
events = []abci.Event{}
14911524
beginBlockReq := abci.RequestBeginBlock{
14921525
Hash: req.GetHash(),
14931526
ByzantineValidators: utils.Map(req.GetByzantineValidators(), func(mis abci.Misbehavior) abci.Evidence {
@@ -1512,9 +1545,16 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ
15121545
beginBlockResp := app.BeginBlock(ctx, beginBlockReq)
15131546
events = append(events, beginBlockResp.Events...)
15141547

1515-
txResults := make([]*abci.ExecTxResult, len(txs))
1548+
txResults = make([]*abci.ExecTxResult, len(txs))
15161549
typedTxs := app.DecodeTransactionsConcurrently(ctx, txs)
15171550

1551+
if app.evmTracer != nil {
1552+
header := ctx.BlockHeader()
1553+
app.evmTracer.OnSeiBlockStart(req.GetHash(), uint64(header.Size()), TmBlockHeaderToEVM(ctx, header, &app.EvmKeeper))
1554+
defer func() {
1555+
app.evmTracer.OnSeiBlockEnd(err)
1556+
}()
1557+
}
15181558
prioritizedTxs, otherTxs, prioritizedTypedTxs, otherTypedTxs, prioritizedIndices, otherIndices := app.PartitionPrioritizedTxs(ctx, txs, typedTxs)
15191559

15201560
// run the prioritized txs
@@ -1540,7 +1580,7 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ
15401580
lazyWriteEvents := app.BankKeeper.WriteDeferredBalances(ctx)
15411581
events = append(events, lazyWriteEvents...)
15421582

1543-
endBlockResp := app.EndBlock(ctx, abci.RequestEndBlock{
1583+
endBlockResp = app.EndBlock(ctx, abci.RequestEndBlock{
15441584
Height: req.GetHeight(),
15451585
})
15461586

@@ -1851,3 +1891,38 @@ func init() {
18511891
// override max wasm size to 2MB
18521892
wasmtypes.MaxWasmSize = 2 * 1024 * 1024
18531893
}
1894+
1895+
func TmBlockHeaderToEVM(
1896+
ctx sdk.Context,
1897+
block tmproto.Header,
1898+
k *evmkeeper.Keeper,
1899+
) (header *ethtypes.Header) {
1900+
number := big.NewInt(block.Height)
1901+
lastHash := ethcommon.BytesToHash(block.LastBlockId.Hash)
1902+
appHash := ethcommon.BytesToHash(block.AppHash)
1903+
txHash := ethcommon.BytesToHash(block.DataHash)
1904+
resultHash := ethcommon.BytesToHash(block.LastResultsHash)
1905+
miner := ethcommon.BytesToAddress(block.ProposerAddress)
1906+
gasLimit, gasWanted := uint64(0), uint64(0)
1907+
1908+
header = &ethtypes.Header{
1909+
Number: number,
1910+
ParentHash: lastHash,
1911+
Nonce: ethtypes.BlockNonce{}, // inapplicable to Sei
1912+
MixDigest: ethcommon.Hash{}, // inapplicable to Sei
1913+
UncleHash: ethtypes.EmptyUncleHash, // inapplicable to Sei
1914+
Bloom: k.GetBlockBloom(ctx, block.Height),
1915+
Root: appHash,
1916+
Coinbase: miner,
1917+
Difficulty: big.NewInt(0), // inapplicable to Sei
1918+
Extra: ethhexutil.Bytes{}, // inapplicable to Sei
1919+
GasLimit: gasLimit,
1920+
GasUsed: gasWanted,
1921+
Time: uint64(block.Time.Unix()),
1922+
TxHash: txHash,
1923+
ReceiptHash: resultHash,
1924+
BaseFee: k.GetBaseFeePerGas(ctx).RoundInt().BigInt(),
1925+
}
1926+
1927+
return
1928+
}

app/eth_replay.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
sdk "github.com/cosmos/cosmos-sdk/types"
1414
"github.com/ethereum/go-ethereum/common"
1515
ethcore "github.com/ethereum/go-ethereum/core"
16-
"github.com/ethereum/go-ethereum/core/tracing"
16+
ethtracing "github.com/ethereum/go-ethereum/core/tracing"
1717
ethtypes "github.com/ethereum/go-ethereum/core/types"
1818
"github.com/ethereum/go-ethereum/params"
1919
ethtests "github.com/ethereum/go-ethereum/tests"
@@ -85,7 +85,7 @@ func Replay(a *App) {
8585
for _, w := range b.Withdrawals() {
8686
amount := new(big.Int).SetUint64(w.Amount)
8787
amount = amount.Mul(amount, big.NewInt(params.GWei))
88-
s.AddBalance(w.Address, amount, tracing.BalanceIncreaseWithdrawal)
88+
s.AddBalance(w.Address, amount, ethtracing.BalanceIncreaseWithdrawal)
8989
}
9090
_, _ = s.Finalize()
9191
for _, tx := range b.Txs {

buf.gen.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: v1
2+
plugins:
3+
- plugin: buf.build/protocolbuffers/go:v1.31.0
4+
out: pb
5+
opt: paths=source_relative
6+

evmrpc/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ type Config struct {
5353
// Timeout for EVM call in simulation
5454
SimulationEVMTimeout time.Duration `mapstructure:"simulation_evm_timeout"`
5555

56+
// The EVM tracer to use when doing node synchronization, applies to
57+
// all block produced but traces only EVM transactions.
58+
//
59+
// Refer to x/evm/tracers/registry.go#GlobalLiveTracerRegistry for registered tracers.
60+
LiveEVMTracer string `mapstructure:"live_evm_tracer"`
61+
5662
// list of CORS allowed origins, separated by comma
5763
CORSOrigins string `mapstructure:"cors_origins"`
5864

@@ -92,6 +98,7 @@ var DefaultConfig = Config{
9298
IdleTimeout: rpc.DefaultHTTPTimeouts.IdleTimeout,
9399
SimulationGasLimit: 10_000_000, // 10M
94100
SimulationEVMTimeout: 60 * time.Second,
101+
LiveEVMTracer: "",
95102
CORSOrigins: "*",
96103
WSOrigins: "*",
97104
FilterTimeout: 120 * time.Second,
@@ -114,6 +121,7 @@ const (
114121
flagIdleTimeout = "evm.idle_timeout"
115122
flagSimulationGasLimit = "evm.simulation_gas_limit"
116123
flagSimulationEVMTimeout = "evm.simulation_evm_timeout"
124+
flagLiveEVMTracer = "evm.live_evm_tracer"
117125
flagCORSOrigins = "evm.cors_origins"
118126
flagWSOrigins = "evm.ws_origins"
119127
flagFilterTimeout = "evm.filter_timeout"
@@ -178,6 +186,11 @@ func ReadConfig(opts servertypes.AppOptions) (Config, error) {
178186
return cfg, err
179187
}
180188
}
189+
if v := opts.Get(flagLiveEVMTracer); v != nil {
190+
if cfg.LiveEVMTracer, err = cast.ToStringE(v); err != nil {
191+
return cfg, err
192+
}
193+
}
181194
if v := opts.Get(flagCORSOrigins); v != nil {
182195
if cfg.CORSOrigins, err = cast.ToStringE(v); err != nil {
183196
return cfg, err
@@ -223,5 +236,6 @@ func ReadConfig(opts servertypes.AppOptions) (Config, error) {
223236
return cfg, err
224237
}
225238
}
239+
226240
return cfg, nil
227241
}

evmrpc/config_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package evmrpc_test
22

33
import (
4+
"fmt"
45
"testing"
56
"time"
67

@@ -19,6 +20,7 @@ type opts struct {
1920
idleTimeout interface{}
2021
simulationGasLimit interface{}
2122
simulationEVMTimeout interface{}
23+
liveEVMTracer interface{}
2224
corsOrigins interface{}
2325
wsOrigins interface{}
2426
filterTimeout interface{}
@@ -61,6 +63,9 @@ func (o *opts) Get(k string) interface{} {
6163
if k == "evm.simulation_evm_timeout" {
6264
return o.simulationEVMTimeout
6365
}
66+
if k == "evm.live_evm_tracer" {
67+
return o.liveEVMTracer
68+
}
6469
if k == "evm.cors_origins" {
6570
return o.corsOrigins
6671
}
@@ -88,7 +93,7 @@ func (o *opts) Get(k string) interface{} {
8893
if k == "evm.max_blocks_for_log" {
8994
return o.maxBlocksForLog
9095
}
91-
panic("unknown key")
96+
panic(fmt.Errorf("unknown key: %s", k))
9297
}
9398

9499
func TestReadConfig(t *testing.T) {
@@ -105,6 +110,7 @@ func TestReadConfig(t *testing.T) {
105110
time.Duration(60),
106111
"",
107112
"",
113+
"",
108114
time.Duration(5),
109115
time.Duration(5),
110116
1000,

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,8 @@ github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8L
14331433
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
14341434
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
14351435
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
1436+
github.com/streamingfast/sei-cosmos v0.0.0-20240327153024-8e22d1da5334 h1:+4kXknHWASf4Qq0yo67kDmZcBDeSUxVICb34CDEY6Kw=
1437+
github.com/streamingfast/sei-cosmos v0.0.0-20240327153024-8e22d1da5334/go.mod h1:ib/gp0gCxN7FXUZ40j5+x8BeyoI7AcX+rTvf53JoDsY=
14361438
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
14371439
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
14381440
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=

pb/sf/ethereum/type/v2/type.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package pbeth
2+
3+
import (
4+
"encoding/hex"
5+
"math/big"
6+
"time"
7+
)
8+
9+
var b0 = big.NewInt(0)
10+
11+
func (b *Block) PreviousID() string {
12+
return hex.EncodeToString(b.Header.ParentHash)
13+
}
14+
15+
func (b *Block) Time() time.Time {
16+
return b.Header.Timestamp.AsTime()
17+
}
18+
19+
func (m *BigInt) Native() *big.Int {
20+
if m == nil {
21+
return b0
22+
}
23+
24+
z := new(big.Int)
25+
z.SetBytes(m.Bytes)
26+
return z
27+
}

0 commit comments

Comments
 (0)