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

     1  package protocol
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/onflow/flow/protobuf/go/flow/access"
     7  	"github.com/onflow/flow/protobuf/go/flow/entities"
     8  
     9  	"github.com/onflow/flow-go/consensus/hotstuff"
    10  	"github.com/onflow/flow-go/consensus/hotstuff/signature"
    11  	"github.com/onflow/flow-go/engine/common/rpc/convert"
    12  	"github.com/onflow/flow-go/model/flow"
    13  )
    14  
    15  type Handler struct {
    16  	api                  API
    17  	signerIndicesDecoder hotstuff.BlockSignerDecoder
    18  }
    19  
    20  // HandlerOption is used to hand over optional constructor parameters
    21  type HandlerOption func(*Handler)
    22  
    23  func NewHandler(api API, options ...HandlerOption) *Handler {
    24  	h := &Handler{
    25  		api:                  api,
    26  		signerIndicesDecoder: &signature.NoopBlockSignerDecoder{},
    27  	}
    28  	for _, opt := range options {
    29  		opt(h)
    30  	}
    31  	return h
    32  }
    33  
    34  func WithBlockSignerDecoder(signerIndicesDecoder hotstuff.BlockSignerDecoder) func(*Handler) {
    35  	return func(handler *Handler) {
    36  		handler.signerIndicesDecoder = signerIndicesDecoder
    37  	}
    38  }
    39  
    40  func (h *Handler) GetNetworkParameters(
    41  	ctx context.Context,
    42  	_ *access.GetNetworkParametersRequest,
    43  ) (*access.GetNetworkParametersResponse, error) {
    44  	params := h.api.GetNetworkParameters(ctx)
    45  
    46  	return &access.GetNetworkParametersResponse{
    47  		ChainId: string(params.ChainID),
    48  	}, nil
    49  }
    50  
    51  func (h *Handler) GetNodeVersionInfo(
    52  	ctx context.Context,
    53  	request *access.GetNodeVersionInfoRequest,
    54  ) (*access.GetNodeVersionInfoResponse, error) {
    55  	nodeVersionInfo, err := h.api.GetNodeVersionInfo(ctx)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	return &access.GetNodeVersionInfoResponse{
    61  		Info: &entities.NodeVersionInfo{
    62  			Semver:          nodeVersionInfo.Semver,
    63  			Commit:          nodeVersionInfo.Commit,
    64  			SporkId:         nodeVersionInfo.SporkId[:],
    65  			ProtocolVersion: nodeVersionInfo.ProtocolVersion,
    66  		},
    67  	}, nil
    68  }
    69  
    70  // GetLatestProtocolStateSnapshot returns the latest serializable Snapshot
    71  func (h *Handler) GetLatestProtocolStateSnapshot(ctx context.Context, req *access.GetLatestProtocolStateSnapshotRequest) (*access.ProtocolStateSnapshotResponse, error) {
    72  	snapshot, err := h.api.GetLatestProtocolStateSnapshot(ctx)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	return &access.ProtocolStateSnapshotResponse{
    78  		SerializedSnapshot: snapshot,
    79  	}, nil
    80  }
    81  
    82  // GetProtocolStateSnapshotByBlockID returns serializable Snapshot by blockID
    83  func (h *Handler) GetProtocolStateSnapshotByBlockID(ctx context.Context, req *access.GetProtocolStateSnapshotByBlockIDRequest) (*access.ProtocolStateSnapshotResponse, error) {
    84  	blockID := convert.MessageToIdentifier(req.GetBlockId())
    85  	snapshot, err := h.api.GetProtocolStateSnapshotByBlockID(ctx, blockID)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	return &access.ProtocolStateSnapshotResponse{
    91  		SerializedSnapshot: snapshot,
    92  	}, nil
    93  }
    94  
    95  // GetProtocolStateSnapshotByHeight returns serializable Snapshot by block height
    96  func (h *Handler) GetProtocolStateSnapshotByHeight(ctx context.Context, req *access.GetProtocolStateSnapshotByHeightRequest) (*access.ProtocolStateSnapshotResponse, error) {
    97  	snapshot, err := h.api.GetProtocolStateSnapshotByHeight(ctx, req.GetBlockHeight())
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  
   102  	return &access.ProtocolStateSnapshotResponse{
   103  		SerializedSnapshot: snapshot,
   104  	}, nil
   105  }
   106  
   107  // GetLatestBlockHeader gets the latest sealed block header.
   108  func (h *Handler) GetLatestBlockHeader(
   109  	ctx context.Context,
   110  	req *access.GetLatestBlockHeaderRequest,
   111  ) (*access.BlockHeaderResponse, error) {
   112  	header, err := h.api.GetLatestBlockHeader(ctx, req.GetIsSealed())
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  	return h.blockHeaderResponse(header)
   117  }
   118  
   119  // GetBlockHeaderByHeight gets a block header by height.
   120  func (h *Handler) GetBlockHeaderByHeight(
   121  	ctx context.Context,
   122  	req *access.GetBlockHeaderByHeightRequest,
   123  ) (*access.BlockHeaderResponse, error) {
   124  	header, err := h.api.GetBlockHeaderByHeight(ctx, req.GetHeight())
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  	return h.blockHeaderResponse(header)
   129  }
   130  
   131  // GetBlockHeaderByID gets a block header by ID.
   132  func (h *Handler) GetBlockHeaderByID(
   133  	ctx context.Context,
   134  	req *access.GetBlockHeaderByIDRequest,
   135  ) (*access.BlockHeaderResponse, error) {
   136  	id, err := convert.BlockID(req.GetId())
   137  	if err != nil {
   138  		return nil, err
   139  	}
   140  	header, err := h.api.GetBlockHeaderByID(ctx, id)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  	return h.blockHeaderResponse(header)
   145  }
   146  
   147  // GetLatestBlock gets the latest sealed block.
   148  func (h *Handler) GetLatestBlock(
   149  	ctx context.Context,
   150  	req *access.GetLatestBlockRequest,
   151  ) (*access.BlockResponse, error) {
   152  	block, err := h.api.GetLatestBlock(ctx, req.GetIsSealed())
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  	return h.blockResponse(block, req.GetFullBlockResponse())
   157  }
   158  
   159  // GetBlockByHeight gets a block by height.
   160  func (h *Handler) GetBlockByHeight(
   161  	ctx context.Context,
   162  	req *access.GetBlockByHeightRequest,
   163  ) (*access.BlockResponse, error) {
   164  	block, err := h.api.GetBlockByHeight(ctx, req.GetHeight())
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	return h.blockResponse(block, req.GetFullBlockResponse())
   169  }
   170  
   171  // GetBlockByID gets a block by ID.
   172  func (h *Handler) GetBlockByID(
   173  	ctx context.Context,
   174  	req *access.GetBlockByIDRequest,
   175  ) (*access.BlockResponse, error) {
   176  	id, err := convert.BlockID(req.GetId())
   177  	if err != nil {
   178  		return nil, err
   179  	}
   180  	block, err := h.api.GetBlockByID(ctx, id)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  	return h.blockResponse(block, req.GetFullBlockResponse())
   185  }
   186  
   187  func (h *Handler) blockResponse(block *flow.Block, fullResponse bool) (*access.BlockResponse, error) {
   188  	signerIDs, err := h.signerIndicesDecoder.DecodeSignerIDs(block.Header)
   189  	if err != nil {
   190  		return nil, err // the block was retrieved from local storage - so no errors are expected
   191  	}
   192  
   193  	var msg *entities.Block
   194  	if fullResponse {
   195  		msg, err = convert.BlockToMessage(block, signerIDs)
   196  		if err != nil {
   197  			return nil, err
   198  		}
   199  	} else {
   200  		msg = convert.BlockToMessageLight(block)
   201  	}
   202  	return &access.BlockResponse{
   203  		Block: msg,
   204  	}, nil
   205  }
   206  
   207  func (h *Handler) blockHeaderResponse(header *flow.Header) (*access.BlockHeaderResponse, error) {
   208  	signerIDs, err := h.signerIndicesDecoder.DecodeSignerIDs(header)
   209  	if err != nil {
   210  		return nil, err // the block was retrieved from local storage - so no errors are expected
   211  	}
   212  
   213  	msg, err := convert.BlockHeaderToMessage(header, signerIDs)
   214  	if err != nil {
   215  		return nil, err
   216  	}
   217  
   218  	return &access.BlockHeaderResponse{
   219  		Block: msg,
   220  	}, nil
   221  }