async def main(start_port: int, show_timing: bool = False, routing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) alice = None faber = None alice_router = None run_timer = log_timer("Total runtime:") run_timer.start() try: alice = AliceAgent(start_port, genesis_data=genesis, timing=show_timing) await alice.listen_webhooks(start_port + 2) faber = FaberAgent(start_port + 3, genesis_data=genesis, timing=show_timing) await faber.listen_webhooks(start_port + 5) await faber.register_did() if routing: alice_router = RoutingAgent(start_port + 6, genesis_data=genesis, timing=show_timing) await alice_router.listen_webhooks(start_port + 8) await alice_router.register_did() with log_timer("Startup duration:"): if alice_router: await alice_router.start_process() await alice.start_process() await faber.start_process() with log_timer("Publish duration:"): await faber.publish_defs() with log_timer("Connect duration:"): if routing: router_invite = await alice_router.get_invite() alice_router_conn_id = await alice.receive_invite(router_invite ) await asyncio.wait_for(alice.detect_connection(), 30) invite = await faber.get_invite() if routing: conn_id = await alice.receive_invite(invite, accept="manual") await alice.establish_inbound(conn_id, alice_router_conn_id) await alice.accept_invite(conn_id) await asyncio.wait_for(alice.detect_connection(), 30) else: await alice.receive_invite(invite) await asyncio.wait_for(faber.detect_connection(), 30) if show_timing: await alice.reset_timing() await faber.reset_timing() if routing: await alice_router.reset_timing() issue_count = 300 batch_size = 100 semaphore = asyncio.Semaphore(10) async def send(): await semaphore.acquire() asyncio.ensure_future(faber.send_credential()).add_done_callback( lambda fut: semaphore.release()) recv_timer = alice.log_timer(f"Received {issue_count} credentials in ") recv_timer.start() batch_timer = faber.log_timer( f"Started {batch_size} credential exchanges in ") batch_timer.start() async def check_received(agent, issue_count, pb): reported = 0 iter_pb = iter(pb) if pb else None while True: pending, total = agent.check_received_creds() if iter_pb and total > reported: try: while next(iter_pb) < total: pass except StopIteration: iter_pb = None reported = total if total == issue_count and not pending: break await asyncio.wait_for(agent.update_creds(), 30) with progress() as pb: receive_task = None try: issue_pg = pb(range(issue_count), label="Issuing credentials") receive_pg = pb(range(issue_count), label="Receiving credentials") issue_task = asyncio.ensure_future( check_received(faber, issue_count, issue_pg)) receive_task = asyncio.ensure_future( check_received(alice, issue_count, receive_pg)) with faber.log_timer( f"Done starting {issue_count} credential exchanges in " ): for idx in range(0, issue_count): await send() if not (idx + 1) % batch_size and idx < issue_count - 1: batch_timer.reset() await issue_task await receive_task except KeyboardInterrupt: if receive_task: receive_task.cancel() print("Canceled") recv_timer.stop() avg = recv_timer.duration / issue_count alice.log(f"Average time per credential: {avg:.2f}s ({1/avg:.2f}/s)") if show_timing: timing = await alice.fetch_timing() if timing: for line in alice.format_timing(timing): alice.log(line) timing = await faber.fetch_timing() if timing: for line in faber.format_timing(timing): faber.log(line) if routing: timing = await alice_router.fetch_timing() if timing: for line in alice_router.format_timing(timing): alice_router.log(line) finally: terminated = True try: if alice: await alice.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False try: if faber: await faber.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False try: if alice_router: await alice_router.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False run_timer.stop() await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main( start_port: int, threads: int = 20, ping_only: bool = False, show_timing: bool = False, routing: bool = False, issue_count: int = 300, ): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) alice = None faber = None alice_router = None run_timer = log_timer("Total runtime:") run_timer.start() try: alice = AliceAgent(start_port, genesis_data=genesis, timing=show_timing) await alice.listen_webhooks(start_port + 2) faber = FaberAgent(start_port + 3, genesis_data=genesis, timing=show_timing) await faber.listen_webhooks(start_port + 5) await faber.register_did() if routing: alice_router = RoutingAgent(start_port + 6, genesis_data=genesis, timing=show_timing) await alice_router.listen_webhooks(start_port + 8) await alice_router.register_did() with log_timer("Startup duration:"): if alice_router: await alice_router.start_process() await alice.start_process() await faber.start_process() if not ping_only: with log_timer("Publish duration:"): await faber.publish_defs() # await alice.set_tag_policy(faber.credential_definition_id, ["name"]) with log_timer("Connect duration:"): if routing: router_invite = await alice_router.get_invite() alice_router_conn_id = await alice.receive_invite(router_invite ) await asyncio.wait_for(alice.detect_connection(), 30) invite = await faber.get_invite() if routing: conn_id = await alice.receive_invite(invite, accept="manual") await alice.establish_inbound(conn_id, alice_router_conn_id) await alice.accept_invite(conn_id) await asyncio.wait_for(alice.detect_connection(), 30) else: await alice.receive_invite(invite) await asyncio.wait_for(faber.detect_connection(), 30) if show_timing: await alice.reset_timing() await faber.reset_timing() if routing: await alice_router.reset_timing() batch_size = 100 semaphore = asyncio.Semaphore(threads) def done_send(fut: asyncio.Task): semaphore.release() faber.check_task_exception(fut) async def send_credential(index: int): await semaphore.acquire() comment = f"issue test credential {index}" attributes = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", } asyncio.ensure_future(faber.send_credential( attributes, comment)).add_done_callback(done_send) async def check_received_creds(agent, issue_count, pb): reported = 0 iter_pb = iter(pb) if pb else None while True: pending, total = await agent.check_received_creds() complete = total - pending if reported == complete: await asyncio.wait_for(agent.update_creds(), 30) continue if iter_pb and complete > reported: try: while next(iter_pb) < complete: pass except StopIteration: iter_pb = None reported = complete if reported == issue_count: break async def send_ping(index: int): await semaphore.acquire() asyncio.ensure_future(faber.send_ping( str(index))).add_done_callback(done_send) async def check_received_pings(agent, issue_count, pb): reported = 0 iter_pb = iter(pb) if pb else None while True: pings = await agent.check_received_pings() complete = sum(len(tids) for tids in pings.values()) if complete == reported: await asyncio.wait_for(agent.update_pings(), 30) continue if iter_pb and complete > reported: try: while next(iter_pb) < complete: pass except StopIteration: iter_pb = None reported = complete if reported >= issue_count: break if ping_only: recv_timer = faber.log_timer( f"Completed {issue_count} ping exchanges in") batch_timer = faber.log_timer( f"Started {batch_size} ping exchanges in") else: recv_timer = faber.log_timer( f"Completed {issue_count} credential exchanges in") batch_timer = faber.log_timer( f"Started {batch_size} credential exchanges in") recv_timer.start() batch_timer.start() with progress() as pb: receive_task = None try: if ping_only: issue_pg = pb(range(issue_count), label="Sending pings") receive_pg = pb(range(issue_count), label="Responding pings") check_received = check_received_pings send = send_ping completed = f"Done sending {issue_count} pings in" else: issue_pg = pb(range(issue_count), label="Issuing credentials") receive_pg = pb(range(issue_count), label="Receiving credentials") check_received = check_received_creds send = send_credential completed = f"Done starting {issue_count} credential exchanges in" issue_task = asyncio.ensure_future( check_received(faber, issue_count, issue_pg)) issue_task.add_done_callback(faber.check_task_exception) receive_task = asyncio.ensure_future( check_received(alice, issue_count, receive_pg)) receive_task.add_done_callback(alice.check_task_exception) with faber.log_timer(completed): for idx in range(0, issue_count): await send(idx + 1) if not (idx + 1) % batch_size and idx < issue_count - 1: batch_timer.reset() await issue_task await receive_task except KeyboardInterrupt: if receive_task: receive_task.cancel() print("Canceled") recv_timer.stop() avg = recv_timer.duration / issue_count item_short = "ping" if ping_only else "cred" item_long = "ping exchange" if ping_only else "credential" faber.log(f"Average time per {item_long}: {avg:.2f}s ({1/avg:.2f}/s)") if alice.postgres: await alice.collect_postgres_stats(f"{issue_count} {item_short}s") for line in alice.format_postgres_stats(): alice.log(line) if faber.postgres: await faber.collect_postgres_stats(f"{issue_count} {item_short}s") for line in faber.format_postgres_stats(): faber.log(line) if show_timing: timing = await alice.fetch_timing() if timing: for line in alice.format_timing(timing): alice.log(line) timing = await faber.fetch_timing() if timing: for line in faber.format_timing(timing): faber.log(line) if routing: timing = await alice_router.fetch_timing() if timing: for line in alice_router.format_timing(timing): alice_router.log(line) finally: terminated = True try: if alice: await alice.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False try: if faber: await faber.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False try: if alice_router: await alice_router.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False run_timer.stop() await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main( start_port: int, threads: int = 20, action: str = None, show_timing: bool = False, multitenant: bool = False, mediation: bool = False, use_did_exchange: bool = False, revocation: bool = False, tails_server_base_url: str = None, issue_count: int = 300, wallet_type: str = None, ): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) alice = None faber = None alice_mediator_agent = None faber_mediator_agent = None run_timer = log_timer("Total runtime:") run_timer.start() try: alice = AliceAgent( start_port, genesis_data=genesis, timing=show_timing, multitenant=multitenant, mediation=mediation, wallet_type=wallet_type, ) await alice.listen_webhooks(start_port + 2) faber = FaberAgent( start_port + 3, genesis_data=genesis, timing=show_timing, tails_server_base_url=tails_server_base_url, multitenant=multitenant, mediation=mediation, wallet_type=wallet_type, ) await faber.listen_webhooks(start_port + 5) await faber.register_did() with log_timer("Startup duration:"): await alice.start_process() await faber.start_process() if mediation: alice_mediator_agent = await start_mediator_agent( start_port + 8, genesis) if not alice_mediator_agent: raise Exception("Mediator agent returns None :-(") faber_mediator_agent = await start_mediator_agent( start_port + 11, genesis) if not faber_mediator_agent: raise Exception("Mediator agent returns None :-(") else: alice_mediator_agent = None faber_mediator_agent = None with log_timer("Connect duration:"): if multitenant: # create an initial managed sub-wallet (also mediated) await alice.register_or_switch_wallet( "Alice.initial", webhook_port=None, mediator_agent=alice_mediator_agent, ) await faber.register_or_switch_wallet( "Faber.initial", public_did=True, webhook_port=None, mediator_agent=faber_mediator_agent, ) elif mediation: # we need to pre-connect the agent(s) to their mediator (use the same # mediator for both) if not await connect_wallet_to_mediator( alice, alice_mediator_agent): log_msg("Mediation setup FAILED :-(") raise Exception("Mediation setup FAILED :-(") if not await connect_wallet_to_mediator( faber, faber_mediator_agent): log_msg("Mediation setup FAILED :-(") raise Exception("Mediation setup FAILED :-(") invite = await faber.get_invite(use_did_exchange) await alice.receive_invite(invite["invitation"]) await asyncio.wait_for(faber.detect_connection(), 30) if action != "ping": with log_timer("Publish duration:"): await faber.publish_defs(revocation) # cache the credential definition await alice.fetch_credential_definition( faber.credential_definition_id) if show_timing: await alice.reset_timing() await faber.reset_timing() if mediation: await alice_mediator_agent.reset_timing() await faber_mediator_agent.reset_timing() batch_size = 100 semaphore = asyncio.Semaphore(threads) def done_propose(fut: asyncio.Task): semaphore.release() alice.check_task_exception(fut) def done_send(fut: asyncio.Task): semaphore.release() faber.check_task_exception(fut) def test_cred(index: int) -> dict: return { "name": "Alice Smith", "date": f"{2020+index}-05-28", "degree": "Maths", "age": "24", } async def propose_credential(index: int): await semaphore.acquire() comment = f"propose test credential {index}" attributes = test_cred(index) asyncio.ensure_future( alice.propose_credential( attributes, faber.credential_definition_id, comment, not revocation)).add_done_callback(done_propose) async def send_credential(index: int): await semaphore.acquire() comment = f"issue test credential {index}" attributes = test_cred(index) asyncio.ensure_future( faber.send_credential( attributes, comment, not revocation)).add_done_callback(done_send) async def check_received_creds(agent, issue_count, pb): reported = 0 iter_pb = iter(pb) if pb else None while True: pending, total = await agent.check_received_creds() complete = total - pending if reported == complete: await asyncio.wait_for(agent.update_creds(), 30) continue if iter_pb and complete > reported: try: while next(iter_pb) < complete: pass except StopIteration: iter_pb = None reported = complete if reported == issue_count: break async def send_ping(index: int): await semaphore.acquire() asyncio.ensure_future(faber.send_ping( str(index))).add_done_callback(done_send) async def check_received_pings(agent, issue_count, pb): reported = 0 iter_pb = iter(pb) if pb else None while True: pings = await agent.check_received_pings() complete = sum(len(tids) for tids in pings.values()) if complete == reported: await asyncio.wait_for(agent.update_pings(), 30) continue if iter_pb and complete > reported: try: while next(iter_pb) < complete: pass except StopIteration: iter_pb = None reported = complete if reported >= issue_count: break if action == "ping": recv_timer = faber.log_timer( f"Completed {issue_count} ping exchanges in") batch_timer = faber.log_timer( f"Started {batch_size} ping exchanges in") else: recv_timer = faber.log_timer( f"Completed {issue_count} credential exchanges in") batch_timer = faber.log_timer( f"Started {batch_size} credential exchanges in") recv_timer.start() batch_timer.start() with progress() as pb: receive_task = None try: if action == "ping": issue_pg = pb(range(issue_count), label="Sending pings") receive_pg = pb(range(issue_count), label="Responding pings") check_received = check_received_pings send = send_ping completed = f"Done sending {issue_count} pings in" else: issue_pg = pb(range(issue_count), label="Issuing credentials") receive_pg = pb(range(issue_count), label="Receiving credentials") check_received = check_received_creds if action == "propose": send = propose_credential else: send = send_credential completed = f"Done starting {issue_count} credential exchanges in" issue_task = asyncio.ensure_future( check_received(faber, issue_count, issue_pg)) issue_task.add_done_callback(faber.check_task_exception) receive_task = asyncio.ensure_future( check_received(alice, issue_count, receive_pg)) receive_task.add_done_callback(alice.check_task_exception) with faber.log_timer(completed): for idx in range(0, issue_count): await send(idx + 1) if not (idx + 1) % batch_size and idx < issue_count - 1: batch_timer.reset() await issue_task await receive_task except KeyboardInterrupt: if receive_task: receive_task.cancel() print("Cancelled") recv_timer.stop() avg = recv_timer.duration / issue_count item_short = "ping" if action == "ping" else "cred" item_long = "ping exchange" if action == "ping" else "credential" faber.log(f"Average time per {item_long}: {avg:.2f}s ({1/avg:.2f}/s)") if alice.postgres: await alice.collect_postgres_stats(f"{issue_count} {item_short}s") for line in alice.format_postgres_stats(): alice.log(line) if faber.postgres: await faber.collect_postgres_stats(f"{issue_count} {item_short}s") for line in faber.format_postgres_stats(): faber.log(line) if revocation and faber.revocations: (rev_reg_id, cred_rev_id) = next(iter(faber.revocations)) print(f"Revoking and publishing cred rev id {cred_rev_id} " f"from rev reg id {rev_reg_id}") if show_timing: timing = await alice.fetch_timing() if timing: for line in alice.format_timing(timing): alice.log(line) timing = await faber.fetch_timing() if timing: for line in faber.format_timing(timing): faber.log(line) if mediation: timing = await alice_mediator_agent.fetch_timing() if timing: for line in alice_mediator_agent.format_timing(timing): alice_mediator_agent.log(line) timing = await faber_mediator_agent.fetch_timing() if timing: for line in faber_mediator_agent.format_timing(timing): faber_mediator_agent.log(line) finally: terminated = True try: if alice: await alice.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False try: if faber: await faber.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False try: if alice_mediator_agent: await alice_mediator_agent.terminate() if faber_mediator_agent: await faber_mediator_agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False run_timer.stop() await asyncio.sleep(0.1) if not terminated: os._exit(1)