def test_init(self, sandbox): for i in range(10): sandbox.add_node(i, params=PARAMS) utils.activate_alpha(sandbox.client(0)) for i in range(5): sandbox.add_baker(i, f'bootstrap{i + 1}', proto=constants.ALPHA_DEAMON)
def scenario(contract, storage, time_between_blocks, proto): if proto is None: proto = 'alpha' assert proto in {'alpha', 'babylon'}, 'unknown protocol' protos = { 'alpha': (constants.ALPHA, constants.ALPHA_DAEMON), 'babylon': (constants.BABYLON, constants.BABYLON_DAEMON) } proto_hash, proto_daemon = protos[proto] if contract: assert os.path.isfile(contract), f'{contract} is not a file' if storage is None: storage = 'unit' with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES, constants.GENESIS_PK) as sandbox: parameters = dict(constants.PARAMETERS) parameters["time_between_blocks"] = [str(time_between_blocks), "0"] sandbox.add_node(1, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(1), parameters, proto=proto_hash) sandbox.add_baker(1, 'bootstrap5', proto=proto_daemon) client = sandbox.client(1) if contract: args = ['--init', storage, '--burn-cap', '10.0'] sender = 'bootstrap2' amount = 0 client.originate('my_contract', sender, amount, sender, contract, args) while 1: client.get_head() time.sleep(time_between_blocks)
def test_init(self, sandbox): sandbox.add_node(0, params=constants.NODE_PARAMS) parameters = dict(constants.PARAMETERS) parameters["time_between_blocks"] = ["1", "0"] utils.activate_alpha(sandbox.client(0), parameters) sandbox.add_baker(0, 'bootstrap1', proto=constants.ALPHA_DAEMON) sandbox.add_node(1, params=constants.NODE_PARAMS) sandbox.add_baker(1, 'bootstrap2', proto=constants.ALPHA_DAEMON)
def client(sandbox): """One snode, 4 blocks per voting period.""" parameters = dict(constants.PARAMETERS) parameters["time_between_blocks"] = ["1", "0"] parameters["blocks_per_voting_period"] = 4 sandbox.add_node(0) utils.activate_alpha(sandbox.client(0), parameters) yield sandbox.client(0)
def sandbox(): """Example of sandbox fixture.""" with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) sandbox.add_node(1, params=constants.NODE_PARAMS) sandbox.add_baker(0, 'bootstrap5', proto=constants.ALPHA_DAEMON) yield sandbox assert sandbox.are_daemons_alive()
def sandbox() -> Iterator[Sandbox]: """Example of sandbox fixture.""" with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) sandbox.add_node(1, params=constants.NODE_PARAMS) # Empty list makes everyone bake sandbox.add_baker(0, [], proto=constants.ALPHA_DAEMON) yield sandbox assert sandbox.are_daemons_alive()
def test_init(self, sandbox: Sandbox): sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) parameters = dict(constants.PARAMETERS) parameters["time_between_blocks"] = ["1", "0"] utils.activate_alpha(sandbox.client(0), parameters) sandbox.add_baker(0, 'bootstrap1', proto=constants.ALPHA_DAEMON) sandbox.add_node(1, params=params(), log_levels=LOG_LEVEL, config_client=False)
def scenario_basic_call(): """ a private tezos network, initialized with network parameters and some accounts. """ with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol alpha sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) sandbox.add_baker(0, 'baker5', proto=constants.ALPHA_DAEMON) time.sleep(5) # Originate external contract # This is a dummy contract for the one that will check the signature. # For now, it returns True input is greate than 9, else False. contract_external = "simple_inter_contract/external_contract.tz" contract_external_name = "external_contract" burncap = "9" args = ["--init", "Unit", "--burn-cap", burncap] sandbox.client(0).originate(contract_external_name, 0, "bootstrap1", contract_external, args) sandbox.client(0).bake('baker5', BAKE_ARGS) external_contract_addr = sandbox.client(0).get_contract_address( contract_external_name) # Originate the main contract contract_main = "simple_inter_contract/main_contract.tz" contract_main_name = "main_contract" burncap = "9" storage = '(Pair \"{addr}\" False)'.format(addr=external_contract_addr) args = ["--init", storage, "--burn-cap", burncap] sandbox.client(0).originate(contract_main_name, 0, "bootstrap1", contract_main, args) sandbox.client(0).bake('baker5', BAKE_ARGS) # Test running the main contract with 9 as an input. # The storage field 'valid' should be set to False. amt = 0 storage = "9" sandbox.client(0).transfer( amt, 'bootstrap1', contract_main_name, ['--entrypoint', 'run', '--burn-cap', burncap, '--arg', storage]) sandbox.client(0).bake('baker5', BAKE_ARGS) # Test running the main contract with 10 as an input. # The storage field 'valid' should be set to True. amt = 0 storage = "10" sandbox.client(0).transfer( amt, 'bootstrap1', contract_main_name, ['--entrypoint', 'run', '--burn-cap', burncap, '--arg', storage]) sandbox.client(0).bake('baker5', BAKE_ARGS)
def sandbox(): """Example of sandbox fixture.""" with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES, constants.GENESIS_PK) as sandbox: sandbox.add_node(0) utils.activate_alpha(sandbox.client(0)) sandbox.add_node(1) sandbox.add_baker(0, 'bootstrap5', proto=constants.ALPHA_DEAMON) yield sandbox assert sandbox.are_daemons_alive()
def run_sig_verify(pubkey, message, signature, verbose): """ a private tezos network, initialized with network parameters and some accounts. """ with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol alpha sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) # Launch a second node on the same private tezos network sandbox.add_node(1, params=constants.NODE_PARAMS) # Test PS sigs verification contract run_psigs_contract(sandbox.client(0), 'unit', pubkey, message, signature, debug=verbose) return
def scenario_basic_call(): """ a private tezos network, initialized with network parameters and some accounts. """ with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol alpha sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) # Launch a baker associated to node 0, baking on behalf of delegate # baker5 sandbox.add_baker(0, 'baker5', proto=constants.ALPHA_DAEMON) # Wait for second node to update its protocol to alpha, if not # it may not know yet the `wait_for_inclusion` operation which is # protocol specific # (Originally this sleep was 15 seconds) time.sleep(5) even = "collatz_even.tz" even_name = "even_contract" burncap = "9" args = ["--init", "Unit", "--burn-cap", burncap] sandbox.client(0).originate(even_name, 0, "bootstrap1", even, args) sandbox.client(0).bake('baker5', BAKE_ARGS) odd = "collatz_odd.tz" odd_name = "odd_contract" burncap = "9" args = ["--init", "Unit", "--burn-cap", burncap] sandbox.client(0).originate(odd_name, 0, "bootstrap1", odd, args) sandbox.client(0).bake('baker5', BAKE_ARGS) even_addr = sandbox.client(0).get_contract_address(even_name) odd_addr = sandbox.client(0).get_contract_address(odd_name) main = "collatz_main.tz" main_name = "main_contract" burncap = "9" storage = '(Pair 0 (Pair "{c1}" "{c2}"))'.format(c1=even_addr, c2=odd_addr) args = ["--init", storage, "--burn-cap", burncap] sandbox.client(0).originate(main_name, 0, "bootstrap1", main, args) sandbox.client(0).bake('baker5', BAKE_ARGS) amt = 0 sandbox.client(0).transfer( amt, 'bootstrap1', main_name, ['--entrypoint', 'run', '--burn-cap', burncap, '--arg', '42']) sandbox.client(0).bake('baker5', BAKE_ARGS)
def test_setup_network(self, sandbox: Sandbox): sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) utils.activate_alpha(sandbox.client(0)) sandbox.add_node(1, params=params(), config_client=False, log_levels=LOG_LEVEL) sandbox.add_node(2, params=params(2), config_client=False, log_levels=LOG_LEVEL) sandbox.add_baker(0, 'bootstrap5', proto=constants.ALPHA_DAEMON)
def test_setup_network(self, sandbox: Sandbox): parameters = dict(constants.PARAMETERS) # each priority has a delay of 1 sec parameters["time_between_blocks"] = ["1"] for i in range(NUM_NODES): sandbox.add_node(i, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0), parameters) sandbox.add_baker(0, 'bootstrap5', proto=constants.ALPHA_DAEMON) sandbox.add_baker(1, 'bootstrap4', proto=constants.ALPHA_DAEMON) sandbox.add_endorser(0, account='bootstrap1', endorsement_delay=1, proto=constants.ALPHA_DAEMON) sandbox.add_endorser(1, account='bootstrap2', endorsement_delay=1, proto=constants.ALPHA_DAEMON)
def clients(sandbox: Sandbox, request) -> Iterator[List[Client]]: """N node with protocol alpha. Parameterized by the number of nodes. Number of nodes is specified as a class annotation. @pytest.mark.parametrize('clients', [N], indirect=True) """ assert request.param is not None num_nodes = request.param for i in range(num_nodes): # Large number may increases peers connection time sandbox.add_node(i, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) clients = sandbox.all_clients() for client in clients: proto = constants.ALPHA assert utils.check_protocol(client, proto) yield clients
def test_setup_network(self, sandbox): # Set appropriate time to avoid double-baking parameters = dict(constants.PARAMETERS) parameters["time_between_blocks"] = ["15", "0"] for i in range(NUM_NODES): sandbox.add_node(i, params=['--connections', '500']) utils.activate_alpha(sandbox.client(0), parameters) sandbox.add_baker(0, 'bootstrap5', proto=constants.ALPHA_DEAMON) sandbox.add_baker(1, 'bootstrap4', proto=constants.ALPHA_DEAMON) sandbox.add_endorser(0, account='bootstrap1', endorsement_delay=1, proto=constants.ALPHA_DEAMON) sandbox.add_endorser(1, account='bootstrap2', endorsement_delay=1, proto=constants.ALPHA_DEAMON)
def client_regtest_bis(sandbox): """One node with protocol alpha, regression test enabled.""" def reg_client_factory(client_path: str, admin_client_path: str, host: str = '127.0.0.1', base_dir: Optional[str] = None, rpc_port: int = 8732, use_tls: bool = False, disable_disclaimer: bool = True): client = ClientRegression(client_path, admin_client_path, host, base_dir, rpc_port, use_tls, disable_disclaimer) return client sandbox.add_node(1, client_factory=reg_client_factory, params=constants.NODE_PARAMS) client = sandbox.client(1) utils.activate_alpha(client) yield client
def run_pairing_tests(): """ a private tezos network, initialized with network parameters and some accounts. """ with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol Alpha sandbox.add_node(0) utils.activate_alpha(sandbox.client(0)) # Launch a second node on the same private tezos network sandbox.add_node(1) # Launch a baker associated to node 0, baking on behalf of delegate # bootstrap5 sandbox.add_baker(0, 'bootstrap5', proto=constants.ALPHA_DAEMON) # first client tells node 0 to transfer money for an account to another # receipt is an object representing the client answer receipt = sandbox.client(0).transfer(500, 'bootstrap1', 'bootstrap3') transfer_hash = receipt.operation_hash print("transfer hash for bootstrap1 -> bootstrap3: ", transfer_hash) # Run the pairing contract run_pairing_property_contract(sandbox.client(0)) run_groth16(sandbox.client(0)) return
def client_regtest_bis(sandbox: Sandbox) -> Iterator[Client]: """One node with protocol alpha, regression test enabled.""" def reg_client_factory( client_path: str, admin_client_path: str, host: Optional[str] = None, base_dir: Optional[str] = None, rpc_port: Optional[int] = None, use_tls: Optional[bool] = None, endpoint: Optional[str] = 'http://127.0.0.1:8732', disable_disclaimer: bool = True) -> ClientRegression: client = ClientRegression(client_path, admin_client_path, host, base_dir, rpc_port, use_tls, endpoint, disable_disclaimer) return client sandbox.add_node(1, client_factory=reg_client_factory, params=constants.NODE_PARAMS) client = sandbox.client(1) utils.activate_alpha(client) yield client
def scenario(): """ a private tezos network, initialized with network parameters and some accounts. """ with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol alpha sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) # Launch a second node on the same private tezos network sandbox.add_node(1, params=constants.NODE_PARAMS) # Launch a baker associated to node 0, baking on behalf of delegate # bootstrap5 sandbox.add_baker(0, 'bootstrap5', proto=constants.ALPHA_DAEMON) # Wait for second node to update its protocol to alpha, if not # it may not know yet the `wait_for_inclusion` operation which is # protocol specific time.sleep(15) # first client tells node 0 to transfer money for an account to another # receipt is an object representing the client answer receipt = sandbox.client(0).transfer(500, 'bootstrap1', 'bootstrap3') transfer_hash = receipt.operation_hash # second client waits for inclusion of operation by the second node sandbox.client(1).wait_for_inclusion(transfer_hash, check_previous=2)
def test_init(self, sandbox): sandbox.add_node(1) sandbox.add_node(2) utils.activate_alpha(sandbox.client(1)) time.sleep(2)
def scenario(): with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol alpha sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) port = sandbox.node(0).rpc_port chain_id = utils.rpc( 'localhost', port, 'get', '/chains/main/chain_id' ).json() counter_path = ( f'/chains/main/blocks/head/context/contracts/' f'{SENDER_ID}/counter' ) counter = utils.rpc('localhost', port, 'get', counter_path).json() head_hash = utils.rpc( 'localhost', port, 'get', '/chains/main/blocks/head/hash' ).json() operation_json = { "branch": head_hash, "contents": [ { "kind": "transaction", "source": SENDER_ID, "fee": "0", "counter": str(int(counter) + 1), "gas_limit": "1040000", "storage_limit": "60000", "amount": '1000', "destination": RECEIVER_ID, } ], } run_json = {'operation': operation_json, 'chain_id': chain_id} # call run_operation dummy_sig = ( 'edsigtkpiSSschcaCt9pUVrpNPf7TTcgvgDEDD6NCEHMy8NNQJCGnMfL' 'ZzYoQj74yLjo9wx6MPVV29CvVzgi7qEcEUok3k7AuMg' ) operation_json['signature'] = dummy_sig run_operation_path = ( '/chains/main/blocks/head/helpers/scripts/run_operation' ) res = utils.rpc( 'localhost', port, 'post', run_operation_path, data=run_json ).json() # update fields before forging gas_limit = res['contents'][0]['metadata']['operation_result'][ 'consumed_gas' ] milligas_limit = res['contents'][0]['metadata']['operation_result'][ 'consumed_milligas' ] gas_from_milligas = math.ceil(float(milligas_limit) / 1000) safer_gas_limit_through_milligas = int(gas_from_milligas) + 100 safer_gas_limit = int(gas_limit) + 100 assert safer_gas_limit == safer_gas_limit_through_milligas operation_json['contents'][0]['gas_limit'] = str(safer_gas_limit) operation_json['contents'][0]['storage_limit'] = '0' operation_json['contents'][0]['fee'] = '1300' # arbitrary fee del operation_json['signature'] # forge operation path_forge = '/chains/main/blocks/head/helpers/forge/operations' operation_hex_string = utils.rpc( 'localhost', port, 'post', path_forge, data=operation_json ).json() # sign operation watermarked_operation = b'\x03' + bytes.fromhex(operation_hex_string) sender_sk_hex = utils.b58_key_to_hex(SENDER_SK) sender_sk_bin = bytes.fromhex(sender_sk_hex) sig_hex = utils.sign(watermarked_operation, sender_sk_bin) sig_b58 = utils.hex_sig_to_b58(sig_hex) # change operation structure as expected by preapply operation_json['signature'] = sig_b58 # preapply require b58 signature # Hard-coded but we could get the protocol hash using an RPC operation_json['protocol'] = constants.ALPHA operation_json_list = [operation_json] preapply_path = '/chains/main/blocks/head/helpers/preapply/operations' preapply_res = utils.rpc( 'localhost', port, 'post', preapply_path, data=operation_json_list ).json() preapply_status = preapply_res[0]['contents'][0]['metadata'][ 'operation_result' ]['status'] assert preapply_status == 'applied' # injection require hex signature signed_op = operation_hex_string + sig_hex op_hash = utils.rpc( 'localhost', port, 'post', 'injection/operation', signed_op ).json() mempool = utils.rpc( 'localhost', port, 'get', '/chains/main/mempool/pending_operations' ).json() assert op_hash == mempool['applied'][0]['hash']
def test_init(self, sandbox): sandbox.add_node(0, params=PARAMS) # Allow fast `bake for` by activating the protocol in the past last_hour_date_time = datetime.utcnow() - timedelta(hours=1) timestamp = last_hour_date_time.strftime("%Y-%m-%dT%H:%M:%SZ") utils.activate_alpha(sandbox.client(0), timestamp=timestamp)
def client(sandbox): """One node running protocol alpha and a baker.""" sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) yield sandbox.client(0)
def client(sandbox: Sandbox) -> Iterator[Client]: """One node with protocol alpha.""" sandbox.add_node(0, params=constants.NODE_PARAMS) client = sandbox.client(0) utils.activate_alpha(client) yield client
def client(sandbox): """One node running protocol alpha and a baker.""" sandbox.add_node(0) utils.activate_alpha(sandbox.client(0)) yield sandbox.client(0)
def scenario_mutual_close(contract_path, message): """ a private tezos network, initialized with network parameters and some accounts. """ with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol alpha sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) sandbox.add_baker(0, 'baker5', proto=constants.ALPHA_DAEMON) time.sleep(5) burncap = "9" cust_addr = constants.IDENTITIES['bootstrap1']['identity'] cust_pk = constants.IDENTITIES['bootstrap1']['public'] merch_addr = constants.IDENTITIES['bootstrap2']['identity'] merch_pk = constants.IDENTITIES['bootstrap2']['public'] cust_bal_start = sandbox.client(0).get_balance(cust_addr) # Originate pssigs contract pssig_contract = contract_path + "pssig_v3.tz" pssig_name = "pssig_contract" args = ["--init", "Unit", "--burn-cap", burncap] sandbox.client(0).originate(pssig_name, 0, "bootstrap1", pssig_contract, args) sandbox.client(0).bake('baker5', BAKE_ARGS) entrypoint_cost = dict() current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["pssig"] = cust_bal_start - current_bal # Define initial storage and channel variables contract = contract_path + "zkchannel_main_v3.tz" chan_id_fr, rev_lock_fr, cust_bal_fr, merch_bal_fr = message sig_s1, sig_s2 = signature contract_name = "my_zkchannel" chan_id = chan_id_fr cust_bal = 21000 / 1000000 merch_bal = 0 cust_bal_mt = int(cust_bal * 1000000) merch_bal_mt = int(merch_bal * 1000000) # Balance in mutez as bytes cust_bal_b = cust_bal_fr merch_bal_b = merch_bal_fr rev_lock0 = "0x1f98c84caf714d00ede5d23142bc166d84f8cd42adc18be22c3d47453853ea49" # self_delay = 86400 # seconds in 1 day (60*60*24) self_delay = 3 pssig_addr = sandbox.client(0).get_contract_address(pssig_name) # Originate zkchannel contract (without funding) initial_storage = form_initial_storage(chan_id, cust_addr, cust_pk, merch_addr, merch_pk, cust_bal_mt, merch_bal_mt, rev_lock0, self_delay, pssig_addr) args = ["--init", initial_storage, "--burn-cap", burncap] sandbox.client(0).originate(contract_name, 0, "bootstrap1", contract, args) sandbox.client(0).bake('baker5', BAKE_ARGS) old_bal = current_bal current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["zkchannel"] = old_bal - current_bal # Add customer's funds sandbox.client(0).transfer( cust_bal, 'bootstrap1', contract_name, ['--entrypoint', 'addFunding', '--burn-cap', burncap]) # Add merchant's funds sandbox.client(0).transfer( merch_bal, 'bootstrap2', contract_name, ['--entrypoint', 'addFunding', '--burn-cap', burncap]) sandbox.client(0).bake('baker5', BAKE_ARGS) merch_old_bal = sandbox.client(0).get_balance(merch_addr) old_bal = current_bal current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["addFunding"] = old_bal - cust_bal - current_bal # Create the mutual close state that customer and merchant settle on new_cust_bal = 19960 / 1000000 new_merch_bal = 1040 / 1000000 new_cust_bal_mt = int(new_cust_bal * 1000000) new_merch_bal_mt = int(new_merch_bal * 1000000) mutual_state = form_mutual_state(chan_id, cust_addr, merch_addr, new_cust_bal_mt, new_merch_bal_mt) # Cust and Merch signs off on mutual close state mutual_type = 'pair (pair bls12_381_fr address) (pair mutez (pair address mutez))' packed = sandbox.client(0).pack(mutual_state, mutual_type) cust_sig = sandbox.client(0).sign_bytes_of_string(packed, "bootstrap1") merch_sig = sandbox.client(0).sign_bytes_of_string( packed, "bootstrap2") storage = '(Pair (Pair {cust_bal_mt} \"{cust_sig}\") (Pair {merch_bal_mt} \"{merch_sig}\"))'.format( cust_sig=cust_sig, merch_sig=merch_sig, cust_bal_mt=new_cust_bal_mt, merch_bal_mt=new_merch_bal_mt) sandbox.client(0).transfer(0, 'bootstrap1', contract_name, [ '--entrypoint', 'mutualClose', '--burn-cap', burncap, '--arg', storage ]) sandbox.client(0).bake('baker5', BAKE_ARGS) old_bal = current_bal current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["mutualClose"] = old_bal + new_cust_bal - current_bal # Make sure every tez has been accounted for assert cust_bal_start == (current_bal + sum(entrypoint_cost.values()) + cust_bal - new_cust_bal) print("Cost incurred when calling the following entrypoints (tez):") for k, v in entrypoint_cost.items(): print(k + ": " + str(v)) return
def test_init(self, sandbox): sandbox.add_node(1, params=constants.NODE_PARAMS) sandbox.add_node(2, params=constants.NODE_PARAMS) sandbox.add_node(3, params=constants.NODE_PARAMS + ['--disable-mempool']) utils.activate_alpha(sandbox.client(1))
def test_init(self, sandbox): for i in GROUP1: sandbox.add_node(i, params=PARAMS) utils.activate_alpha(sandbox.client(GROUP1[0]))
def test_init(self, sandbox: Sandbox): for i in range(NUM_NODES): sandbox.add_node(i, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0))
def scenario_cust_close(contract_path, pubkey, message, signature, balances): """ a private tezos network, initialized with network parameters and some accounts. """ with Sandbox(paths.TEZOS_HOME, constants.IDENTITIES) as sandbox: # Launch node running protocol alpha sandbox.add_node(0, params=constants.NODE_PARAMS) utils.activate_alpha(sandbox.client(0)) sandbox.add_baker(0, 'baker5', proto=constants.ALPHA_DAEMON) time.sleep(5) burncap = "9" cust_addr = constants.IDENTITIES['bootstrap1']['identity'] cust_pk = constants.IDENTITIES['bootstrap1']['public'] merch_addr = constants.IDENTITIES['bootstrap2']['identity'] merch_pk = constants.IDENTITIES['bootstrap2']['public'] cust_bal_start = sandbox.client(0).get_balance(cust_addr) # Originate pssigs contract pssig_contract = contract_path + "zkchannel_pssig.tz" pssig_name = "pssig_contract" args = ["--init", "Unit", "--burn-cap", burncap] sandbox.client(0).originate(pssig_name, 0, "bootstrap1", pssig_contract, args) sandbox.client(0).bake('baker5', BAKE_ARGS) entrypoint_cost = dict() current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["pssig"] = cust_bal_start - current_bal # Define initial storage and channel variables contract = contract_path + "zkchannel_main.tz" chan_id_fr, rev_lock_fr, cust_bal_fr, merch_bal_fr = message sig_s1, sig_s2 = signature contract_name = "my_zkchannel" chan_id = chan_id_fr init_bal = balances["cust_bal"] + balances["merch_bal"] cust_bal = init_bal / 1000000 merch_bal = 0 cust_bal_mt = int(cust_bal * 1000000) merch_bal_mt = int(merch_bal * 1000000) # Balance in mutez as bytes cust_bal_b = cust_bal_fr merch_bal_b = merch_bal_fr rev_lock0 = "0x1f98c84caf714d00ede5d23142bc166d84f8cd42adc18be22c3d47453853ea49" # self_delay = 86400 # seconds in 1 day (60*60*24) self_delay = 3 pssig_addr = sandbox.client(0).get_contract_address(pssig_name) # Originate zkchannel contract (without funding) initial_storage = form_initial_storage(chan_id, cust_addr, cust_pk, merch_addr, merch_pk, cust_bal_mt, merch_bal_mt, rev_lock0, self_delay, pssig_addr) args = ["--init", initial_storage, "--burn-cap", burncap] sandbox.client(0).originate(contract_name, 0, "bootstrap1", contract, args) sandbox.client(0).bake('baker5', BAKE_ARGS) old_bal = current_bal current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["zkchannel"] = old_bal - current_bal # Add customer's funds sandbox.client(0).transfer( cust_bal, 'bootstrap1', contract_name, ['--entrypoint', 'addFunding', '--burn-cap', burncap]) # Add merchant's funds sandbox.client(0).transfer( merch_bal, 'bootstrap2', contract_name, ['--entrypoint', 'addFunding', '--burn-cap', burncap]) sandbox.client(0).bake('baker5', BAKE_ARGS) merch_old_bal = sandbox.client(0).get_balance(merch_addr) old_bal = current_bal current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["addFunding"] = old_bal - cust_bal - current_bal # Merchant initiates merch close sandbox.client(0).transfer( 0, 'bootstrap2', contract_name, ['--entrypoint', 'merchClose', '--burn-cap', burncap]) sandbox.client(0).bake('baker5', BAKE_ARGS) merch_current_bal = sandbox.client(0).get_balance(merch_addr) entrypoint_cost["merchClose"] = merch_old_bal - merch_current_bal # A final payment happens - Merchant signs off on chanID, balances, # revlock (and for now addresses, although that may change) new_cust_bal = balances["cust_bal"] / 1000000 new_merch_bal = balances["merch_bal"] / 1000000 new_cust_bal_mt = int(new_cust_bal * 1000000) new_merch_bal_mt = int(new_merch_bal * 1000000) rev_lock_final = rev_lock_fr print("rev_lock_final: " + str(rev_lock_final)) # sample signature, merch-pk and g2 s1 = sig_s1 s2 = sig_s2 g2 = pubkey.get("g2") merchPk0 = pubkey.get("Y0") merchPk1 = pubkey.get("Y1") merchPk2 = pubkey.get("Y2") merchPk3 = pubkey.get("Y3") merchPk4 = pubkey.get("X") # # self contained value # chan_id = add_hex_prefix(convert_to_little_endian("0x5dffcd6f357f20a862f927fb7919e28ff3214977ed0a38232e907c4ab73691f0")) # print("Chan ID: %s" % chan_id) # rev_lock_final = add_hex_prefix(convert_to_little_endian("0x5c2e79664c13a8fc34b93e8882b9abf583208c6bc8cd2ad11e68d1232e88e68f")) # print("Revlock: %s" % rev_lock_final) # new_cust_bal_mt = "19999800" # new_merch_bal_mt = "10000200" # # new_cust_bal_mt = "0x382c310100000000000000000000000000000000000000000000000000000000" # # new_merch_bal_mt = "0x4897980000000000000000000000000000000000000000000000000000000000" # s1 = "0x1713091665473295e5ef2f6994c2a20aef21b38685558a4f938ed2cbdda411edf584bcfab31a3d55634ee08dfd5376bc19abad5e5e2e8e64d21b13ecb810601b49ae708fc383609068bee51e69db56af9030693a645fc0ef7df2024a4cde456d" # s2 = "0x0ef3081cbce139afe9f14da76b5e337b5a097c20bb62226f97086d851dc66bf72e85258eee96297fb9f6f955c74d65b00f9587346e58af360f8c7bb6e7d729c0fc99a8976d7ccd96c0c662ec974e05e44fc6be7ca3ef540998839b8ffdad2128" # g2 = "0x0990a9b13921c01f387c2725ee5c4c47a56825136dc85f9b55f5244dfe45be8aa610a7358905fc6a9ab848c850fb45ac097fc1f3b2aa09b660b8a7069d2db75f21fd9a924d15a855d93f8f4540f7626a4df560e9c12e215db86fdebb9b6bf8b5086129163c9e6071207ff43743012d37893e2b52fb75ff63dc35fefb7266af9883f4566ae2762862ae7084c4fd39381d185946e1c1280d87d3256673b9bb680cefe926e3e5ae194d732f762c62725ad13d3cecaefa1a75a724b58af3f1c9bd18" # merchPk0 = "0x083930b7626dbe92878de408eea223a6f7a183a6d18c6442ab801d558639322d7f37bd27073532e551d5e31a5b48a7fb055ac29b37c1d1f9092a57a476758e0be023cb43dd368d6dc30223a648324ce93d051469ffbcfe20a038bced8dbff606174e12e8a91c6a2e511c7b9aaae76a66191bb960b2571def75e231d3f6211aa98004cbb4e70ad9668fd8d386957479cb040bfc6519d793a8db488a0c604471deed80bb942c5730b8a94f54e898cbfc33ccfac15268b808c806b84111a5af921e" # merchPk1 = "0x11773bb86f7d8a50c5ef88ef515ed4ef3313278c67ce800196ee13d790a3f88a0ea094f9a67422fee73ecc5199ac109a1839d74d054d0cfe8467e773a6e0f2c81848c562035d4132b5f1e1fec343a77c1490c113316b92c2a7314ca33aa4932608df39e38326c3069c53c9fe877794f01e279621599123cbad1025fe87aedf763455ea457226d2f9a8d53d307d65e14510d1ad7031dae45c1e51b971c4964b549572b44edf97493b231a3d83c9474da416f53a8f036b07110a5577830987b76a" # merchPk2 = "0x1622c35b21afdd2223db3baa7ae35a6b6981951c711cf851dc1935e59a49f581cf7e33b8a5af1743bfe1e5c029cc12780021ab98bbb27eaf0031e3c7aebb8e496c7b4f0d6b210e8523b63b64be9105eeda7caf8ab34100c63e124fc647acd5c311feaeecc7fab921cb38b81d382398976e37b9a883d1b79c9c100849b5df3576af38870629269bb9342ea1d02cab3f5b018057f5c59e8f7a391348f34f31e7c3b1c375d6a03e065f29cd7ac3db28808ddf0f4367c3614dc995104f9103317f70" # merchPk3 = "0x18be8b41978a2aa56e77a46246438c20edb5145dcc53c8430ebe809899a0ab1db74c29038d10fb72707d6630b00d00bd048c0508011220765f4be805fc4d600562ce28b9aa6174880fd83d1bec0848df8b92d16906341d374156dbf0bf3b0111049e562db0222d419a2e3e11430b1acad3466506499a1f2f4872a03f7dfb97b92466d9723b411309b2cf5bbab043ae840d1f67d445ddfb776db6c524c14467faddd7fa7adfabbbb5edbb60631c5c52d7283802e9073d9b345e12fdde2517796e" # merchPk4 = "0x08f55c27b65bfe1cb0fc182a73c799f4955e13f3d48387422bffb81d7baf811098b19685558caa0c8f2834ef32d1a3910a55bfb3362d4545b8e8bf5e155af782930f120e295d95aaa9c144f4a37bb32363f7738d43c6c6aceef1e210187813c3164e73cc036b738436b7621e414bcebab60c3e6f6700be7fda35303c8b9e4ccc168db7f65e66739f37109760eb848fdf0a71d5bacacf1518e17948d266effe04b97a7b21336e33a68d0eba07a51c5360231df2dc1efba4f8a5a33296b3e723c7" # stack_args = "(Pair (Pair (Pair {chan_id} (Pair {custBal} {g2})) (Pair {merchBal} (Pair {merchPk0} {merchPk1}))) (Pair (Pair {merchPk2} (Pair {merchPk3} {merchPk4})) (Pair {rev_lock_final} (Pair {s1} {s2}))))".format(chan_id=chan_id, s1=s1, s2=s2, g2=g2, merchPk0=merchPk0, merchPk1=merchPk1, merchPk2=merchPk2, merchPk3=merchPk3, merchPk4=merchPk4, rev_lock_final=rev_lock_final, custBal=new_cust_bal_mt, merchBal=new_merch_bal_mt) # result = sandbox.client(0).run_script(pssig_contract, 'Unit', stack_args, trace_stack=True) # sys.exit(0) # This storage format is for pssig_v3.tz storage = '(Pair (Pair (Pair {custBal} {g2}) (Pair {merchBal} (Pair {merchPk0} {merchPk1}))) (Pair (Pair {merchPk2} (Pair {merchPk3} {merchPk4})) (Pair {rev_lock_final} (Pair {s1} {s2}))))'.format( s1=s1, s2=s2, g2=g2, merchPk0=merchPk0, merchPk1=merchPk1, merchPk2=merchPk2, merchPk3=merchPk3, merchPk4=merchPk4, rev_lock_final=rev_lock_final, custBal=new_cust_bal_mt, merchBal=new_merch_bal_mt) # This storage format is for pssig_v2.tz # storage = '(Pair (Pair (Pair {custBal} (Pair {custBalB} {g2})) (Pair (Pair {merchBal} {merchBalB}) (Pair {merchPk0} {merchPk1}))) (Pair (Pair {merchPk2} (Pair {merchPk3} {merchPk4})) (Pair (Pair {rev_lock_final} {rev_lock_final_b}) (Pair {s1} {s2}))))'.format(s1=s1, s2=s2, g2=g2, merchPk0=merchPk0, merchPk1=merchPk1, merchPk2=merchPk2, merchPk3=merchPk3, merchPk4=merchPk4, rev_lock_final=rev_lock_final, custBal=new_cust_bal_mt, merchBal=new_merch_bal_mt, custBalB=cust_bal_b, merchBalB=merch_bal_b, rev_lock_final_b=rev_lock_final_b) # Customer broadcasts custClose with the merchant's signature sandbox.client(0).transfer(0, 'bootstrap1', contract_name, [ '--entrypoint', 'custClose', '--burn-cap', burncap, '--arg', storage ]) # Each baked block increments the timestamp by 2 seconds. With a # self_delay of 3 seconds, the customer will be able to claim their # balance. sandbox.client(0).bake('baker5', BAKE_ARGS) sandbox.client(0).bake('baker5', BAKE_ARGS) old_bal = current_bal current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["custClose"] = old_bal - current_bal # Custer claims their balance with custClaim sandbox.client(0).transfer( 0, 'bootstrap1', contract_name, ['--entrypoint', 'custClaim', '--burn-cap', burncap]) sandbox.client(0).bake('baker5', BAKE_ARGS) old_bal = current_bal current_bal = sandbox.client(0).get_balance(cust_addr) entrypoint_cost["custClaim"] = old_bal - (current_bal - new_cust_bal) # Make sure every tez has been accounted for assert cust_bal_start == (current_bal + sum(entrypoint_cost.values()) - entrypoint_cost["merchClose"] + cust_bal - new_cust_bal) print("Cost incurred when calling the following entrypoints (tez):") for k, v in entrypoint_cost.items(): print(k + ": " + str(v)) return