def get_client_contract_hash(client: casperlabs_client.CasperLabsClient, account: Account, bhash: str, contract_name: str) -> str: """Returns chain hash of a deployed client side conttract. :param client: A python client instance. :param account: Account to be associated with contract. :param bhash: Hash of block which processed deploy. :param contract_name: Name of smart contract (within wasm blob). :returns: Deploy client side contract hash. """ q = client.queryState(bhash, account.public_key, "", keyType="address") for nk in q.account.named_keys: if nk.name == contract_name: return nk.key.hash.hash.hex() raise ValueError( f"{contract_name} contract hash could not be found on-chain")
class PythonClient(CasperLabsClientBase, LoggingMixin): def __init__(self, node: "DockerNode"): # NOQA super(PythonClient, self).__init__() self.node = node self.abi = ABI host = node.node_host certificate_file = None node_id = None if self.node.config.grpc_encryption: certificate_file = self.node.config.tls_certificate_local_path() node_id = extract_common_name(certificate_file) self.client = CasperLabsClient( host=host, port_internal=self.node.grpc_internal_docker_port, port=self.node.grpc_external_docker_port, node_id=node_id, certificate_file=certificate_file, ) logging.info(f"PythonClient(host={self.client.host}, " f"port={self.node.grpc_external_docker_port}, " f"port_internal={self.node.grpc_internal_docker_port})") def __getattr__(self, name): """ Compatibility with the times when this class was derived from CasperLabsClient, some tests may need to call methods of self.client directly """ return getattr(self.client, name) @property def client_type(self) -> str: return "python" def deploy( self, from_address: str = None, gas_price: int = 1, session_contract: Optional[Union[str, Path]] = None, payment_contract: Optional[Union[str, Path]] = Contract.STANDARD_PAYMENT, private_key: Optional[str] = None, public_key: Optional[str] = None, session_args: list = None, payment_args: bytes = DEFAULT_PAYMENT_ABI, alt_session_path: Optional[Path] = None, alt_payment_path: Optional[Path] = None, ) -> str: if session_contract is None: raise Exception("session_contract is required.") public_key = public_key or self.node.test_account.public_key_path private_key = private_key or self.node.test_account.private_key_path address = from_address or self.node.from_address # dApp test framework will specify alternate location for non-framework contracts session_path = (alt_session_path if alt_session_path else self.node.resources_folder) session_contract_path = session_path / session_contract payment_path = (alt_payment_path if alt_payment_path else self.node.resources_folder) payment_contract_path = payment_path / payment_contract logging.info(f"PY_CLIENT.deploy(from_address={address}, " f"gas_price={gas_price}, " f"payment_contract={payment_contract_path}, " f"session_contract={session_contract_path}, " f"private_key={private_key}, " f"public_key={public_key} ") return self.client.deploy( bytes.fromhex(address), gas_price, payment_contract_path, session_contract_path, public_key, private_key, session_args, payment_args, ) def propose(self): logging.info(f"PY_CLIENT.propose() for {self.client.host}") return self.client.propose() def query_state(self, block_hash: str, key: str, path: str, key_type: str): return self.client.queryState(block_hash, key, path, key_type) def show_block(self, block_hash: str): return self.client.showBlock(block_hash) def show_blocks(self, depth: int): return self.client.showBlocks(depth) def get_blocks_count(self, depth: int) -> int: return len(list(self.show_blocks(depth))) def show_deploys(self, block_hash: str): return self.client.showDeploys(block_hash) def show_deploy(self, deploy_hash: str): return self.client.showDeploy(deploy_hash) def propose_with_retry(self, max_attempts: int, retry_seconds: int) -> str: attempt = 0 while True: try: return self.propose() except InternalError 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(self, **deploy_kwargs) -> str: if "from_address" not in deploy_kwargs: deploy_kwargs["from_address"] = self.node.from_address self.deploy(**deploy_kwargs) propose_output = self.propose() block_hash = propose_output.block_hash.hex() logging.info( f"The block hash: {block_hash} generated for {self.node.container_name}" ) return block_hash def deploy_and_propose_with_retry(self, max_attempts: int, retry_seconds: int, **deploy_kwargs) -> str: self.deploy(**deploy_kwargs) block_hash = self.propose_with_retry(max_attempts, retry_seconds) logging.info( f"The block hash: {block_hash} generated for {self.node.container_name}" ) if block_hash is None: raise Exception("No block_hash received from propose_with_retry") return block_hash
class PythonClient(CasperLabsClientBase, LoggingMixin): def __init__(self, node: "DockerNode"): # NOQA super(PythonClient, self).__init__() self.node = node self.abi = ABI host = node.node_host certificate_file = None node_id = None if self.node.config.grpc_encryption: certificate_file = self.node.config.tls_certificate_local_path() node_id = extract_common_name(certificate_file) self.client = CasperLabsClient( host=host, port_internal=self.node.grpc_internal_docker_port, port=self.node.grpc_external_docker_port, node_id=node_id, certificate_file=certificate_file, ) logging.info( f"PythonClient(host={self.client.host}, " f"port={self.node.grpc_external_docker_port}, " f"port_internal={self.node.grpc_internal_docker_port})" ) def __getattr__(self, name): """ Compatibility with the times when this class was derived from CasperLabsClient, some tests may need to call methods of self.client directly """ return getattr(self.client, name) @property def client_type(self) -> str: return "python" def deploy( self, from_address: str = None, gas_price: int = 1, session_contract: Optional[Union[str, Path]] = None, payment_contract: Optional[Union[str, Path]] = Contract.STANDARD_PAYMENT, private_key: Optional[str] = None, public_key: Optional[str] = None, session_args: list = None, payment_args: bytes = DEFAULT_PAYMENT_ABI, alt_session_path: Optional[Path] = None, alt_payment_path: Optional[Path] = None, ) -> str: if session_contract is None: raise Exception("session_contract is required.") public_key = public_key or self.node.test_account.public_key_path private_key = private_key or self.node.test_account.private_key_path address = from_address or self.node.from_address # dApp test framework will specify alternate location for non-framework contracts session_path = ( alt_session_path if alt_session_path else self.node.resources_folder ) session_contract_path = session_path / session_contract payment_path = ( alt_payment_path if alt_payment_path else self.node.resources_folder ) payment_contract_path = payment_path / payment_contract logging.info( f"PY_CLIENT.deploy(from_address={address}, " f"gas_price={gas_price}, " f"payment_contract={payment_contract_path}, " f"session_contract={session_contract_path}, " f"private_key={private_key}, " f"public_key={public_key} " ) return self.client.deploy( bytes.fromhex(address), gas_price, payment_contract_path, session_contract_path, public_key, private_key, session_args, payment_args, ) def query_state(self, block_hash: str, key: str, path: str, key_type: str): return self.client.queryState(block_hash, key, path, key_type) def show_block(self, block_hash: str): return self.client.showBlock(block_hash) def show_blocks(self, depth: int): return self.client.showBlocks(depth) def get_blocks_count(self, depth: int) -> int: return len(list(self.show_blocks(depth))) def show_deploys(self, block_hash: str): return self.client.showDeploys(block_hash) def show_deploy(self, deploy_hash: str): return self.client.showDeploy(deploy_hash)
class PythonClient(CasperLabsClient, LoggingMixin): def __init__(self, node: "DockerNode"): # NOQA super(PythonClient, self).__init__() self.node = node self.abi = ABI # If $TAG_NAME is set it means we are running in docker, see docker_run_test.sh host = (os.environ.get("TAG_NAME", None) and self.node.container_name or "localhost") certificate_file = None node_id = None if self.node.config.grpc_encryption: certificate_file = self.node.config.tls_certificate_local_path() node_id = extract_common_name(certificate_file) self.client = CasperLabsClient( host=host, internal_port=self.node.grpc_internal_docker_port, port=self.node.grpc_external_docker_port, node_id=node_id, certificate_file=certificate_file, ) logging.info(f"PythonClient(host={self.client.host}, " f"port={self.node.grpc_external_docker_port}, " f"internal_port={self.node.grpc_internal_docker_port})") @property def client_type(self) -> str: return "python" def deploy( self, from_address: str = None, gas_price: int = 1, session_contract: Optional[Union[str, Path]] = None, payment_contract: Optional[Union[str, Path]] = Contract.STANDARD_PAYMENT, private_key: Optional[str] = None, public_key: Optional[str] = None, session_args: list = None, payment_args: list = MAX_PAYMENT_ABI, ) -> str: assert session_contract is not None public_key = public_key or self.node.test_account.public_key_path private_key = private_key or self.node.test_account.private_key_path address = from_address or self.node.from_address resources_path = self.node.resources_folder session_contract_path = str(resources_path / session_contract) payment_contract_path = str(resources_path / payment_contract) logging.info( f"PY_CLIENT.deploy(from_address={address}, gas_price={gas_price}, " f"payment_contract={payment_contract_path}, session_contract={session_contract_path}, " f"private_key={private_key}, " f"public_key={public_key} ") return self.client.deploy( bytes.fromhex(address), gas_price, payment_contract_path, session_contract_path, public_key, private_key, session_args, payment_args, ) def propose(self): logging.info(f"PY_CLIENT.propose() for {self.client.host}") return self.client.propose() def query_state(self, block_hash: str, key: str, path: str, key_type: str): return self.client.queryState(block_hash, key, path, key_type) def show_block(self, block_hash: str): return self.client.showBlock(block_hash) def show_blocks(self, depth: int): return self.client.showBlocks(depth) def get_blocks_count(self, depth: int) -> int: return len(list(self.show_blocks(depth))) def show_deploys(self, block_hash: str): return self.client.showDeploys(block_hash) def show_deploy(self, deploy_hash: str): return self.client.showDeploy(deploy_hash) def propose_with_retry(self, max_attempts: int, retry_seconds: int) -> str: attempt = 0 while True: try: return self.propose() except InternalError 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(self, **deploy_kwargs) -> str: if "from_address" not in deploy_kwargs: deploy_kwargs["from_address"] = self.node.from_address self.deploy(**deploy_kwargs) propose_output = self.propose() block_hash = propose_output.block_hash.hex() logging.info( f"The block hash: {block_hash} generated for {self.node.container_name}" ) return block_hash def deploy_and_propose_with_retry(self, max_attempts: int, retry_seconds: int, **deploy_kwargs) -> str: self.deploy(**deploy_kwargs) block_hash = self.propose_with_retry(max_attempts, retry_seconds) logging.info( f"The block hash: {block_hash} generated for {self.node.container_name}" ) if block_hash is None: raise Exception("No block_hash received from propose_with_retry") return block_hash
class PythonClient(CasperLabsClient, LoggingMixin): def __init__(self, node: "DockerNode"): # NOQA super(PythonClient, self).__init__() self.node = node self.abi = ABI # If $TAG_NAME is set it means we are running in docker, see docker_run_test.sh host = (os.environ.get("TAG_NAME", None) and self.node.container_name or "localhost") self.client = CasperLabsClient( host=host, internal_port=self.node.grpc_internal_docker_port, port=self.node.grpc_external_docker_port, ) logging.info(f"PythonClient(host={self.client.host}, " f"port={self.node.grpc_external_docker_port}, " f"internal_port={self.node.grpc_internal_docker_port})") @property def client_type(self) -> str: return "python" def deploy( self, from_address: str = None, gas_limit: int = 1000000, gas_price: int = 1, nonce: int = None, session_contract: Optional[str] = None, payment_contract: Optional[str] = None, private_key: Optional[str] = None, public_key: Optional[str] = None, session_args: list = None, payment_args: list = None, ) -> str: assert session_contract is not None assert payment_contract is not None public_key = public_key or self.node.test_account.public_key_path private_key = private_key or self.node.test_account.private_key_path address = from_address or self.node.from_address deploy_nonce = nonce if nonce is not None else NonceRegistry.next( address) resources_path = self.node.resources_folder session_contract_path = str(resources_path / session_contract) payment_contract_path = str(resources_path / payment_contract) logging.info( f"PY_CLIENT.deploy(from_address={address}, gas_limit={gas_limit}, gas_price={gas_price}, " f"payment_contract={payment_contract_path}, session_contract={session_contract_path}, " f"private_key={private_key}, " f"public_key={public_key}, " f"nonce={deploy_nonce})") try: r = self.client.deploy( bytes.fromhex(address), gas_limit, gas_price, payment_contract_path, session_contract_path, deploy_nonce, public_key, private_key, session_args, payment_args, ) return r except Exception: if nonce is None: NonceRegistry.revert(address) raise def propose(self) -> str: logging.info(f"PY_CLIENT.propose() for {self.client.host}") return self.client.propose() def query_state(self, block_hash: str, key: str, path: str, key_type: str): return self.client.queryState(block_hash, key, path, key_type) def show_block(self, block_hash: str): return self.client.showBlock(block_hash) def show_blocks(self, depth: int): return self.client.showBlocks(depth) def get_blocks_count(self, depth: int) -> int: return len(list(self.show_blocks(depth))) def show_deploys(self, block_hash: str): return self.client.showDeploys(block_hash) def show_deploy(self, deploy_hash: str): return self.client.showDeploy(deploy_hash) def propose_with_retry(self, max_attempts: int, retry_seconds: int) -> str: attempt = 0 while True: try: return self.propose() except InternalError 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