github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/jobqueue/sealed_header_reader.go (about)

     1  package jobqueue
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/flow-go/module"
     7  	"github.com/onflow/flow-go/state/protocol"
     8  	"github.com/onflow/flow-go/storage"
     9  )
    10  
    11  // SealedBlockHeaderReader provides an abstraction for consumers to read blocks as job.
    12  type SealedBlockHeaderReader struct {
    13  	state   protocol.State
    14  	headers storage.Headers
    15  }
    16  
    17  var _ module.Jobs = (*SealedBlockHeaderReader)(nil)
    18  
    19  // NewSealedBlockHeaderReader creates and returns a SealedBlockHeaderReader.
    20  func NewSealedBlockHeaderReader(state protocol.State, headers storage.Headers) *SealedBlockHeaderReader {
    21  	return &SealedBlockHeaderReader{
    22  		state:   state,
    23  		headers: headers,
    24  	}
    25  }
    26  
    27  // AtIndex returns the block header job at the given index.
    28  // The block header job at an index is just the finalized block header at that index (i.e., height).
    29  // Error returns:
    30  //   - storage.ErrNotFound if the provided index is not sealed
    31  func (r SealedBlockHeaderReader) AtIndex(index uint64) (module.Job, error) {
    32  	sealed, err := r.Head()
    33  	if err != nil {
    34  		return nil, fmt.Errorf("could not get last sealed block height: %w", err)
    35  	}
    36  
    37  	if index > sealed {
    38  		// return not found error to indicate there is no job available at this height
    39  		return nil, fmt.Errorf("block at index %d is not sealed: %w", index, storage.ErrNotFound)
    40  	}
    41  
    42  	header, err := r.headers.ByHeight(index)
    43  	if err != nil {
    44  		return nil, fmt.Errorf("could not get block by height %d: %w", index, err)
    45  	}
    46  
    47  	// the block at height index is sealed
    48  	return BlockHeaderToJob(header), nil
    49  }
    50  
    51  // Head returns the last sealed height as job index.
    52  func (r SealedBlockHeaderReader) Head() (uint64, error) {
    53  	header, err := r.state.Sealed().Head()
    54  	if err != nil {
    55  		return 0, fmt.Errorf("could not get header of last sealed block: %w", err)
    56  	}
    57  
    58  	return header.Height, nil
    59  }