async def test__threadbased_protocol_on_hub(test_suite: ServerTestSuite): agent1_params = test_suite.get_agent_params('agent1') agent2_params = test_suite.get_agent_params('agent2') agent1 = Agent( server_address=agent1_params['server_address'], credentials=agent1_params['credentials'], p2p=agent1_params['p2p'], timeout=5, ) agent2 = Agent( server_address=agent2_params['server_address'], credentials=agent2_params['credentials'], p2p=agent2_params['p2p'], timeout=5, ) await agent1.open() await agent2.open() try: # Get endpoints agent1_endpoint = [ e for e in agent1.endpoints if e.routing_keys == [] ][0].address agent2_endpoint = [ e for e in agent2.endpoints if e.routing_keys == [] ][0].address # Init pairwise list #1 did1, verkey1 = await agent1.wallet.did.create_and_store_my_did() did2, verkey2 = await agent2.wallet.did.create_and_store_my_did() await agent1.wallet.did.store_their_did(did2, verkey2) await agent1.wallet.pairwise.create_pairwise(their_did=did2, my_did=did1) await agent2.wallet.did.store_their_did(did1, verkey1) await agent2.wallet.pairwise.create_pairwise(their_did=did1, my_did=did2) # Init pairwise list #2 pairwise1 = Pairwise(me=Pairwise.Me(did=did1, verkey=verkey1), their=Pairwise.Their(did=did2, label='Label-2', endpoint=agent2_endpoint, verkey=verkey2)) pairwise2 = Pairwise(me=Pairwise.Me(did=did2, verkey=verkey2), their=Pairwise.Their(did=did1, label='Label-1', endpoint=agent1_endpoint, verkey=verkey1)) finally: await agent1.close() await agent2.close() thread_id = uuid.uuid4().hex co1 = sirius_sdk.CoProtocolThreadedP2P(thread_id, pairwise1) co2 = sirius_sdk.CoProtocolThreadedP2P(thread_id, pairwise2) MSG_LOG.clear() await run_coroutines(routine1_on_hub(co1, **agent1_params), routine2_on_hub(co2, **agent2_params)) check_msg_log()
async def accept_transaction(self, leader: sirius_sdk.Pairwise, txn_propose: Message) -> bool: # Act as transaction acceptor self.ledger.add_transaction(txn_propose['txn']) assert txn_propose['@type'] == TYPE_BFT_CONSENSUS_PROPOSE co = sirius_sdk.CoProtocolThreadedP2P( thid=txn_propose['~thread']['thid'], to=leader ) # Stage-1: Check local ledger is in consistent state with leader if self.ledger.uncommitted_root_hash != txn_propose['uncommitted_root_hash']: await co.send(message=Message({ '@type': TYPE_BFT_CONSENSUS_PROBLEM, 'problem-code': 'some-code', 'explain': 'non consistent ledger states' })) self.ledger.reset_uncommitted() return False # stage-2: send pre-commit response and wait commits from all participants # (assumed in production commits will be signed) ok, response = await co.switch(message=Message({ '@type': TYPE_BFT_CONSENSUS_PRE_COMMIT, 'uncommitted_root_hash': self.ledger.uncommitted_root_hash })) if ok: assert response['@type'] == TYPE_BFT_CONSENSUS_COMMIT pre_commits = response['pre_commits'] # Here developers may check signatures and consistent for pre_commit in pre_commits: if pre_commit['uncommitted_root_hash'] != self.ledger.uncommitted_root_hash: await co.send(message=Message({ '@type': TYPE_BFT_CONSENSUS_PROBLEM, 'problem-code': 'some-code', 'explain': 'non consistent ledger states' })) self.ledger.reset_uncommitted() return False # Ack commit await co.send(message=Message({ '@type': TYPE_BFT_CONSENSUS_COMMIT, })) self.ledger.commit() return True else: # Timeout occur or something else self.ledger.reset_uncommitted() return False
async def coroutine2(server_address: str, credentials: bytes, p2p: sirius_sdk.P2PConnection, **kwargs): nonlocal co nonlocal pw1 nonlocal new_thread_id await asyncio.sleep(3) await co.abort() await asyncio.sleep(3) async with sirius_sdk.context(server_address, credentials, p2p): try: new_co_on_same_hub = sirius_sdk.CoProtocolThreadedP2P( thid=new_thread_id, to=pw2) await new_co_on_same_hub.send( sirius_sdk.aries_rfc.Ping(comment='Test Ping')) except Exception as e: raise
async def __detect_current_environment(self) -> Environment: async with sirius_sdk.context(**self.hub_credentials): # Open communication channel to transmit requests and await events from participants communication = sirius_sdk.CoProtocolThreadedP2P( thid='request-id-' + uuid.uuid4().hex, to=self.baydoor, time_to_live=5) log(f'AirLock[{self.index}]: check environment') # SWITCH method suspend runtime thread until participant will respond or error/timeout occur ok, response = await communication.switch( message=Message({'@type': TYPE_STATE_REQUEST})) if ok: if response['status'] == State.CLOSED.value: ret = Environment.FRIENDLY # Bay door should be closed for Friendly environment else: ret = Environment.HOSTILE else: # Timeout occur ret = Environment.HOSTILE log(f'AitLock[{self.index}]: current environment: {ret}') return ret
async def coroutine1(server_address: str, credentials: bytes, p2p: sirius_sdk.P2PConnection, **kwargs): nonlocal co nonlocal pw1 nonlocal msg_log nonlocal new_thread_id async with sirius_sdk.context(server_address, credentials, p2p): try: while True: msg = await co.get_one() print(str(msg)) except OperationAbortedManually: pass try: new_co_on_same_hub = sirius_sdk.CoProtocolThreadedP2P( thid=new_thread_id, to=pw1) msg, _, _ = await new_co_on_same_hub.get_one() print('!') msg_log.append(msg) except Exception as e: raise
async def test_coprotocol_abort(test_suite: ServerTestSuite, agent1: Agent, agent2: Agent): agent1_params = test_suite.get_agent_params('agent1') await agent1.open() await agent2.open() try: pw1 = await get_pairwise(agent1, agent2) finally: await agent1.close() await agent2.close() co = sirius_sdk.CoProtocolThreadedP2P(thid=uuid.uuid4().hex, to=pw1) exc = None async def infinite_reader(server_address: str, credentials: bytes, p2p: sirius_sdk.P2PConnection, **kwargs): nonlocal co nonlocal exc try: async with sirius_sdk.context(server_address, credentials, p2p): while True: msg = await co.get_one() print(str(msg)) except OperationAbortedManually as e: exc = e async def delayed_aborter(): nonlocal co await asyncio.sleep(3) await co.abort() await run_coroutines( infinite_reader(**agent1_params), delayed_aborter(), ) assert exc is not None assert isinstance(exc, OperationAbortedManually)
async def test_coprotocol_abort_multiple_ops_single_hub( test_suite: ServerTestSuite, agent1: Agent, agent2: Agent): agent1_params = test_suite.get_agent_params('agent1') agent2_params = test_suite.get_agent_params('agent2') await agent1.open() await agent2.open() try: pw1 = await get_pairwise(agent1, agent2) pw2 = await get_pairwise(agent2, agent1) finally: await agent1.close() await agent2.close() co = sirius_sdk.CoProtocolThreadedP2P(thid=uuid.uuid4().hex, to=pw1) new_thread_id = 'new-thread-id-' + uuid.uuid4().hex msg_log = [] async def coroutine1(server_address: str, credentials: bytes, p2p: sirius_sdk.P2PConnection, **kwargs): nonlocal co nonlocal pw1 nonlocal msg_log nonlocal new_thread_id async with sirius_sdk.context(server_address, credentials, p2p): try: while True: msg = await co.get_one() print(str(msg)) except OperationAbortedManually: pass try: new_co_on_same_hub = sirius_sdk.CoProtocolThreadedP2P( thid=new_thread_id, to=pw1) msg, _, _ = await new_co_on_same_hub.get_one() print('!') msg_log.append(msg) except Exception as e: raise async def coroutine2(server_address: str, credentials: bytes, p2p: sirius_sdk.P2PConnection, **kwargs): nonlocal co nonlocal pw1 nonlocal new_thread_id await asyncio.sleep(3) await co.abort() await asyncio.sleep(3) async with sirius_sdk.context(server_address, credentials, p2p): try: new_co_on_same_hub = sirius_sdk.CoProtocolThreadedP2P( thid=new_thread_id, to=pw2) await new_co_on_same_hub.send( sirius_sdk.aries_rfc.Ping(comment='Test Ping')) except Exception as e: raise await run_coroutines(coroutine1(**agent1_params), coroutine2(**agent2_params)) assert len(msg_log) == 1 msg = msg_log[0] assert isinstance(msg, sirius_sdk.aries_rfc.Ping) assert msg.comment == 'Test Ping'