def test_transfer_funds(self): """Tests the transfer funds to another wallet""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) bob_keys = KeyPair.generate() crypto_client.create_wallet(bob_keys, "Bob" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() # TODO: Sometimes it fails without time.sleep() [ECR-3876] time.sleep(2) crypto_client.transfer(20, alice_keys, bob_keys.public_key.value) subscriber.wait_for_new_event() # TODO: Sometimes it fails without time.sleep() [ECR-3876] time.sleep(2) alice_balance = (crypto_client.get_wallet_info( alice_keys).json()['wallet_proof']['to_wallet'] ['entries'][0]['value']['balance']) bob_balance = (crypto_client.get_wallet_info( bob_keys).json()['wallet_proof']['to_wallet'] ['entries'][0]['value']['balance']) self.assertEqual(alice_balance, 80) self.assertEqual(bob_balance, 120)
def test_transfer_funds_insufficient(self): """Tests the transfer insufficient amount of funds is failed""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) bob_keys = KeyPair.generate() crypto_client.create_wallet(bob_keys, "Bob" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() tx_response = crypto_client.transfer( 110, alice_keys, bob_keys.public_key) subscriber.wait_for_new_event() tx_info = client.public_api.get_tx_info( tx_response.json()["tx_hash"]).json() tx_status = tx_info["status"]["type"] self.assertEqual(tx_status, "service_error") alice_balance = crypto_client.get_balance(alice_keys) bob_balance = crypto_client.get_balance(bob_keys) self.assertEqual(alice_balance, 100) self.assertEqual(bob_balance, 100)
def test_transfer_funds(self): """Tests the transfer funds to another wallet""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() bob_keys = KeyPair.generate() with client.create_subscriber("transactions") as subscriber: crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) subscriber.wait_for_new_event() crypto_client.create_wallet(bob_keys, "Bob" + str(validator_id)) subscriber.wait_for_new_event() crypto_client.transfer(20, alice_keys, bob_keys.public_key.value) subscriber.wait_for_new_event() alice_wallet = crypto_client.get_wallet_info( alice_keys).json() alice_balance = alice_wallet["wallet_proof"]["to_wallet"][ "entries"][0]["value"]["balance"] bob_wallet = crypto_client.get_wallet_info(bob_keys).json() bob_balance = bob_wallet["wallet_proof"]["to_wallet"][ "entries"][0]["value"]["balance"] self.assertEqual(alice_balance, 80) self.assertEqual(bob_balance, 120)
def test_transfer_funds_insufficient(self): """Tests the transfer insufficient amount of funds is failed""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) bob_keys = KeyPair.generate() crypto_client.create_wallet(bob_keys, "Bob" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() tx_response = crypto_client.transfer( 110, alice_keys, bob_keys.public_key.value) subscriber.wait_for_new_event() tx_status = client.get_tx_info( tx_response.json()['tx_hash']).json()['status']['type'] self.assertEqual(tx_status, 'service_error') alice_balance = (crypto_client.get_wallet_info( alice_keys).json()['wallet_proof']['to_wallet'] ['entries'][0]['value']['balance']) bob_balance = (crypto_client.get_wallet_info( bob_keys).json()['wallet_proof']['to_wallet'] ['entries'][0]['value']['balance']) self.assertEqual(alice_balance, 100) self.assertEqual(bob_balance, 100)
def test_freeze_service(self): host, public_port, private_port = self.network.api_address(0) client = ExonumClient(host, public_port, private_port) # Create wallet alice_keys = KeyPair.generate() with ExonumCryptoAdvancedClient(client) as crypto_client: crypto_client.create_wallet(alice_keys, "Alice") with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() alice_balance = crypto_client.get_balance(alice_keys) self.assertEqual(alice_balance, 100) # Freeze the service instances = { "crypto": { "artifact": "cryptocurrency", "action": "freeze" } } cryptocurrency_advanced_config_dict = generate_config( self.network, instances=instances, artifact_action="none") cryptocurrency_advanced_config = Configuration( cryptocurrency_advanced_config_dict) with Launcher(cryptocurrency_advanced_config) as launcher: launcher.deploy_all() launcher.wait_for_deploy() launcher.start_all() launcher.wait_for_start() # Check that the service status has been changed to `frozen`. for service in client.public_api.available_services().json( )["services"]: if service["spec"]["name"] == "crypto": self.assertEqual(service["status"]["type"], "frozen") # Try to create a new wallet. The operation should fail. with ExonumCryptoAdvancedClient(client) as crypto_client: bob_keys = KeyPair.generate() response = crypto_client.create_wallet(bob_keys, "Bob") self.assertEqual(response.status_code, 400) # Because the service is frozen, transaction should be inadmissible. self.assertEqual(response.json()["title"], "Failed to add transaction to memory pool") # Check that we can use service endpoints for data retrieving. Check wallet once again. with ExonumCryptoAdvancedClient(client) as crypto_client: alice_balance = crypto_client.get_balance(alice_keys) self.assertEqual(alice_balance, 100)
def test_tx_validation(self): exonum_message = self.exonum_message # Gen init data: fake_keys = KeyPair.generate() # Check that validation of the original message passes successfully: self.assertTrue(exonum_message.validate()) # Check a corrupted author message: corrupt_message = copy.deepcopy(exonum_message) corrupt_message._author = fake_keys.public_key self.assertFalse(corrupt_message.validate()) # Check a corrupted signature message: corrupt_message = copy.deepcopy(exonum_message) sig = bytearray(corrupt_message._signature.value) sig[0] = sig[0] ^ 1 corrupt_message._signature.value = bytes(sig) self.assertFalse(corrupt_message.validate()) # Check a corrupted payload message: corrupt_message = copy.deepcopy(exonum_message) raw = bytearray(corrupt_message._signed_tx_raw) raw[0] = raw[0] ^ 1 corrupt_message._signed_tx_raw = bytes(raw) self.assertFalse(corrupt_message.validate())
def create_wallet(client: ExonumClient, message_generator: MessageGenerator, name: str) -> KeyPair: """Creates a wallet with the given name and returns a KeyPair for it.""" key_pair = KeyPair.generate() # Load the "service.proto" from the Cryptocurrency service: cryptocurrency_module = ModuleManager.import_service_module( CRYPTOCURRENCY_ARTIFACT_NAME, "service") # Create a Protobuf message: create_wallet_message = cryptocurrency_module.TxCreateWallet() create_wallet_message.name = name # Convert the Protobuf message to an Exonum message and sign it: create_wallet_tx = message_generator.create_message(create_wallet_message) create_wallet_tx.sign(key_pair) # Send the transaction to Exonum: response = client.send_transaction(create_wallet_tx) ensure_status_code(response) tx_hash = response.json()["tx_hash"] # Wait for new blocks: with client.create_subscriber() as subscriber: subscriber.wait_for_new_block() subscriber.wait_for_new_block() ensure_transaction_success(client, tx_hash) print(f"Successfully created wallet with name '{name}'") return key_pair
def setUpClass(cls): # Add a folder with the pre-compiled Protobuf messages to the path (so that it could be imported): sys.path.append(os.path.abspath("tests/proto_dir")) # Unload any previously loaded `exonum_main` modules from test_exonum_client: loaded_modules = list(sys.modules.keys()) for module in loaded_modules: if module.startswith("exonum_modules"): del sys.modules[module] # Gen init data: keys = KeyPair.generate() # Prepare an original message: cryptocurrency_service_name = "exonum-cryptocurrency-advanced:0.11.0" cryptocurrency_module = ModuleManager.import_service_module(cryptocurrency_service_name, "service") cryptocurrency_message_generator = MessageGenerator(1024, cryptocurrency_service_name) create_wallet_alice = cryptocurrency_module.CreateWallet() create_wallet_alice.name = "Alice" # Create an original message: create_wallet_alice_tx = cryptocurrency_message_generator.create_message(create_wallet_alice) create_wallet_alice_tx.sign(keys) cls.keys = keys cls.exonum_message = create_wallet_alice_tx cls.cryptocurrency_service_name = cryptocurrency_service_name
def test_create_wallet_unique_for_key_pair(self): """Tests the transaction with the same keys for different wallets is failed""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() tx_response = crypto_client.create_wallet( alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() # TODO: Sometimes it fails without time.sleep() [ECR-3876] time.sleep(2) tx_status = client.get_tx_info( tx_response.json()['tx_hash']).json()['status']['type'] self.assertEqual(tx_status, 'success') # create the wallet with the same keys again tx_same_keys = crypto_client.create_wallet( alice_keys, "Alice_Dublicate" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() tx_status = client.get_tx_info( tx_same_keys.json()['tx_hash']).json()['status']['type'] self.assertEqual(tx_status, 'service_error')
def setUpClass(cls): # Add a folder with the pre-compiled Protobuf messages to the path (so that it could be imported): sys.path.append(os.path.abspath("tests/proto_dir")) # Gen init data: keys = KeyPair.generate() # Prepare an original message: cryptocurrency_service_name = "exonum-cryptocurrency-advanced" version = "1.0.0" cryptocurrency_module = ModuleManager.import_service_module( cryptocurrency_service_name, version, "service") cryptocurrency_message_generator = MessageGenerator( 1024, cryptocurrency_service_name, version) create_wallet_alice = cryptocurrency_module.CreateWallet() create_wallet_alice.name = "Alice" # Create an original message: create_wallet_alice_tx = cryptocurrency_message_generator.create_message( create_wallet_alice) create_wallet_alice_tx.sign(keys) cls.keys = keys cls.exonum_message = create_wallet_alice_tx cls.cryptocurrency_service_name = cryptocurrency_service_name
def _create_wallet(self, client: ExonumClient, wallet_name: str, version: str) -> KeyPair: with ExonumCryptoAdvancedClient(client, INSTANCE_NAME, version) as crypto_client: keys = KeyPair.generate() response = crypto_client.create_wallet(keys, wallet_name) self.assertEqual(response.status_code, 200) with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() return keys
def test_keypair(self) -> None: """Tests the KeyPair class.""" public_key = PublicKey(bytes([i for i in range(PUBLIC_KEY_BYTES_LEN)])) secret_key = SecretKey(bytes([i for i in range(SECRET_KEY_BYTES_LEN)])) # Check that creation with unmatched keys raises an error: with self.assertRaises(ValueError): KeyPair(public_key, secret_key) # Check that generation of the keypair works: keypair = KeyPair.generate() self.assertTrue(isinstance(keypair.public_key, PublicKey)) self.assertTrue(isinstance(keypair.secret_key, SecretKey)) self.assertNotEqual(keypair.public_key, keypair.secret_key) self.assertEqual(keypair.secret_key.value[PUBLIC_KEY_BYTES_LEN:], keypair.public_key.value) # Check that creating a keypair from the matched keys works: _new_keypair = KeyPair(keypair.public_key, keypair.secret_key)
def test_get_nonexistent_wallet(self): """Tests the wallet history is None for nonexistent wallet""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() wallet_history = crypto_client.get_wallet_info( alice_keys).json()["wallet_history"] self.assertIsNone(wallet_history)
def test_add_funds_to_nonexistent_wallet(self): """Tests the funds issue is failed if wallet doesn't exist""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() tx_response = crypto_client.issue(alice_keys, 100) with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() tx_info = client.public_api.get_tx_info( tx_response.json()["tx_hash"]).json() tx_status = tx_info["status"]["type"] self.assertEqual(tx_status, "service_error")
def test_add_funds_to_nonexistent_wallet(self): """Tests the funds issue is failed if wallet doesn't exist""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() tx_response = crypto_client.issue(alice_keys, 100) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() # TODO: Sometimes it fails without time.sleep() [ECR-3876] time.sleep(2) tx_status = client.get_tx_info( tx_response.json()['tx_hash']).json()['status']['type'] self.assertEqual(tx_status, 'service_error')
def test_token_issue(self): """Tests the token issue""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() crypto_client.issue(alice_keys, 100) subscriber.wait_for_new_event() alice_balance = crypto_client.get_balance(alice_keys) self.assertEqual(alice_balance, 200)
def test_signature(self) -> None: """Tests the Signature class.""" keypair = KeyPair.generate() data = bytes([i for i in range(10)]) signature = Signature.sign(data, keypair.secret_key) self.assertTrue(isinstance(signature, Signature)) self.assertTrue(isinstance(signature, _FixedByteArray)) self.assertEqual(signature.value, crypto_sign_detached(data, keypair.secret_key.value)) self.assertTrue(signature.verify(data, keypair.public_key)) wrong_data = bytes([1, 2]) wrong_pk = PublicKey(bytes([i for i in range(_PUBLIC_KEY_BYTES_LEN)])) self.assertFalse(signature.verify(wrong_data, keypair.public_key)) self.assertFalse(signature.verify(data, wrong_pk))
def test_create_wallet(self): """Tests the wallet creation""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() self.assertEqual( crypto_client.get_wallet_info(alice_keys).status_code, 200) alice_wallet = crypto_client.get_wallet_info(alice_keys).json() alice_balance = alice_wallet["wallet_proof"]["to_wallet"][ "entries"][0]["value"]["balance"] self.assertEqual(alice_balance, 100)
def test_transfer_to_yourself(self): """Tests the transfer funds to yourself is impossible""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() crypto_client.transfer(10, alice_keys, alice_keys.public_key.value) subscriber.wait_for_new_event() alice_balance = (crypto_client.get_wallet_info( alice_keys).json()['wallet_proof']['to_wallet'] ['entries'][0]['value']['balance']) self.assertEqual(alice_balance, 100)
def test_create_wallet_same_name(self): """Tests the transaction with the same wallet name is rejected""" client = None for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() # create the wallet with the same name again crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() # it should contain 4 txs for wallet creation plus 6 services txs self.assertEqual(client.public_api.stats().json()["tx_count"], 10)
def test_create_wallet(self): """Tests the wallet creation""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() self.assertEqual( crypto_client.get_wallet_info(alice_keys).status_code, 200) # TODO: Sometimes it fails without time.sleep() [ECR-3876] time.sleep(2) alice_balance = (crypto_client.get_wallet_info( alice_keys).json()['wallet_proof']['to_wallet']['entries'] [0]['value']['balance']) self.assertEqual(alice_balance, 100)
def test_token_issue(self): """Tests the token issue""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() # TODO: Sometimes it fails without time.sleep() [ECR-3876] time.sleep(2) crypto_client.issue(alice_keys, 100) subscriber.wait_for_new_event() # TODO: Sometimes it fails without time.sleep() [ECR-3876] time.sleep(2) alice_wallet = crypto_client.get_wallet_info( alice_keys).json() alice_balance = alice_wallet["wallet_proof"]["to_wallet"][ "entries"][0]["value"]["balance"] self.assertEqual(alice_balance, 200)
def test_create_wallet_unique_for_key_pair(self): """Tests the transaction with the same keys for different wallets is failed""" for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address( validator_id) client = ExonumClient(host, public_port, private_port) with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() tx_response = crypto_client.create_wallet( alice_keys, "Alice" + str(validator_id)) with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() tx_status = client.public_api.get_tx_info( tx_response.json()["tx_hash"]).json()["status"]["type"] self.assertEqual(tx_status, "success") # create the wallet with the same keys again tx_same_keys = crypto_client.create_wallet( alice_keys, "Alice_Dublicate" + str(validator_id)) with client.create_subscriber("blocks") as subscriber: subscriber.wait_for_new_event() tx_status = client.public_api.get_tx_info( tx_same_keys.json()["tx_hash"]).json()["status"]["type"] self.assertEqual(tx_status, "service_error")
def test_deploy_regular_stop_and_resume_running_instance(self): """Tests the deploy mechanism to stop and resume running instance.""" instances = {"crypto": {"artifact": "cryptocurrency"}} cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances) cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict) with Launcher(cryptocurrency_advanced_config) as launcher: explorer = launcher.explorer() launcher.deploy_all() launcher.wait_for_deploy() launcher.start_all() launcher.wait_for_start() self.wait_for_api_restart() for artifact in launcher.launch_state.completed_deployments(): deployed = explorer.is_deployed(artifact) self.assertEqual(deployed, True) self.assertEqual(len(launcher.launch_state.completed_configs()), 1) # stop service instances = {"crypto": {"artifact": "cryptocurrency", "action": "stop"}} cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances, artifact_action="none") cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict) with Launcher(cryptocurrency_advanced_config) as launcher: launcher.deploy_all() launcher.wait_for_deploy() launcher.start_all() launcher.wait_for_start() # The changes restart the HTTP servers of the nodes, so we wait for the servers to restart. wait_network_to_start(self.network) for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address(validator_id) client = ExonumClient(host, public_port, private_port) available_services = client.public_api.available_services().json() service_status = find_service_status(available_services, "crypto") self.assertEqual(service_status, "stopped") with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() tx_response = crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) # in case of stopped service its tx will not be processed self.assertEqual(tx_response.status_code, 400) self.assertIn("Cannot dispatch transaction to non-active service", str(tx_response.content)) # resume service instances = {"crypto": {"artifact": "cryptocurrency", "action": "resume"}} cryptocurrency_advanced_config_dict = generate_config(self.network, instances=instances, artifact_action="none") cryptocurrency_advanced_config = Configuration(cryptocurrency_advanced_config_dict) with Launcher(cryptocurrency_advanced_config) as launcher: launcher.deploy_all() launcher.wait_for_deploy() launcher.start_all() launcher.wait_for_start() # The changes restart the HTTP servers of the nodes, so we wait for the servers to restart. self.wait_for_api_restart() for validator_id in range(self.network.validators_count()): host, public_port, private_port = self.network.api_address(validator_id) client = ExonumClient(host, public_port, private_port) available_services = client.public_api.available_services().json() service_status = find_service_status(available_services, "crypto") self.assertEqual(service_status, "active") with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() tx_response = crypto_client.create_wallet(alice_keys, "Alice" + str(validator_id)) # resumed service must process txs as usual self.assertEqual(tx_response.status_code, 200)
def test_resume_after_freeze_service(self): host, public_port, private_port = self.network.api_address(0) client = ExonumClient(host, public_port, private_port) # Create wallet with ExonumCryptoAdvancedClient(client) as crypto_client: alice_keys = KeyPair.generate() crypto_client.create_wallet(alice_keys, "Alice") with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() alice_balance = crypto_client.get_balance(alice_keys) self.assertEqual(alice_balance, 100) # Freeze the service instances = { "crypto": { "artifact": "cryptocurrency", "action": "freeze" } } cryptocurrency_advanced_config_dict = generate_config( self.network, instances=instances, artifact_action="none") cryptocurrency_advanced_config = Configuration( cryptocurrency_advanced_config_dict) with Launcher(cryptocurrency_advanced_config) as launcher: launcher.deploy_all() launcher.wait_for_deploy() launcher.start_all() launcher.wait_for_start() # Resume the service instances = { "crypto": { "artifact": "cryptocurrency", "action": "resume" } } cryptocurrency_advanced_config_dict = generate_config( self.network, instances=instances, artifact_action="none") cryptocurrency_advanced_config = Configuration( cryptocurrency_advanced_config_dict) with Launcher(cryptocurrency_advanced_config) as launcher: launcher.deploy_all() launcher.wait_for_deploy() launcher.start_all() launcher.wait_for_start() # Check that the service status has been changed to `active`. for service in client.public_api.available_services().json( )["services"]: if service["spec"]["name"] == "crypto": self.assertEqual(service["status"]["type"], "active") # Check that an ability to create wallets has been restored. with ExonumCryptoAdvancedClient(client) as crypto_client: bob_keys = KeyPair.generate() crypto_client.create_wallet(bob_keys, "Bob") with client.create_subscriber("transactions") as subscriber: subscriber.wait_for_new_event() bob_balance = crypto_client.get_balance(bob_keys) self.assertEqual(bob_balance, 100)