def test_policy_before_future( self, cluster: clusterlib.ClusterLib, issuers_addrs: List[clusterlib.AddressRecord]): """Test that it's NOT possible to mint tokens. The "before" slot is in the future and the given range is invalid. """ temp_template = helpers.get_func_name() rand = clusterlib.get_rand_str(4) amount = 5 token_mint_addr = issuers_addrs[0] payment_vkey_files = [p.vkey_file for p in issuers_addrs] before_slot = cluster.get_slot_no() + 10_000 # create multisig script multisig_script = cluster.build_multisig_script( script_name=temp_template, script_type_arg=clusterlib.MultiSigTypeArgs.ALL, payment_vkey_files=payment_vkey_files[1:], slot=before_slot, slot_type_arg=clusterlib.MultiSlotTypeArgs.BEFORE, ) policyid = cluster.get_policyid(multisig_script) tokens_to_mint = [] for tnum in range(5): asset_name = f"couttscoin{rand}{tnum}" token = f"{policyid}.{asset_name}" assert not cluster.get_utxo(token_mint_addr.address, coins=[ token ]), "The token already exists" tokens_to_mint.append( clusterlib_utils.TokenRecord( token=token, asset_name=asset_name, amount=amount, issuers_addrs=issuers_addrs, token_mint_addr=token_mint_addr, script=multisig_script, )) # token minting - invalid range, slot is in the future with pytest.raises(clusterlib.CLIError) as excinfo: _mint_or_burn_witness( cluster_obj=cluster, new_tokens=tokens_to_mint, temp_template=f"{temp_template}_mint", invalid_before=1, invalid_hereafter=before_slot + 1, ) assert "ScriptWitnessNotValidatingUTXOW" in str(excinfo.value) for t in tokens_to_mint: token_utxo = cluster.get_utxo(token_mint_addr.address, coins=[t.token]) assert not token_utxo, "The token was minted unexpectedly"
def new_token( self, cluster_manager: cluster_management.ClusterManager, cluster: clusterlib.ClusterLib, payment_addrs: List[clusterlib.AddressRecord], ) -> clusterlib_utils.TokenRecord: with cluster_manager.cache_fixture() as fixture_cache: if fixture_cache.value: return fixture_cache.value # type: ignore rand = clusterlib.get_rand_str(4) temp_template = f"test_tx_new_token_{rand}" asset_name = f"couttscoin{rand}" new_tokens = clusterlib_utils.new_tokens( asset_name, cluster_obj=cluster, temp_template=temp_template, token_mint_addr=payment_addrs[0], issuer_addr=payment_addrs[1], amount=20_000_000, ) new_token = new_tokens[0] fixture_cache.value = new_token return new_token
def test_pool_registration_fees( self, cluster: clusterlib.ClusterLib, temp_dir: Path, pool_users: List[clusterlib.PoolUser], addr_fee: Tuple[int, int], ): """Test pool registration fees.""" no_of_addr, expected_fee = addr_fee rand_str = clusterlib.get_rand_str(4) temp_template = f"{helpers.get_func_name()}_{rand_str}_{no_of_addr}" pool_name = f"pool_{rand_str}" pool_metadata = { "name": pool_name, "description": "Shelley QA E2E test Test", "ticker": "QA1", "homepage": "www.test1.com", } pool_metadata_file = helpers.write_json( temp_dir / f"{pool_name}_registration_metadata.json", pool_metadata) pool_data = clusterlib.PoolData( pool_name=pool_name, pool_pledge=1000, pool_cost=15, pool_margin=0.2, pool_metadata_url="https://www.where_metadata_file_is_located.com", pool_metadata_hash=cluster.gen_pool_metadata_hash( pool_metadata_file), ) # create pool owners selected_owners = pool_users[:no_of_addr] # create certificates src_address, tx_files = self._create_pool_certificates( cluster_obj=cluster, pool_owners=selected_owners, temp_template=temp_template, pool_data=pool_data, ) # calculate TX fee tx_fee = cluster.calculate_tx_fee(src_address=src_address, tx_name=temp_template, tx_files=tx_files) assert helpers.is_in_interval( tx_fee, expected_fee), "Expected fee doesn't match the actual fee"
def get_test_id(cluster_obj: clusterlib.ClusterLib) -> str: """Return unique test ID - function name + assigned cluster instance + random string. Log the test ID into cluster manager log file. """ curr_test = get_current_test() rand_str = clusterlib.get_rand_str(3) test_id = f"{curr_test.test_function}_ci{cluster_obj.cluster_id}_{rand_str}" # log test ID to cluster manager log file - getting test ID happens early # after the start of a test, so the log entry can be used for determining # time of the test start cm: cluster_management.ClusterManager = cluster_obj._cluster_manager # type: ignore cm._log( f"c{cm.cluster_instance_num}: got ID `{test_id}` for `{curr_test.full}`" ) return test_id
def _create_startup_files_dir(self, instance_num: int) -> Path: instance_dir = self.pytest_tmp_dir / f"{CLUSTER_DIR_TEMPLATE}{instance_num}" rand_str = clusterlib.get_rand_str(8) startup_files_dir = instance_dir / "startup_files" / rand_str startup_files_dir.mkdir(exist_ok=True, parents=True) return startup_files_dir
def test_pool_deregistration_fees( self, cluster: clusterlib.ClusterLib, temp_dir: Path, pool_users: List[clusterlib.PoolUser], addr_fee: Tuple[int, int], ): """Test pool deregistration fees.""" no_of_addr, expected_fee = addr_fee rand_str = clusterlib.get_rand_str(4) temp_template = f"{helpers.get_func_name()}_{rand_str}_{no_of_addr}" src_address = pool_users[0].payment.address pool_name = f"pool_{rand_str}" pool_metadata = { "name": pool_name, "description": "Shelley QA E2E test Test", "ticker": "QA1", "homepage": "www.test1.com", } pool_metadata_file = helpers.write_json( temp_dir / f"{pool_name}_registration_metadata.json", pool_metadata) pool_data = clusterlib.PoolData( pool_name=pool_name, pool_pledge=222, pool_cost=123, pool_margin=0.512, pool_metadata_url="https://www.where_metadata_file_is_located.com", pool_metadata_hash=cluster.gen_pool_metadata_hash( pool_metadata_file), ) # create pool owners selected_owners = pool_users[:no_of_addr] # create node cold key pair and counter node_cold = cluster.gen_cold_key_pair_and_counter( node_name=pool_data.pool_name) # create deregistration certificate pool_dereg_cert_file = cluster.gen_pool_deregistration_cert( pool_name=pool_data.pool_name, cold_vkey_file=node_cold.vkey_file, epoch=cluster.get_epoch() + 1, ) tx_files = clusterlib.TxFiles( certificate_files=[pool_dereg_cert_file], signing_key_files=[ *[p.payment.skey_file for p in selected_owners], *[p.stake.skey_file for p in selected_owners], node_cold.skey_file, ], ) # calculate TX fee tx_fee = cluster.calculate_tx_fee(src_address=src_address, tx_name=temp_template, tx_files=tx_files) assert helpers.is_in_interval( tx_fee, expected_fee), "Expected fee doesn't match the actual fee"
def test_valid_policy_before( self, cluster: clusterlib.ClusterLib, issuers_addrs: List[clusterlib.AddressRecord]): """Test minting and burning tokens before given slot.""" expected_fee = 351093 temp_template = helpers.get_func_name() rand = clusterlib.get_rand_str(4) amount = 5 token_mint_addr = issuers_addrs[0] payment_vkey_files = [p.vkey_file for p in issuers_addrs] before_slot = cluster.get_slot_no() + 10_000 # create multisig script multisig_script = cluster.build_multisig_script( script_name=temp_template, script_type_arg=clusterlib.MultiSigTypeArgs.ALL, payment_vkey_files=payment_vkey_files[1:], slot=before_slot, slot_type_arg=clusterlib.MultiSlotTypeArgs.BEFORE, ) policyid = cluster.get_policyid(multisig_script) tokens_to_mint = [] for tnum in range(5): asset_name = f"couttscoin{rand}{tnum}" token = f"{policyid}.{asset_name}" assert not cluster.get_utxo(token_mint_addr.address, coins=[ token ]), "The token already exists" tokens_to_mint.append( clusterlib_utils.TokenRecord( token=token, asset_name=asset_name, amount=amount, issuers_addrs=issuers_addrs, token_mint_addr=token_mint_addr, script=multisig_script, )) # token minting tx_out_mint = _mint_or_burn_witness( cluster_obj=cluster, new_tokens=tokens_to_mint, temp_template=f"{temp_template}_mint", invalid_before=100, invalid_hereafter=cluster.get_slot_no() + 1000, ) for t in tokens_to_mint: token_utxo = cluster.get_utxo(token_mint_addr.address, coins=[t.token]) assert token_utxo and token_utxo[ 0].amount == amount, "The token was not minted" # token burning tokens_to_burn = [t._replace(amount=-amount) for t in tokens_to_mint] tx_out_burn = _mint_or_burn_witness( cluster_obj=cluster, new_tokens=tokens_to_burn, temp_template=f"{temp_template}_burn", invalid_before=100, invalid_hereafter=cluster.get_slot_no() + 1000, ) for t in tokens_to_burn: token_utxo = cluster.get_utxo(token_mint_addr.address, coins=[t.token]) assert not token_utxo, "The token was not burnt" # check expected fees assert helpers.is_in_interval( tx_out_mint.fee, expected_fee, frac=0.15) and helpers.is_in_interval( tx_out_burn.fee, expected_fee, frac=0.15), "TX fee doesn't fit the expected interval"
def test_multi_minting_and_burning_sign( self, cluster: clusterlib.ClusterLib, issuers_addrs: List[clusterlib.AddressRecord], simple_script_policyid: Tuple[Path, str], tokens_db: Tuple[int, int], ): """Test minting and burning multiple different tokens, sign the TX using skeys.""" temp_template = helpers.get_func_name() rand = clusterlib.get_rand_str(8) amount = 5 tokens_num, expected_fee = tokens_db token_mint_addr = issuers_addrs[0] issuer_addr = issuers_addrs[1] script, policyid = simple_script_policyid tokens_to_mint = [] for tnum in range(tokens_num): asset_name = f"couttscoin{rand}{tnum}" token = f"{policyid}.{asset_name}" tokens_to_mint.append( clusterlib_utils.TokenRecord( token=token, asset_name=asset_name, amount=amount, issuers_addrs=[issuer_addr], token_mint_addr=token_mint_addr, script=script, )) # token minting minting_args = { "cluster_obj": cluster, "new_tokens": tokens_to_mint, "temp_template": f"{temp_template}_mint", } if tokens_num >= 500: with pytest.raises(clusterlib.CLIError) as excinfo: clusterlib_utils.mint_or_burn_sign( **minting_args) # type: ignore if tokens_num >= 1000: assert "(UtxoFailure (MaxTxSizeUTxO" in str(excinfo.value) else: assert "(UtxoFailure (OutputTooBigUTxO" in str(excinfo.value) return tx_out_mint = clusterlib_utils.mint_or_burn_sign( **minting_args) # type: ignore for t in tokens_to_mint: token_utxo = cluster.get_utxo(token_mint_addr.address, coins=[t.token]) assert token_utxo and token_utxo[ 0].amount == amount, "The token was not minted" # token burning tokens_to_burn = [t._replace(amount=-amount) for t in tokens_to_mint] tx_out_burn = clusterlib_utils.mint_or_burn_sign( cluster_obj=cluster, new_tokens=tokens_to_burn, temp_template=f"{temp_template}_burn", ) for t in tokens_to_burn: token_utxo = cluster.get_utxo(token_mint_addr.address, coins=[t.token]) assert not token_utxo, "The token was not burnt" # check expected fees assert helpers.is_in_interval( tx_out_mint.fee, expected_fee, frac=0.15) and helpers.is_in_interval( tx_out_burn.fee, expected_fee, frac=0.15), "TX fee doesn't fit the expected interval"
def test_transfer_multiple_tokens( self, cluster: clusterlib.ClusterLib, payment_addrs: List[clusterlib.AddressRecord], new_token: clusterlib_utils.TokenRecord, ): """Test sending multiple different tokens to payment address. * send multiple different tokens from 1 source address to 1 destination address * check expected token balances for both source and destination addresses for each token * check fees in Lovelace """ temp_template = helpers.get_func_name() amount = 1000 amount_lovelace = 10 rand = clusterlib.get_rand_str(5) new_tokens = clusterlib_utils.new_tokens( *[f"couttscoin{rand}{i}" for i in range(5)], cluster_obj=cluster, temp_template=f"{temp_template}_{rand}", token_mint_addr=payment_addrs[0], issuer_addr=payment_addrs[1], amount=1_000_000, ) new_tokens.append(new_token) src_address = new_token.token_mint_addr.address dst_address = payment_addrs[2].address src_init_balance = cluster.get_address_balance(src_address) src_init_balance_tokens = [ cluster.get_address_balance(src_address, coin=t.token) for t in new_tokens ] dst_init_balance_tokens = [ cluster.get_address_balance(dst_address, coin=t.token) for t in new_tokens ] destinations = [ clusterlib.TxOut(address=dst_address, amount=amount, coin=t.token) for t in new_tokens ] destinations.append( clusterlib.TxOut(address=dst_address, amount=amount_lovelace)) tx_files = clusterlib.TxFiles(signing_key_files={ t.token_mint_addr.skey_file for t in new_tokens }) tx_raw_output = cluster.send_funds( src_address=src_address, destinations=destinations, tx_name=temp_template, tx_files=tx_files, ) cluster.wait_for_new_block(new_blocks=2) assert ( cluster.get_address_balance(src_address) == src_init_balance - tx_raw_output.fee - amount_lovelace ), f"Incorrect Lovelace balance for source address `{src_address}`" for idx, token in enumerate(new_tokens): assert ( cluster.get_address_balance( src_address, coin=token.token) == src_init_balance_tokens[idx] - amount ), f"Incorrect token #{idx} balance for source address `{src_address}`" assert ( cluster.get_address_balance( dst_address, coin=token.token) == dst_init_balance_tokens[idx] + amount ), f"Incorrect token #{idx} balance for destination address `{dst_address}`"