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 }