github.com/koko1123/flow-go-1@v0.29.6/admin/commands/storage/read_blocks.go (about) 1 package storage 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/koko1123/flow-go-1/admin" 8 "github.com/koko1123/flow-go-1/admin/commands" 9 "github.com/koko1123/flow-go-1/model/flow" 10 "github.com/koko1123/flow-go-1/state/protocol" 11 "github.com/koko1123/flow-go-1/storage" 12 ) 13 14 var _ commands.AdminCommand = (*ReadBlocksCommand)(nil) 15 16 type readBlocksRequest struct { 17 blocksRequest *blocksRequest 18 numBlocksToQuery uint64 19 } 20 21 type ReadBlocksCommand struct { 22 state protocol.State 23 blocks storage.Blocks 24 } 25 26 func (r *ReadBlocksCommand) Handler(ctx context.Context, req *admin.CommandRequest) (interface{}, error) { 27 data := req.ValidatorData.(*readBlocksRequest) 28 var result []*flow.Block 29 var blockID flow.Identifier 30 31 if header, err := getBlockHeader(r.state, data.blocksRequest); err != nil { 32 return nil, fmt.Errorf("failed to get block header: %w", err) 33 } else { 34 blockID = header.ID() 35 } 36 37 for i := uint64(0); i < data.numBlocksToQuery; i++ { 38 block, err := r.blocks.ByID(blockID) 39 if err != nil { 40 return nil, fmt.Errorf("failed to get block by ID: %w", err) 41 } 42 result = append(result, block) 43 if block.Header.Height == 0 { 44 break 45 } 46 blockID = block.Header.ParentID 47 } 48 49 return commands.ConvertToInterfaceList(result) 50 } 51 52 // Validator validates the request. 53 // Returns admin.InvalidAdminReqError for invalid/malformed requests. 54 func (r *ReadBlocksCommand) Validator(req *admin.CommandRequest) error { 55 input, ok := req.Data.(map[string]interface{}) 56 if !ok { 57 return admin.NewInvalidAdminReqFormatError("expected map[string]any") 58 } 59 60 block, ok := input["block"] 61 if !ok { 62 return admin.NewInvalidAdminReqErrorf("the \"block\" field is required") 63 } 64 65 data := &readBlocksRequest{} 66 if blocksRequest, err := parseBlocksRequest(block); err != nil { 67 return admin.NewInvalidAdminReqErrorf("invalid 'block' field: %w", err) 68 } else { 69 data.blocksRequest = blocksRequest 70 } 71 72 if n, ok := input["n"]; ok { 73 if n, err := parseN(n); err != nil { 74 return admin.NewInvalidAdminReqErrorf("invalid 'n' field: %w", err) 75 } else { 76 data.numBlocksToQuery = n 77 } 78 } else { 79 data.numBlocksToQuery = 1 80 } 81 82 req.ValidatorData = data 83 84 return nil 85 86 } 87 88 func NewReadBlocksCommand(state protocol.State, storage storage.Blocks) commands.AdminCommand { 89 return &ReadBlocksCommand{ 90 state, 91 storage, 92 } 93 }