def test_multicast_sends_to_multiple(self): authenticator = authentication.SocketAuthenticator( client=ContractingClient(), ctx=self.ctx) w1 = Wallet() w2 = Wallet() w3 = Wallet() authenticator.add_verifying_key(w1.verifying_key) authenticator.add_verifying_key(w2.verifying_key) authenticator.add_verifying_key(w3.verifying_key) authenticator.configure() m1 = router.Router(socket_id='tcp://127.0.0.1:10000', ctx=self.ctx, linger=2000, poll_timeout=50, secure=True, wallet=w1) q1 = router.QueueProcessor() m1.add_service('something', q1) m2 = router.Router(socket_id='tcp://127.0.0.1:10001', ctx=self.ctx, linger=2000, poll_timeout=50, secure=True, wallet=w2) q2 = router.QueueProcessor() m2.add_service('something', q2) async def get(): peers = { w1.verifying_key: 'tcp://127.0.0.1:10000', w2.verifying_key: 'tcp://127.0.0.1:10001' } await router.secure_multicast(msg={'hello': 'there'}, service='something', wallet=w3, peer_map=peers, ctx=self.ctx) tasks = asyncio.gather( m1.serve(), m2.serve(), get(), stop_server(m1, 1), stop_server(m2, 1), ) loop = asyncio.get_event_loop() loop.run_until_complete(tasks) self.assertEqual(q1.q[0], {'hello': 'there'}) self.assertEqual(q2.q[0], {'hello': 'there'})
def test_send_work_multicasts_tx_batch_to_delegates(self): ips = [ 'tcp://127.0.0.1:18001', 'tcp://127.0.0.1:18002', 'tcp://127.0.0.1:18003' ] d1w = Wallet() d2w = Wallet() m1w = Wallet() self.authenticator.add_verifying_key(d1w.verifying_key) self.authenticator.add_verifying_key(d2w.verifying_key) self.authenticator.add_verifying_key(m1w.verifying_key) self.authenticator.configure() d1_r = router.Router(socket_id=ips[0], ctx=self.ctx, wallet=d1w, secure=True) d2_r = router.Router(socket_id=ips[1], ctx=self.ctx, wallet=d2w, secure=True) d1_q = router.QueueProcessor() d2_q = router.QueueProcessor() d1_r.add_service(base.WORK_SERVICE, d1_q) d2_r.add_service(base.WORK_SERVICE, d2_q) node = masternode.Masternode( socket_base=ips[2], ctx=self.ctx, wallet=m1w, constitution={ 'masternodes': [m1w.verifying_key], 'delegates': [d1w.verifying_key, d2w.verifying_key] }, driver=self.driver) node.network.peers = { d1w.verifying_key: ips[0], d2w.verifying_key: ips[1], m1w.verifying_key: ips[2] } tasks = asyncio.gather(d1_r.serve(), d2_r.serve(), node.send_work(), stop_server(d1_r, 1), stop_server(d2_r, 1)) self.loop.run_until_complete(tasks) txb1 = d1_q.q.pop(0) txb2 = d2_q.q.pop(0) self.assertDictEqual(txb1, txb2)
def test_broadcast_new_chain_sends_messages_to_all_peers(self): mn_wallet = Wallet() mn_bootnode = 'tcp://127.0.0.1:18001' mn_router = router.Router(wallet=mn_wallet, socket_id=mn_bootnode, ctx=self.ctx, secure=True) dl_wallet = Wallet() dl_bootnode = 'tcp://127.0.0.1:18002' dl_router = router.Router(wallet=dl_wallet, socket_id=dl_bootnode, ctx=self.ctx, secure=True) driver = ContractDriver(driver=InMemDriver()) node = masternode.Masternode(socket_base='tcp://127.0.0.1:18003', ctx=self.ctx, wallet=Wallet(), constitution={ 'masternodes': [mn_wallet.verifying_key], 'delegates': [dl_wallet.verifying_key] }, driver=driver) node.client.set_var(contract='masternodes', variable='S', arguments=['members'], value=[mn_wallet.verifying_key]) node.client.set_var(contract='delegates', variable='S', arguments=['members'], value=[dl_wallet.verifying_key]) node.socket_authenticator.refresh_governance_sockets() node.network.peers = { mn_wallet.verifying_key: mn_bootnode, dl_wallet.verifying_key: dl_bootnode } node.tx_batcher.queue.append('MOCK TX') tasks = asyncio.gather(mn_router.serve(), dl_router.serve(), node.broadcast_new_blockchain_started(), stop_server(mn_router, 0.2), stop_server(dl_router, 0.2)) self.loop.run_until_complete(tasks)
def test_request_none_returns_default_message(self): r = router.Router(socket_id='ipc:///tmp/router', ctx=self.ctx, linger=50) async def request(msg): msg = encode(msg).encode() socket = self.ctx.socket(zmq.DEALER) socket.connect('ipc:///tmp/router') await socket.send(msg) resp = await socket.recv() resp = decode(resp) return resp bad_message = {'service': 'hello', 'blah': 123} tasks = asyncio.gather( r.serve(), request(bad_message), stop_server(r, 1), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) self.assertEqual(res[1], router.OK)
def test_get_latest_block_height(self): storage.set_latest_block_height(1337, self.b.driver) vk = Wallet() w = Wallet() self.authenticator.add_verifying_key(vk.verifying_key) self.authenticator.add_verifying_key(w.verifying_key) self.authenticator.configure() mn_bootnode = 'tcp://127.0.0.1:18001' mn_router = router.Router(socket_id=mn_bootnode, ctx=self.ctx, secure=True, wallet=vk) mn_router.add_service(base.BLOCK_SERVICE, self.b) async def send_msg(): res = await base.get_latest_block_height(ip=mn_bootnode, vk=vk.verifying_key, wallet=w, ctx=self.ctx) return res tasks = asyncio.gather(mn_router.serve(), send_msg(), stop_server(mn_router, 1)) _, res, _ = self.loop.run_until_complete(tasks) self.assertEqual(res, 1337)
def test_add_service(self): r = router.Router(socket_id='ipc:///tmp/router', ctx=self.ctx, linger=50) q = router.QueueProcessor() r.add_service('test', q) self.assertEqual(r.services['test'], q)
def setUp(self): self.ctx = zmq.asyncio.Context() self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.authenticator = authentication.SocketAuthenticator( client=ContractingClient(), ctx=self.ctx) self.b = masternode.BlockService(blocks=storage.BlockStorage(), driver=ContractDriver()) self.r = router.Router(socket_id='tcp://127.0.0.1:18001', ctx=self.ctx) self.r.add_service(base.BLOCK_SERVICE, self.b)
def test_secure_request_returns_result(self): authenticator = authentication.SocketAuthenticator( client=ContractingClient(), ctx=self.ctx) w = Wallet() w2 = Wallet() authenticator.add_verifying_key(w.verifying_key) authenticator.add_verifying_key(w2.verifying_key) authenticator.configure() class MockProcessor(router.Processor): async def process_message(self, msg): return {'whats': 'good'} m = router.Router(socket_id='tcp://127.0.0.1:10000', ctx=self.ctx, linger=2000, poll_timeout=50, secure=True, wallet=w) m.add_service('something', MockProcessor()) async def get(): r = await router.secure_request(msg={'hello': 'there'}, service='something', wallet=w2, vk=w.verifying_key, ip='tcp://127.0.0.1:10000', ctx=self.ctx) return r tasks = asyncio.gather( m.serve(), get(), stop_server(m, 1), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) self.assertDictEqual(res[1], {'whats': 'good'}) authenticator.authenticator.stop()
def test_catchup_with_nbn_added(self): driver = ContractDriver(driver=InMemDriver()) mn_bootnode = 'tcp://127.0.0.1:18001' mn_wallet = Wallet() mn_router = router.Router(socket_id=mn_bootnode, ctx=self.ctx, secure=True, wallet=mn_wallet) mn_router.add_service(base.BLOCK_SERVICE, self.b) nw = Wallet() dlw = Wallet() node = base.Node(socket_base='tcp://127.0.0.1:18002', ctx=self.ctx, wallet=nw, constitution={ 'masternodes': [mn_wallet.verifying_key], 'delegates': [dlw.verifying_key] }, driver=driver) self.authenticator.add_verifying_key(mn_wallet.verifying_key) self.authenticator.add_verifying_key(nw.verifying_key) self.authenticator.add_verifying_key(dlw.verifying_key) self.authenticator.configure() blocks = generate_blocks(4) self.blocks.store_block(blocks[0]) self.blocks.store_block(blocks[1]) self.blocks.store_block(blocks[2]) storage.set_latest_block_height(3, self.driver) node.new_block_processor.q.append(blocks[3]) tasks = asyncio.gather( mn_router.serve(), node.catchup('tcp://127.0.0.1:18001', mn_wallet.verifying_key), stop_server(mn_router, 1)) self.loop.run_until_complete(tasks) self.assertEqual(storage.get_latest_block_height(node.driver), 4)
def test_secure_send_receives_messages(self): authenticator = authentication.SocketAuthenticator( client=ContractingClient(), ctx=self.ctx) w = Wallet() w2 = Wallet() authenticator.add_verifying_key(w.verifying_key) authenticator.add_verifying_key(w2.verifying_key) authenticator.configure() m = router.Router(socket_id='tcp://127.0.0.1:10000', ctx=self.ctx, linger=2000, poll_timeout=50, secure=True, wallet=w) q = router.QueueProcessor() m.add_service('something', q) async def get(): await router.secure_send(msg={'hello': 'there'}, service='something', wallet=w2, vk=w.verifying_key, ip='tcp://127.0.0.1:10000', ctx=self.ctx) tasks = asyncio.gather( m.serve(), get(), stop_server(m, 1), ) loop = asyncio.get_event_loop() loop.run_until_complete(tasks) self.assertEqual(q.q[0], {'hello': 'there'}) authenticator.authenticator.stop()
def test_mock_processor_returns_custom_message(self): r = router.Router(socket_id='ipc:///tmp/router', ctx=self.ctx, linger=50) class MockProcessor(router.Processor): async def process_message(self, msg): return {'whats': 'good'} q = MockProcessor() r.add_service('test', q) async def request(msg): msg = encode(msg).encode() socket = self.ctx.socket(zmq.DEALER) socket.connect('ipc:///tmp/router') await socket.send(msg) resp = await socket.recv() resp = decode(resp) return resp message = {'service': 'test', 'msg': {'howdy': 'there'}} expected_msg = {'whats': 'good'} tasks = asyncio.gather( r.serve(), request(message), stop_server(r, 1), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) self.assertDictEqual(res[1], expected_msg)
def test_router_returns_none_if_no_block_found(self): block = { 'hash': '0' * 64, 'number': 1337, 'previous': '0' * 64, 'subblocks': [] } self.b.blocks.store_block(block) vk = Wallet() w = Wallet() self.authenticator.add_verifying_key(vk.verifying_key) self.authenticator.add_verifying_key(w.verifying_key) self.authenticator.configure() mn_bootnode = 'tcp://127.0.0.1:18001' mn_router = router.Router(socket_id=mn_bootnode, ctx=self.ctx, secure=True, wallet=vk) mn_router.add_service(base.BLOCK_SERVICE, self.b) async def send_msg(): res = await base.get_block(block_num=7331, ip=mn_bootnode, vk=vk.verifying_key, wallet=w, ctx=self.ctx) return res tasks = asyncio.gather(mn_router.serve(), send_msg(), stop_server(mn_router, 1)) _, res, _ = self.loop.run_until_complete(tasks) self.assertDictEqual(res, router.OK)
def test_queue_processor_returns_default_message(self): r = router.Router(socket_id='ipc:///tmp/router', ctx=self.ctx, linger=50) q = router.QueueProcessor() r.add_service('test', q) async def request(msg): msg = encode(msg).encode() socket = self.ctx.socket(zmq.DEALER) socket.connect('ipc:///tmp/router') await socket.send(msg) resp = await socket.recv() resp = decode(resp) return resp message = {'service': 'test', 'msg': {'howdy': 'there'}} expected_q = [{'howdy': 'there'}] tasks = asyncio.gather( r.serve(), request(message), stop_server(r, 1), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) self.assertEqual(res[1], router.OK) self.assertListEqual(expected_q, q.q)
def __init__(self, socket_base, ctx: zmq.asyncio.Context, wallet, constitution: dict, bootnodes={}, blocks=storage.BlockStorage(), driver=ContractDriver(), debug=True, store=False, seed=None, bypass_catchup=False, node_type=None, genesis_path=lamden.contracts.__path__[0], reward_manager=rewards.RewardManager(), nonces=storage.NonceStorage()): self.driver = driver self.nonces = nonces self.store = store self.seed = seed self.blocks = blocks self.event_writer = EventWriter() self.log = get_logger('Base') self.log.propagate = debug self.socket_base = socket_base self.wallet = wallet self.ctx = ctx self.genesis_path = genesis_path self.client = ContractingClient(driver=self.driver, submission_filename=genesis_path + '/submission.s.py') self.bootnodes = bootnodes self.constitution = constitution self.seed_genesis_contracts() self.socket_authenticator = authentication.SocketAuthenticator( bootnodes=self.bootnodes, ctx=self.ctx, client=self.client) self.upgrade_manager = upgrade.UpgradeManager(client=self.client, wallet=self.wallet, node_type=node_type) self.router = router.Router(socket_id=socket_base, ctx=self.ctx, wallet=wallet, secure=True) self.network = network.Network(wallet=wallet, ip_string=socket_base, ctx=self.ctx, router=self.router) self.new_block_processor = NewBlock(driver=self.driver) self.router.add_service( NEW_BLOCK_SERVICE, self.new_block_processor) # Add this after catch up? self.running = False self.upgrade = False self.reward_manager = reward_manager self.current_height = storage.get_latest_block_height(self.driver) self.current_hash = storage.get_latest_block_hash(self.driver) self.bypass_catchup = bypass_catchup
def test_start_boots_up_normally(self): # This MN will also provide 'catch up' services mn_bootnode = 'tcp://127.0.0.1:18001' mn_wallet = Wallet() mn_router = router.Router(socket_id=mn_bootnode, ctx=self.ctx, secure=True, wallet=mn_wallet) mn_network = network.Network(wallet=mn_wallet, ip_string=mn_bootnode, ctx=self.ctx, router=mn_router) blocks = generate_blocks(4) self.blocks.store_block(blocks[0]) self.blocks.store_block(blocks[1]) self.blocks.store_block(blocks[2]) storage.set_latest_block_height(3, self.driver) mn_router.add_service( base.BLOCK_SERVICE, masternode.BlockService(self.blocks, self.driver)) dl_bootnode = 'tcp://127.0.0.1:18002' dl_wallet = Wallet() dl_router = router.Router(socket_id=dl_bootnode, ctx=self.ctx, secure=True, wallet=dl_wallet) dl_network = network.Network(wallet=dl_wallet, ip_string=dl_bootnode, ctx=self.ctx, router=dl_router) constitution = { 'masternodes': [mn_wallet.verifying_key], 'delegates': [dl_wallet.verifying_key] } bootnodes = { mn_wallet.verifying_key: mn_bootnode, dl_wallet.verifying_key: dl_bootnode } node_w = Wallet() driver = ContractDriver(driver=InMemDriver()) node = base.Node(socket_base='tcp://127.0.0.1:18003', ctx=self.ctx, wallet=node_w, constitution=constitution, driver=driver, store=False, bootnodes=bootnodes) self.authenticator.add_verifying_key(mn_wallet.verifying_key) self.authenticator.add_verifying_key(dl_wallet.verifying_key) self.authenticator.add_verifying_key(node_w.verifying_key) self.authenticator.configure() vks = [mn_wallet.verifying_key, dl_wallet.verifying_key] tasks = asyncio.gather( mn_router.serve(), dl_router.serve(), mn_network.start(bootnodes, vks), dl_network.start(bootnodes, vks), stop_server(mn_router, 0.2), stop_server(dl_router, 0.2), ) self.loop.run_until_complete(tasks) tasks = asyncio.gather(mn_router.serve(), dl_router.serve(), node.start(), stop_server(mn_router, 1), stop_server(dl_router, 1), stop_server(node.router, 1)) self.loop.run_until_complete(tasks) self.assertEqual(storage.get_latest_block_height(node.driver), 3) self.assertEqual(storage.get_latest_block_hash(node.driver), blocks[2]['hash'])