github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/protocol/api.go (about)

     1  package protocol
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/onflow/flow-go/access"
     7  	"github.com/onflow/flow-go/engine/common/rpc"
     8  	"github.com/onflow/flow-go/model/flow"
     9  	"github.com/onflow/flow-go/state/protocol"
    10  	"github.com/onflow/flow-go/storage"
    11  )
    12  
    13  type NetworkAPI interface {
    14  	GetNetworkParameters(ctx context.Context) access.NetworkParameters
    15  	GetLatestProtocolStateSnapshot(ctx context.Context) ([]byte, error)
    16  	GetProtocolStateSnapshotByBlockID(ctx context.Context, blockID flow.Identifier) ([]byte, error)
    17  	GetProtocolStateSnapshotByHeight(ctx context.Context, blockHeight uint64) ([]byte, error)
    18  	GetNodeVersionInfo(ctx context.Context) (*access.NodeVersionInfo, error)
    19  }
    20  
    21  type API interface {
    22  	NetworkAPI
    23  	GetLatestBlockHeader(ctx context.Context, isSealed bool) (*flow.Header, error)
    24  	GetBlockHeaderByID(ctx context.Context, id flow.Identifier) (*flow.Header, error)
    25  	GetBlockHeaderByHeight(ctx context.Context, height uint64) (*flow.Header, error)
    26  	GetLatestBlock(ctx context.Context, isSealed bool) (*flow.Block, error)
    27  	GetBlockByID(ctx context.Context, id flow.Identifier) (*flow.Block, error)
    28  	GetBlockByHeight(ctx context.Context, height uint64) (*flow.Block, error)
    29  }
    30  
    31  type backend struct {
    32  	NetworkAPI
    33  	blocks  storage.Blocks
    34  	headers storage.Headers
    35  	state   protocol.State
    36  }
    37  
    38  func New(
    39  	state protocol.State,
    40  	blocks storage.Blocks,
    41  	headers storage.Headers,
    42  	network NetworkAPI,
    43  ) API {
    44  	return &backend{
    45  		NetworkAPI: network,
    46  		headers:    headers,
    47  		blocks:     blocks,
    48  		state:      state,
    49  	}
    50  }
    51  
    52  func (b *backend) GetLatestBlock(_ context.Context, isSealed bool) (*flow.Block, error) {
    53  	header, err := b.getLatestHeader(isSealed)
    54  	if err != nil {
    55  		err = rpc.ConvertStorageError(err)
    56  		return nil, err
    57  	}
    58  
    59  	block, err := b.blocks.ByID(header.ID())
    60  	if err != nil {
    61  		err = rpc.ConvertStorageError(err)
    62  		return nil, err
    63  	}
    64  
    65  	return block, nil
    66  }
    67  
    68  func (b *backend) GetBlockByID(_ context.Context, id flow.Identifier) (*flow.Block, error) {
    69  	block, err := b.blocks.ByID(id)
    70  	if err != nil {
    71  		err = rpc.ConvertStorageError(err)
    72  		return nil, err
    73  	}
    74  
    75  	return block, nil
    76  }
    77  
    78  func (b *backend) GetBlockByHeight(_ context.Context, height uint64) (*flow.Block, error) {
    79  	block, err := b.blocks.ByHeight(height)
    80  	if err != nil {
    81  		err = rpc.ConvertStorageError(err)
    82  		return nil, err
    83  	}
    84  
    85  	return block, nil
    86  }
    87  
    88  func (b *backend) GetLatestBlockHeader(_ context.Context, isSealed bool) (*flow.Header, error) {
    89  	header, err := b.getLatestHeader(isSealed)
    90  	if err != nil {
    91  		err = rpc.ConvertStorageError(err)
    92  		return nil, err
    93  	}
    94  
    95  	return header, nil
    96  }
    97  
    98  func (b *backend) GetBlockHeaderByID(_ context.Context, id flow.Identifier) (*flow.Header, error) {
    99  	header, err := b.headers.ByBlockID(id)
   100  	if err != nil {
   101  		err = rpc.ConvertStorageError(err)
   102  		return nil, err
   103  	}
   104  
   105  	return header, nil
   106  }
   107  
   108  func (b *backend) GetBlockHeaderByHeight(_ context.Context, height uint64) (*flow.Header, error) {
   109  	header, err := b.headers.ByHeight(height)
   110  	if err != nil {
   111  		err = rpc.ConvertStorageError(err)
   112  		return nil, err
   113  	}
   114  
   115  	return header, nil
   116  }
   117  
   118  func (b *backend) getLatestHeader(isSealed bool) (*flow.Header, error) {
   119  	var header *flow.Header
   120  	var err error
   121  
   122  	if isSealed {
   123  		// get the latest seal header from storage
   124  		header, err = b.state.Sealed().Head()
   125  		return header, err
   126  	} else {
   127  		// get the finalized header from state
   128  		header, err = b.state.Final().Head()
   129  		return header, err
   130  	}
   131  }