async def _send_and_wait_for_commit(self, batch): # Send transaction to validator submit_request = client_batch_submit_pb2.ClientBatchSubmitRequest( batches=[batch]) await self._connection.send( validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST, submit_request.SerializeToString()) # Send status request to validator batch_id = batch.header_signature status_request = client_batch_submit_pb2.ClientBatchStatusRequest( batch_ids=[batch_id], wait=True) validator_response = await self._connection.send( validator_pb2.Message.CLIENT_BATCH_STATUS_REQUEST, status_request.SerializeToString()) # Parse response status_response = client_batch_submit_pb2.ClientBatchStatusResponse() status_response.ParseFromString(validator_response.content) status = status_response.batch_statuses[0].status if status == client_batch_submit_pb2.ClientBatchStatus.INVALID: error = status_response.batch_statuses[0].invalid_transactions[0] raise ApiBadRequest(error.message) elif status == client_batch_submit_pb2.ClientBatchStatus.PENDING: raise ApiInternalError('Transaction submitted but timed out') elif status == client_batch_submit_pb2.ClientBatchStatus.UNKNOWN: raise ApiInternalError('Something went wrong. Try again later')
async def _send_and_wait_for_commit(self, batch): # Send transaction to validator submit_request = client_batch_submit_pb2.ClientBatchSubmitRequest( batches=[batch]) res = await self._connection.send( validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST, submit_request.SerializeToString(), 500) submit_response = client_batch_submit_pb2.ClientBatchSubmitResponse() submit_response.ParseFromString(res.content) # Send status request to validator batch_id = batch.header_signature status_request = client_batch_submit_pb2.ClientBatchStatusRequest( batch_ids=[batch_id], wait=True, timeout=500) validator_response = await self._connection.send( validator_pb2.Message.CLIENT_BATCH_STATUS_REQUEST, status_request.SerializeToString(), 500) # Parse response status_response = client_batch_submit_pb2.ClientBatchStatusResponse() status_response.ParseFromString(validator_response.content) status = status_response.batch_statuses[0].status if status == client_batch_submit_pb2.ClientBatchStatus.INVALID \ or status == client_batch_submit_pb2.ClientBatchStatus.PENDING \ or status == client_batch_submit_pb2.ClientBatchStatus.UNKNOWN: return False return True
async def list_statuses(self, request): """Fetches the committed status of batches by either a POST or GET. Request: body: A JSON array of one or more id strings (if POST) query: - id: A comma separated list of up to 15 ids (if GET) - wait: Request should not return until all batches committed Response: data: A JSON object, with batch ids as keys, and statuses as values link: The /batch_statuses link queried (if GET) """ error_traps = [error_handlers.StatusResponseMissing] # Parse batch ids from POST body, or query paramaters if request.method == 'POST': if request.headers['Content-Type'] != 'application/json': LOGGER.debug( 'Request headers had wrong Content-Type: %s', request.headers['Content-Type']) raise errors.StatusWrongContentType() ids = await request.json() if (not ids or not isinstance(ids, list) or not all(isinstance(i, str) for i in ids)): LOGGER.debug('Request body was invalid: %s', ids) raise errors.StatusBodyInvalid() else: ids = self._get_filter_ids(request) if not ids: LOGGER.debug('Request for statuses missing id query') raise errors.StatusIdQueryInvalid() # Query validator validator_query = \ client_batch_submit_pb2.ClientBatchStatusRequest( batch_ids=ids) self._set_wait(request, validator_query) response = await self._query_validator( Message.CLIENT_BATCH_STATUS_REQUEST, client_batch_submit_pb2.ClientBatchStatusResponse, validator_query, error_traps) # Send response if request.method != 'POST': metadata = self._get_metadata(request, response) else: metadata = None data = self._drop_id_prefixes( self._drop_empty_props(response['batch_statuses'])) return self._wrap_response(request, data=data, metadata=metadata)
async def send(conn, batch_list, timeout): batch_request = client_batch_submit_pb2.ClientBatchSubmitRequest() batch_request.batches.extend(list(batch_list.batches)) validator_response = await conn.send( validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST, batch_request.SerializeToString(), timeout, ) client_response = client_batch_submit_pb2.ClientBatchSubmitResponse() client_response.ParseFromString(validator_response.content) if (client_response.status == client_batch_submit_pb2.ClientBatchSubmitResponse.INTERNAL_ERROR): raise ApiInternalError("Internal Error") elif (client_response.status == client_batch_submit_pb2.ClientBatchSubmitResponse.INVALID_BATCH): raise ApiBadRequest("Invalid Batch") elif (client_response.status == client_batch_submit_pb2.ClientBatchSubmitResponse.QUEUE_FULL): raise ApiInternalError("Queue Full") status_request = client_batch_submit_pb2.ClientBatchStatusRequest() status_request.batch_ids.extend( list(b.header_signature for b in batch_list.batches)) status_request.wait = True status_request.timeout = timeout validator_response = await conn.send( validator_pb2.Message.CLIENT_BATCH_STATUS_REQUEST, status_request.SerializeToString(), timeout, ) status_response = client_batch_submit_pb2.ClientBatchStatusResponse() status_response.ParseFromString(validator_response.content) if status_response.status != client_batch_submit_pb2.ClientBatchStatusResponse.OK: raise ApiInternalError("Internal Error") resp = status_response.batch_statuses[0] if resp.status == client_batch_submit_pb2.ClientBatchStatus.COMMITTED: return resp elif resp.status == client_batch_submit_pb2.ClientBatchStatus.INVALID: raise ApiBadRequest("Bad Request: {}".format( resp.invalid_transactions[0].message)) elif resp.status == client_batch_submit_pb2.ClientBatchStatus.PENDING: raise ApiInternalError( "Internal Error: Transaction submitted but timed out.") elif resp.status == client_batch_submit_pb2.ClientBatchStatus.UNKNOWN: raise ApiInternalError( "Internal Error: Something went wrong. Try again later.")
async def check_batch_status(conn, batch_id): status_request = client_batch_submit_pb2.ClientBatchStatusRequest( batch_ids=[batch_id], wait=True) validator_response = await conn.send( validator_pb2.Message.CLIENT_BATCH_STATUS_REQUEST, status_request.SerializeToString()) status_response = client_batch_submit_pb2.ClientBatchStatusResponse() status_response.ParseFromString(validator_response.content) batch_status = status_response.batch_statuses[0].status if batch_status == client_batch_submit_pb2.ClientBatchStatus.INVALID: invalid = status_response.batch_statuses[0].invalid_transactions[0] raise ApiBadRequest(invalid.message) elif batch_status == client_batch_submit_pb2.ClientBatchStatus.PENDING: raise ApiInternalError("Transaction submitted but timed out") elif batch_status == client_batch_submit_pb2.ClientBatchStatus.UNKNOWN: raise ApiInternalError("Something went wrong. Try again later")