github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/access/legacy/handler.go (about) 1 package handler 2 3 import ( 4 "context" 5 6 "github.com/onflow/flow/protobuf/go/flow/entities" 7 accessproto "github.com/onflow/flow/protobuf/go/flow/legacy/access" 8 entitiesproto "github.com/onflow/flow/protobuf/go/flow/legacy/entities" 9 "google.golang.org/grpc/codes" 10 "google.golang.org/grpc/status" 11 12 "github.com/onflow/flow-go/access" 13 "github.com/onflow/flow-go/access/legacy/convert" 14 "github.com/onflow/flow-go/model/flow" 15 ) 16 17 type Handler struct { 18 api access.API 19 chain flow.Chain 20 } 21 22 func NewHandler(api access.API, chain flow.Chain) *Handler { 23 return &Handler{ 24 api: api, 25 chain: chain, 26 } 27 } 28 29 // Ping the Access API server for a response. 30 func (h *Handler) Ping(context.Context, *accessproto.PingRequest) (*accessproto.PingResponse, error) { 31 return &accessproto.PingResponse{}, nil 32 } 33 34 func (h *Handler) GetNetworkParameters( 35 context.Context, 36 *accessproto.GetNetworkParametersRequest, 37 ) (*accessproto.GetNetworkParametersResponse, error) { 38 panic("implement me") 39 } 40 41 // SendTransaction submits a transaction to the network. 42 func (h *Handler) SendTransaction( 43 ctx context.Context, 44 req *accessproto.SendTransactionRequest, 45 ) (*accessproto.SendTransactionResponse, error) { 46 txMsg := req.GetTransaction() 47 48 tx, err := convert.MessageToTransaction(txMsg, h.chain) 49 if err != nil { 50 return nil, status.Error(codes.InvalidArgument, err.Error()) 51 } 52 53 err = h.api.SendTransaction(ctx, &tx) 54 if err != nil { 55 return nil, err 56 } 57 58 txID := tx.ID() 59 60 return &accessproto.SendTransactionResponse{ 61 Id: txID[:], 62 }, nil 63 } 64 65 // GetLatestBlockHeader gets the latest sealed block header. 66 func (h *Handler) GetLatestBlockHeader( 67 ctx context.Context, 68 req *accessproto.GetLatestBlockHeaderRequest, 69 ) (*accessproto.BlockHeaderResponse, error) { 70 header, _, err := h.api.GetLatestBlockHeader(ctx, req.GetIsSealed()) 71 if err != nil { 72 return nil, err 73 } 74 75 return blockHeaderResponse(header) 76 } 77 78 // GetBlockHeaderByHeight gets a block header by height. 79 func (h *Handler) GetBlockHeaderByHeight( 80 ctx context.Context, 81 req *accessproto.GetBlockHeaderByHeightRequest, 82 ) (*accessproto.BlockHeaderResponse, error) { 83 header, _, err := h.api.GetBlockHeaderByHeight(ctx, req.GetHeight()) 84 if err != nil { 85 return nil, err 86 } 87 88 return blockHeaderResponse(header) 89 } 90 91 // GetBlockHeaderByID gets a block header by ID. 92 func (h *Handler) GetBlockHeaderByID( 93 ctx context.Context, 94 req *accessproto.GetBlockHeaderByIDRequest, 95 ) (*accessproto.BlockHeaderResponse, error) { 96 blockID := convert.MessageToIdentifier(req.GetId()) 97 98 header, _, err := h.api.GetBlockHeaderByID(ctx, blockID) 99 if err != nil { 100 return nil, err 101 } 102 103 return blockHeaderResponse(header) 104 } 105 106 // GetLatestBlock gets the latest sealed block. 107 func (h *Handler) GetLatestBlock( 108 ctx context.Context, 109 req *accessproto.GetLatestBlockRequest, 110 ) (*accessproto.BlockResponse, error) { 111 block, _, err := h.api.GetLatestBlock(ctx, req.GetIsSealed()) 112 if err != nil { 113 return nil, err 114 } 115 116 return blockResponse(block) 117 } 118 119 // GetBlockByHeight gets a block by height. 120 func (h *Handler) GetBlockByHeight( 121 ctx context.Context, 122 req *accessproto.GetBlockByHeightRequest, 123 ) (*accessproto.BlockResponse, error) { 124 block, _, err := h.api.GetBlockByHeight(ctx, req.GetHeight()) 125 if err != nil { 126 return nil, err 127 } 128 129 return blockResponse(block) 130 } 131 132 // GetBlockByHeight gets a block by ID. 133 func (h *Handler) GetBlockByID( 134 ctx context.Context, 135 req *accessproto.GetBlockByIDRequest, 136 ) (*accessproto.BlockResponse, error) { 137 blockID := convert.MessageToIdentifier(req.GetId()) 138 139 block, _, err := h.api.GetBlockByID(ctx, blockID) 140 if err != nil { 141 return nil, err 142 } 143 144 return blockResponse(block) 145 } 146 147 // GetCollectionByID gets a collection by ID. 148 func (h *Handler) GetCollectionByID( 149 ctx context.Context, 150 req *accessproto.GetCollectionByIDRequest, 151 ) (*accessproto.CollectionResponse, error) { 152 id := convert.MessageToIdentifier(req.GetId()) 153 154 col, err := h.api.GetCollectionByID(ctx, id) 155 if err != nil { 156 return nil, err 157 } 158 159 colMsg, err := convert.LightCollectionToMessage(col) 160 if err != nil { 161 return nil, status.Error(codes.Internal, err.Error()) 162 } 163 164 return &accessproto.CollectionResponse{ 165 Collection: colMsg, 166 }, nil 167 } 168 169 // GetTransaction gets a transaction by ID. 170 func (h *Handler) GetTransaction( 171 ctx context.Context, 172 req *accessproto.GetTransactionRequest, 173 ) (*accessproto.TransactionResponse, error) { 174 id := convert.MessageToIdentifier(req.GetId()) 175 176 tx, err := h.api.GetTransaction(ctx, id) 177 if err != nil { 178 return nil, err 179 } 180 181 return &accessproto.TransactionResponse{ 182 Transaction: convert.TransactionToMessage(*tx), 183 }, nil 184 } 185 186 // GetTransactionResult gets a transaction by ID. 187 func (h *Handler) GetTransactionResult( 188 ctx context.Context, 189 req *accessproto.GetTransactionRequest, 190 ) (*accessproto.TransactionResultResponse, error) { 191 id := convert.MessageToIdentifier(req.GetId()) 192 193 result, err := h.api.GetTransactionResult( 194 ctx, 195 id, 196 flow.ZeroID, 197 flow.ZeroID, 198 entities.EventEncodingVersion_JSON_CDC_V0, 199 ) 200 if err != nil { 201 return nil, err 202 } 203 204 return convert.TransactionResultToMessage(*result), nil 205 } 206 207 // GetAccount returns an account by address at the latest sealed block. 208 func (h *Handler) GetAccount( 209 ctx context.Context, 210 req *accessproto.GetAccountRequest, 211 ) (*accessproto.GetAccountResponse, error) { 212 address := flow.BytesToAddress(req.GetAddress()) 213 214 account, err := h.api.GetAccount(ctx, address) 215 if err != nil { 216 return nil, err 217 } 218 219 accountMsg, err := convert.AccountToMessage(account) 220 if err != nil { 221 return nil, status.Error(codes.Internal, err.Error()) 222 } 223 224 return &accessproto.GetAccountResponse{ 225 Account: accountMsg, 226 }, nil 227 } 228 229 // GetAccountAtLatestBlock returns an account by address at the latest sealed block. 230 func (h *Handler) GetAccountAtLatestBlock( 231 ctx context.Context, 232 req *accessproto.GetAccountAtLatestBlockRequest, 233 ) (*accessproto.AccountResponse, error) { 234 address := flow.BytesToAddress(req.GetAddress()) 235 236 account, err := h.api.GetAccountAtLatestBlock(ctx, address) 237 if err != nil { 238 return nil, err 239 } 240 241 accountMsg, err := convert.AccountToMessage(account) 242 if err != nil { 243 return nil, status.Error(codes.Internal, err.Error()) 244 } 245 246 return &accessproto.AccountResponse{ 247 Account: accountMsg, 248 }, nil 249 } 250 251 func (h *Handler) GetAccountAtBlockHeight( 252 ctx context.Context, 253 request *accessproto.GetAccountAtBlockHeightRequest, 254 ) (*accessproto.AccountResponse, error) { 255 panic("implement me") 256 } 257 258 // ExecuteScriptAtLatestBlock executes a script at a the latest block 259 func (h *Handler) ExecuteScriptAtLatestBlock( 260 ctx context.Context, 261 req *accessproto.ExecuteScriptAtLatestBlockRequest, 262 ) (*accessproto.ExecuteScriptResponse, error) { 263 script := req.GetScript() 264 arguments := req.GetArguments() 265 266 value, err := h.api.ExecuteScriptAtLatestBlock(ctx, script, arguments) 267 if err != nil { 268 return nil, err 269 } 270 271 return &accessproto.ExecuteScriptResponse{ 272 Value: value, 273 }, nil 274 } 275 276 // ExecuteScriptAtBlockHeight executes a script at a specific block height 277 func (h *Handler) ExecuteScriptAtBlockHeight( 278 ctx context.Context, 279 req *accessproto.ExecuteScriptAtBlockHeightRequest, 280 ) (*accessproto.ExecuteScriptResponse, error) { 281 script := req.GetScript() 282 arguments := req.GetArguments() 283 blockHeight := req.GetBlockHeight() 284 285 value, err := h.api.ExecuteScriptAtBlockHeight(ctx, blockHeight, script, arguments) 286 if err != nil { 287 return nil, err 288 } 289 290 return &accessproto.ExecuteScriptResponse{ 291 Value: value, 292 }, nil 293 } 294 295 // ExecuteScriptAtBlockID executes a script at a specific block ID 296 func (h *Handler) ExecuteScriptAtBlockID( 297 ctx context.Context, 298 req *accessproto.ExecuteScriptAtBlockIDRequest, 299 ) (*accessproto.ExecuteScriptResponse, error) { 300 script := req.GetScript() 301 arguments := req.GetArguments() 302 blockID := convert.MessageToIdentifier(req.GetBlockId()) 303 304 value, err := h.api.ExecuteScriptAtBlockID(ctx, blockID, script, arguments) 305 if err != nil { 306 return nil, err 307 } 308 309 return &accessproto.ExecuteScriptResponse{ 310 Value: value, 311 }, nil 312 } 313 314 // GetEventsForHeightRange returns events matching a query. 315 func (h *Handler) GetEventsForHeightRange( 316 ctx context.Context, 317 req *accessproto.GetEventsForHeightRangeRequest, 318 ) (*accessproto.EventsResponse, error) { 319 eventType := req.GetType() 320 startHeight := req.GetStartHeight() 321 endHeight := req.GetEndHeight() 322 323 results, err := h.api.GetEventsForHeightRange(ctx, eventType, startHeight, endHeight, entities.EventEncodingVersion_JSON_CDC_V0) 324 if err != nil { 325 return nil, err 326 } 327 328 return &accessproto.EventsResponse{ 329 Results: blockEventsToMessages(results), 330 }, nil 331 } 332 333 // GetEventsForBlockIDs returns events matching a set of block IDs. 334 func (h *Handler) GetEventsForBlockIDs( 335 ctx context.Context, 336 req *accessproto.GetEventsForBlockIDsRequest, 337 ) (*accessproto.EventsResponse, error) { 338 eventType := req.GetType() 339 blockIDs := convert.MessagesToIdentifiers(req.GetBlockIds()) 340 341 results, err := h.api.GetEventsForBlockIDs(ctx, eventType, blockIDs, entities.EventEncodingVersion_JSON_CDC_V0) 342 if err != nil { 343 return nil, err 344 } 345 346 return &accessproto.EventsResponse{ 347 Results: blockEventsToMessages(results), 348 }, nil 349 } 350 351 func blockResponse(block *flow.Block) (*accessproto.BlockResponse, error) { 352 msg, err := convert.BlockToMessage(block) 353 if err != nil { 354 return nil, err 355 } 356 357 return &accessproto.BlockResponse{ 358 Block: msg, 359 }, nil 360 } 361 362 func blockHeaderResponse(header *flow.Header) (*accessproto.BlockHeaderResponse, error) { 363 msg, err := convert.BlockHeaderToMessage(header) 364 if err != nil { 365 return nil, err 366 } 367 368 return &accessproto.BlockHeaderResponse{ 369 Block: msg, 370 }, nil 371 } 372 373 func blockEventsToMessages(blocks []flow.BlockEvents) []*accessproto.EventsResponse_Result { 374 results := make([]*accessproto.EventsResponse_Result, len(blocks)) 375 376 for i, block := range blocks { 377 results[i] = blockEventsToMessage(block) 378 } 379 380 return results 381 } 382 383 func blockEventsToMessage(block flow.BlockEvents) *accessproto.EventsResponse_Result { 384 eventMessages := make([]*entitiesproto.Event, len(block.Events)) 385 for i, event := range block.Events { 386 eventMessages[i] = convert.EventToMessage(event) 387 } 388 389 return &accessproto.EventsResponse_Result{ 390 BlockId: block.BlockID[:], 391 BlockHeight: block.BlockHeight, 392 Events: eventMessages, 393 } 394 }