@@ -7,14 +7,19 @@ import (
7
7
"encoding/json"
8
8
"fmt"
9
9
"io"
10
+ "math/big"
10
11
"os"
11
12
"path/filepath"
12
13
"strings"
13
14
"sync"
14
15
"time"
15
16
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"
16
20
"github.com/ethereum/go-ethereum/ethclient"
17
21
ethrpc "github.com/ethereum/go-ethereum/rpc"
22
+
18
23
"github.com/sei-protocol/sei-chain/app/antedecorators"
19
24
"github.com/sei-protocol/sei-chain/evmrpc"
20
25
"github.com/sei-protocol/sei-chain/precompiles"
@@ -124,6 +129,8 @@ import (
124
129
"github.com/sei-protocol/sei-chain/x/evm/blocktest"
125
130
evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper"
126
131
"github.com/sei-protocol/sei-chain/x/evm/replay"
132
+ evmtracers "github.com/sei-protocol/sei-chain/x/evm/tracers"
133
+ "github.com/sei-protocol/sei-chain/x/evm/tracing"
127
134
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
128
135
"github.com/spf13/cast"
129
136
abci "github.com/tendermint/tendermint/abci/types"
@@ -373,6 +380,7 @@ type App struct {
373
380
374
381
encodingConfig appparams.EncodingConfig
375
382
evmRPCConfig evmrpc.Config
383
+ evmTracer * tracing.Hooks
376
384
}
377
385
378
386
// New returns a reference to an initialized blockchain app
@@ -609,6 +617,20 @@ func New(
609
617
app .EvmKeeper .EthClient = ethclient .NewClient (rpcclient )
610
618
}
611
619
620
+ if app .evmRPCConfig .LiveEVMTracer != "" {
621
+ // PR_REVIEW_NOTE: So I moved this code from `ProcessBlock` and there, I had access to `ctx` so the code was actually looking
622
+ // like `evmtypes.DefaultChainConfig().EthereumConfig(app.EvmKeeper.ChainID(ctx))`. But here, I don't have access to `ctx`
623
+ // Is there another mean to get the EVM chainID from here? I need it to call `OnSeiBlockchainInit` on the logger,
624
+ // so another solution would be to call this one later when EVM chainID is known. Last resort, we have a sync.Once
625
+ // that we can use to call it only once.
626
+ chainConfig := evmtypes .DefaultChainConfig ().EthereumConfig (big .NewInt (int64 (app .evmRPCConfig .LiveEVMTracerChainID )))
627
+ evmTracer , err := evmtracers .NewBlockchainTracer (evmtracers .GlobalLiveTracerRegistry , app .evmRPCConfig .LiveEVMTracer , chainConfig )
628
+ if err != nil {
629
+ panic (fmt .Sprintf ("error creating EVM tracer due to %s" , err ))
630
+ }
631
+ app .evmTracer = evmTracer
632
+ }
633
+
612
634
customDependencyGenerators := aclmapping .NewCustomDependencyGenerator ()
613
635
aclOpts = append (aclOpts , aclkeeper .WithResourceTypeToStoreKeyMap (aclutils .ResourceTypeToStoreKeyMap ))
614
636
aclOpts = append (aclOpts , aclkeeper .WithDependencyGeneratorMappings (customDependencyGenerators .GetCustomDependencyGenerators (app .EvmKeeper )))
@@ -1401,12 +1423,23 @@ func (app *App) ProcessTXsWithOCC(ctx sdk.Context, txs [][]byte, typedTxs []sdk.
1401
1423
wg .Add (1 )
1402
1424
go func (txIndex int , tx []byte ) {
1403
1425
defer wg .Done ()
1426
+
1427
+ var txTracer sdk.TxTracer
1428
+ if app .evmTracer != nil {
1429
+ txTracer = app .evmTracer
1430
+ if app .evmTracer .GetTxTracer != nil {
1431
+ txTracer = app .evmTracer .GetTxTracer (absoluteTxIndices [txIndex ])
1432
+ }
1433
+ }
1434
+
1404
1435
deliverTxEntry := & sdk.DeliverTxEntry {
1405
1436
Request : abci.RequestDeliverTx {Tx : tx },
1406
1437
SdkTx : typedTxs [txIndex ],
1407
1438
Checksum : sha256 .Sum256 (tx ),
1408
1439
AbsoluteIndex : absoluteTxIndices [txIndex ],
1440
+ TxTracer : txTracer ,
1409
1441
}
1442
+
1410
1443
// get prefill estimate
1411
1444
estimatedWritesets , err := app .AccessControlKeeper .GenerateEstimatedWritesets (ctx , app .GetAnteDepGenerator (), txIndex , typedTxs [txIndex ])
1412
1445
// if no error, then we assign the mapped writesets for prefill estimate
@@ -1466,12 +1499,17 @@ func (app *App) BuildDependenciesAndRunTxs(ctx sdk.Context, txs [][]byte, typedT
1466
1499
return app .ProcessBlockSynchronous (ctx , txs , typedTxs , absoluteTxIndices ), ctx
1467
1500
}
1468
1501
1469
- func (app * App ) ProcessBlock (ctx sdk.Context , txs [][]byte , req BlockProcessRequest , lastCommit abci.CommitInfo ) ([]abci.Event , []* abci.ExecTxResult , abci.ResponseEndBlock , error ) {
1502
+ 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 ) {
1470
1503
ctx = ctx .WithIsOCCEnabled (app .OccEnabled ())
1504
+
1471
1505
goCtx := app .decorateContextWithDexMemState (ctx .Context ())
1472
1506
ctx = ctx .WithContext (goCtx )
1473
1507
1474
- events := []abci.Event {}
1508
+ if app .evmTracer != nil {
1509
+ ctx = evmtracers .SetCtxBlockchainTracer (ctx , app .evmTracer )
1510
+ }
1511
+
1512
+ events = []abci.Event {}
1475
1513
beginBlockReq := abci.RequestBeginBlock {
1476
1514
Hash : req .GetHash (),
1477
1515
ByzantineValidators : utils .Map (req .GetByzantineValidators (), func (mis abci.Misbehavior ) abci.Evidence {
@@ -1496,9 +1534,16 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ
1496
1534
beginBlockResp := app .BeginBlock (ctx , beginBlockReq )
1497
1535
events = append (events , beginBlockResp .Events ... )
1498
1536
1499
- txResults : = make ([]* abci.ExecTxResult , len (txs ))
1537
+ txResults = make ([]* abci.ExecTxResult , len (txs ))
1500
1538
typedTxs := app .DecodeTransactionsConcurrently (ctx , txs )
1501
1539
1540
+ if app .evmTracer != nil {
1541
+ header := ctx .BlockHeader ()
1542
+ app .evmTracer .OnSeiBlockStart (req .GetHash (), uint64 (header .Size ()), TmBlockHeaderToEVM (ctx , header , & app .EvmKeeper ))
1543
+ defer func () {
1544
+ app .evmTracer .OnSeiBlockEnd (err )
1545
+ }()
1546
+ }
1502
1547
prioritizedTxs , otherTxs , prioritizedTypedTxs , otherTypedTxs , prioritizedIndices , otherIndices := app .PartitionPrioritizedTxs (ctx , txs , typedTxs )
1503
1548
1504
1549
// run the prioritized txs
@@ -1524,7 +1569,7 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ
1524
1569
lazyWriteEvents := app .BankKeeper .WriteDeferredBalances (ctx )
1525
1570
events = append (events , lazyWriteEvents ... )
1526
1571
1527
- endBlockResp : = app .EndBlock (ctx , abci.RequestEndBlock {
1572
+ endBlockResp = app .EndBlock (ctx , abci.RequestEndBlock {
1528
1573
Height : req .GetHeight (),
1529
1574
})
1530
1575
@@ -1835,3 +1880,38 @@ func init() {
1835
1880
// override max wasm size to 2MB
1836
1881
wasmtypes .MaxWasmSize = 2 * 1024 * 1024
1837
1882
}
1883
+
1884
+ func TmBlockHeaderToEVM (
1885
+ ctx sdk.Context ,
1886
+ block tmproto.Header ,
1887
+ k * evmkeeper.Keeper ,
1888
+ ) (header * ethtypes.Header ) {
1889
+ number := big .NewInt (block .Height )
1890
+ lastHash := ethcommon .BytesToHash (block .LastBlockId .Hash )
1891
+ appHash := ethcommon .BytesToHash (block .AppHash )
1892
+ txHash := ethcommon .BytesToHash (block .DataHash )
1893
+ resultHash := ethcommon .BytesToHash (block .LastResultsHash )
1894
+ miner := ethcommon .BytesToAddress (block .ProposerAddress )
1895
+ gasLimit , gasWanted := uint64 (0 ), uint64 (0 )
1896
+
1897
+ header = & ethtypes.Header {
1898
+ Number : number ,
1899
+ ParentHash : lastHash ,
1900
+ Nonce : ethtypes.BlockNonce {}, // inapplicable to Sei
1901
+ MixDigest : ethcommon.Hash {}, // inapplicable to Sei
1902
+ UncleHash : ethtypes .EmptyUncleHash , // inapplicable to Sei
1903
+ Bloom : k .GetBlockBloom (ctx , block .Height ),
1904
+ Root : appHash ,
1905
+ Coinbase : miner ,
1906
+ Difficulty : big .NewInt (0 ), // inapplicable to Sei
1907
+ Extra : ethhexutil.Bytes {}, // inapplicable to Sei
1908
+ GasLimit : gasLimit ,
1909
+ GasUsed : gasWanted ,
1910
+ Time : uint64 (block .Time .Unix ()),
1911
+ TxHash : txHash ,
1912
+ ReceiptHash : resultHash ,
1913
+ BaseFee : k .GetBaseFeePerGas (ctx ).RoundInt ().BigInt (),
1914
+ }
1915
+
1916
+ return
1917
+ }
0 commit comments