diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 8a85800dd8..1995916d81 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -209,6 +209,12 @@ func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*type return } +// GetReceiptByHash retrieves the receipt by transaction hash +func (bc *BlockChain) GetReceiptByHash(txHash common.Hash) *types.Receipt { + receipt, _, _, _ := rawdb.ReadReceipt(bc.db, txHash, bc.chainConfig) + return receipt +} + // GetReceiptsByHash retrieves the receipts for all transactions in a given block. func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { if receipts, ok := bc.receiptsCache.Get(hash); ok { diff --git a/eth/api_backend.go b/eth/api_backend.go index 8a9898b956..78209415de 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -234,6 +234,10 @@ func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockN return nil, nil, errors.New("invalid arguments; neither block nor hash specified") } +func (b *EthAPIBackend) GetReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return b.eth.blockchain.GetReceiptByHash(txHash), nil +} + func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { return b.eth.blockchain.GetReceiptsByHash(hash), nil } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 013b9f7bc2..fbca4efc2d 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -107,6 +107,11 @@ func (b *testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc. return nil, errors.New("block body not found") } +func (b *testBackend) GetReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + receipt, _, _, _ := rawdb.ReadReceipt(b.db, txHash, params.TestChainConfig) + return receipt, nil +} + func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil { if header := rawdb.ReadHeader(b.db, hash, *number); header != nil { diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index b22e75666f..b1d6839d12 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -99,6 +99,10 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) return b.chain.GetBlockByNumber(uint64(number)), nil } +func (b *testBackend) GetReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return b.chain.GetReceiptByHash(txHash), nil +} + func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { return b.chain.GetReceiptsByHash(hash), nil } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index cf5160caf7..3ea246e864 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -550,6 +550,10 @@ func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOr panic("only implemented for number") } func (b testBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { panic("implement me") } +func (b testBackend) GetReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + receipt, _, _, _ := rawdb.ReadReceipt(b.db, txHash, b.chain.Config()) + return receipt, nil +} func (b testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { header, err := b.HeaderByHash(ctx, hash) if header == nil || err != nil { diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 2a45ba0921..1a97f588fc 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -67,6 +67,7 @@ type Backend interface { StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) Pending() (*types.Block, types.Receipts, *state.StateDB) + GetReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) GetTd(ctx context.Context, hash common.Hash) *big.Int GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 6750fc07a9..8d41bbc610 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -361,6 +361,9 @@ func (b *backendMock) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrO return nil, nil, nil } func (b *backendMock) Pending() (*types.Block, types.Receipts, *state.StateDB) { return nil, nil, nil } +func (b *backendMock) GetReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return nil, nil +} func (b *backendMock) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { return nil, nil }