async def test_interledger_confirm_transfer_abort(): async def foo(): return {'abort_status': True, 'abort_tx_hash': '0x444'} i = Interledger(MockInitiator([]), MockResponder()) t = Transfer() t.payload = {} t.payload['id'] = str(uuid4().int) t.result = {} t.state = State.CONFIRMING t.confirm_task = asyncio.ensure_future(foo()) i.results_aborting = [t] task = asyncio.ensure_future(i.confirm_transfer()) assert task.done() == False await task res = i.results_abort[0] assert t.state == State.FINALIZED assert res['abort_status'] == True assert res['abort_tx_hash'] == '0x444' assert len(i.results_abort) == 1 assert len(i.results_commit) == 0 assert len(i.results_aborting) == 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_interledger_cleanup(): interledger = Interledger(None, None) ts1 = return_transfer_list() interledger.transfers.extend(ts1) interledger.transfers_sent.extend(ts1) interledger.cleanup() assert len(interledger.transfers) is 4 assert len(interledger.transfers_sent) is 5
async def test_interledger_receive_transfer(): t = Transfer() t.payload = {} init = MockInitiator([t]) resp = MockResponder() interledger = Interledger(init, resp) # interledger.test_interrupt = True task = asyncio.ensure_future(interledger.receive_transfer()) assert task.done() == False l = await task assert init.events == [] assert len(interledger.transfers) == 1 assert l == 1 assert interledger.transfers[0].state == State.READY
async def test_interledger_transfer_result(): async def foo(): return 42 i = Interledger(MockInitiator([]), MockResponder()) t = Transfer() t.state = State.SENT t.send_task = asyncio.ensure_future(foo()) i.transfers_sent = [t] task = asyncio.ensure_future(i.transfer_result()) assert task.done() == False await task assert len(i.transfers_sent) == 0 assert len(i.transfers_responded) == 1 tr = i.transfers_responded[0] assert tr.state == State.RESPONDED assert tr.result == 42
async def test_interledger_send_transfer(): t = Transfer() t.payload = {} t.payload['nonce'] = str(uuid4().int) t.payload['data'] = b"dummy" i = Interledger(MockInitiator([]), MockResponder()) i.transfers = [t] task = asyncio.ensure_future(i.send_transfer()) assert task.done() == False await task assert len(i.transfers_sent) == 1 tr = i.transfers[0] assert tr.state == State.SENT assert asyncio.isfuture(tr.send_task) await tr.send_task assert tr.send_task.done() == True
async def test_interledger_process_result_abort(): i = Interledger(MockInitiator([]), MockResponder()) t = Transfer() t.payload = {} t.payload['id'] = str(uuid4().int) t.state = State.RESPONDED t.result = {"status": False} i.transfers_responded = [t] task = asyncio.ensure_future(i.process_result()) assert task.done() == False await task tr = i.results_aborting[0] assert tr.state == State.CONFIRMING assert tr.result['status'] == False assert len(i.results_commit) == 0 assert len(i.results_abort) == 0 assert len(i.transfers_responded) == 0
def test_interledger_init(): # Test initialization of interledger init = Initiator() resp = Responder() interledger = Interledger(init, resp) assert interledger.initiator == init assert interledger.responder == resp assert len(interledger.transfers) == 0 assert len(interledger.transfers_sent) == 0 assert len(interledger.results_committing) == 0 assert len(interledger.results_commit) == 0 assert len(interledger.results_aborting) == 0 assert len(interledger.results_abort) == 0 assert interledger.up == False
async def test_interledger_run_no_cleanup(): l1, l2, l3 = [], [], [] for i in range(4): t1, t2, t3 = Transfer(), Transfer(), Transfer() t1.payload, t2.payload, t3.payload = {}, {}, {} t1.payload['nonce'], t1.payload['id'], t1.payload['data'] = str(uuid4().int), '1', b"dummy1" t2.payload['nonce'], t2.payload['id'], t2.payload['data'] = str(uuid4().int), '2', b"dummy2" t3.payload['nonce'], t3.payload['id'], t3.payload['data'] = str(uuid4().int), '3', b"dummy3" l1.append(t1) l2.append(t2) l3.append(t3) init = MockInitiator(l1) i = Interledger(init, MockResponder()) with patch("data_transfer.interledger.Interledger.cleanup") as mock_cleanup: task = asyncio.ensure_future(i.run()) time = 0.5 # Consume l1 await asyncio.sleep(time) # Simulate interledger running # New events init.events = l2 # Consume l2 await asyncio.sleep(time) # Simulate interledger running # New events i.responder = MockResponderAbort() init.events = l3 # Consume l3, but with a responder returning False -> abort await asyncio.sleep(time) # Simulate interledger running assert len(i.transfers) == 12 assert len(i.transfers_sent) == 0 assert len(i.transfers_responded) == 0 assert len(i.results_committing) == 0 assert len(i.results_aborting) == 0 assert len(i.results_commit) == 8 assert len(i.results_abort) == 4 i.stop() await 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)
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
def test_interledger_stop(): interledger = Interledger(None, None) interledger.stop() assert interledger.up == False
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("*----------------------------------------------------*")
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
async def async_main(): assert sys.argv[1] # ensures a configuration file 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, 'left') net_profile = os.path.join('.', net_profile) # have the data sender and receiver deployed cli = await fabric_setup() # connect to initiator initiator = 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 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, 'right') # connect to responder responder = 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 initiator connected ***") # instantiate the Interledger component interledger = Interledger(initiator, responder) # get the interledger running task = asyncio.ensure_future(interledger.run()) set_gopath() await asyncio.sleep(7) org1_admin = cli.get_user(org_name='org1.example.com', name='Admin') # emit data print("********************************") print(f"emit data at: {datetime.now()}") print("********************************") 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(5) interledger.stop() await asyncio.sleep(5) exit(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') w3_A = Web3(Web3.HTTPProvider(url + ":" + str(portA))) token_instance_A = w3_A.eth.contract(abi=contract_abi_A, address=contract_address_A) (tokenId, cost) = await create_token(contract_minter_A, token_instance_A, w3_A, tokenId) (url_ksi, hash_algorithm, username, password) = setUp_ksi(config) 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 = KSIResponder(url_ksi, hash_algorithm, username, password) 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 await transfer_token(contract_minter_A, token_instance_A, w3_A, tokenId) assert token_instance_A.functions.getStateOfToken(tokenId).call() == 1 await asyncio.sleep(2) # Simulate Interledger running assert token_instance_A.functions.getStateOfToken(tokenId).call() == 0 assert len(interledger.transfers) == 1 assert len(interledger.transfers_sent) == 1 url = responder.url + "/" + interledger.transfers_sent[0].result[ "tx_hash"] # send it as a GET request and check for the result ksi_request = requests.get(url, auth=(responder.username, responder.password)) assert ksi_request.status_code == 200 assert ksi_request.json()['verificationResult']['status'] == "OK" assert len(interledger.results_commit) == 1 print("Stopping Interledger run coroutine") interledger.stop() await interledger_task print("*----------*")
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