예제 #1
0
async def test_interledger_with_two_ethereum_transaction_failure(config):
    # set up ledgerA and ledgerB
    tokenId = uuid4().int
    total_cost = 0
    (contract_minter_A, contract_address_A, contract_abi_A, url, portA) = setUp(config, 'left')
    (contract_minter_B, contract_address_B, contract_abi_B, url, portB) = setUp(config, 'right')

    w3_A = Web3(Web3.HTTPProvider(url+":"+str(portA)))
    w3_B = Web3(Web3.HTTPProvider(url+":"+str(portB)))
    token_instance_A = w3_A.eth.contract(abi=contract_abi_A, address=contract_address_A)
    token_instance_B = w3_B.eth.contract(abi=contract_abi_B, address=contract_address_B)

    (tokenId, cost) = await create_token(contract_minter_A, token_instance_A, w3_A, tokenId)
    # Activate token in ledgerA
    cost = await accept_token(contract_minter_A, token_instance_A, w3_A, tokenId)
    assert token_instance_A.functions.getStateOfToken(tokenId).call() == 2
    #the token will not be created on ledgerB to emulate transaction failure on the responder side 

    print("Test setup ready, performing measurement for unsuccessful asset transfer")

    with patch("data_transfer.interledger.Interledger.cleanup") as mock_cleanup:
        # mock cleanup to check the transfer reaches the end

        # Create interledger with a bridge in direction from A to B
        print("Building Interledger bridge A -> B...")
        start_time = time.time()
        inititator = EthereumInitiator(contract_minter_A, contract_address_A, contract_abi_A, url, port=portA)
        responder = EthereumResponder(contract_minter_B, contract_address_B, contract_abi_B, url, port=portB)
        interledger = Interledger(inititator, responder)

        print("Creating Intelredger run coroutine...")


        interledger_task = asyncio.ensure_future(interledger.run())

        print("A smart contract call in ledger A marks the token in 'TransferOut'...")

        (data, blockNumber,gas_used)= await transfer_token(contract_minter_A, token_instance_A, w3_A, tokenId)

        await asyncio.sleep(1.5) # Simulate Interledger running, should be longer than block time

        tx_hash = interledger.results_abort[0]["abort_tx_hash"]
        assert token_instance_A.functions.getStateOfToken(tokenId).call() == 2
        
        elapsed_time = time.time() - start_time
        print("Time interval: ", elapsed_time)
        
        total_cost += gas_used
        total_cost += calculate_used_gas(tx_hash, w3_A)

        print("Total cost: ", total_cost)
        print("Stopping Interledger run coroutine")
        interledger.stop()
        await interledger_task
        print("*----------------------------------------------------*")
def test_init(config):

    # Setup web3 and state

    (contract_minter, contract_address, contract_abi, url, port) = setUp(config, 'right')
    resp = EthereumResponder(contract_minter, contract_address, contract_abi, url, port=port)
    w3 = Web3(Web3.HTTPProvider(url+":"+str(port)))
    token_instance = w3.eth.contract(abi=contract_abi, address=contract_address)

    assert resp.web3.isConnected()
    assert resp.minter == contract_minter
    #assert resp.contract == token_instance
    assert resp.timeout == 120
async def test_responder_receive_reject_event(config):

    (contract_minter, contract_address, contract_abi, url, port) = setUp(config, 'right')
    w3 = Web3(Web3.HTTPProvider(url+":"+str(port)))
    token_instance = w3.eth.contract(abi=contract_abi, address=contract_address)
    # # Create a token
    (tokenId,cost) = await create_token(contract_minter, token_instance, w3)
    assert token_instance.functions.getStateOfToken(tokenId).call() == 0
    await accept_token(contract_minter, token_instance, w3, tokenId)
    assert token_instance.functions.getStateOfToken(tokenId).call() == 2
    ## Test Ethereum Responder ###

    resp = EthereumResponder(contract_minter, contract_address, contract_abi, url, port=port)

    #passing an asset with the wrong state to simulate emitting a reject event
    nonce = "42"
    data = encode_abi(['uint256'], [tokenId])
    result = await resp.send_data(nonce, data)


    tx_hash = result["tx_hash"]
    tx_info = w3.eth.getTransaction(tx_hash)
    tx_receipt = w3.eth.getTransactionReceipt(tx_hash)

    assert tx_info ['blockHash'] != None
    assert tx_info ['hash'] == tx_hash
    assert tx_info ['to'] == contract_address
    
    # check function name and abi
    decoded_input = token_instance.decode_function_input(tx_info['input'])
    assert decoded_input[0].fn_name == token_instance.get_function_by_name("interledgerReceive").fn_name
    assert decoded_input[0].abi == token_instance.get_function_by_name("interledgerReceive").abi


    # check for accepted/rejected events
    logs_accept = token_instance.events.InterledgerEventAccepted().processReceipt(tx_receipt)
    logs_reject = token_instance.events.InterledgerEventRejected().processReceipt(tx_receipt)

    assert len(logs_accept) == 0
    assert len(logs_reject) == 1
    assert logs_reject[0]['args']['nonce'] == int(nonce)


    assert result["status"] == False
    assert result["error_code"] == ErrorCode.APPLICATION_REJECT
    assert result["message"] == "InterledgerEventRejected() event received"
async def test_responder_receive(config):

    (contract_minter, contract_address, contract_abi, url, port) = setUp(config, 'right')
    w3 = Web3(Web3.HTTPProvider(url+":"+str(port)))
    token_instance = w3.eth.contract(abi=contract_abi, address=contract_address)
    # # Create a token
    (tokenId,cost) = await create_token(contract_minter, token_instance, w3)
    assert token_instance.functions.getStateOfToken(tokenId).call() == 0
    ## Test Ethereum Responder ###

    resp = EthereumResponder(contract_minter, contract_address, contract_abi, url, port=port)

    data = encode_abi(['uint256'], [tokenId])
    nonce= "42"
    result = await resp.send_data(nonce, data)
    print(result)
    tx_hash = result["tx_hash"]
    tx_info = w3.eth.getTransaction(tx_hash)
    tx_receipt = w3.eth.getTransactionReceipt(tx_hash)

    assert tx_info ['blockHash'] != None
    assert tx_info ['hash'] == tx_hash
    assert tx_info ['to'] == contract_address
    
    # check function name and abi
    decoded_input = token_instance.decode_function_input(tx_info['input'])
    assert decoded_input[0].fn_name == token_instance.get_function_by_name("interledgerReceive").fn_name
    assert decoded_input[0].abi == token_instance.get_function_by_name("interledgerReceive").abi
        
    # check function parameters
    assert decoded_input[1]['data'] == data
        
    # check for accepted/rejected events
    logs_accept = token_instance.events.InterledgerEventAccepted().processReceipt(tx_receipt)
    logs_reject = token_instance.events.InterledgerEventRejected().processReceipt(tx_receipt)

    assert len(logs_accept) == 1
    assert logs_accept[0]['args']['nonce'] == int(nonce)
    assert len(logs_reject) == 0



    assert result["status"] == True
async def test_responder_receive_transaction_failure(config):

    (contract_minter, contract_address, contract_abi, url, port) = setUp(config, 'right')
    w3 = Web3(Web3.HTTPProvider(url+":"+str(port)))
    token_instance = w3.eth.contract(abi=contract_abi, address=contract_address)
    # # Create a token
    (tokenId,cost) = await create_token(contract_minter, token_instance, w3)
    assert token_instance.functions.getStateOfToken(tokenId).call() == 0
    ## Test Ethereum Responder ###

    resp = EthereumResponder(contract_minter, contract_address, contract_abi, url, port=port)

    #passing wrong tokenId to simulate transaction failure
    nonce, data = "42", b"dummy"
    result = await resp.send_data(nonce, data)

    assert result["status"] == False
    assert result["tx_hash"] == None
    assert result["error_code"] == ErrorCode.TRANSACTION_FAILURE
    assert result["message"].find('revert') >= 0
async def test_interledger_with_two_ethereum_multiple_transfer(config):
   

    total_cost = 0

    # set up ledgerA and ledgerB
    print("Test setup ready, performing measurement for multiple asset transfers")
    (contract_minter_A, contract_address_A, contract_abi_A, url, portA) = setUp(config, 'left')
    (contract_minter_B, contract_address_B, contract_abi_B, url, portB) = setUp(config, 'right')

    w3_A = Web3(Web3.HTTPProvider(url+":"+str(portA)))
    w3_B = Web3(Web3.HTTPProvider(url+":"+str(portB)))
    token_instance_A = w3_A.eth.contract(abi=contract_abi_A, address=contract_address_A)
    token_instance_B = w3_B.eth.contract(abi=contract_abi_B, address=contract_address_B)


    # prepare for asset transfer
    simultaneous_transfers = [1, 2, 5, 10, 20, 50]
    #simultaneous_transfers = [2, 5, 10]
    for transfers in simultaneous_transfers:
        tokens = []
        
        # needed for token creation
        create = []
        
        # these contain tokens transiting between various states
        transfer_out = []
        need_accept = []
        accept = []
        completed = []

        # Create tokens in both ledgers and set their state in ledger A
        start_time = time.time()

        filter_A = token_instance_A.events.NewTokenAsset().createFilter(fromBlock = 'latest')
        filter_B = token_instance_B.events.NewTokenAsset().createFilter(fromBlock = 'latest')

        for i in range(transfers):
            (tokenId, tx_hash) = non_blocking_create_token(contract_minter_A, token_instance_A, w3_A)
            (tokenId, tx_hash) = non_blocking_create_token(contract_minter_B, token_instance_B, w3_B, tokenId)
            create.append(tokenId)
            
        while(True):
            # Check wherever token has been created in both ledgers
            to_remove = []
            entries = filter_A.get_new_entries()
            
            for entry in entries:
                token = entry['args']['tokenId']
                if token in create:
                    need_accept.append(token)
                    to_remove.append(token)
                        
            create = [x for x in create if x not in to_remove]

            # Accept created tokens in ledger A
            to_remove = []
            for token in need_accept:
                non_blocking_accept_token(contract_minter_A, token_instance_A, w3_A, token)
                accept.append(token)
                to_remove.append(token)
                
            need_accept = [x for x in need_accept if x not in to_remove]
            
            # Check wherever token is in Here state in ledger A
            to_remove = []
            for token in accept:
                if token_instance_A.functions.getStateOfToken(tokenId).call() == 2:
                    tokens.append(token)
                    to_remove.append(token)
                    
            accept = [x for x in accept if x not in to_remove]
            
            if (len(tokens) == transfers) and (len(need_accept) == 0) and (len(accept) == 0):
                # all tokens have been created and accepted in ledger A
                break

        elapsed_time = time.time() - start_time
        print(f"Token setup ready for {transfers} simultaneous transfers, took: {elapsed_time} seconds")
        #print("\t", tokens)

        
        inititator = EthereumInitiator(contract_minter_A, contract_address_A, contract_abi_A, url, port=portA)
        responder = EthereumResponder(contract_minter_B, contract_address_B, contract_abi_B, url, port=portB)
        interledger = Interledger(inititator, responder)

        print("Creating Intelredger run coroutine")
        
        start_time = time.time()
        interledger_task = asyncio.ensure_future(interledger.run())
        
        # Initiate transfer by calling transferOut for each token
        
        for token in tokens:
            tx_hash1 = non_blocking_transfer_token(contract_minter_A, token_instance_A, w3_A, token)
            transfer_out.append(token)

        while(True):
            # Check wherever some tokens have moved to Here state on ledger B and Not Here state on ledger 
            to_remove = []
            for token in transfer_out:
                 if (token_instance_B.functions.getStateOfToken(token).call() == 2)  and (token_instance_A.functions.getStateOfToken(token).call() == 0):
                    completed.append(token)
                    to_remove.append(token)

            transfer_out = [x for x in transfer_out if x not in to_remove]

            # Check wherever we have completed all transfers
            if len(completed) == transfers:
                elapsed_time = time.time() - start_time
                print(f"Took {elapsed_time} seconds for completing {transfers} transfers\n")
                break
            
            # Simulate Interledger running
            await asyncio.sleep(0.00001)
            

        interledger.stop()
        await interledger_task
예제 #7
0
async def test_interledger_with_two_ethereum_multiple_transfer(config):
   
#set up ledgerA and ledgerB
    ids = [[],[],[],[],[],[]]
    (contract_minter_A, contract_address_A, contract_abi_A, url, portA) = setUp(config, 'left')
    (contract_minter_B, contract_address_B, contract_abi_B, url, portB) = setUp(config, 'right')

    w3_A = Web3(Web3.HTTPProvider(url+":"+str(portA)))
    w3_B = Web3(Web3.HTTPProvider(url+":"+str(portB)))
    token_instance_A = w3_A.eth.contract(abi=contract_abi_A, address=contract_address_A)
    token_instance_B = w3_B.eth.contract(abi=contract_abi_B, address=contract_address_B)
    
    #prepare for asset transfer
    indexes = [2, 5, 10, 20, 50, 100] #
    for i in range (0,6):
        index = indexes[i]
        for j in range(0, index):
            tokenId = uuid4().int
            ids[i].append(tokenId)
            (tokenId,cost) = await create_token(contract_minter_A, token_instance_A, w3_A, tokenId)
            (tokenId,cost) = await create_token(contract_minter_B, token_instance_B, w3_B, tokenId)
            assert token_instance_B.functions.getStateOfToken(tokenId).call() == 0
            assert token_instance_A.functions.getStateOfToken(tokenId).call() == 0
            #Activate token in ledgerA
            cost = await accept_token(contract_minter_A, token_instance_A, w3_A, tokenId)
            assert token_instance_A.functions.getStateOfToken(tokenId).call() == 2

        print("Test setup ready, performing measurement for multiple asset transfers")

        with patch("data_transfer.interledger.Interledger.cleanup") as mock_cleanup:
        #mock cleanup to check the transfer reaches the end

        #Create interledger with a bridge in direction from A to B
            print("Building Interledger bridge A -> B")
            inititator = EthereumInitiator(contract_minter_A, contract_address_A, contract_abi_A, url, port=portA)
            responder = EthereumResponder(contract_minter_B, contract_address_B, contract_abi_B, url, port=portB)
            interledger = Interledger(inititator, responder)

            print("Creating Intelredger run coroutine")
        
    
            interledger_task = asyncio.ensure_future(interledger.run())

            print("A smart contract call in ledger A marks the token in 'TransferOut'")

            start_time = time.time()
            total_cost = 0
            for j in range(0, index):
                (data, blockNumber,gas_used)= await transfer_token(contract_minter_A, token_instance_A, w3_A, ids[i][j])
                total_cost += gas_used 
        
            await asyncio.sleep(1.5*index) # Simulate Interledger running, should be longer than block time

            for j in range(0, index):
                tx_hash1 = interledger.transfers_sent[j].result["tx_hash"]
                tx_hash2 = interledger.results_commit[j]["commit_tx_hash"]

                assert token_instance_B.functions.getStateOfToken(ids[i][j]).call() == 2 # Here
                assert token_instance_A.functions.getStateOfToken(ids[i][j]).call() == 0 # Not Here

                total_cost += calculate_used_gas(tx_hash1, w3_B)
                total_cost += calculate_used_gas(tx_hash2, w3_A)
            elapsed_time = time.time() - start_time
            print("number of transfers: ", index)
            print("time: ", elapsed_time)
            print("Total cost: ", total_cost) 
            
            print("Stopping Interledger run coroutine")
            interledger.stop()
            await interledger_task


        print("*----------------------------------------------------*")
예제 #8
0
async def test_interledger_with_two_ethereum_transaction_failure(config):
    # set up ledgerA and ledgerB
    tokenId = uuid4().int
    (contract_minter_A, contract_address_A, contract_abi_A, url,
     portA) = setUp(config, 'left')
    (contract_minter_B, contract_address_B, contract_abi_B, url,
     portB) = setUp(config, 'right')

    w3_A = Web3(Web3.HTTPProvider(url + ":" + str(portA)))
    w3_B = Web3(Web3.HTTPProvider(url + ":" + str(portB)))
    token_instance_A = w3_A.eth.contract(abi=contract_abi_A,
                                         address=contract_address_A)
    token_instance_B = w3_B.eth.contract(abi=contract_abi_B,
                                         address=contract_address_B)
    await create_token(contract_minter_A, token_instance_A, w3_A, tokenId)
    #the token will not be created on ledgerB to emulate transaction failure on the responder side

    assert token_instance_A.functions.getStateOfToken(tokenId).call() == 0

    print("Test setup ready")

    with patch(
            "data_transfer.interledger.Interledger.cleanup") as mock_cleanup:
        # mock cleanup to check the transfer reaches the end

        # Create interledger with a bridge in direction from A to B
        print("Building Interledger bridge A -> B...")
        inititator = EthereumInitiator(contract_minter_A,
                                       contract_address_A,
                                       contract_abi_A,
                                       url,
                                       port=portA)
        responder = EthereumResponder(contract_minter_B,
                                      contract_address_B,
                                      contract_abi_B,
                                      url,
                                      port=portB)
        interledger = Interledger(inititator, responder)

        print("Creating Intelredger run coroutine...")

        interledger_task = asyncio.ensure_future(interledger.run())

        print(
            "A smart contract call in ledger A marks the token in 'TransferOut'..."
        )

        # Activate token in ledgerA
        await accept_token(contract_minter_A, token_instance_A, w3_A, tokenId)
        assert token_instance_A.functions.getStateOfToken(tokenId).call() == 2
        (data, blockNumber,
         gas_used) = await transfer_token(contract_minter_A, token_instance_A,
                                          w3_A, tokenId)
        assert token_instance_A.functions.getStateOfToken(tokenId).call() == 1

        await asyncio.sleep(
            4
        )  # Simulate Interledger running, should be longer than block time

        assert len(interledger.transfers) == 1
        assert len(interledger.results_abort) == 1

        tx_hash = interledger.results_abort[0]["tx_hash"]
        status = interledger.results_abort[0]["status"]
        assert tx_hash == None
        assert status == False

        assert token_instance_A.functions.getStateOfToken(tokenId).call() == 2

        assert len(interledger.results_commit) == 0
        assert len(interledger.results_abort) == 1

        tx_hash = interledger.results_abort[0]["abort_tx_hash"]
        status = interledger.results_abort[0]["abort_status"]
        assert status == True
        tx_info = w3_A.eth.getTransaction(tx_hash)
        tx_receipt = w3_A.eth.getTransactionReceipt(tx_hash)
        # check also other information about the transaction
        assert tx_info['hash'] == tx_hash
        assert tx_info['blockHash'] != None
        assert tx_info['to'] == contract_address_A
        print(tx_info)
        # check function name and abi
        decoded_input = token_instance_A.decode_function_input(
            tx_info['input'])
        assert decoded_input[
            0].fn_name == token_instance_A.get_function_by_name(
                "interledgerAbort").fn_name
        assert decoded_input[0].abi == token_instance_A.get_function_by_name(
            "interledgerAbort").abi
        # check function parameters
        assert decoded_input[1]['tokenId'] == tokenId
        assert decoded_input[1]['reason'] == 2  #ErrorCode.TRANSACTION_FAILURE
        print("Stopping Interledger run coroutine")
        interledger.stop()
        await interledger_task
예제 #9
0
async def test_interledger_with_two_ethereum(config):
    # set up ledgerA and ledgerB
    tokenId = uuid4().int
    (contract_minter_A, contract_address_A, contract_abi_A, url,
     portA) = setUp(config, 'left')
    (contract_minter_B, contract_address_B, contract_abi_B, url,
     portB) = setUp(config, 'right')

    w3_A = Web3(Web3.HTTPProvider(url + ":" + str(portA)))
    w3_B = Web3(Web3.HTTPProvider(url + ":" + str(portB)))
    token_instance_A = w3_A.eth.contract(abi=contract_abi_A,
                                         address=contract_address_A)
    token_instance_B = w3_B.eth.contract(abi=contract_abi_B,
                                         address=contract_address_B)

    await create_token(contract_minter_A, token_instance_A, w3_A, tokenId)
    await create_token(contract_minter_B, token_instance_B, w3_B, tokenId)
    assert token_instance_B.functions.getStateOfToken(tokenId).call() == 0
    assert token_instance_A.functions.getStateOfToken(tokenId).call() == 0

    print("Test setup ready")

    with patch(
            "data_transfer.interledger.Interledger.cleanup") as mock_cleanup:
        # mock cleanup to check the transfer reaches the end

        # Create interledger with a bridge in direction from A to B
        print("Building Interledger bridge A -> B")
        inititator = EthereumInitiator(contract_minter_A,
                                       contract_address_A,
                                       contract_abi_A,
                                       url,
                                       port=portA)
        responder = EthereumResponder(contract_minter_B,
                                      contract_address_B,
                                      contract_abi_B,
                                      url,
                                      port=portB)
        interledger = Interledger(inititator, responder)

        print("Creating Intelredger run coroutine")

        interledger_task = asyncio.ensure_future(interledger.run())

        print(
            "A smart contract call in ledger A marks the token in 'TransferOut'"
        )

        # Activate token in ledgerA

        await accept_token(contract_minter_A, token_instance_A, w3_A, tokenId)
        assert token_instance_A.functions.getStateOfToken(tokenId).call() == 2
        (data, blockNumber,
         gas_used) = await transfer_token(contract_minter_A, token_instance_A,
                                          w3_A, tokenId)
        assert token_instance_A.functions.getStateOfToken(tokenId).call() == 1

        await asyncio.sleep(
            4
        )  # Simulate Interledger running, should be longer than block time

        assert token_instance_B.functions.getStateOfToken(
            tokenId).call() == 2  # Here
        assert token_instance_A.functions.getStateOfToken(
            tokenId).call() == 0  # Not Here

        assert len(interledger.transfers) == 1
        assert len(interledger.results_commit) == 1
        print(interledger.results_commit[0])
        tx_hash = interledger.results_commit[0]["tx_hash"]
        status = interledger.results_commit[0]["status"]
        assert status == True
        tx_info = w3_B.eth.getTransaction(tx_hash)
        tx_receipt = w3_B.eth.getTransactionReceipt(tx_hash)

        # check also other information about the transaction
        assert tx_info['hash'] == tx_hash
        assert tx_info['blockHash'] != None
        assert tx_info['to'] == contract_address_B
        print(tx_info)

        # check function name and abi
        decoded_input = token_instance_B.decode_function_input(
            tx_info['input'])
        assert decoded_input[
            0].fn_name == token_instance_B.get_function_by_name(
                "interledgerReceive").fn_name
        assert decoded_input[0].abi == token_instance_B.get_function_by_name(
            "interledgerReceive").abi

        # check function parameters
        assert decoded_input[1]['data'] == data
        nonce = decoded_input[1]['nonce']

        # check for accepted/rejected events
        logs_accept = token_instance_B.events.InterledgerEventAccepted(
        ).processReceipt(tx_receipt)
        logs_reject = token_instance_B.events.InterledgerEventRejected(
        ).processReceipt(tx_receipt)

        assert len(logs_accept) == 1
        assert logs_accept[0]['args']['nonce'] == nonce
        assert len(logs_reject) == 0

        assert len(interledger.results_commit) == 1
        tx_hash = interledger.results_commit[0]["commit_tx_hash"]
        status = interledger.results_commit[0]["commit_status"]
        assert status == True
        tx_info = w3_A.eth.getTransaction(tx_hash)
        tx_receipt = w3_A.eth.getTransactionReceipt(tx_hash)
        # check also other information about the transaction
        assert tx_info['hash'] == tx_hash
        assert tx_info['blockHash'] != None
        assert tx_info['to'] == contract_address_A
        print(tx_info)
        # check function name and abi
        decoded_input = token_instance_A.decode_function_input(
            tx_info['input'])
        assert decoded_input[
            0].fn_name == token_instance_A.get_function_by_signature(
                'interledgerCommit(uint256)').fn_name
        assert decoded_input[
            0].abi == token_instance_A.get_function_by_signature(
                'interledgerCommit(uint256)').abi
        # check function parameters
        assert decoded_input[1]['tokenId'] == tokenId

        print("Stopping Interledger run coroutine")
        interledger.stop()
        await interledger_task

        print("*----------*")

        print("Building Interledger bridge B -> A")
        inititator = EthereumInitiator(contract_minter_B,
                                       contract_address_B,
                                       contract_abi_B,
                                       url,
                                       port=portB)
        responder = EthereumResponder(contract_minter_A,
                                      contract_address_A,
                                      contract_abi_A,
                                      url,
                                      port=portA)
        interledger = Interledger(inititator, responder)

        print("Creating Intelredger run coroutine")

        interledger_task = asyncio.ensure_future(interledger.run())

        print(
            "A smart contract call in ledger B marks the token in 'TransferOut'"
        )
        (data, blockNumber,
         gas_used) = await transfer_token(contract_minter_B, token_instance_B,
                                          w3_B, tokenId)
        assert token_instance_B.functions.getStateOfToken(tokenId).call() == 1

        await asyncio.sleep(
            4
        )  # Simulate Interledger running, should be longer than block time

        assert token_instance_A.functions.getStateOfToken(tokenId).call() == 2
        assert token_instance_B.functions.getStateOfToken(tokenId).call() == 0
        assert len(interledger.transfers) == 1
        assert len(interledger.results_commit) == 1
        tx_hash = interledger.results_commit[0]["tx_hash"]
        status = interledger.results_commit[0]["status"]
        assert status == True
        tx_info = w3_A.eth.getTransaction(tx_hash)
        tx_receipt = w3_A.eth.getTransactionReceipt(tx_hash)
        assert tx_info['blockHash'] != None
        assert tx_info['hash'] == tx_hash
        assert tx_info['to'] == contract_address_A
        print(tx_info)

        # check function name and abi
        decoded_input = token_instance_A.decode_function_input(
            tx_info['input'])
        assert decoded_input[
            0].fn_name == token_instance_A.get_function_by_name(
                "interledgerReceive").fn_name
        assert decoded_input[0].abi == token_instance_A.get_function_by_name(
            "interledgerReceive").abi

        # check function parameters
        assert decoded_input[1]['data'] == data
        nonce = decoded_input[1]['nonce']

        # check for accepted/rejected events
        logs_accept = token_instance_A.events.InterledgerEventAccepted(
        ).processReceipt(tx_receipt)
        logs_reject = token_instance_A.events.InterledgerEventRejected(
        ).processReceipt(tx_receipt)
        assert len(logs_accept) == 1
        assert logs_accept[0]['args']['nonce'] == nonce
        assert len(logs_reject) == 0

        assert len(interledger.results_commit) == 1

        tx_hash = interledger.results_commit[0]["commit_tx_hash"]
        status = interledger.results_commit[0]["commit_status"]
        assert status == True
        tx_info = w3_B.eth.getTransaction(tx_hash)
        tx_receipt = w3_B.eth.getTransactionReceipt(tx_hash)
        # check also other information about the transaction
        assert tx_info['hash'] == tx_hash
        assert tx_info['blockHash'] != None
        assert tx_info['to'] == contract_address_B
        print(tx_info)
        # check function name and abi
        decoded_input = token_instance_B.decode_function_input(
            tx_info['input'])
        assert decoded_input[
            0].fn_name == token_instance_B.get_function_by_signature(
                'interledgerCommit(uint256)').fn_name
        assert decoded_input[
            0].abi == token_instance_B.get_function_by_signature(
                'interledgerCommit(uint256)').abi
        # check function parameters
        assert decoded_input[1]['tokenId'] == tokenId

        print("Stopping Interledger run coroutine")
        interledger.stop()
        await interledger_task
async def async_main():
    assert sys.argv[1]  # configuration file, e.g. local-config-HF-ETH.cfg
    config_file = sys.argv[1]

    parser = ConfigParser()
    try:
        parser.read(config_file)
    except:
        print("Parsing configuration fails...")
        exit(-1)

    print(
        "Parsing configuarations for HyperLedger Fabric network interaction..."
    )
    # parse the configs for network at left side
    (net_profile, channel_name, cc_name, cc_version, org_name, user_name,
     peer_name) = parse_fabric(parser, 'left1')
    net_profile = os.path.join('.', net_profile)

    # set up channel and get client
    cli = await channel_setup(net_profile, channel_name, org_name, user_name)

    # deploy chaincodes for data sender
    await data_sender_setup(cli, net_profile, channel_name, cc_name,
                            cc_version, org_name, user_name, peer_name)

    # connect to initiator 1
    initiator1 = FabricInitiator(net_profile=net_profile,
                                 channel_name=channel_name,
                                 cc_name=cc_name,
                                 cc_version=cc_version,
                                 org_name=org_name,
                                 user_name=user_name,
                                 peer_name=peer_name)
    print("*** Have the Interledger initiator 1 connected ***")

    # parse the configs for network at right side
    (net_profile, channel_name, cc_name, cc_version, org_name, user_name,
     peer_name) = parse_fabric(parser, 'right2')
    net_profile = os.path.join('.', net_profile)

    # deploy chaincodes for data receiver
    await data_receiver_setup(cli, net_profile, channel_name, cc_name,
                              cc_version, org_name, user_name, peer_name)

    # connect to responder 2
    responder2 = FabricResponder(net_profile=net_profile,
                                 channel_name=channel_name,
                                 cc_name=cc_name,
                                 cc_version=cc_version,
                                 org_name=org_name,
                                 user_name=user_name,
                                 peer_name=peer_name)
    print("*** Have the Interledger responder 2 connected ***")

    # parse ethereum network
    (minter, contract_address, contract_abi, url, port, private_key, password,
     poa) = parse_ethereum(parser, "right1")

    # connect responder 1
    responder1 = EthereumResponder(minter, contract_address, contract_abi, url,
                                   port, private_key, password, poa)
    print("*** Have the Interledger responder 1 connected ***")

    # parse ethereum network
    (minter, contract_address, contract_abi, url, port, private_key, password,
     poa) = parse_ethereum(parser, "left2")

    # connect initiator 2
    initiator2 = EthereumInitiator(minter, contract_address, contract_abi, url,
                                   port, private_key, password, poa)
    print("*** Have the Interledger initiator 2 connected ***")

    # instantiate the Interledger components
    interledger1 = Interledger(initiator1, responder1)
    print("*** Have the interledger ready for HF --> ETH ***")

    interledger2 = Interledger(initiator2, responder2)
    print("*** Have the interledger ready for ETH --> HF ***")

    print('\n' * 5)

    print("*********************************************")
    print("Data transfer: Hyperledger Fabric => Ethereum")
    print("*********************************************")

    task1 = asyncio.ensure_future(interledger1.run())

    set_gopath()
    await asyncio.sleep(5)

    org1_admin = cli.get_user(org_name='org1.example.com', name='Admin')

    # emit data
    print(f"--- emit data at: {datetime.now()} ---")

    args = ['0xabc123']
    # The response should be true if succeed
    response = await cli.chaincode_invoke(requestor=org1_admin,
                                          channel_name='mychannel',
                                          peers=['peer0.org1.example.com'],
                                          args=args,
                                          cc_name='data_sender',
                                          fcn='emitData',
                                          wait_for_event=True)

    await asyncio.sleep(3)
    interledger1.stop()
    await asyncio.sleep(1)
    task1.cancel()

    print('\n' * 5)

    print("*********************************************")
    print("Data transfer: Ethereum => Hyperledger Fabric")
    print("*********************************************")

    task2 = asyncio.ensure_future(interledger2.run())

    await asyncio.sleep(5)

    # prepare data sender contract for emitting data
    w3 = Web3(Web3.HTTPProvider(url + ":" + str(port)))
    data_sender = w3.eth.contract(abi=contract_abi, address=contract_address)

    tx_hash = data_sender.functions.emitData(b"0xdef456").transact(
        {'from': minter})
    w3.eth.waitForTransactionReceipt(tx_hash)

    await asyncio.sleep(3)
    interledger2.stop()
    await asyncio.sleep(1)
    task2.cancel()

    exit(0)