def test_big_map_arity_error(self, client): def cmd(): client.typecheck( os.path.join(CONTRACT_PATH, 'ill_typed', 'big_map_arity.tz')) utils.assert_run_failure( cmd, 'primitive EMPTY_BIG_MAP expects 2 arguments but is given 1.')
def test_ticket_user_forge(self, client): bake(client) init_with_transfer( client, path.join(OPCODES_CONTRACT_PATH, 'ticket_store-2.tz'), 'None', 100, 'bootstrap1', 'storer', ) # Create parameter by hand with a ticket type but no ticket in it client.transfer(100, 'bootstrap1', 'storer', ['-arg', 'None', '--burn-cap', '10']) with assert_run_failure(r'Unexpected forged value'): # Create parameter by hand with a ticket in it client.transfer( 100, 'bootstrap1', 'storer', ['-arg', 'Some 1', '--burn-cap', '10'], ) with assert_run_failure(r'Unexpected forged value'): # Create storage by hand with a ticket in it init_with_transfer( client, path.join(OPCODES_CONTRACT_PATH, 'ticket_bad.tz'), '1', 100, 'bootstrap1', 'ticket_bad', )
def test_vote_for_delegate_wrong_identity2(self, client): def client_cmd(): client.transfer(0, "bootstrap2", "vote_for_delegate", ['-arg', 'None', '--burn-cap', '10']) # We check failure of CHECK_SIGNATURE ; ASSERT in the script. utils.assert_run_failure(client_cmd, "At line 15 characters 57 to 61")
def test_typecheck_set_bad_ordering(self, client): def client_cmd(): client.typecheck_data('{ "A" ; "C" ; "B" }', '(set string)') expected_error = \ ("Values in a set literal must be in strictly" + " ascending order, but they were unordered in literal") utils.assert_run_failure(client_cmd, expected_error)
def test_typecheck_set_no_duplicates(self, client): def client_cmd(): client.typecheck_data('{ "A" ; "B" ; "B" }', '(set string)') expected_error = \ ("Set literals cannot contain duplicate values," + " however a duplicate value was found") utils.assert_run_failure(client_cmd, expected_error)
def test_typecheck_map_dup_key(self, client): def client_cmd(): client.typecheck_data('{ Elt 0 1 ; Elt 0 1}', '(map nat nat)') expected_error = \ ('Map literals cannot contain duplicate' + ' keys, however a duplicate key was found') utils.assert_run_failure(client_cmd, expected_error)
def test_legacy_typecheck(self, client_regtest, contract): client = client_regtest def cmd(): client.typecheck(path.join(CONTRACT_PATH, contract)) utils.assert_run_failure(cmd, r'Use of deprecated instruction')
def test_typecheck_map_bad_ordering(self, client): def client_cmd(): client.typecheck_data('{ Elt 0 1 ; Elt 10 1 ; Elt 5 1 }', '(map nat nat)') expected_error = \ ("Keys in a map literal must be in strictly" + " ascending order, but they were unordered in literal") utils.assert_run_failure(client_cmd, expected_error)
def test_slice_fails(self, client_regtest_scrubbed, contract_arg): client = client_regtest_scrubbed def cmd(): client.transfer(0, 'bootstrap1', 'slices', ['-arg', contract_arg, '--burn-cap', '10']) assert_run_failure(cmd, r'script reached FAILWITH instruction')
def test_fails_annotated_set_car_cdr(self, client_regtest): """Tests the SET_CAR and SET_CDR instructions.""" client = client_regtest def cmd(): client.run_script(path.join(OPCODES_CONTRACT_PATH, 'set_car.tz'), '(Pair %wrong %field "hello" 0)', '""') assert_run_failure(cmd, r'The two annotations do not match')
def test_arithmetic_overflow(self, client_regtest_scrubbed, contract, param, storage): client = client_regtest_scrubbed contract = path.join(OPCODES_CONTRACT_PATH, contract) def cmd(): client.run_script(contract, param, storage) assert_run_failure(cmd, r'unexpected arithmetic overflow')
def test_transfer_failure(self, client, session): def cmd(): client.msig_transfer('msig', 10, 'bootstrap2', 'bootstrap1', [session['sig2']]) error_pattern = (r"Not enough signatures: " + r"only 1 signatures were given " + r"but the threshold is currently 2") utils.assert_run_failure(cmd, error_pattern)
def test_originate_first_explosion(self, client, session): name = 'first_explosion.tz' contract = session[name] client.typecheck(contract) args = ['-G', '8000', '--burn-cap', '10'] def client_cmd(): client.originate(f'{name}', 0, 'bootstrap1', contract, args) expected_error = "Gas limit exceeded during typechecking or execution" utils.assert_run_failure(client_cmd, expected_error)
def test_originate_big_type(self, client, session): name = 'first_explosion_bigtype.tz' contract = session[name] def client_cmd(): client.typecheck(contract) # We could not be bothered with finding how to escape parentheses # so we put dots expected_error = "type size .1023. exceeded maximum type size .1000." utils.assert_run_failure(client_cmd, expected_error)
def test_activate(self, client, sandbox): # 2: activated PROTO_A client.bake(BAKER, BAKE_ARGS) assert client.get_protocol() == PROTO_A assert sandbox.client(0).get_head()['header']['proto'] == 1 metadata = client.get_metadata() assert metadata['balance_updates'] == DEPOSIT_RECEIPTS # PROTO_A is using env. V0, metadata hashes should not be present with assert_run_failure('No service found at this URL'): _ops_metadata_hash = client.get_operations_metadata_hash() with assert_run_failure('No service found at this URL'): _block_metadata_hash = client.get_block_metadata_hash()
def test_originate_second_explosion_fail(self, client, session): name = 'second_explosion.tz' contract = session[name] storage = '{}' inp = ('{1;2;3;4;5;6;7;8;9;0;1;2;3;4;5;6;7;1;1;1;1;1;1;1;1;1;1;1' + ';1;1;1;1;1;1;1;1;1;1;1;1;1;1}') def client_cmd(): client.run_script(contract, storage, inp) expected_error = \ ("Cannot serialize the resulting storage" + " value within the provided gas bounds.") utils.assert_run_failure(client_cmd, expected_error)
def test_wrong_signature(self, client): byt = ('0x050100000027566f756c657a2d766f757320636' + 'f75636865722061766563206d6f692c20636520736f6972203f') sign = ('p2sigvgDSBnN1bUsfwyMvqpJA1cFhE5s5oi7SetJVQ6' + 'LJsbFrU2idPvnvwJhf5v9DhM9ZTX1euS9DgWozVw6BTHiK9VcQVpAU8') arg = f'(Pair {byt} "{sign}")' def client_cmd(): client.transfer(0, "bootstrap1", "reveal_signed_preimage", ['-arg', arg, '--burn-cap', '10']) # We check failure of CHECK_SIGNATURE ; ASSERT in the script. utils.assert_run_failure(client_cmd, "At line 15 characters 9 to 15")
def test_non_originated_contract_no_forcing_and_saved_before( self, client, contract_name, non_originated_contract_address, ): expected_error = f"The contract alias {contract_name} already exists" def cmd(): client.remember_contract(contract_name, non_originated_contract_address, force=False) assert_run_failure(cmd, re.compile(expected_error))
def test_unavailable_blocks_node3(self, sandbox: Sandbox): savepoint = int(sandbox.client(3).get_savepoint()) assert utils.get_block_at_level(sandbox.client(3), savepoint) # We must fail while requesting blocks before savepoint for i in range(1, savepoint): with utils.assert_run_failure(EXPECTED_COMMAND_ERROR): utils.get_block_metadata_at_level(sandbox.client(3), i)
def test_gen_key_from_menmonic_bad_mnemonic(self, client: Client): """ Tests that the command fails if the user gives a bad mnemonic. """ prms = ["import", "keys", "from", "mnemonic", "alias", "--force"] stdin = "hello\n\n" expected_error = '"hello" is not a valid BIP39 mnemonic.' with assert_run_failure(expected_error): client.run_generic(prms, stdin=stdin)
def test_fail_inject_signed_arbitrary_ope(self, client, identity, message, head_block): if head_block: signature = client.sign_message(message, identity, block="head") else: signature = client.sign_message(message, identity) chain_id = client.rpc('get', '/chains/main/chain_id') head_hash = client.rpc('get', '/chains/main/blocks/head/hash') run_json = { 'operation': { "branch": head_hash, "contents": [{ "kind": "failing_noop", "arbitrary": message }], 'signature': signature, }, 'chain_id': chain_id, } run_operation_path = ( '/chains/main/blocks/head/helpers/scripts/run_operation') with assert_run_failure( 'The failing_noop operation cannot be executed by the protocol' ): client.rpc('post', run_operation_path, data=run_json)
def test_transfer_ill_typed(self, msig, client: Client): """Test that the multisig transfer preparation command type checks the parameter.""" error_pattern = ( ( r'The entrypoint b of contract .* ' 'called from a multisig contract is of type string; ' 'the provided parameter 42 is ill-typed.' ) if msig['version'] == 'generic' else ( r'This multisig contract can only transfer tokens to' ' contracts of type unit; calling a contract with argument 42' ' is not supported.' ) ) args = ['--entrypoint', 'b', '--arg', '42'] def cmd(): client.msig_prepare_transfer( msig_name=msig['handle'], amount=10, dest='dest', args=args + ['--bytes-only'], ) with utils.assert_run_failure(error_pattern): cmd()
def test_transfer_with_arg(self, msig, client: Client): """The generic multisig contract can call other contracts with arbitrary parameters but the legacy one can only send Unit.""" contract = ( 'parameter (or (int %a) (string %b)); ' 'storage unit; ' 'code {CDR; NIL operation; PAIR}' ) client.originate( 'dest', 0, 'bootstrap1', contract, args=['--burn-cap', '10.0', '--force'], ) args = ['--entrypoint', 'a', '--arg', '42'] utils.bake(client) def cmd(): return client.msig_prepare_transfer( msig_name=msig['handle'], amount=10, dest='dest', args=args + ['--bytes-only'], ) if msig['version'] == 'legacy': error_pattern = ( r'This multisig contract can only transfer tokens to' ' contracts of type unit; calling a contract with argument 42' ' is not supported.' ) with utils.assert_run_failure(error_pattern): cmd() else: current_storage = client.get_storage(msig['handle']) current_balance = client.get_balance(msig['handle']) to_sign = cmd() utils.bake(client) sig0 = client.sign_bytes_of_string(to_sign, msig['keys'][0]) sig2 = client.msig_sign_transfer( msig_name=msig['handle'], amount=10, dest='dest', secret_key=msig['keys'][2], args=args, ) client.msig_transfer( msig_name=msig['handle'], amount=10, dest='dest', src='bootstrap1', signatures=[sig0, sig2], args=args, ) utils.bake(client) new_storage = client.get_storage(msig['handle']) new_balance = client.get_balance(msig['handle']) assert_msig_counter_incr(current_storage, new_storage) assert new_balance == current_balance - 10
def test_forge_alice_to_bob_insufficient_funds( self, client, tmpdir, contract_name, session, transaction_file, use_json, ): transaction_file = f'{tmpdir}/{transaction_file}' amount = 2100000000.0 account = 'alice' additional_args = [] if use_json: additional_args += ["--json"] with assert_run_failure(r"Balance too low \({}\) to spend {}".format( 100, int(amount))): client.sapling_forge_transaction( amount=amount, src=account, dest=session['bob_address_1'], contract=contract_name, file=transaction_file, args=additional_args, )
def test_shield_with_different_memo_size(self, contract_path, client): contract_name = "sapling_memo_size_different" implicit_account = "bootstrap1" contract_address = client.originate( contract_name=contract_name, amount=0, sender=implicit_account, contract=contract_path, args=["--init", "{ }", "--burn-cap", "3.0"], ).contract client.bake(implicit_account, ["--minimal-timestamp"]) client.sapling_gen_key(key_name='alice') client.sapling_use_key_for_contract('alice', contract_name, memo_size=16) address = client.sapling_gen_address(key_name='alice').address # Key was registered with a memo_size of 16, it should fail with assert_run_failure(r"Memo sizes of two sapling states"): client.sapling_shield( amount=TX_AMOUNT, src=implicit_account, dest=address, contract=contract_address, args=["--burn-cap", "3.0"], )
def test_slice_fails(self, client_regtest_scrubbed: ClientRegression, contract_arg: str): client = client_regtest_scrubbed with assert_run_failure(r'script reached FAILWITH instruction'): client.transfer(0, 'bootstrap1', 'slices', ['-arg', contract_arg, '--burn-cap', '10'])
def test_ticket_split(self, client): def ticket(target_addr, param, utxo_amount): param = ('(Pair (Pair "' + target_addr + '" ' + str(param) + ') ' + str(utxo_amount) + ')') client.transfer( 100, 'bootstrap1', 'ticketer', ['-arg', param, '--burn-cap', '10'], ) init_with_transfer( client, path.join(OPCODES_CONTRACT_PATH, 'ticketer-2.tz'), 'Unit', 100, 'bootstrap1', 'ticketer', ) init_with_transfer( client, path.join(OPCODES_CONTRACT_PATH, 'ticket_split.tz'), 'Unit', 100, 'bootstrap1', 'splitter', ) bake(client) splitter_addr = client.get_contract_address('splitter') ticket(splitter_addr, 42, 3) with assert_run_failure(r'script reached FAILWITH instruction'): # Wrong Split Amount ticket(splitter_addr, 42, 4) bake(client)
def test_bad_ticket(self, client): init_with_transfer( client, path.join(OPCODES_CONTRACT_PATH, 'ticketer.tz'), '42', 100, 'bootstrap1', 'ticketer_bad', ) bake(client) ticketer_addr = client.get_contract_address('ticketer_bad') init_with_transfer( client, path.join(OPCODES_CONTRACT_PATH, 'ticket_read.tz'), '"' + ticketer_addr + '"', 100, 'bootstrap1', 'reader_bad', ) bake(client) with assert_run_failure(r'Unexpected forged value'): client.transfer( 100, 'bootstrap1', 'reader_bad', ['-arg', '1', '--burn-cap', '10'], ) bake(client)
def test_contract_fails(self, client_regtest_scrubbed): client = client_regtest_scrubbed client.set_regtest(None) init_with_transfer(client, path.join(OPCODES_CONTRACT_PATH, 'contract.tz'), 'Unit', 1000, 'bootstrap1') client.transfer(0, 'bootstrap1', 'self', ['--burn-cap', '10']) bake(client) addr = client.get_contract_address('contract') def cmd(): client.transfer(0, 'bootstrap1', 'contract', ['-arg', f'"{addr}"', '--burn-cap', '10']) assert_run_failure(cmd, r'script reached FAILWITH instruction')
def test_reconstruct_on_bootstrapped_node(self, sandbox: Sandbox): # Stop, reconstruct the storage and restart the node sandbox.node(3).terminate_or_kill() pattern = 'nothing to reconstruct.' with utils.assert_run_failure(pattern): sandbox.node(3).reconstruct() sandbox.node(3).run() assert sandbox.client(3).check_node_listening()