예제 #1
0
    def test_start_and_stopping_destroys_servers_ipc(self):
        # Create Network service
        w1 = Wallet()
        n1 = NetworkParameters(peer_ipc='peers1',
                               event_ipc='events1',
                               discovery_ipc='discovery1')
        p1 = Network(wallet=w1,
                     ctx=self.ctx,
                     socket_base='ipc:///tmp',
                     params=n1)

        # Create Network service
        w2 = Wallet()
        n2 = NetworkParameters(peer_ipc='peers2', event_port='events2')
        p2 = Network(wallet=w2,
                     ctx=self.ctx,
                     socket_base='ipc:///tmp',
                     params=n2)

        async def stop(n: Network, s):
            await asyncio.sleep(s)
            n.peer_service.stop()

        tasks = asyncio.gather(p1.peer_service.start(),
                               p2.peer_service.start(), stop(p1, 0.3),
                               stop(p2, 0.3))

        loop = asyncio.get_event_loop()
        loop.run_until_complete(tasks)
예제 #2
0
    def test_start_and_stopping_destroys_servers(self):
        # Create Network service
        w1 = Wallet()
        n1 = NetworkParameters(peer_port=10001, event_port=10002)
        p1 = Network(wallet=w1,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n1)

        # Create Network service
        w2 = Wallet()
        n2 = NetworkParameters(peer_port=10003, event_port=10004)
        p2 = Network(wallet=w2,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n2)

        async def stop(n: Network, s):
            await asyncio.sleep(s)
            n.peer_service.stop()

        tasks = asyncio.gather(p1.peer_service.start(),
                               p2.peer_service.start(), stop(p1, 0.3),
                               stop(p2, 0.3))

        loop = asyncio.get_event_loop()
        loop.run_until_complete(tasks)
예제 #3
0
    def __init__(self,
                 wallet,
                 socket_base,
                 ctx=None,
                 network_parameters=NetworkParameters(),
                 linger=500,
                 poll_timeout=200,
                 blocks: CilantroStorageDriver = None,
                 driver=BlockchainDriver()):

        self.wallet = wallet
        self.ctx = ctx or zmq.asyncio.Context()
        self.address = network_parameters.resolve(socket_base,
                                                  ServiceType.BLOCK_SERVER,
                                                  bind=True)

        super().__init__(socket_id=self.address,
                         wallet=self.wallet,
                         ctx=self.ctx,
                         linger=linger,
                         poll_timeout=poll_timeout)

        self.blocks = blocks or CilantroStorageDriver(
            key=self.wallet.signing_key())
        self.driver = driver
        self.log = get_logger('BlockServer')
예제 #4
0
    def test_find_node_fails_if_cant_find_and_retries_are_up(self):
        # Create Network service
        w1 = Wallet()
        n1 = NetworkParameters(peer_port=10001, event_port=10002)
        p1 = Network(wallet=w1,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n1)

        # Create Network service
        w2 = Wallet()
        n2 = NetworkParameters(peer_port=10003, event_port=10004)
        p2 = Network(wallet=w2,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n2)

        w3 = Wallet()

        async def get():
            return await p1.find_node(_socket('tcp://127.0.0.1:10003'),
                                      w3.verifying_key().hex(),
                                      retries=1)

        async def stop(n: Network, s):
            await asyncio.sleep(s)
            n.peer_service.stop()

        tasks = asyncio.gather(
            p1.peer_service.start(),
            p2.peer_service.start(),
            get(),
            stop(p1, 0.3),
            stop(p2, 0.3),
        )

        loop = asyncio.get_event_loop()
        res = loop.run_until_complete(tasks)

        self.assertIsNone(res[2])
예제 #5
0
    def test_find_node_requests_from_others_and_returns_key_if_they_have_it_ipc(
            self):
        # Create Network service
        w1 = Wallet()
        n1 = NetworkParameters(peer_ipc='peers1',
                               event_ipc='events1',
                               discovery_ipc='discovery1')
        p1 = Network(wallet=w1,
                     ctx=self.ctx,
                     socket_base='ipc:///tmp',
                     params=n1)

        # Create Network service
        w2 = Wallet()
        n2 = NetworkParameters(peer_ipc='peers2', event_port='events2')
        p2 = Network(wallet=w2,
                     ctx=self.ctx,
                     socket_base='ipc:///tmp',
                     params=n2)

        async def get():
            return await p1.find_node(_socket('ipc:///tmp/peers2'),
                                      w2.verifying_key().hex())

        async def stop(n: Network, s):
            await asyncio.sleep(s)
            n.peer_service.stop()

        tasks = asyncio.gather(
            p1.peer_service.start(),
            p2.peer_service.start(),
            get(),
            stop(p1, 0.3),
            stop(p2, 0.3),
        )

        loop = asyncio.get_event_loop()
        res = loop.run_until_complete(tasks)

        self.assertEqual(res[2].get(w2.verifying_key().hex()), 'ipc:///tmp')
    def __init__(self,
                 socket_base,
                 service_type,
                 ctx: zmq.asyncio.Context,
                 network_parameters=NetworkParameters(),
                 phonebook_function: callable = None):
        # self.port = port
        self.network_parameters = network_parameters

        self.peer_service_address = self.network_parameters.resolve(
            socket_base, ServiceType.PEER)
        self.service_type = service_type

        self.phonebook_function = phonebook_function
        self.sockets = {}
        self.ctx = ctx
예제 #7
0
    def __init__(self,
                 wallet,
                 params=NetworkParameters(),
                 ctx=zmq.asyncio.Context(),
                 bootnodes=[],
                 initial_mn_quorum=1,
                 initial_del_quorum=1,
                 mn_to_find=[],
                 del_to_find=[],
                 socket_base='tcp://0.0.0.0',
                 poll_timeout=200,
                 linger=1000,
                 debug=True,
                 mn_seed=None):

        self.log = get_logger('NetworkService')
        self.log.propagate = debug

        self.mn_seed = mn_seed  # Set this to a single masternode if you are joining the network!!

        # General Instance Variables
        self.wallet = wallet
        self.ctx = ctx

        self.bootnodes = bootnodes
        self.ip = socket_base

        # Peer Service Constants
        self.params = params

        self.socket_base = socket_base

        self.peer_service_address = self.params.resolve(socket_base,
                                                        ServiceType.PEER,
                                                        bind=True)
        self.event_server_address = self.params.resolve(socket_base,
                                                        ServiceType.EVENT,
                                                        bind=True)
        self.peer_service = PeerServer(
            self.peer_service_address,
            event_address=self.event_server_address,
            table={self.wallet.verifying_key().hex(): socket_base},
            wallet=self.wallet,
            ctx=self.ctx,
            poll_timeout=poll_timeout,
            linger=linger)

        self.discovery_server_address = self.params.resolve(
            self.socket_base, ServiceType.DISCOVERY, bind=True)
        self.discovery_server = discovery.DiscoveryServer(
            pepper=PEPPER.encode(),
            socket_id=self.discovery_server_address,
            wallet=self.wallet,
            ctx=self.ctx,
            poll_timeout=poll_timeout,
            linger=linger)

        # Quorum Constants
        self.initial_mn_quorum = initial_mn_quorum
        self.initial_del_quorum = initial_del_quorum

        self.mn_to_find = mn_to_find
        self.del_to_find = del_to_find

        self.ready = False

        self.outbox = services.Outbox(self.ctx)
예제 #8
0
    def __init__(self,
                 socket_base,
                 ctx: zmq.asyncio.Context,
                 wallet,
                 constitution: dict,
                 overwrite=False,
                 bootnodes=[],
                 network_parameters=NetworkParameters(),
                 driver=BlockchainDriver(),
                 mn_seed=None,
                 debug=True,
                 store=False):

        self.driver = driver
        self.store = store

        self.blocks = None
        if self.store:
            self.blocks = MasterStorage()

        self.waiting_for_confirmation = False

        self.log = get_logger('NODE')
        self.log.propagate = debug
        self.log.info(constitution)
        self.socket_base = socket_base
        self.wallet = wallet
        self.ctx = ctx
        self.ctx.max_sockets = 50_000

        self.client = ContractingClient(
            driver=self.driver,
            submission_filename=cilantro_ee.contracts.__path__[0] +
            '/submission.s.py')

        # Sync contracts

        sync.submit_from_genesis_json_file(cilantro_ee.contracts.__path__[0] +
                                           '/genesis.json',
                                           client=self.client)
        sync.submit_node_election_contracts(
            initial_masternodes=constitution['masternodes'],
            boot_mns=constitution['masternode_min_quorum'],
            initial_delegates=constitution['delegates'],
            boot_dels=constitution['delegate_min_quorum'],
            client=self.client)

        self.driver.commit()
        self.driver.clear_pending_state()

        self.contacts = VKBook(
            client=self.client,
            boot_mn=constitution['masternode_min_quorum'],
            boot_del=constitution['delegate_min_quorum'],
        )

        self.current_masters = deepcopy(self.contacts.masternodes)
        self.current_delegates = deepcopy(self.contacts.delegates)

        self.parameters = Parameters(socket_base,
                                     ctx,
                                     wallet,
                                     contacts=self.contacts)

        self.socket_authenticator = SocketAuthenticator(ctx=self.ctx)

        self.elect_masternodes = self.client.get_contract('elect_masternodes')
        self.elect_delegates = self.client.get_contract('elect_delegates')

        self.masternode_contract = self.client.get_contract('masternodes')
        self.delegate_contract = self.client.get_contract('delegates')

        self.update_sockets()

        # Cilantro version / upgrade

        self.version_state = self.client.get_contract('upgrade')
        self.active_upgrade = self.version_state.quick_read('upg_lock')

        self.tol_mn = self.version_state.quick_read('tol_mn')
        self.tot_dl = self.version_state.quick_read('tot_dl')

        if self.tol_mn is None:
            self.tol_mn = 0

        if self.tot_dl is None:
            self.tot_dl = 0

        self.all_votes = self.tol_mn + self.tot_dl
        self.mn_votes = self.version_state.quick_read('mn_vote')
        self.dl_votes = self.version_state.quick_read('dl_vote')
        # self.pending_cnt = self.all_votes - self.vote_cnt
        # stuff

        self.network_parameters = network_parameters

        self.bootnodes = bootnodes
        self.constitution = constitution
        self.overwrite = overwrite

        # Should have a function to get the current NBN
        self.block_fetcher = BlockFetcher(
            wallet=self.wallet,
            ctx=self.ctx,
            parameters=self.parameters,
        )

        self.network = Network(
            wallet=self.wallet,
            ctx=self.ctx,
            socket_base=socket_base,
            bootnodes=self.bootnodes,
            params=self.network_parameters,
            initial_del_quorum=deepcopy(self.contacts.delegate_quorum_min),
            initial_mn_quorum=deepcopy(self.contacts.masternode_quorum_min),
            mn_to_find=deepcopy(self.contacts.masternodes),
            del_to_find=deepcopy(self.contacts.delegates),
            mn_seed=mn_seed)

        self.nbn_inbox = NBNInbox(socket_id=self.network_parameters.resolve(
            self.socket_base,
            service_type=ServiceType.BLOCK_NOTIFICATIONS,
            bind=True),
                                  ctx=self.ctx,
                                  driver=self.driver,
                                  contacts=self.contacts,
                                  wallet=wallet)

        self.reward_manager = RewardManager(driver=self.driver, debug=True)

        self.running = False
예제 #9
0
    def test_wait_for_quorum_to_succeed_only_one_master(self):
        # 0 tries
        mnw1 = Wallet()
        n1 = NetworkParameters(peer_port=10001, event_port=10002)
        mn1 = Network(wallet=mnw1,
                      ctx=self.ctx,
                      socket_base='tcp://127.0.0.1',
                      params=n1)

        # 1 try
        mnw2 = Wallet()
        n2 = NetworkParameters(peer_port=10003, event_port=10004)
        mn2 = Network(wallet=mnw2,
                      ctx=self.ctx,
                      socket_base='tcp://127.0.0.1',
                      params=n2)

        dw1 = Wallet()
        n3 = NetworkParameters(peer_port=10005, event_port=10006)
        d1 = Network(wallet=dw1,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n3)

        # 2 tries <- info in this node should be returned
        dw2 = Wallet()
        n4 = NetworkParameters(peer_port=10007, event_port=10008)
        d2 = Network(wallet=dw2,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n4)

        async def get():
            return await mn1.wait_for_quorum(
                1,
                0, [mnw1.verifying_key().hex(),
                    mnw2.verifying_key().hex()],
                [dw1.verifying_key().hex(),
                 dw2.verifying_key().hex()],
                initial_peers=[_socket('tcp://127.0.0.1:10003')])

        async def stop(n: Network, s):
            await asyncio.sleep(s)
            n.peer_service.stop()

        timeout = 0.3

        tasks = asyncio.gather(
            mn1.peer_service.start(),
            mn2.peer_service.start(),
            d1.peer_service.start(),
            d2.peer_service.start(),
            get(),
            stop(mn1, timeout),
            stop(mn2, timeout),
            stop(d1, timeout),
            stop(d1, timeout),
        )

        loop = asyncio.get_event_loop()
        loop.run_until_complete(tasks)

        self.assertIn(mnw2.verifying_key().hex(), mn1.peer_service.table)
예제 #10
0
    def test_wait_for_quorum_resolves_when_late_joiner(self):
        # 0 tries
        mnw1 = Wallet()
        n1 = NetworkParameters(peer_port=10001, event_port=10002)
        mn1 = Network(wallet=mnw1,
                      ctx=self.ctx,
                      socket_base='tcp://127.0.0.1',
                      params=n1)

        # 1 try
        mnw2 = Wallet()
        n2 = NetworkParameters(peer_port=10003, event_port=10004)
        mn2 = Network(wallet=mnw2,
                      ctx=self.ctx,
                      socket_base='tcp://127.0.0.1',
                      params=n2)

        dw1 = Wallet()
        n3 = NetworkParameters(peer_port=10005, event_port=10006)
        d1 = Network(wallet=dw1,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n3)

        # 2 tries <- info in this node should be returned
        dw2 = Wallet()
        n4 = NetworkParameters(peer_port=10007, event_port=10008)
        d2 = Network(wallet=dw2,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1',
                     params=n4)
        # Add various info to each so that a crawl is successful
        mn2.peer_service.table[
            dw1.verifying_key().hex()] = 'tcp://127.0.0.1:10005'
        d1.peer_service.table[
            dw2.verifying_key().hex()] = 'tcp://127.0.0.1:10007'

        async def get():
            return await mn1.wait_for_quorum(
                2,
                2, [mnw1.verifying_key().hex(),
                    mnw2.verifying_key().hex()],
                [dw1.verifying_key().hex(),
                 dw2.verifying_key().hex()],
                initial_peers=[_socket('tcp://127.0.0.1:10003')])

        async def stop(n: Network, s):
            await asyncio.sleep(s)
            n.peer_service.stop()

        async def start_late(n: Network, s):
            await asyncio.sleep(s)
            await n.peer_service.start()

        timeout = 2

        tasks = asyncio.gather(
            mn1.peer_service.start(),
            start_late(mn2, 0.1),
            start_late(d1, 0.5),
            start_late(d2, 1),
            get(),
            stop(mn1, timeout),
            stop(mn2, timeout),
            stop(d1, timeout),
            stop(d1, timeout),
        )

        loop = asyncio.get_event_loop()
        loop.run_until_complete(tasks)

        self.assertIn(mnw2.verifying_key().hex(), mn1.peers)
        self.assertIn(dw1.verifying_key().hex(), mn1.peers)
        self.assertIn(dw2.verifying_key().hex(), mn1.peers)