class Messenger(object): def __init__(self, validator_url): self._connection = Connection(validator_url) self._context = create_context('secp256k1') self._crypto_factory = CryptoFactory(self._context) self._batch_signer = self._crypto_factory.new_signer( self._context.new_random_private_key()) def open_validator_connection(self): self._connection.open() def close_validator_connection(self): self._connection.close() def get_new_key_pair(self): private_key = self._context.new_random_private_key() public_key = self._context.get_public_key(private_key) return public_key.as_hex(), private_key.as_hex() async def send_create_agent_transaction(self, private_key, name, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_agent_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, name=name, timestamp=timestamp) await self._send_and_wait_for_commit(batch) 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')
def main(): loop = ZMQEventLoop() asyncio.set_event_loop(loop) connection = None try: opts = parse_args(sys.argv[1:]) init_console_logging(verbose_level=opts.verbose) url = opts.connect if "tcp://" not in url: url = "tcp://" + url connection = Connection(url) try: host, port = opts.bind.split(":") port = int(port) except ValueError: print("Unable to parse binding {}: Must be in the format" " host:port".format(opts.bind)) sys.exit(1) start_rest_api(host, port, connection) except Exception as err: # pylint: disable=broad-except LOGGER.exception(err) sys.exit(1) finally: if connection is not None: connection.close()
def __init__(self, validator_url, database): self._connection = Connection(validator_url) self._context = create_context('secp256k1') self._crypto_factory = CryptoFactory(self._context) self._batch_signer = self._crypto_factory.new_signer( self._context.new_random_private_key()) self._database = database
async def open_connections(appl): appl.config.INVESTIGATOR_VAL_CONN = Connection(appl.config.TRIAL_VALIDATOR_URL) appl.config.CONSENT_VAL_CONN = Connection(appl.config.CONSENT_VALIDATOR_URL) LOGGER.warning('opening validator connection for Investigator network: ' + str(appl.config.TRIAL_VALIDATOR_URL)) LOGGER.warning('opening validator connection for Consent network: ' + str(appl.config.CONSENT_VALIDATOR_URL)) appl.config.INVESTIGATOR_VAL_CONN.open() appl.config.CONSENT_VAL_CONN.open()
def main(): loop = ZMQEventLoop() asyncio.set_event_loop(loop) connection = None try: opts = parse_args(sys.argv[1:]) opts_config = RestApiConfig( bind=opts.bind, connect=opts.connect, timeout=opts.timeout) rest_api_config = load_rest_api_config(opts_config) url = None if "tcp://" not in rest_api_config.connect: url = "tcp://" + rest_api_config.connect else: url = rest_api_config.connect connection = Connection(url) log_config = get_log_config(filename="rest_api_log_config.toml") # If no toml, try loading yaml if log_config is None: log_config = get_log_config(filename="rest_api_log_config.yaml") if log_config is not None: log_configuration(log_config=log_config) else: log_dir = get_log_dir() log_configuration(log_dir=log_dir, name="rest_api") init_console_logging(verbose_level=opts.verbose) try: host, port = rest_api_config.bind[0].split(":") port = int(port) except ValueError as e: print("Unable to parse binding {}: Must be in the format" " host:port".format(rest_api_config.bind[0])) sys.exit(1) start_rest_api( host, port, connection, int(rest_api_config.timeout)) # pylint: disable=broad-except except Exception as e: print("Error: {}".format(e), file=sys.stderr) finally: if connection is not None: connection.close()
def main(): loop = ZMQEventLoop() asyncio.set_event_loop(loop) connection = None try: opts = parse_args(sys.argv[1:]) opts_config = RestApiConfig( bind=opts.bind, connect=opts.connect, timeout=opts.timeout) rest_api_config = load_rest_api_config(opts_config) url = None if "tcp://" not in rest_api_config.connect: url = "tcp://" + rest_api_config.connect else: url = rest_api_config.connect connection = Connection(url) log_config = get_log_config(filename="rest_api_log_config.toml") if log_config is not None: log_configuration(log_config=log_config) else: log_dir = get_log_dir() log_configuration(log_dir=log_dir, name="sawtooth_rest_api") init_console_logging(verbose_level=opts.verbose) try: host, port = rest_api_config.bind[0].split(":") port = int(port) except ValueError as e: print("Unable to parse binding {}: Must be in the format" " host:port".format(rest_api_config.bind[0])) sys.exit(1) start_rest_api( host, port, connection, int(rest_api_config.timeout)) # pylint: disable=broad-except except Exception as e: print("Error: {}".format(e), file=sys.stderr) finally: if connection is not None: connection.close()
async def open_connections(appl): # LOGGER.warning('opening database connection') # r.set_loop_type('asyncio') # app.config.DB_CONN = await r.connect( # host=app.config.DB_HOST, # port=app.config.DB_PORT, # db=app.config.DB_NAME) appl.config.EHR_VAL_CONN = Connection(appl.config.EHR_VALIDATOR_URL) appl.config.CONSENT_VAL_CONN = Connection( appl.config.CONSENT_VALIDATOR_URL) LOGGER.warning('opening validator connection for EHR network: ' + str(appl.config.EHR_VALIDATOR_URL)) LOGGER.warning('opening validator connection for Consent network: ' + str(appl.config.CONSENT_VALIDATOR_URL)) appl.config.EHR_VAL_CONN.open() appl.config.CONSENT_VAL_CONN.open()
async def open_connections(app): LOGGER.warning('opening database connection') r.set_loop_type('asyncio') app.config.DB_CONN = await r.connect(host=app.config.DB_HOST, port=app.config.DB_PORT, db=app.config.DB_NAME) app.config.VAL_CONN = Connection(app.config.VALIDATOR_URL) LOGGER.warning('opening validator connection') app.config.VAL_CONN.open()
async def open_connections(app): LOGGER.warning("opening database connection") app.config.DB_CONN = await db_utils.create_connection( app.config.DB_HOST, app.config.DB_PORT, app.config.DB_NAME ) validator_url = "{}:{}".format(app.config.VALIDATOR_HOST, app.config.VALIDATOR_PORT) if "tcp://" not in app.config.VALIDATOR_HOST: validator_url = "tcp://" + validator_url app.config.VAL_CONN = Connection(validator_url) LOGGER.warning("opening validator connection") app.config.VAL_CONN.open()
def main(): loop = ZMQEventLoop() asyncio.set_event_loop(loop) connection = None try: opts = parse_args(sys.argv[1:]) opts_config = RestApiConfig(bind=opts.bind, connect=opts.connect, timeout=opts.timeout, opentsdb_url=opts.opentsdb_url, opentsdb_db=opts.opentsdb_db) rest_api_config = load_rest_api_config(opts_config) url = None if "tcp://" not in rest_api_config.connect: url = "tcp://" + rest_api_config.connect else: url = rest_api_config.connect connection = Connection(url) log_config = get_log_config(filename="rest_api_log_config.toml") # If no toml, try loading yaml if log_config is None: log_config = get_log_config(filename="rest_api_log_config.yaml") if log_config is not None: log_configuration(log_config=log_config) else: log_dir = get_log_dir() log_configuration(log_dir=log_dir, name="rest_api") init_console_logging(verbose_level=opts.verbose) try: host, port = rest_api_config.bind[0].split(":") port = int(port) except ValueError as e: print("Unable to parse binding {}: Must be in the format" " host:port".format(rest_api_config.bind[0])) sys.exit(1) wrapped_registry = None if rest_api_config.opentsdb_url: LOGGER.info("Adding metrics reporter: url=%s, db=%s", rest_api_config.opentsdb_url, rest_api_config.opentsdb_db) url = urlparse(rest_api_config.opentsdb_url) proto, db_server, db_port, = url.scheme, url.hostname, url.port registry = MetricsRegistry() wrapped_registry = MetricsRegistryWrapper(registry) reporter = InfluxReporter( registry=registry, reporting_interval=10, database=rest_api_config.opentsdb_db, prefix="sawtooth_rest_api", port=db_port, protocol=proto, server=db_server, username=rest_api_config.opentsdb_username, password=rest_api_config.opentsdb_password) reporter.start() start_rest_api(host, port, connection, int(rest_api_config.timeout), wrapped_registry) # pylint: disable=broad-except except Exception as e: LOGGER.exception(e) sys.exit(1) finally: if connection is not None: connection.close()
class Messenger(object): TIMEOUT = 300 def __init__(self, validator_url): self._connection = Connection(validator_url) self._context = create_context('secp256k1') self._crypto_factory = CryptoFactory(self._context) self._batch_signer = self._crypto_factory.new_signer( self._context.new_random_private_key()) def open_validator_connection(self): self._connection.open() def close_validator_connection(self): self._connection.close() def get_new_key_pair(self): private_key = self._context.new_random_private_key() public_key = self._context.get_public_key(private_key) return public_key.as_hex(), private_key.as_hex() async def send_create_agent_transaction(self, private_key, name, timestamp, role): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_agent_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, name=name, timestamp=timestamp, role=role) await self._send_and_wait_for_commit(batch) async def send_create_record_transaction(self, private_key, record_id, description, price, quantity, units, parent_id, other_fields, remarks, new, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_record_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, record_id=record_id, description=description, price=price, quantity=quantity, units=units, parent_id=parent_id, other_fields=other_fields, remarks=remarks, new=new, timestamp=timestamp) await self._send_and_wait_for_commit(batch) async def send_transfer_record_transaction(self, private_key, receiving_agent, record_id, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_transfer_record_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, receiving_agent=receiving_agent, record_id=record_id, timestamp=timestamp) await self._send_and_wait_for_commit(batch) async def send_update_record_transaction(self, private_key, record_id, description, price, quantity, units, parent_id, other_fields, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_record_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, record_id=record_id, description=description, price=price, quantity=quantity, units=units, parent_id=parent_id, other_fields=other_fields, timestamp=timestamp) await self._send_and_wait_for_commit(batch) async def send_finalize_record_transaction(self, private_key, record_id, status, remarks, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_finalize_record_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, record_id=record_id, status=status, remarks=remarks, timestamp=timestamp) await self._send_and_wait_for_commit(batch) 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 _query_validator(self, request_type, response_proto, payload, error_traps=None): """Sends a request to the validator and parses the response. """ LOGGER.debug('Sending %s request to validator', self._get_type_name(request_type)) payload_bytes = payload.SerializeToString() response = await self._send_request(request_type, payload_bytes) content = self._parse_response(response_proto, response) LOGGER.debug('Received %s response from validator with status %s', self._get_type_name(response.message_type), self._get_status_name(response_proto, content.status)) self._check_status_errors(response_proto, content, error_traps) return self._message_to_dict(content) async def _send_request(self, request_type, payload): """Uses an executor to send an asynchronous ZMQ request to the validator with the handler's Connection """ try: return await self._connection.send(message_type=request_type, message_content=payload, timeout=self.TIMEOUT) except DisconnectError: LOGGER.warning('Validator disconnected while waiting for response') raise errors.ValidatorDisconnected() except asyncio.TimeoutError: LOGGER.warning('Timed out while waiting for validator response') raise errors.ValidatorTimedOut() @staticmethod def _parse_response(proto, response): """Parses the content from a validator response Message. """ try: content = proto() content.ParseFromString(response.content) return content except (DecodeError, AttributeError): LOGGER.error('Validator response was not parsable: %s', response) raise errors.ValidatorResponseInvalid() @staticmethod def _get_type_name(type_enum): return Message.MessageType.Name(type_enum) @staticmethod def _get_status_name(proto, status_enum): try: return proto.Status.Name(status_enum) except ValueError: return 'Unknown ({})'.format(status_enum) @staticmethod def _check_status_errors(proto, content, error_traps=None): """Raises HTTPErrors based on error statuses sent from validator. Checks for common statuses and runs route specific error traps. """ if content.status == proto.OK: return try: if content.status == proto.INTERNAL_ERROR: raise errors.UnknownValidatorError() except AttributeError: # Not every protobuf has every status enum, so pass AttributeErrors pass try: if content.status == proto.NOT_READY: raise errors.ValidatorNotReady() except AttributeError: pass try: if content.status == proto.NO_ROOT: raise errors.HeadNotFound() except AttributeError: pass try: if content.status == proto.INVALID_PAGING: raise errors.PagingInvalid() except AttributeError: pass try: if content.status == proto.INVALID_SORT: raise errors.SortInvalid() except AttributeError: pass # Check custom error traps from the particular route message if error_traps is not None: for trap in error_traps: trap.check(content.status) @staticmethod def _message_to_dict(message): """Converts a Protobuf object to a python dict with desired settings. """ return MessageToDict(message, including_default_value_fields=True, preserving_proto_field_name=True)
class Messenger(object): def __init__(self, validator_url, database): self._connection = Connection(validator_url) self._context = create_context('secp256k1') self._crypto_factory = CryptoFactory(self._context) self._batch_signer = self._crypto_factory.new_signer( self._context.new_random_private_key()) self._database = database def open_validator_connection(self): self._connection.open() def close_validator_connection(self): self._connection.close() def get_new_key_pair(self): private_key = self._context.new_random_private_key() public_key = self._context.get_public_key(private_key) return public_key.as_hex(), private_key.as_hex() async def send_create_election_transaction( self, private_key, election_id, name, description, start_timestamp, end_timestamp, results_permission, can_change_vote, can_show_realtime, admin_id, status, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_election_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, election_id=election_id, name=name, description=description, start_timestamp=start_timestamp, end_timestamp=end_timestamp, results_permission=results_permission, can_change_vote=can_change_vote, can_show_realtime=can_show_realtime, admin_id=admin_id, status=status, timestamp=timestamp) count_tries = 0 while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: election = await self._database.fetch_election_resource( election_id=election_id) if election is not None: break LOGGER.info("Invalid transaction. Retrying...") count_tries = count_tries + 1 if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_create_voting_option_transaction(self, private_key, voting_option_id, name, description, election_id, status, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_voting_option_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, voting_option_id=voting_option_id, name=name, description=description, election_id=election_id, status=status, timestamp=timestamp) count_tries = 0 while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: voting_option = await self._database.fetch_voting_option_resource( voting_option_id=voting_option_id) if voting_option is not None: break LOGGER.info("Invalid transaction. Retrying...") count_tries = count_tries + 1 if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_create_poll_registration_transaction( self, private_key, voter_id, name, election_id, status, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_poll_registration_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, voter_id=voter_id, name=name, election_id=election_id, status=status, timestamp=timestamp) count_tries = 0 while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: poll_book_registration = await self._database.fetch_poll_book_registration( election_id=election_id, voter_id=voter_id) if poll_book_registration is not None: break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_create_voter_transaction(self, private_key, voter_id, public_key, name, created_at, type): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_voter_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, voter_id=voter_id, public_key=public_key, name=name, created_at=created_at, type=type) count_tries = 0 while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: voter = await self._database.fetch_voter_resource(voter_id=voter_id ) if voter is not None: break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_update_voter_transaction(self, private_key, voter_id, public_key, name, created_at, type): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_voter_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, voter_id=voter_id, public_key=public_key, name=name, created_at=created_at, type=type) count_tries = 0 original_voter = await self._database.fetch_voter_resource( voter_id=voter_id) while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: voter = await self._database.fetch_voter_resource(voter_id=voter_id ) if voter is not None and original_voter.get("end_block_num") == voter.get("end_block_num") \ and original_voter.get("start_block_num") != voter.get("start_block_num"): break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_create_vote_transaction(self, private_key, vote_id, timestamp, voter_id, election_id, voting_option_id): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_vote_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, vote_id=vote_id, timestamp=timestamp, voter_id=voter_id, election_id=election_id, voting_option_id=voting_option_id) count_tries = 0 while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: vote = await self._database.fetch_vote_resource(vote_id=vote_id) if vote is not None: break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_update_vote_transaction(self, private_key, vote_id, timestamp, voting_option_id): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_vote_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, vote_id=vote_id, timestamp=timestamp, voting_option_id=voting_option_id) count_tries = 0 original_vote = await self._database.fetch_vote_resource( vote_id=vote_id) while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: vote = await self._database.fetch_vote_resource(vote_id=vote_id) if vote is not None and original_vote.get("end_block_num") == vote.get("end_block_num") \ and original_vote.get("start_block_num") != vote.get("start_block_num"): break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_update_election_transaction( self, private_key, election_id, name, description, start_timestamp, end_timestamp, results_permission, can_change_vote, can_show_realtime, admin_id, status, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_election_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, election_id=election_id, name=name, description=description, start_timestamp=start_timestamp, end_timestamp=end_timestamp, results_permission=results_permission, can_change_vote=can_change_vote, can_show_realtime=can_show_realtime, admin_id=admin_id, status=status, timestamp=timestamp) count_tries = 0 original_election = await self._database.fetch_election_resource( election_id=election_id) while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: election = await self._database.fetch_election_resource( election_id=election_id) if election is not None and original_election.get("end_block_num") == election.get("end_block_num") \ and original_election.get("start_block_num") != election.get("start_block_num"): break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_update_voting_option_status_transaction( self, private_key, voting_option_id, name, description, election_id, status, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_voting_option_status_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, voting_option_id=voting_option_id, name=name, description=description, election_id=election_id, status=status, timestamp=timestamp) count_tries = 0 original_voting_option = await self._database.fetch_voting_option_resource( voting_option_id=voting_option_id) while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: voting_option = await self._database.fetch_voting_option_resource( voting_option_id=voting_option_id) if voting_option is not None and original_voting_option.get("end_block_num") == voting_option.get("end_block_num") \ and original_voting_option.get("start_block_num") != voting_option.get("start_block_num"): break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") async def send_update_voter_poll_book_status_transaction( self, private_key, voter_id, name, election_id, status, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_poll_book_status_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, voter_id=voter_id, name=name, election_id=election_id, status=status, timestamp=timestamp) count_tries = 0 original_poll_book_registration = await self._database.fetch_poll_book_registration( election_id=election_id, voter_id=voter_id) while await self._send_and_wait_for_commit( batch) is False and count_tries < MAX_TRIES: poll_book_registration = await self._database.fetch_poll_book_registration( election_id=election_id, voter_id=voter_id) if poll_book_registration is not None \ and original_poll_book_registration.get("end_block_num") == poll_book_registration.get("end_block_num") \ and original_poll_book_registration.get("start_block_num") != poll_book_registration.get("start_block_num"): break LOGGER.debug("Invalid transaction. Retrying...") if count_tries == MAX_TRIES: raise ApiInternalError( "Invalid transaction. MAX_TRIES limit reached.") 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
def main(): loop = ZMQEventLoop() asyncio.set_event_loop(loop) connection = None try: opts = parse_args(sys.argv[1:]) opts_config = RestApiConfig( bind=opts.bind, connect=opts.connect, timeout=opts.timeout, opentsdb_url=opts.opentsdb_url, opentsdb_db=opts.opentsdb_db) rest_api_config = load_rest_api_config(opts_config) url = None if "tcp://" not in rest_api_config.connect: url = "tcp://" + rest_api_config.connect else: url = rest_api_config.connect connection = Connection(url) log_config = get_log_config(filename="rest_api_log_config.toml") # If no toml, try loading yaml if log_config is None: log_config = get_log_config(filename="rest_api_log_config.yaml") if log_config is not None: log_configuration(log_config=log_config) else: log_dir = get_log_dir() log_configuration(log_dir=log_dir, name="rest_api") init_console_logging(verbose_level=opts.verbose) try: host, port = rest_api_config.bind[0].split(":") port = int(port) except ValueError as e: print("Unable to parse binding {}: Must be in the format" " host:port".format(rest_api_config.bind[0])) sys.exit(1) wrapped_registry = None if rest_api_config.opentsdb_url: LOGGER.info("Adding metrics reporter: url=%s, db=%s", rest_api_config.opentsdb_url, rest_api_config.opentsdb_db) url = urlparse(rest_api_config.opentsdb_url) proto, db_server, db_port, = url.scheme, url.hostname, url.port registry = MetricsRegistry() wrapped_registry = MetricsRegistryWrapper(registry) reporter = InfluxReporter( registry=registry, reporting_interval=10, database=rest_api_config.opentsdb_db, prefix="sawtooth_rest_api", port=db_port, protocol=proto, server=db_server, username=rest_api_config.opentsdb_username, password=rest_api_config.opentsdb_password) reporter.start() start_rest_api( host, port, connection, int(rest_api_config.timeout), wrapped_registry) # pylint: disable=broad-except except Exception as e: LOGGER.exception(e) sys.exit(1) finally: if connection is not None: connection.close()
class Messenger(object): def __init__(self, validator_url): self._connection = Connection(validator_url) self._context = create_context('secp256k1') self._crypto_factory = CryptoFactory(self._context) self._batch_signer = self._crypto_factory.new_signer( self._context.new_random_private_key()) def open_validator_connection(self): self._connection.open() def close_validator_connection(self): self._connection.close() def get_new_key_pair(self): private_key = self._context.new_random_private_key() public_key = self._context.get_public_key(private_key) return public_key.as_hex(), private_key.as_hex() async def send_create_user_transaction(self, private_key, username, role, timestamp): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_create_user_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, username=username, role=role, timestamp=timestamp) await self._send_and_wait_for_commit(batch) return batch async def send_drug_import_transaction(self, private_key, timestamp, id, name ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_drug_import_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id, name=name ) await self._send_and_wait_for_commit(batch) return batch async def send_company_import_transaction(self, private_key, timestamp, id, name, date, address ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_company_import_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id, name=name, date=date, address=address ) await self._send_and_wait_for_commit(batch) return batch async def send_employee_import_transaction(self, private_key, timestamp, id, name, age, address, email, company_id ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_employee_import_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id, name=name, age=age, address=address, email=email, company_id=company_id ) await self._send_and_wait_for_commit(batch) return batch async def send_get_drug_transaction(self, private_key, timestamp, id ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_get_drug_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id ) await self._send_and_wait_for_commit(batch) return batch async def send_get_company_transaction(self, private_key, timestamp, id ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_get_company_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id ) await self._send_and_wait_for_commit(batch) return batch async def send_get_employee_transaction(self, private_key, timestamp, id ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_get_employee_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id ) await self._send_and_wait_for_commit(batch) return batch async def send_update_status_transaction(self, private_key, timestamp, id, quantity, price ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_status_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id, quantity=quantity, price=price ) await self._send_and_wait_for_commit(batch) return batch async def send_update_location_transaction(self, private_key, timestamp, id, longitude, latitude ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_location_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id, longitude=longitude, latitude=latitude ) await self._send_and_wait_for_commit(batch) return batch async def send_update_company_transaction(self, private_key, timestamp, id, address, price_IPO ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_company_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id, address=address, price_IPO=price_IPO ) await self._send_and_wait_for_commit(batch) return batch async def send_update_employee_transaction(self, private_key, timestamp, id, position, salary ): transaction_signer = self._crypto_factory.new_signer( secp256k1.Secp256k1PrivateKey.from_hex(private_key)) batch = make_update_employee_transaction( transaction_signer=transaction_signer, batch_signer=self._batch_signer, timestamp=timestamp, id=id, position=position, salary=salary ) await self._send_and_wait_for_commit(batch) return batch 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')