mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 11:41:19 +00:00
f3ce5f8a36
Added initial proof generation tests for polygon reverse flow for devnet Blocks tested, receipts need trie proof clarification
281 lines
8.5 KiB
Go
281 lines
8.5 KiB
Go
package jsonrpc
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"math/big"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/common/hexutil"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/common"
|
|
"github.com/ledgerwatch/erigon-lib/common/hexutility"
|
|
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
|
"github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
|
|
"github.com/ledgerwatch/erigon-lib/gointerfaces/types"
|
|
|
|
"github.com/ledgerwatch/erigon/core/rawdb"
|
|
types2 "github.com/ledgerwatch/erigon/core/types"
|
|
"github.com/ledgerwatch/erigon/rpc"
|
|
"github.com/ledgerwatch/erigon/turbo/rpchelper"
|
|
)
|
|
|
|
// GetTransactionByHash implements eth_getTransactionByHash. Returns information about a transaction given the transaction's hash.
|
|
func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Hash) (*RPCTransaction, error) {
|
|
tx, err := api.db.BeginRo(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
chainConfig, err := api.chainConfig(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByHash
|
|
blockNum, ok, err := api.txnLookup(tx, txnHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Private API returns 0 if transaction is not found.
|
|
if blockNum == 0 && chainConfig.Bor != nil {
|
|
blockNum, ok, err = api._blockReader.EventLookup(ctx, tx, txnHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
if ok {
|
|
block, err := api.blockByNumberWithSenders(tx, blockNum)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if block == nil {
|
|
return nil, nil
|
|
}
|
|
blockHash := block.Hash()
|
|
var txnIndex uint64
|
|
var txn types2.Transaction
|
|
for i, transaction := range block.Transactions() {
|
|
if transaction.Hash() == txnHash {
|
|
txn = transaction
|
|
txnIndex = uint64(i)
|
|
break
|
|
}
|
|
}
|
|
|
|
// Add GasPrice for the DynamicFeeTransaction
|
|
var baseFee *big.Int
|
|
if chainConfig.IsLondon(blockNum) && blockHash != (common.Hash{}) {
|
|
baseFee = block.BaseFee()
|
|
}
|
|
|
|
// if no transaction was found then we return nil
|
|
if txn == nil {
|
|
if chainConfig.Bor == nil {
|
|
return nil, nil
|
|
}
|
|
borTx := types2.NewBorTransaction()
|
|
return newRPCBorTransaction(borTx, txnHash, blockHash, blockNum, uint64(len(block.Transactions())), baseFee, chainConfig.ChainID), nil
|
|
}
|
|
|
|
return NewRPCTransaction(txn, blockHash, blockNum, txnIndex, baseFee), nil
|
|
}
|
|
|
|
curHeader := rawdb.ReadCurrentHeader(tx)
|
|
if curHeader == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// No finalized transaction, try to retrieve it from the pool
|
|
reply, err := api.txPool.Transactions(ctx, &txpool.TransactionsRequest{Hashes: []*types.H256{gointerfaces.ConvertHashToH256(txnHash)}})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(reply.RlpTxs[0]) > 0 {
|
|
txn, err := types2.DecodeWrappedTransaction(reply.RlpTxs[0])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// if no transaction was found in the txpool then we return nil and an error warning that we didn't find the transaction by the hash
|
|
if txn == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
return newRPCPendingTransaction(txn, curHeader, chainConfig), nil
|
|
}
|
|
|
|
// Transaction unknown, return as such
|
|
return nil, nil
|
|
}
|
|
|
|
// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
|
|
func (api *APIImpl) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) {
|
|
tx, err := api.db.BeginRo(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByHash
|
|
blockNum, ok, err := api.txnLookup(tx, hash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !ok {
|
|
return nil, nil
|
|
}
|
|
block, err := api.blockByNumberWithSenders(tx, blockNum)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if block == nil {
|
|
return nil, nil
|
|
}
|
|
var txn types2.Transaction
|
|
for _, transaction := range block.Transactions() {
|
|
if transaction.Hash() == hash {
|
|
txn = transaction
|
|
break
|
|
}
|
|
}
|
|
|
|
if txn != nil {
|
|
var buf bytes.Buffer
|
|
err = txn.MarshalBinary(&buf)
|
|
return buf.Bytes(), err
|
|
}
|
|
|
|
// No finalized transaction, try to retrieve it from the pool
|
|
reply, err := api.txPool.Transactions(ctx, &txpool.TransactionsRequest{Hashes: []*types.H256{gointerfaces.ConvertHashToH256(hash)}})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(reply.RlpTxs[0]) > 0 {
|
|
return reply.RlpTxs[0], nil
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
// 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) {
|
|
tx, err := api.db.BeginRo(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
chainConfig, err := api.chainConfig(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByBlockHashAndIndex
|
|
block, err := api.blockByHashWithSenders(tx, blockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if block == nil {
|
|
return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645
|
|
}
|
|
|
|
txs := block.Transactions()
|
|
if uint64(txIndex) > uint64(len(txs)) {
|
|
return nil, nil // not error
|
|
} else if uint64(txIndex) == uint64(len(txs)) {
|
|
if chainConfig.Bor == nil {
|
|
return nil, nil // not error
|
|
}
|
|
borTx := rawdb.ReadBorTransactionForBlock(tx, block.NumberU64())
|
|
if borTx == nil {
|
|
return nil, nil // not error
|
|
}
|
|
derivedBorTxHash := types2.ComputeBorTxHash(block.NumberU64(), block.Hash())
|
|
return newRPCBorTransaction(borTx, derivedBorTxHash, block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee(), chainConfig.ChainID), nil
|
|
}
|
|
|
|
return NewRPCTransaction(txs[txIndex], block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil
|
|
}
|
|
|
|
// GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index.
|
|
func (api *APIImpl) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutility.Bytes, error) {
|
|
tx, err := api.db.BeginRo(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
// https://infura.io/docs/ethereum/json-rpc/eth-getRawTransactionByBlockHashAndIndex
|
|
block, err := api.blockByHashWithSenders(tx, blockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if block == nil {
|
|
return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645
|
|
}
|
|
|
|
return newRPCRawTransactionFromBlockIndex(block, uint64(index))
|
|
}
|
|
|
|
// 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) {
|
|
tx, err := api.db.BeginRo(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
chainConfig, err := api.chainConfig(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByBlockNumberAndIndex
|
|
blockNum, hash, _, err := rpchelper.GetBlockNumber(rpc.BlockNumberOrHashWithNumber(blockNr), tx, api.filters)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
block, err := api.blockWithSenders(tx, hash, blockNum)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if block == nil {
|
|
return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645
|
|
}
|
|
|
|
txs := block.Transactions()
|
|
if uint64(txIndex) > uint64(len(txs)) {
|
|
return nil, nil // not error
|
|
} else if uint64(txIndex) == uint64(len(txs)) {
|
|
if chainConfig.Bor == nil {
|
|
return nil, nil // not error
|
|
}
|
|
borTx := rawdb.ReadBorTransactionForBlock(tx, blockNum)
|
|
if borTx == nil {
|
|
return nil, nil
|
|
}
|
|
derivedBorTxHash := types2.ComputeBorTxHash(blockNum, hash)
|
|
return newRPCBorTransaction(borTx, derivedBorTxHash, hash, blockNum, uint64(txIndex), block.BaseFee(), chainConfig.ChainID), nil
|
|
}
|
|
|
|
return NewRPCTransaction(txs[txIndex], hash, blockNum, uint64(txIndex), block.BaseFee()), nil
|
|
}
|
|
|
|
// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index.
|
|
func (api *APIImpl) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutility.Bytes, error) {
|
|
tx, err := api.db.BeginRo(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
// https://infura.io/docs/ethereum/json-rpc/eth-getRawTransactionByBlockNumberAndIndex
|
|
block, err := api.blockByRPCNumber(blockNr, tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if block == nil {
|
|
return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645
|
|
}
|
|
|
|
return newRPCRawTransactionFromBlockIndex(block, uint64(index))
|
|
}
|