From 7fce1013943b700d5635a20ddba85bdd21139b84 Mon Sep 17 00:00:00 2001 From: vahoo5 Date: Tue, 29 Aug 2023 13:20:12 +0200 Subject: [PATCH] f --- ethclient/ethclient.go | 11 ++++++ internal/ethapi/api.go | 76 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 4508027fa4..bb5c133d95 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -670,3 +670,14 @@ func (p *rpcProgress) toSyncProgress() *ethereum.SyncProgress { HealingBytecode: uint64(p.HealingBytecode), } } + +func (ec *Client) GetBlockReceipts(ctx context.Context, txHash common.Hash) (types.Receipts, error) { + var r types.Receipts + err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", txHash) + if err == nil { + if r == nil { + return nil, ethereum.NotFound + } + } + return r, err +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index cd59d21efb..7159ff8e5a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -419,6 +419,82 @@ func (s *BundleAPI) SearchMaxWallet(ctx context.Context, args MaxWalletSearchArg return lastResult, nil } +type PackedReceipt map[string]interface{} +type ReceiptsPackage struct { + Receipts []PackedReceipt +} + +func (s *TransactionAPI) GetBlockReceipts(ctx context.Context, blocks_hash common.Hash) (ReceiptsPackage, error) { + var output ReceiptsPackage + receipts, err := s.b.GetReceipts(ctx, blocks_hash) + if err != nil { + return output, err + } + header, err := s.b.HeaderByHash(ctx, blocks_hash) + if err != nil { + return output, err + } + if header == nil { + return output, errors.New(fmt.Sprintf(("Header not found for provided block hash"))) + } + output.Receipts = make([]PackedReceipt, 0, 512) + for i := 0; i < len(receipts); i++ { + // note: the body of this loop was copied from GetTransactionReceipt() function + receipt := receipts[i] + tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, receipt.TxHash) + if err != nil { + return output, err + } + if tx == nil { + return output, errors.New("Transaction not present in database") + } + if uint(len(receipts)) <= receipt.TransactionIndex { + return output, errors.New(fmt.Sprintf("Transaction index overflow for receipt %v\n", i)) + } + // Derive the sender. + bigblock := new(big.Int).SetUint64(blockNumber) + signer := types.MakeSigner(s.b.ChainConfig(), bigblock, header.Time) + from, _ := types.Sender(signer, tx) + + fields := map[string]interface{}{ + "blockHash": blockHash, + "blockNumber": hexutil.Uint64(blockNumber), + "transactionHash": receipt.TxHash, + "transactionIndex": hexutil.Uint64(index), + "from": from, + "to": tx.To(), + "gasUsed": hexutil.Uint64(receipt.GasUsed), + "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), + "contractAddress": nil, + "logs": receipt.Logs, + "logsBloom": receipt.Bloom, + "type": hexutil.Uint(tx.Type()), + } + // Assign the effective gas price paid + if !s.b.ChainConfig().IsLondon(bigblock) { + fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) + } else { + gasPrice := new(big.Int).Add(header.BaseFee, tx.EffectiveGasTipValue(header.BaseFee)) + fields["effectiveGasPrice"] = hexutil.Uint64(gasPrice.Uint64()) + } + // Assign receipt status or post state. + if len(receipt.PostState) > 0 { + fields["root"] = hexutil.Bytes(receipt.PostState) + } else { + fields["status"] = hexutil.Uint(receipt.Status) + } + if receipt.Logs == nil { + fields["logs"] = [][]*types.Log{} + } + // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation + if receipt.ContractAddress != (common.Address{}) { + fields["contractAddress"] = receipt.ContractAddress + } + output.Receipts = append(output.Receipts, fields) + } + return output, nil +} + // EthereumAPI provides an API to access Ethereum related information. type EthereumAPI struct { b Backend