@@ -337,27 +337,27 @@ func (b *ethAPIBackend) SyncProgress() ethereum.SyncProgress {
337337}
338338
339339func (b * ethAPIBackend ) HeaderByNumber (ctx context.Context , n rpc.BlockNumber ) (* types.Header , error ) {
340- return readByNumber (b , n , rawdb .ReadHeader )
340+ return readByNumber (b , n , neverErrs ( rawdb .ReadHeader ) )
341341}
342342
343343func (b * ethAPIBackend ) BlockByNumber (ctx context.Context , n rpc.BlockNumber ) (* types.Block , error ) {
344- return readByNumber (b , n , rawdb .ReadBlock )
344+ return readByNumber (b , n , neverErrs ( rawdb .ReadBlock ) )
345345}
346346
347347func (b * ethAPIBackend ) HeaderByHash (ctx context.Context , hash common.Hash ) (* types.Header , error ) {
348- return readByHash (b , hash , (* blocks .Block ).Header , rawdb .ReadHeader ), nil
348+ return readByHash (b . vm , hash , (* blocks .Block ).Header , neverErrs ( rawdb .ReadHeader ), nil /* errWhenNotFound */ )
349349}
350350
351351func (b * ethAPIBackend ) BlockByHash (ctx context.Context , hash common.Hash ) (* types.Block , error ) {
352- return readByHash (b , hash , (* blocks .Block ).EthBlock , rawdb .ReadBlock ), nil
352+ return readByHash (b . vm , hash , (* blocks .Block ).EthBlock , neverErrs ( rawdb .ReadBlock ), nil /* errWhenNotFound */ )
353353}
354354
355355func (b * ethAPIBackend ) HeaderByNumberOrHash (ctx context.Context , blockNrOrHash rpc.BlockNumberOrHash ) (* types.Header , error ) {
356- return readByNumberOrHash (b , blockNrOrHash , (* blocks .Block ).Header , rawdb .ReadHeader )
356+ return readByNumberOrHash (b , blockNrOrHash , (* blocks .Block ).Header , neverErrs ( rawdb .ReadHeader ) )
357357}
358358
359359func (b * ethAPIBackend ) BlockByNumberOrHash (ctx context.Context , blockNrOrHash rpc.BlockNumberOrHash ) (* types.Block , error ) {
360- return readByNumberOrHash (b , blockNrOrHash , (* blocks .Block ).EthBlock , rawdb .ReadBlock )
360+ return readByNumberOrHash (b , blockNrOrHash , (* blocks .Block ).EthBlock , neverErrs ( rawdb .ReadBlock ) )
361361}
362362
363363func (b * ethAPIBackend ) GetTransaction (ctx context.Context , txHash common.Hash ) (exists bool , tx * types.Transaction , blockHash common.Hash , blockNumber uint64 , index uint64 , err error ) {
@@ -415,29 +415,43 @@ func (b *ethAPIBackend) GetPoolTransactions() (types.Transactions, error) {
415415}
416416
417417type (
418- canonicalReader [T any ] func (ethdb.Reader , common.Hash , uint64 ) * T
418+ canonicalReader [T any ] func (ethdb.Reader , common.Hash , uint64 ) ( * T , error )
419419 blockAccessor [T any ] func (* blocks.Block ) * T
420420)
421421
422+ func neverErrs [T any ](fn func (ethdb.Reader , common.Hash , uint64 ) * T ) canonicalReader [T ] {
423+ return func (r ethdb.Reader , h common.Hash , n uint64 ) (* T , error ) {
424+ return fn (r , h , n ), nil
425+ }
426+ }
427+
422428func readByNumber [T any ](b * ethAPIBackend , n rpc.BlockNumber , read canonicalReader [T ]) (* T , error ) {
423429 num , err := b .resolveBlockNumber (n )
424430 if errors .Is (err , errFutureBlockNotResolved ) {
425431 return nil , nil
426432 } else if err != nil {
427433 return nil , err
428434 }
429- return read (b .vm .db , rawdb .ReadCanonicalHash (b .vm .db , num ), num ), nil
435+ return read (b .vm .db , rawdb .ReadCanonicalHash (b .vm .db , num ), num )
430436}
431437
432- func readByHash [T any ](b * ethAPIBackend , hash common.Hash , fromMem blockAccessor [T ], fromDB canonicalReader [T ]) * T {
433- if blk , ok := b .vm .blocks .Load (hash ); ok {
434- return fromMem (blk )
438+ // readByHash returns `fromMem(b)` if a block with the specified hash is in the
439+ // VM's memory, otherwise it returns `fromDB()` i.f.f. the block was previously
440+ // accepted. If `fromDB()` is called then the block is guaranteed to exist if
441+ // read with [rawdb] functions.
442+ //
443+ // A hash that is in neither of the VM's memory nor the database will result in
444+ // a return of `(nil, errWhenNotFound)` to allow for usage with the [rawdb]
445+ // pattern of returning `(nil, nil)`.
446+ func readByHash [T any ](vm * VM , hash common.Hash , fromMem blockAccessor [T ], fromDB canonicalReader [T ], errWhenNotFound error ) (* T , error ) {
447+ if blk , ok := vm .blocks .Load (hash ); ok {
448+ return fromMem (blk ), nil
435449 }
436- num := rawdb .ReadHeaderNumber (b . vm .db , hash )
450+ num := rawdb .ReadHeaderNumber (vm .db , hash )
437451 if num == nil {
438- return nil
452+ return nil , errWhenNotFound
439453 }
440- return fromDB (b . vm .db , hash , * num )
454+ return fromDB (vm .db , hash , * num )
441455}
442456
443457// TODO(arr4n) DRY [readByHash] and [readByNumberOrHash]
@@ -450,7 +464,7 @@ func readByNumberOrHash[T any](b *ethAPIBackend, blockNrOrHash rpc.BlockNumberOr
450464 if blk , ok := b .vm .blocks .Load (hash ); ok {
451465 return fromMem (blk ), nil
452466 }
453- return fromDB (b .vm .db , hash , n ), nil
467+ return fromDB (b .vm .db , hash , n )
454468}
455469
456470var (
0 commit comments