github.com/onflow/flow-go@v0.33.17/access/handler.go (about) 1 package access 2 3 import ( 4 "context" 5 6 "google.golang.org/grpc/codes" 7 "google.golang.org/grpc/status" 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 "github.com/onflow/flow-go/module" 14 15 "github.com/onflow/flow/protobuf/go/flow/access" 16 "github.com/onflow/flow/protobuf/go/flow/entities" 17 ) 18 19 type Handler struct { 20 api API 21 chain flow.Chain 22 signerIndicesDecoder hotstuff.BlockSignerDecoder 23 finalizedHeaderCache module.FinalizedHeaderCache 24 me module.Local 25 } 26 27 // HandlerOption is used to hand over optional constructor parameters 28 type HandlerOption func(*Handler) 29 30 var _ access.AccessAPIServer = (*Handler)(nil) 31 32 func NewHandler(api API, chain flow.Chain, finalizedHeader module.FinalizedHeaderCache, me module.Local, options ...HandlerOption) *Handler { 33 h := &Handler{ 34 api: api, 35 chain: chain, 36 finalizedHeaderCache: finalizedHeader, 37 me: me, 38 signerIndicesDecoder: &signature.NoopBlockSignerDecoder{}, 39 } 40 for _, opt := range options { 41 opt(h) 42 } 43 return h 44 } 45 46 // Ping the Access API server for a response. 47 func (h *Handler) Ping(ctx context.Context, _ *access.PingRequest) (*access.PingResponse, error) { 48 err := h.api.Ping(ctx) 49 if err != nil { 50 return nil, err 51 } 52 53 return &access.PingResponse{}, nil 54 } 55 56 // GetNodeVersionInfo gets node version information such as semver, commit, sporkID, protocolVersion, etc 57 func (h *Handler) GetNodeVersionInfo( 58 ctx context.Context, 59 _ *access.GetNodeVersionInfoRequest, 60 ) (*access.GetNodeVersionInfoResponse, error) { 61 nodeVersionInfo, err := h.api.GetNodeVersionInfo(ctx) 62 if err != nil { 63 return nil, err 64 } 65 66 return &access.GetNodeVersionInfoResponse{ 67 Info: &entities.NodeVersionInfo{ 68 Semver: nodeVersionInfo.Semver, 69 Commit: nodeVersionInfo.Commit, 70 SporkId: nodeVersionInfo.SporkId[:], 71 ProtocolVersion: nodeVersionInfo.ProtocolVersion, 72 SporkRootBlockHeight: nodeVersionInfo.SporkRootBlockHeight, 73 NodeRootBlockHeight: nodeVersionInfo.NodeRootBlockHeight, 74 }, 75 }, nil 76 } 77 78 func (h *Handler) GetNetworkParameters( 79 ctx context.Context, 80 _ *access.GetNetworkParametersRequest, 81 ) (*access.GetNetworkParametersResponse, error) { 82 params := h.api.GetNetworkParameters(ctx) 83 84 return &access.GetNetworkParametersResponse{ 85 ChainId: string(params.ChainID), 86 }, nil 87 } 88 89 // GetLatestBlockHeader gets the latest sealed block header. 90 func (h *Handler) GetLatestBlockHeader( 91 ctx context.Context, 92 req *access.GetLatestBlockHeaderRequest, 93 ) (*access.BlockHeaderResponse, error) { 94 header, status, err := h.api.GetLatestBlockHeader(ctx, req.GetIsSealed()) 95 if err != nil { 96 return nil, err 97 } 98 return h.blockHeaderResponse(header, status) 99 } 100 101 // GetBlockHeaderByHeight gets a block header by height. 102 func (h *Handler) GetBlockHeaderByHeight( 103 ctx context.Context, 104 req *access.GetBlockHeaderByHeightRequest, 105 ) (*access.BlockHeaderResponse, error) { 106 header, status, err := h.api.GetBlockHeaderByHeight(ctx, req.GetHeight()) 107 if err != nil { 108 return nil, err 109 } 110 return h.blockHeaderResponse(header, status) 111 } 112 113 // GetBlockHeaderByID gets a block header by ID. 114 func (h *Handler) GetBlockHeaderByID( 115 ctx context.Context, 116 req *access.GetBlockHeaderByIDRequest, 117 ) (*access.BlockHeaderResponse, error) { 118 id, err := convert.BlockID(req.GetId()) 119 if err != nil { 120 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 121 } 122 header, status, err := h.api.GetBlockHeaderByID(ctx, id) 123 if err != nil { 124 return nil, err 125 } 126 return h.blockHeaderResponse(header, status) 127 } 128 129 // GetLatestBlock gets the latest sealed block. 130 func (h *Handler) GetLatestBlock( 131 ctx context.Context, 132 req *access.GetLatestBlockRequest, 133 ) (*access.BlockResponse, error) { 134 block, status, err := h.api.GetLatestBlock(ctx, req.GetIsSealed()) 135 if err != nil { 136 return nil, err 137 } 138 return h.blockResponse(block, req.GetFullBlockResponse(), status) 139 } 140 141 // GetBlockByHeight gets a block by height. 142 func (h *Handler) GetBlockByHeight( 143 ctx context.Context, 144 req *access.GetBlockByHeightRequest, 145 ) (*access.BlockResponse, error) { 146 block, status, err := h.api.GetBlockByHeight(ctx, req.GetHeight()) 147 if err != nil { 148 return nil, err 149 } 150 return h.blockResponse(block, req.GetFullBlockResponse(), status) 151 } 152 153 // GetBlockByID gets a block by ID. 154 func (h *Handler) GetBlockByID( 155 ctx context.Context, 156 req *access.GetBlockByIDRequest, 157 ) (*access.BlockResponse, error) { 158 id, err := convert.BlockID(req.GetId()) 159 if err != nil { 160 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 161 } 162 block, status, err := h.api.GetBlockByID(ctx, id) 163 if err != nil { 164 return nil, err 165 } 166 return h.blockResponse(block, req.GetFullBlockResponse(), status) 167 } 168 169 // GetCollectionByID gets a collection by ID. 170 func (h *Handler) GetCollectionByID( 171 ctx context.Context, 172 req *access.GetCollectionByIDRequest, 173 ) (*access.CollectionResponse, error) { 174 metadata := h.buildMetadataResponse() 175 176 id, err := convert.CollectionID(req.GetId()) 177 if err != nil { 178 return nil, status.Errorf(codes.InvalidArgument, "invalid collection id: %v", err) 179 } 180 181 col, err := h.api.GetCollectionByID(ctx, id) 182 if err != nil { 183 return nil, err 184 } 185 186 colMsg, err := convert.LightCollectionToMessage(col) 187 if err != nil { 188 return nil, status.Error(codes.Internal, err.Error()) 189 } 190 191 return &access.CollectionResponse{ 192 Collection: colMsg, 193 Metadata: metadata, 194 }, nil 195 } 196 197 // SendTransaction submits a transaction to the network. 198 func (h *Handler) SendTransaction( 199 ctx context.Context, 200 req *access.SendTransactionRequest, 201 ) (*access.SendTransactionResponse, error) { 202 metadata := h.buildMetadataResponse() 203 204 txMsg := req.GetTransaction() 205 206 tx, err := convert.MessageToTransaction(txMsg, h.chain) 207 if err != nil { 208 return nil, status.Error(codes.InvalidArgument, err.Error()) 209 } 210 211 err = h.api.SendTransaction(ctx, &tx) 212 if err != nil { 213 return nil, err 214 } 215 216 txID := tx.ID() 217 218 return &access.SendTransactionResponse{ 219 Id: txID[:], 220 Metadata: metadata, 221 }, nil 222 } 223 224 // GetTransaction gets a transaction by ID. 225 func (h *Handler) GetTransaction( 226 ctx context.Context, 227 req *access.GetTransactionRequest, 228 ) (*access.TransactionResponse, error) { 229 metadata := h.buildMetadataResponse() 230 231 id, err := convert.TransactionID(req.GetId()) 232 if err != nil { 233 return nil, status.Errorf(codes.InvalidArgument, "invalid transaction id: %v", err) 234 } 235 236 tx, err := h.api.GetTransaction(ctx, id) 237 if err != nil { 238 return nil, err 239 } 240 241 return &access.TransactionResponse{ 242 Transaction: convert.TransactionToMessage(*tx), 243 Metadata: metadata, 244 }, nil 245 } 246 247 // GetTransactionResult gets a transaction by ID. 248 func (h *Handler) GetTransactionResult( 249 ctx context.Context, 250 req *access.GetTransactionRequest, 251 ) (*access.TransactionResultResponse, error) { 252 metadata := h.buildMetadataResponse() 253 254 transactionID, err := convert.TransactionID(req.GetId()) 255 if err != nil { 256 return nil, status.Errorf(codes.InvalidArgument, "invalid transaction id: %v", err) 257 } 258 259 blockId := flow.ZeroID 260 requestBlockId := req.GetBlockId() 261 if requestBlockId != nil { 262 blockId, err = convert.BlockID(requestBlockId) 263 if err != nil { 264 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 265 } 266 } 267 268 collectionId := flow.ZeroID 269 requestCollectionId := req.GetCollectionId() 270 if requestCollectionId != nil { 271 collectionId, err = convert.CollectionID(requestCollectionId) 272 if err != nil { 273 return nil, status.Errorf(codes.InvalidArgument, "invalid collection id: %v", err) 274 } 275 } 276 277 eventEncodingVersion := req.GetEventEncodingVersion() 278 result, err := h.api.GetTransactionResult(ctx, transactionID, blockId, collectionId, eventEncodingVersion) 279 if err != nil { 280 return nil, err 281 } 282 283 message := TransactionResultToMessage(result) 284 message.Metadata = metadata 285 286 return message, nil 287 } 288 289 func (h *Handler) GetTransactionResultsByBlockID( 290 ctx context.Context, 291 req *access.GetTransactionsByBlockIDRequest, 292 ) (*access.TransactionResultsResponse, error) { 293 metadata := h.buildMetadataResponse() 294 295 id, err := convert.BlockID(req.GetBlockId()) 296 if err != nil { 297 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 298 } 299 300 eventEncodingVersion := req.GetEventEncodingVersion() 301 302 results, err := h.api.GetTransactionResultsByBlockID(ctx, id, eventEncodingVersion) 303 if err != nil { 304 return nil, err 305 } 306 307 message := TransactionResultsToMessage(results) 308 message.Metadata = metadata 309 310 return message, nil 311 } 312 313 func (h *Handler) GetSystemTransaction( 314 ctx context.Context, 315 req *access.GetSystemTransactionRequest, 316 ) (*access.TransactionResponse, error) { 317 metadata := h.buildMetadataResponse() 318 319 id, err := convert.BlockID(req.GetBlockId()) 320 if err != nil { 321 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 322 } 323 324 tx, err := h.api.GetSystemTransaction(ctx, id) 325 if err != nil { 326 return nil, err 327 } 328 329 return &access.TransactionResponse{ 330 Transaction: convert.TransactionToMessage(*tx), 331 Metadata: metadata, 332 }, nil 333 } 334 335 func (h *Handler) GetSystemTransactionResult( 336 ctx context.Context, 337 req *access.GetSystemTransactionResultRequest, 338 ) (*access.TransactionResultResponse, error) { 339 metadata := h.buildMetadataResponse() 340 341 id, err := convert.BlockID(req.GetBlockId()) 342 if err != nil { 343 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 344 } 345 346 result, err := h.api.GetSystemTransactionResult(ctx, id, req.GetEventEncodingVersion()) 347 if err != nil { 348 return nil, err 349 } 350 351 message := TransactionResultToMessage(result) 352 message.Metadata = metadata 353 354 return message, nil 355 } 356 357 func (h *Handler) GetTransactionsByBlockID( 358 ctx context.Context, 359 req *access.GetTransactionsByBlockIDRequest, 360 ) (*access.TransactionsResponse, error) { 361 metadata := h.buildMetadataResponse() 362 363 id, err := convert.BlockID(req.GetBlockId()) 364 if err != nil { 365 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 366 } 367 368 transactions, err := h.api.GetTransactionsByBlockID(ctx, id) 369 if err != nil { 370 return nil, err 371 } 372 373 return &access.TransactionsResponse{ 374 Transactions: convert.TransactionsToMessages(transactions), 375 Metadata: metadata, 376 }, nil 377 } 378 379 // GetTransactionResultByIndex gets a transaction at a specific index for in a block that is executed, 380 // pending or finalized transactions return errors 381 func (h *Handler) GetTransactionResultByIndex( 382 ctx context.Context, 383 req *access.GetTransactionByIndexRequest, 384 ) (*access.TransactionResultResponse, error) { 385 metadata := h.buildMetadataResponse() 386 387 blockID, err := convert.BlockID(req.GetBlockId()) 388 if err != nil { 389 return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err) 390 } 391 392 eventEncodingVersion := req.GetEventEncodingVersion() 393 394 result, err := h.api.GetTransactionResultByIndex(ctx, blockID, req.GetIndex(), eventEncodingVersion) 395 if err != nil { 396 return nil, err 397 } 398 399 message := TransactionResultToMessage(result) 400 message.Metadata = metadata 401 402 return message, nil 403 } 404 405 // GetAccount returns an account by address at the latest sealed block. 406 func (h *Handler) GetAccount( 407 ctx context.Context, 408 req *access.GetAccountRequest, 409 ) (*access.GetAccountResponse, error) { 410 metadata := h.buildMetadataResponse() 411 412 address, err := convert.Address(req.GetAddress(), h.chain) 413 if err != nil { 414 return nil, status.Errorf(codes.InvalidArgument, "invalid address: %v", err) 415 } 416 417 account, err := h.api.GetAccount(ctx, address) 418 if err != nil { 419 return nil, err 420 } 421 422 accountMsg, err := convert.AccountToMessage(account) 423 if err != nil { 424 return nil, status.Error(codes.Internal, err.Error()) 425 } 426 427 return &access.GetAccountResponse{ 428 Account: accountMsg, 429 Metadata: metadata, 430 }, nil 431 } 432 433 // GetAccountAtLatestBlock returns an account by address at the latest sealed block. 434 func (h *Handler) GetAccountAtLatestBlock( 435 ctx context.Context, 436 req *access.GetAccountAtLatestBlockRequest, 437 ) (*access.AccountResponse, error) { 438 metadata := h.buildMetadataResponse() 439 440 address, err := convert.Address(req.GetAddress(), h.chain) 441 if err != nil { 442 return nil, status.Errorf(codes.InvalidArgument, "invalid address: %v", err) 443 } 444 445 account, err := h.api.GetAccountAtLatestBlock(ctx, address) 446 if err != nil { 447 return nil, err 448 } 449 450 accountMsg, err := convert.AccountToMessage(account) 451 if err != nil { 452 return nil, status.Error(codes.Internal, err.Error()) 453 } 454 455 return &access.AccountResponse{ 456 Account: accountMsg, 457 Metadata: metadata, 458 }, nil 459 } 460 461 func (h *Handler) GetAccountAtBlockHeight( 462 ctx context.Context, 463 req *access.GetAccountAtBlockHeightRequest, 464 ) (*access.AccountResponse, error) { 465 metadata := h.buildMetadataResponse() 466 467 address, err := convert.Address(req.GetAddress(), h.chain) 468 if err != nil { 469 return nil, status.Errorf(codes.InvalidArgument, "invalid address: %v", err) 470 } 471 472 account, err := h.api.GetAccountAtBlockHeight(ctx, address, req.GetBlockHeight()) 473 if err != nil { 474 return nil, err 475 } 476 477 accountMsg, err := convert.AccountToMessage(account) 478 if err != nil { 479 return nil, status.Error(codes.Internal, err.Error()) 480 } 481 482 return &access.AccountResponse{ 483 Account: accountMsg, 484 Metadata: metadata, 485 }, nil 486 } 487 488 // ExecuteScriptAtLatestBlock executes a script at a the latest block. 489 func (h *Handler) ExecuteScriptAtLatestBlock( 490 ctx context.Context, 491 req *access.ExecuteScriptAtLatestBlockRequest, 492 ) (*access.ExecuteScriptResponse, error) { 493 metadata := h.buildMetadataResponse() 494 495 script := req.GetScript() 496 arguments := req.GetArguments() 497 498 value, err := h.api.ExecuteScriptAtLatestBlock(ctx, script, arguments) 499 if err != nil { 500 return nil, err 501 } 502 503 return &access.ExecuteScriptResponse{ 504 Value: value, 505 Metadata: metadata, 506 }, nil 507 } 508 509 // ExecuteScriptAtBlockHeight executes a script at a specific block height. 510 func (h *Handler) ExecuteScriptAtBlockHeight( 511 ctx context.Context, 512 req *access.ExecuteScriptAtBlockHeightRequest, 513 ) (*access.ExecuteScriptResponse, error) { 514 metadata := h.buildMetadataResponse() 515 516 script := req.GetScript() 517 arguments := req.GetArguments() 518 blockHeight := req.GetBlockHeight() 519 520 value, err := h.api.ExecuteScriptAtBlockHeight(ctx, blockHeight, script, arguments) 521 if err != nil { 522 return nil, err 523 } 524 525 return &access.ExecuteScriptResponse{ 526 Value: value, 527 Metadata: metadata, 528 }, nil 529 } 530 531 // ExecuteScriptAtBlockID executes a script at a specific block ID. 532 func (h *Handler) ExecuteScriptAtBlockID( 533 ctx context.Context, 534 req *access.ExecuteScriptAtBlockIDRequest, 535 ) (*access.ExecuteScriptResponse, error) { 536 metadata := h.buildMetadataResponse() 537 538 script := req.GetScript() 539 arguments := req.GetArguments() 540 blockID := convert.MessageToIdentifier(req.GetBlockId()) 541 542 value, err := h.api.ExecuteScriptAtBlockID(ctx, blockID, script, arguments) 543 if err != nil { 544 return nil, err 545 } 546 547 return &access.ExecuteScriptResponse{ 548 Value: value, 549 Metadata: metadata, 550 }, nil 551 } 552 553 // GetEventsForHeightRange returns events matching a query. 554 func (h *Handler) GetEventsForHeightRange( 555 ctx context.Context, 556 req *access.GetEventsForHeightRangeRequest, 557 ) (*access.EventsResponse, error) { 558 metadata := h.buildMetadataResponse() 559 560 eventType, err := convert.EventType(req.GetType()) 561 if err != nil { 562 return nil, err 563 } 564 565 startHeight := req.GetStartHeight() 566 endHeight := req.GetEndHeight() 567 568 eventEncodingVersion := req.GetEventEncodingVersion() 569 570 results, err := h.api.GetEventsForHeightRange(ctx, eventType, startHeight, endHeight, eventEncodingVersion) 571 if err != nil { 572 return nil, err 573 } 574 575 resultEvents, err := convert.BlockEventsToMessages(results) 576 if err != nil { 577 return nil, err 578 } 579 return &access.EventsResponse{ 580 Results: resultEvents, 581 Metadata: metadata, 582 }, nil 583 } 584 585 // GetEventsForBlockIDs returns events matching a set of block IDs. 586 func (h *Handler) GetEventsForBlockIDs( 587 ctx context.Context, 588 req *access.GetEventsForBlockIDsRequest, 589 ) (*access.EventsResponse, error) { 590 metadata := h.buildMetadataResponse() 591 592 eventType, err := convert.EventType(req.GetType()) 593 if err != nil { 594 return nil, err 595 } 596 597 blockIDs, err := convert.BlockIDs(req.GetBlockIds()) 598 if err != nil { 599 return nil, err 600 } 601 602 eventEncodingVersion := req.GetEventEncodingVersion() 603 604 results, err := h.api.GetEventsForBlockIDs(ctx, eventType, blockIDs, eventEncodingVersion) 605 if err != nil { 606 return nil, err 607 } 608 609 resultEvents, err := convert.BlockEventsToMessages(results) 610 if err != nil { 611 return nil, err 612 } 613 614 return &access.EventsResponse{ 615 Results: resultEvents, 616 Metadata: metadata, 617 }, nil 618 } 619 620 // GetLatestProtocolStateSnapshot returns the latest serializable Snapshot 621 func (h *Handler) GetLatestProtocolStateSnapshot(ctx context.Context, req *access.GetLatestProtocolStateSnapshotRequest) (*access.ProtocolStateSnapshotResponse, error) { 622 metadata := h.buildMetadataResponse() 623 624 snapshot, err := h.api.GetLatestProtocolStateSnapshot(ctx) 625 if err != nil { 626 return nil, err 627 } 628 629 return &access.ProtocolStateSnapshotResponse{ 630 SerializedSnapshot: snapshot, 631 Metadata: metadata, 632 }, nil 633 } 634 635 // GetProtocolStateSnapshotByBlockID returns serializable Snapshot by blockID 636 func (h *Handler) GetProtocolStateSnapshotByBlockID(ctx context.Context, req *access.GetProtocolStateSnapshotByBlockIDRequest) (*access.ProtocolStateSnapshotResponse, error) { 637 metadata := h.buildMetadataResponse() 638 639 blockID := convert.MessageToIdentifier(req.GetBlockId()) 640 641 snapshot, err := h.api.GetProtocolStateSnapshotByBlockID(ctx, blockID) 642 if err != nil { 643 return nil, err 644 } 645 646 return &access.ProtocolStateSnapshotResponse{ 647 SerializedSnapshot: snapshot, 648 Metadata: metadata, 649 }, nil 650 } 651 652 // GetProtocolStateSnapshotByHeight returns serializable Snapshot by block height 653 func (h *Handler) GetProtocolStateSnapshotByHeight(ctx context.Context, req *access.GetProtocolStateSnapshotByHeightRequest) (*access.ProtocolStateSnapshotResponse, error) { 654 metadata := h.buildMetadataResponse() 655 656 snapshot, err := h.api.GetProtocolStateSnapshotByHeight(ctx, req.GetBlockHeight()) 657 if err != nil { 658 return nil, err 659 } 660 661 return &access.ProtocolStateSnapshotResponse{ 662 SerializedSnapshot: snapshot, 663 Metadata: metadata, 664 }, nil 665 } 666 667 // GetExecutionResultForBlockID returns the latest received execution result for the given block ID. 668 // AN might receive multiple receipts with conflicting results for unsealed blocks. 669 // If this case happens, since AN is not able to determine which result is the correct one until the block is sealed, it has to pick one result to respond to this query. For now, we return the result from the latest received receipt. 670 func (h *Handler) GetExecutionResultForBlockID(ctx context.Context, req *access.GetExecutionResultForBlockIDRequest) (*access.ExecutionResultForBlockIDResponse, error) { 671 metadata := h.buildMetadataResponse() 672 673 blockID := convert.MessageToIdentifier(req.GetBlockId()) 674 675 result, err := h.api.GetExecutionResultForBlockID(ctx, blockID) 676 if err != nil { 677 return nil, err 678 } 679 680 return executionResultToMessages(result, metadata) 681 } 682 683 // GetExecutionResultByID returns the execution result for the given ID. 684 func (h *Handler) GetExecutionResultByID(ctx context.Context, req *access.GetExecutionResultByIDRequest) (*access.ExecutionResultByIDResponse, error) { 685 metadata := h.buildMetadataResponse() 686 687 blockID := convert.MessageToIdentifier(req.GetId()) 688 689 result, err := h.api.GetExecutionResultByID(ctx, blockID) 690 if err != nil { 691 return nil, err 692 } 693 694 execResult, err := convert.ExecutionResultToMessage(result) 695 if err != nil { 696 return nil, err 697 } 698 return &access.ExecutionResultByIDResponse{ 699 ExecutionResult: execResult, 700 Metadata: metadata, 701 }, nil 702 } 703 704 func (h *Handler) blockResponse(block *flow.Block, fullResponse bool, status flow.BlockStatus) (*access.BlockResponse, error) { 705 metadata := h.buildMetadataResponse() 706 707 signerIDs, err := h.signerIndicesDecoder.DecodeSignerIDs(block.Header) 708 if err != nil { 709 return nil, err // the block was retrieved from local storage - so no errors are expected 710 } 711 712 var msg *entities.Block 713 if fullResponse { 714 msg, err = convert.BlockToMessage(block, signerIDs) 715 if err != nil { 716 return nil, err 717 } 718 } else { 719 msg = convert.BlockToMessageLight(block) 720 } 721 722 return &access.BlockResponse{ 723 Block: msg, 724 BlockStatus: entities.BlockStatus(status), 725 Metadata: metadata, 726 }, nil 727 } 728 729 func (h *Handler) blockHeaderResponse(header *flow.Header, status flow.BlockStatus) (*access.BlockHeaderResponse, error) { 730 metadata := h.buildMetadataResponse() 731 732 signerIDs, err := h.signerIndicesDecoder.DecodeSignerIDs(header) 733 if err != nil { 734 return nil, err // the block was retrieved from local storage - so no errors are expected 735 } 736 737 msg, err := convert.BlockHeaderToMessage(header, signerIDs) 738 if err != nil { 739 return nil, err 740 } 741 742 return &access.BlockHeaderResponse{ 743 Block: msg, 744 BlockStatus: entities.BlockStatus(status), 745 Metadata: metadata, 746 }, nil 747 } 748 749 // buildMetadataResponse builds and returns the metadata response object. 750 func (h *Handler) buildMetadataResponse() *entities.Metadata { 751 lastFinalizedHeader := h.finalizedHeaderCache.Get() 752 blockId := lastFinalizedHeader.ID() 753 nodeId := h.me.NodeID() 754 755 return &entities.Metadata{ 756 LatestFinalizedBlockId: blockId[:], 757 LatestFinalizedHeight: lastFinalizedHeader.Height, 758 NodeId: nodeId[:], 759 } 760 } 761 762 func executionResultToMessages(er *flow.ExecutionResult, metadata *entities.Metadata) (*access.ExecutionResultForBlockIDResponse, error) { 763 execResult, err := convert.ExecutionResultToMessage(er) 764 if err != nil { 765 return nil, err 766 } 767 return &access.ExecutionResultForBlockIDResponse{ 768 ExecutionResult: execResult, 769 Metadata: metadata, 770 }, nil 771 } 772 773 // WithBlockSignerDecoder configures the Handler to decode signer indices 774 // via the provided hotstuff.BlockSignerDecoder 775 func WithBlockSignerDecoder(signerIndicesDecoder hotstuff.BlockSignerDecoder) func(*Handler) { 776 return func(handler *Handler) { 777 handler.signerIndicesDecoder = signerIndicesDecoder 778 } 779 }