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

fix(interface): fix getTransactionFromBlockIndex and getTransactionCount interfaces #56

Merged
merged 4 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs,
} else {
blockRlp = fmt.Sprintf("0x%x", rlpBytes)
}
if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true); err != nil {
if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true, api.eth.chainDb); err != nil {
blockJSON = map[string]interface{}{"error": err.Error()}
}
results = append(results, &BadBlockArgs{
Expand Down
56 changes: 45 additions & 11 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"strings"
"time"

"github.com/ethereum/go-ethereum/ethdb"

"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi"
Expand Down Expand Up @@ -634,7 +636,7 @@ func (s *PublicBlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context,
}

if len(txs) != len(receipts) {
return nil, fmt.Errorf("txs length doesn't equal to receipts' length", len(txs), len(receipts))
return nil, fmt.Errorf("txs length %d doesn't equal to receipts' length %d", len(txs), len(receipts))
}

txReceipts := make([]map[string]interface{}, 0, len(txs))
Expand Down Expand Up @@ -1294,7 +1296,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
// transaction hashes.
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, db ethdb.Database) (map[string]interface{}, error) {
fields := RPCMarshalHeader(block.Header())
fields["size"] = hexutil.Uint64(block.Size())

Expand All @@ -1304,7 +1306,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]i
}
if fullTx {
formatTx = func(tx *types.Transaction) (interface{}, error) {
return newRPCTransactionFromBlockHash(block, tx.Hash()), nil
return newRPCTransactionFromBlockHash(block, tx.Hash(), db), nil
}
}
txs := block.Transactions()
Expand Down Expand Up @@ -1338,7 +1340,7 @@ func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *type
// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
// a `PublicBlockchainAPI`.
func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
fields, err := RPCMarshalBlock(b, inclTx, fullTx)
fields, err := RPCMarshalBlock(b, inclTx, fullTx, s.b.ChainDb())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1438,8 +1440,18 @@ func newRPCPendingTransaction(tx *types.Transaction, current *types.Header, conf
}

// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction {
func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, db ethdb.Database) *RPCTransaction {
txs := b.Transactions()

borReceipt := rawdb.ReadBorReceipt(db, b.Hash(), b.NumberU64())
if borReceipt != nil {
tx, _, _, _ := rawdb.ReadBorTransaction(db, borReceipt.TxHash)

if tx != nil {
txs = append(txs, tx)
}
}

if index >= uint64(len(txs)) {
return nil
}
Expand All @@ -1457,10 +1469,10 @@ func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.By
}

// newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation.
func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction {
func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash, db ethdb.Database) *RPCTransaction {
for idx, tx := range b.Transactions() {
if tx.Hash() == hash {
return newRPCTransactionFromBlockIndex(b, uint64(idx))
return newRPCTransactionFromBlockIndex(b, uint64(idx), db)
}
}
return nil
Expand Down Expand Up @@ -1580,10 +1592,31 @@ func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransa
return &PublicTransactionPoolAPI{b, nonceLock, signer}
}

// returns block transactions along with state-sync transaction if present
// nolint: unparam
func (api *PublicTransactionPoolAPI) getAllBlockTransactions(ctx context.Context, block *types.Block) (types.Transactions, bool) {
txs := block.Transactions()

stateSyncPresent := false

borReceipt := rawdb.ReadBorReceipt(api.b.ChainDb(), block.Hash(), block.NumberU64())
if borReceipt != nil {
txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash()))
if txHash != (common.Hash{}) {
borTx, _, _, _, _ := api.b.GetBorBlockTransactionWithBlockHash(ctx, txHash, block.Hash())
txs = append(txs, borTx)
stateSyncPresent = true
}
}

return txs, stateSyncPresent
}

// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
n := hexutil.Uint(len(block.Transactions()))
txs, _ := s.getAllBlockTransactions(ctx, block)
n := hexutil.Uint(len(txs))
return &n
}
return nil
Expand All @@ -1592,7 +1625,8 @@ func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.
// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint {
if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil {
n := hexutil.Uint(len(block.Transactions()))
txs, _ := s.getAllBlockTransactions(ctx, block)
n := hexutil.Uint(len(txs))
return &n
}
return nil
Expand All @@ -1601,15 +1635,15 @@ func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Co
// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index))
return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainDb())
}
return nil
}

// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction {
if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index))
return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainDb())
}
return nil
}
Expand Down