def test_unbonding_without_bonding(one_node_network_fn): """ Feature file: consensus.feature Scenario: unbonding a validator node which was not bonded to an existing network. """ bonding_amount = 1 account = Account(BONDING_ACCT) assert_pre_state_of_network(one_node_network_fn) add_funded_account_to_network(one_node_network_fn, BONDING_ACCT) assert ( len(one_node_network_fn.docker_nodes) == 2 ), "Total number of nodes should be 2." node0, node1 = one_node_network_fn.docker_nodes r = node0.d_client.unbond(bonding_amount, account.private_key_docker_path) assert "Success!" in r r = node0.d_client.propose() block_hash = extract_block_hash_from_propose_output(r) assert block_hash is not None # block_hash, account = unbond_from_network(one_node_network_fn, bonding_amount, BONDING_ACCT) r = node0.client.show_deploys(block_hash)[0] assert r.is_error is True assert r.error_message == "Exit code: 65280" block = node1.client.show_block(block_hash) block_ds = parse_show_block(block) bonds = list( filter( lambda x: x.validator_public_key == account.public_key_hex, block_ds.summary.header.state.bonds, ) ) assert len(bonds) == 0
def my_call(self, kwargs): self.block_hash = None try: self.block_hash = extract_block_hash_from_propose_output( self.node.client.propose()) except NonZeroExitCodeError: # Ignore error for no new deploys pass
def deploy_and_propose(node, contract): node.p_client.deploy( session_contract=contract, from_address=GENESIS_ACCOUNT.public_key_hex, public_key=GENESIS_ACCOUNT.public_key_path, private_key=GENESIS_ACCOUNT.private_key_path, ) return extract_block_hash_from_propose_output(node.client.propose())
def unbond_from_network( network: OneNodeNetwork, bonding_amount: int, account_number: int ): node = network.docker_nodes[1] account = Account(account_number) r = node.d_client.unbond(bonding_amount, account.private_key_docker_path) assert "Success!" in r r = node.d_client.propose() block_hash = extract_block_hash_from_propose_output(r) assert block_hash is not None return block_hash, account
def bond_to_the_network(network: OneNodeNetwork, bond_amount: int, account_number: int): # Using account that will not exist in bonds.txt from high number account = Account(account_number) node0, node1 = network.docker_nodes response = node0.d_client.bond( amount=bond_amount, private_key=account.private_key_docker_path ) assert "Success!" in response response = node0.d_client.propose() block_hash = extract_block_hash_from_propose_output(response) assert block_hash is not None return block_hash, account
def propose_with_retry(self, max_attempts: int, retry_seconds: int) -> str: # TODO: Is this still true with Nonces gone. # With many threads using the same account the nonces will be interleaved. # Only one node can propose at a time, the others have to wait until they # receive the block and then try proposing again. attempt = 0 while True: try: return extract_block_hash_from_propose_output(self.propose()) except NonZeroExitCodeError as ex: if attempt < max_attempts: self.logger.debug("Could not propose; retrying later.") attempt += 1 time.sleep(retry_seconds) else: self.logger.debug("Could not propose; no more retries!") raise ex
def deploy_and_propose(node, contract): deploy_output = node.client.deploy( from_address=GENESIS_ACCOUNT.public_key_hex, public_key=GENESIS_ACCOUNT.public_key_path, private_key=GENESIS_ACCOUNT.private_key_path, session_contract=contract, ) if type(deploy_output) == str: assert "Success" in deploy_output else: logging.info(f"deploy_output: {deploy_output}") pass # TODO: assert output of Python client propose_output = node.client.propose() if type(propose_output) == str: return extract_block_hash_from_propose_output(propose_output) else: return propose_output.block_hash.hex()
def add_funded_account_to_network(network: OneNodeNetwork, account_number: int): node0 = network.docker_nodes[0] prev_number = len(network.docker_nodes) account = network.add_new_node_to_network(account=Account(account_number)) assert ( len(network.docker_nodes) == prev_number + 1 ), f"Total number of nodes should be {prev_number + 1}." response = node0.d_client.transfer( amount=1000000000, private_key=GENESIS_ACCOUNT.private_key_docker_path, target_account=account.public_key, ) assert "Success!" in response response = node0.d_client.propose() block_hash = extract_block_hash_from_propose_output(response) assert block_hash is not None r = node0.client.show_deploys(block_hash)[0] assert r.is_error is False, f"Transfer Failed: {r.error_message}" assert r.error_message == ""
def deploy_and_propose(self, **deploy_kwargs) -> str: if "from_address" not in deploy_kwargs: deploy_kwargs["from_address"] = self.node.from_address deploy_output = self.deploy(**deploy_kwargs) if "Success!" not in deploy_output: raise Exception(f"Deploy failed: {deploy_output}") propose_output = self.propose() block_hash = extract_block_hash_from_propose_output(propose_output) if block_hash is None: raise Exception( f"Block Hash not extracted from propose output: {propose_output}" ) self.logger.info( f"The block hash: {block_hash} generated for {self.node.container_name}" ) return block_hash
def test_extract_block_hash_from_propose_output() -> None: response = "Response: Success! Block a91208047c created and added.\n" assert extract_block_hash_from_propose_output(response) == "a91208047c"
def propose(node): return extract_block_hash_from_propose_output(node.d_client.propose())