Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added l2txhash to transaction arpc responces #1079

Merged
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
55 changes: 27 additions & 28 deletions cmd/rpcdaemon/commands/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"github.com/gateway-fm/cdk-erigon-lib/kv/kvcache"
"github.com/gateway-fm/cdk-erigon-lib/kv/kvcfg"
libstate "github.com/gateway-fm/cdk-erigon-lib/state"
types2 "github.com/gateway-fm/cdk-erigon-lib/types"

"github.com/ledgerwatch/erigon/chain"
"github.com/ledgerwatch/erigon/zk/hermez_db"
Expand All @@ -46,15 +45,15 @@ import (
// EthAPI is a collection of functions that are exposed in the
type EthAPI interface {
// Block related (proposed file: ./eth_blocks.go)
GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetBlockByHash(ctx context.Context, hash rpc.BlockNumberOrHash, fullTx bool) (map[string]interface{}, error)
GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx *bool) (map[string]interface{}, error)
GetBlockByHash(ctx context.Context, hash rpc.BlockNumberOrHash, fullTx *bool) (map[string]interface{}, error)
GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*hexutil.Uint, error)
GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) (*hexutil.Uint, error)

// Transaction related (see ./eth_txs.go)
GetTransactionByHash(ctx context.Context, hash common.Hash) (interface{}, error)
GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, txIndex hexutil.Uint64) (*RPCTransaction, error)
GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, txIndex hexutil.Uint) (*RPCTransaction, error)
GetTransactionByHash(ctx context.Context, hash common.Hash, includeExtraInfo *bool) (interface{}, error)
GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, txIndex hexutil.Uint64, includeExtraInfo *bool) (*RPCTransaction, error)
GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, txIndex hexutil.Uint, includeExtraInfo *bool) (*RPCTransaction, error)
GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutility.Bytes, error)
GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutility.Bytes, error)
GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutility.Bytes, error)
Expand Down Expand Up @@ -378,28 +377,28 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo
}
}

// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
type RPCTransaction struct {
BlockHash *common.Hash `json:"blockHash"`
BlockNumber *hexutil.Big `json:"blockNumber"`
From common.Address `json:"from"`
Gas hexutil.Uint64 `json:"gas"`
GasPrice *hexutil.Big `json:"gasPrice,omitempty"`
Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
Hash common.Hash `json:"hash"`
Input hexutility.Bytes `json:"input"`
Nonce hexutil.Uint64 `json:"nonce"`
To *common.Address `json:"to"`
TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
Value *hexutil.Big `json:"value"`
Type hexutil.Uint64 `json:"type"`
Accesses *types2.AccessList `json:"accessList,omitempty"`
ChainID *hexutil.Big `json:"chainId,omitempty"`
V *hexutil.Big `json:"v"`
R *hexutil.Big `json:"r"`
S *hexutil.Big `json:"s"`
}
// // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
// type RPCTransaction struct {
// BlockHash *common.Hash `json:"blockHash"`
// BlockNumber *hexutil.Big `json:"blockNumber"`
// From common.Address `json:"from"`
// Gas hexutil.Uint64 `json:"gas"`
// GasPrice *hexutil.Big `json:"gasPrice,omitempty"`
// Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
// FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
// Hash common.Hash `json:"hash"`
// Input hexutility.Bytes `json:"input"`
// Nonce hexutil.Uint64 `json:"nonce"`
// To *common.Address `json:"to"`
// TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
// Value *hexutil.Big `json:"value"`
// Type hexutil.Uint64 `json:"type"`
// Accesses *types2.AccessList `json:"accessList,omitempty"`
// ChainID *hexutil.Big `json:"chainId,omitempty"`
// V *hexutil.Big `json:"v"`
// R *hexutil.Big `json:"r"`
// S *hexutil.Big `json:"s"`
// }

// newRPCTransaction returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available).
Expand Down
70 changes: 70 additions & 0 deletions cmd/rpcdaemon/commands/eth_api_zkevm.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
package commands

import (
"math/big"

"github.com/gateway-fm/cdk-erigon-lib/common"
"github.com/gateway-fm/cdk-erigon-lib/common/hexutility"
types2 "github.com/gateway-fm/cdk-erigon-lib/types"
"github.com/ledgerwatch/erigon/chain"
"github.com/ledgerwatch/erigon/common/hexutil"
"github.com/ledgerwatch/erigon/consensus/misc"
"github.com/ledgerwatch/erigon/core/types"
zktx "github.com/ledgerwatch/erigon/zk/tx"
)

func (api *BaseAPI) SetL2RpcUrl(url string) {
api.l2RpcUrl = url
}
Expand All @@ -10,3 +23,60 @@ func (api *BaseAPI) GetL2RpcUrl() string {
}
return api.l2RpcUrl
}

// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
type RPCTransaction struct {
BlockHash *common.Hash `json:"blockHash"`
BlockNumber *hexutil.Big `json:"blockNumber"`
From common.Address `json:"from"`
Gas hexutil.Uint64 `json:"gas"`
GasPrice *hexutil.Big `json:"gasPrice,omitempty"`
Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
Hash common.Hash `json:"hash"`
Input hexutility.Bytes `json:"input"`
Nonce hexutil.Uint64 `json:"nonce"`
To *common.Address `json:"to"`
TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
Value *hexutil.Big `json:"value"`
Type hexutil.Uint64 `json:"type"`
Accesses *types2.AccessList `json:"accessList,omitempty"`
ChainID *hexutil.Big `json:"chainId,omitempty"`
V *hexutil.Big `json:"v"`
R *hexutil.Big `json:"r"`
S *hexutil.Big `json:"s"`
L2Hash *common.Hash `json:"l2Hash,omitempty"`
}

// newRPCTransaction returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available).
func newRPCTransaction_zkevm(tx types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int, includeL2TxHash bool) *RPCTransaction {
result := newRPCTransaction(tx, blockHash, blockNumber, index, baseFee)

if includeL2TxHash {
l2TxHash, err := zktx.ComputeL2TxHash(
tx.GetChainID().ToBig(),
tx.GetValue(),
tx.GetPrice(),
tx.GetNonce(),
tx.GetGas(),
tx.GetTo(),
&result.From,
tx.GetData(),
)
if err == nil {
result.L2Hash = &l2TxHash
}
}

return result
}

// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
func newRPCPendingTransaction_zkevm(tx types.Transaction, current *types.Header, config *chain.Config, includeL2TxHash bool) *RPCTransaction {
var baseFee *big.Int
if current != nil {
baseFee = misc.CalcBaseFeeZk(config, current)
}
return newRPCTransaction_zkevm(tx, common.Hash{}, 0, 0, baseFee, includeL2TxHash)
}
8 changes: 4 additions & 4 deletions cmd/rpcdaemon/commands/eth_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"github.com/ledgerwatch/erigon/turbo/transactions"
)

func (api *APIImpl) CallBundle_deprecated(ctx context.Context, txHashes []common.Hash, stateBlockNumberOrHash rpc.BlockNumberOrHash, timeoutMilliSecondsPtr *int64) (map[string]interface{}, error) {
func (api *APIImpl) deprecated_CallBundle(ctx context.Context, txHashes []common.Hash, stateBlockNumberOrHash rpc.BlockNumberOrHash, timeoutMilliSecondsPtr *int64) (map[string]interface{}, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -197,7 +197,7 @@ func (api *APIImpl) CallBundle_deprecated(ctx context.Context, txHashes []common
}

// GetBlockByNumber implements eth_getBlockByNumber. Returns information about a block given the block's number.
func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
func (api *APIImpl) GetBlockByNumber_deprecated(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -255,15 +255,15 @@ func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber
}

// GetBlockByHash implements eth_getBlockByHash. Returns information about a block given the block's hash.
func (api *APIImpl) GetBlockByHash(ctx context.Context, numberOrHash rpc.BlockNumberOrHash, fullTx bool) (map[string]interface{}, error) {
func (api *APIImpl) GetBlockByHash_deprecated(ctx context.Context, numberOrHash rpc.BlockNumberOrHash, fullTx bool) (map[string]interface{}, error) {
if numberOrHash.BlockHash == nil {
// some web3.js based apps (like ethstats client) for some reason call
// eth_getBlockByHash with a block number as a parameter
// so no matter how weird that is, we would love to support that.
if numberOrHash.BlockNumber == nil {
return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645
}
return api.GetBlockByNumber(ctx, *numberOrHash.BlockNumber, fullTx)
return api.GetBlockByNumber(ctx, *numberOrHash.BlockNumber, nil)
}

hash := *numberOrHash.BlockHash
Expand Down
132 changes: 132 additions & 0 deletions cmd/rpcdaemon/commands/eth_block_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import (
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/crypto/cryptopool"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
"github.com/ledgerwatch/erigon/rpc"
"github.com/ledgerwatch/erigon/turbo/adapter/ethapi"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/turbo/transactions"
"github.com/ledgerwatch/erigon/zk/hermez_db"
Expand Down Expand Up @@ -199,3 +201,133 @@ func (api *APIImpl) CallBundle(ctx context.Context, txHashes []common.Hash, stat
ret["bundleHash"] = hexutility.Encode(bundleHash.Sum(nil))
return ret, nil
}

// GetBlockByNumber implements eth_getBlockByNumber. Returns information about a block given the block's number.
func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx *bool) (map[string]interface{}, error) {
if fullTx == nil {
fullTx = new(bool)
}

tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()

// get latest executed block
executedBlock, err := stages.GetStageProgress(tx, stages.Execution)
if err != nil {
return nil, err
}

// return null if requested block is higher than executed
// made for consistency with zkevm
if number > 0 && executedBlock < uint64(number.Int64()) {
return nil, nil
}

b, err := api.blockByNumber(ctx, number, tx)
if err != nil {
return nil, err
}
if b == nil {
return nil, nil
}
additionalFields := make(map[string]interface{})
td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64())
if err != nil {
return nil, err
}

additionalFields["totalDifficulty"] = getTdField(td)

_, err = api.chainConfig(tx)
if err != nil {
return nil, err
}
var borTx types.Transaction
var borTxHash common.Hash
//if chainConfig.Bor != nil {
// borTx, _, _, _ = rawdb.ReadBorTransactionForBlock(tx, b)
// if borTx != nil {
// borTxHash = types.ComputeBorTxHash(b.NumberU64(), b.Hash())
// }
//}

response, err := ethapi.RPCMarshalBlockEx(b, true, *fullTx, borTx, borTxHash, additionalFields)
if err == nil && number == rpc.PendingBlockNumber {
// Pending blocks need to nil out a few fields
for _, field := range []string{"hash", "nonce", "miner"} {
response[field] = nil
}
}
return response, err
}

// GetBlockByHash implements eth_getBlockByHash. Returns information about a block given the block's hash.
func (api *APIImpl) GetBlockByHash(ctx context.Context, numberOrHash rpc.BlockNumberOrHash, fullTx *bool) (map[string]interface{}, error) {
if fullTx == nil {
fullTx = new(bool)
}

if numberOrHash.BlockHash == nil {
// some web3.js based apps (like ethstats client) for some reason call
// eth_getBlockByHash with a block number as a parameter
// so no matter how weird that is, we would love to support that.
if numberOrHash.BlockNumber == nil {
return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645
}
return api.GetBlockByNumber(ctx, *numberOrHash.BlockNumber, fullTx)
}

hash := *numberOrHash.BlockHash
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()

additionalFields := make(map[string]interface{})

block, err := api.blockByHashWithSenders(tx, hash)
if err != nil {
return nil, err
}
if block == nil {
return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645
}
number := block.NumberU64()

td, err := rawdb.ReadTd(tx, hash, number)
if err != nil {
return nil, err
}
additionalFields["totalDifficulty"] = getTdField(td)

chainConfig, err := api.chainConfig(tx)
if err != nil {
return nil, err
}
var borTx types.Transaction
var borTxHash common.Hash
if chainConfig.Bor != nil {
borTx, _, _, _ = rawdb.ReadBorTransactionForBlock(tx, block)
if borTx != nil {
borTxHash = types.ComputeBorTxHash(block.NumberU64(), block.Hash())
}
}

response, err := ethapi.RPCMarshalBlockEx(block, true, *fullTx, borTx, borTxHash, additionalFields)

if chainConfig.Bor != nil {
response["miner"], _ = ecrecover(block.Header(), chainConfig.Bor)
}

if err == nil && int64(number) == rpc.PendingBlockNumber.Int64() {
// Pending blocks need to nil out a few fields
for _, field := range []string{"hash", "nonce", "miner"} {
response[field] = nil
}
}
return response, err
}
9 changes: 5 additions & 4 deletions cmd/rpcdaemon/commands/eth_txs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
)

// GetTransactionByHash implements eth_getTransactionByHash. Returns information about a transaction given the transaction's hash.
func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Hash) (interface{}, error) {
func (api *APIImpl) GetTransactionByHash_deprecated(ctx context.Context, txnHash common.Hash) (interface{}, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
Expand All @@ -37,6 +37,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Has
if err != nil {
return nil, err
}

// Private API returns 0 if transaction is not found.
if blockNum == 0 && chainConfig.Bor != nil {
blockNumPtr, err := rawdb.ReadBorTxLookupEntry(tx, txnHash)
Expand Down Expand Up @@ -91,7 +92,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Has

if !sequencer.IsSequencer() {
// forward the request on to the sequencer at this point as it is the only node with an active txpool
return api.forwardGetTransactionByHash(api.l2RpcUrl, txnHash)
return api.forwardGetTransactionByHash(api.l2RpcUrl, txnHash, nil)
}

curHeader := rawdb.ReadCurrentHeader(tx)
Expand Down Expand Up @@ -172,7 +173,7 @@ func (api *APIImpl) GetRawTransactionByHash(ctx context.Context, hash common.Has
}

// GetTransactionByBlockHashAndIndex implements eth_getTransactionByBlockHashAndIndex. Returns information about a transaction given the block's hash and a transaction index.
func (api *APIImpl) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, txIndex hexutil.Uint64) (*RPCTransaction, error) {
func (api *APIImpl) GetTransactionByBlockHashAndIndex_deprecated(ctx context.Context, blockHash common.Hash, txIndex hexutil.Uint64) (*RPCTransaction, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -231,7 +232,7 @@ func (api *APIImpl) GetRawTransactionByBlockHashAndIndex(ctx context.Context, bl
}

// GetTransactionByBlockNumberAndIndex implements eth_getTransactionByBlockNumberAndIndex. Returns information about a transaction given a block number and transaction index.
func (api *APIImpl) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, txIndex hexutil.Uint) (*RPCTransaction, error) {
func (api *APIImpl) GetTransactionByBlockNumberAndIndex_deprecated(ctx context.Context, blockNr rpc.BlockNumber, txIndex hexutil.Uint) (*RPCTransaction, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
Expand Down
Loading
Loading