Skip to content

Commit

Permalink
Merge pull request #3502 from vitaliy-io/add-trace-by-block-eps
Browse files Browse the repository at this point in the history
Add new rpc endpoints
  • Loading branch information
vitaliy-io authored Sep 11, 2024
2 parents 9076460 + 5bffb35 commit cb4115a
Show file tree
Hide file tree
Showing 12 changed files with 393 additions and 46 deletions.
10 changes: 6 additions & 4 deletions packages/chainutil/evmtrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import (
"github.com/iotaledger/wasp/packages/isc"
)

func EVMTraceTransaction(
func EVMTrace(
ch chain.ChainCore,
aliasOutput *isc.AliasOutputWithID,
blockTime time.Time,
iscRequestsInBlock []isc.Request,
txIndex uint64,
txIndex *uint64,
blockNumber *uint64,
tracer *tracers.Tracer,
) error {
_, err := runISCTask(
Expand All @@ -24,8 +25,9 @@ func EVMTraceTransaction(
iscRequestsInBlock,
false,
&isc.EVMTracer{
Tracer: tracer,
TxIndex: txIndex,
Tracer: tracer,
TxIndex: txIndex,
BlockNumber: blockNumber,
},
)
return err
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/jsonrpc/chainbackend.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type ChainBackend interface {
EVMSendTransaction(tx *types.Transaction) error
EVMCall(aliasOutput *isc.AliasOutputWithID, callMsg ethereum.CallMsg) ([]byte, error)
EVMEstimateGas(aliasOutput *isc.AliasOutputWithID, callMsg ethereum.CallMsg) (uint64, error)
EVMTraceTransaction(aliasOutput *isc.AliasOutputWithID, blockTime time.Time, iscRequestsInBlock []isc.Request, txIndex uint64, tracer *tracers.Tracer) error
EVMTrace(aliasOutput *isc.AliasOutputWithID, blockTime time.Time, iscRequestsInBlock []isc.Request, txIndex *uint64, blockNumber *uint64, tracer *tracers.Tracer) error
FeePolicy(blockIndex uint32) (*gas.FeePolicy, error)
ISCChainID() *isc.ChainID
ISCCallView(chainState state.State, scName string, funName string, args dict.Dict) (dict.Dict, error)
Expand Down
95 changes: 83 additions & 12 deletions packages/evm/jsonrpc/evmchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,25 @@ func (e *EVMChain) TransactionByBlockNumberAndIndex(blockNumber *big.Int, index
return txs[index], block.Hash(), bn, nil
}

func (e *EVMChain) txsByBlockNumber(blockNumber *big.Int) (txs types.Transactions, err error) {
e.log.Debugf("TxsByBlockNumber(blockNumber=%v, index=%v)", blockNumber)
cachedTxs := e.index.TxsByBlockNumber(blockNumber)
if cachedTxs != nil {
return cachedTxs, nil
}
latestState, err := e.backend.ISCLatestState()
if err != nil {
return nil, err
}
db := blockchainDB(latestState)
block := db.GetBlockByNumber(blockNumber.Uint64())
if block == nil {
return nil, err
}

return block.Transactions(), nil
}

func (e *EVMChain) BlockByHash(hash common.Hash) *types.Block {
e.log.Debugf("BlockByHash(hash=%v)", hash)

Expand Down Expand Up @@ -639,44 +658,48 @@ func (e *EVMChain) iscRequestsInBlock(evmBlockNumber uint64) (*blocklog.BlockInf
}
iscBlockIndex := iscState.BlockIndex()
blocklogStatePartition := subrealm.NewReadOnly(iscState, kv.Key(blocklog.Contract.Hname().Bytes()))

return blocklog.GetRequestsInBlock(blocklogStatePartition, iscBlockIndex)
}

func (e *EVMChain) TraceTransaction(txHash common.Hash, config *tracers.TraceConfig) (any, error) {
e.log.Debugf("TraceTransaction(txHash=%v, config=?)", txHash)
func (e *EVMChain) Trace(config *tracers.TraceConfig, txIndex *uint64, txHash common.Hash, blockNumber uint64, blockHash common.Hash) (any, error) {
tracerType := "callTracer"
if config.Tracer != nil {
tracerType = *config.Tracer
}

_, blockHash, blockNumber, txIndex, err := e.TransactionByHash(txHash)
iscBlock, iscRequestsInBlock, err := e.iscRequestsInBlock(blockNumber)
if err != nil {
return nil, err
}
if blockNumber == 0 {
return nil, errors.New("tx not found")
}

iscBlock, iscRequestsInBlock, err := e.iscRequestsInBlock(blockNumber)
if err != nil {
return nil, err
var blockTxs types.Transactions
var txi int
if txIndex != nil {
txi = int(*txIndex)
} else {
blockTxs, err = e.txsByBlockNumber(new(big.Int).SetUint64(blockNumber))
if err != nil {
return nil, err
}
}

tracer, err := newTracer(tracerType, &tracers.Context{
BlockHash: blockHash,
BlockNumber: new(big.Int).SetUint64(blockNumber),
TxIndex: int(txIndex),
TxIndex: txi,
TxHash: txHash,
}, config.TracerConfig)
}, config.TracerConfig, blockTxs)
if err != nil {
return nil, err
}

err = e.backend.EVMTraceTransaction(
err = e.backend.EVMTrace(
iscBlock.PreviousAliasOutput,
iscBlock.Timestamp,
iscRequestsInBlock,
txIndex,
&blockNumber,
tracer,
)
if err != nil {
Expand All @@ -686,6 +709,54 @@ func (e *EVMChain) TraceTransaction(txHash common.Hash, config *tracers.TraceCon
return tracer.GetResult()
}

func (e *EVMChain) TraceTransaction(txHash common.Hash, config *tracers.TraceConfig) (any, error) {
e.log.Debugf("TraceTransaction(txHash=%v, config=?)", txHash)

_, blockHash, blockNumber, txIndex, err := e.TransactionByHash(txHash)
if err != nil {
return nil, err
}
if blockNumber == 0 {
return nil, errors.New("tx not found")
}

return e.Trace(config, &txIndex, txHash, blockNumber, blockHash)
}

func (e *EVMChain) TraceBlockByHash(blockHash common.Hash, config *tracers.TraceConfig) (any, error) {
e.log.Debugf("TraceBlockByHash(blockHash=%v, config=?)", blockHash)

block := e.BlockByHash(blockHash)
if block == nil {
return nil, errors.New("block not found")
}

return e.Trace(config, nil, common.Hash{}, block.Number().Uint64(), blockHash)
}

func (e *EVMChain) TraceBlockByNumber(blockNumber uint64, config *tracers.TraceConfig) (any, error) {
e.log.Debugf("TraceBlockByNumber(blockNumber=%v, config=?)", blockNumber)

block, err := e.BlockByNumber(big.NewInt(int64(blockNumber)))
if err != nil {
return nil, fmt.Errorf("block not found: %w", err)
}

return e.Trace(config, nil, common.Hash{}, blockNumber, block.Hash())
}

func (e *EVMChain) GetBlockReceipts(blockNumber rpc.BlockNumber) ([]*types.Receipt, error) {
e.log.Debugf("GetBlockReceipts(blockNumber=%v)", blockNumber)
bn := parseBlockNumber(blockNumber)
chainState, err := e.iscStateFromEVMBlockNumber(bn)
if err != nil {
return nil, err
}

db := blockchainDB(chainState)
return db.GetReceiptsByBlockNumber(bn.Uint64()), nil
}

var maxUint32 = big.NewInt(math.MaxUint32)

// the first EVM block (number 0) is "minted" at ISC block index 0 (init chain)
Expand Down
15 changes: 15 additions & 0 deletions packages/evm/jsonrpc/jsonrpcindex/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,21 @@ func (c *Index) TxByBlockNumberAndIndex(blockNumber *big.Int, txIndex uint64) (t
return txs[txIndex], block.Hash()
}

func (c *Index) TxsByBlockNumber(blockNumber *big.Int) types.Transactions {
if blockNumber == nil {
return nil
}
db := c.evmDBFromBlockIndex(uint32(blockNumber.Uint64()))
if db == nil {
return nil
}
block := db.GetBlockByNumber(blockNumber.Uint64())
if block == nil {
return nil
}
return block.Transactions()
}

// internals

const (
Expand Down
Loading

0 comments on commit cb4115a

Please sign in to comment.