Beispiel #1
0
    def test_update_with_block_sets_hash_and_height(self):
        _hash = storage.get_latest_block_hash(self.driver)
        num = storage.get_latest_block_height(self.driver)

        self.assertEqual(_hash, '0' * 64)
        self.assertEqual(num, 0)

        storage.update_state_with_block(block=block,
                                        driver=self.driver,
                                        nonces=self.nonces)

        _hash = storage.get_latest_block_hash(self.driver)
        num = storage.get_latest_block_height(self.driver)

        self.assertEqual(_hash, 'f' * 64)
        self.assertEqual(num, 555)
Beispiel #2
0
    def update_state(self, block):
        self.driver.clear_pending_state()

        # Check if the block is valid
        if self.should_process(block):
            self.log.info('Storing new block.')
            # Commit the state changes and nonces to the database
            storage.update_state_with_block(
                block=block,
                driver=self.driver,
                nonces=self.nonces
            )

            self.log.info('Issuing rewards.')
            # Calculate and issue the rewards for the governance nodes
            self.reward_manager.issue_rewards(
                block=block,
                client=self.client
            )

        self.log.info('Updating metadata.')
        self.current_height = storage.get_latest_block_height(self.driver)
        self.current_hash = storage.get_latest_block_hash(self.driver)

        self.new_block_processor.clean(self.current_height)
Beispiel #3
0
    async def get_latest_block_number(self, request):
        self.driver.clear_pending_state()

        num = storage.get_latest_block_height(self.driver)

        return response.json({'latest_block_number': num},
                             headers={'Access-Control-Allow-Origin': '*'})
Beispiel #4
0
 async def get_latest_block_number(self, request):
     return response.json(
         {
             'latest_block_number': storage.get_latest_block_height(
                 self.driver)
         },
         headers={'Access-Control-Allow-Origin': '*'})
Beispiel #5
0
    def test_generate_environment_creates_block_num(self):
        timestamp = time.time()

        exe = execution.SerialExecutor(executor=self.client.executor)

        e = exe.generate_environment(self.client.raw_driver, timestamp, 'A' * 64)

        self.assertEqual(e['block_num'], storage.get_latest_block_height(self.client.raw_driver) + 1)
Beispiel #6
0
    async def get_latest_block(self, request):
        self.driver.clear_pending_state()

        num = storage.get_latest_block_height(self.driver)
        block = await self.blocks.get_block(int(num))
        return response.json(block,
                             dumps=NonceEncoder().encode,
                             headers={'Access-Control-Allow-Origin': '*'})
Beispiel #7
0
    async def gather_subblocks(self,
                               total_contacts,
                               current_height=0,
                               current_hash='0' * 64,
                               quorum_ratio=0.66,
                               adequate_ratio=0.5,
                               expected_subblocks=4):
        self.sbc_inbox.expected_subblocks = expected_subblocks

        block = storage.get_latest_block_height(self.driver)

        self.log.info(
            f'Expecting {expected_subblocks} subblocks from {total_contacts} delegates.'
        )

        contenders = BlockContender(total_contacts=total_contacts,
                                    required_consensus=quorum_ratio,
                                    total_subblocks=expected_subblocks,
                                    acceptable_consensus=adequate_ratio)

        # Add timeout condition.
        started = time.time()
        last_log = started
        while (not contenders.block_has_consensus() and contenders.responses < contenders.total_contacts) and \
                time.time() - started < self.seconds_to_timeout:

            if self.sbc_inbox.has_sbc():
                sbcs = await self.sbc_inbox.receive_sbc(
                )  # Can probably make this raw sync code
                self.log.info('Pop it in there.')
                contenders.add_sbcs(sbcs)

            if time.time() - last_log > 5:
                self.log.error(
                    f'Waiting for contenders for {int(time.time() - started)}s.'
                )
                last_log = time.time()

            await asyncio.sleep(0)

        if time.time() - started > self.seconds_to_timeout:
            self.log.error(
                f'Block timeout. Too many delegates are offline! Kick out the non-responsive ones! {block}'
            )

        self.log.info('Done aggregating new block.')

        block = contenders.get_current_best_block()
        self.log.error(block)
        self.sbc_inbox.q.clear()

        # self.log.info(f'Best block: {block}')

        return block_from_subblocks(block,
                                    previous_hash=current_hash,
                                    block_num=current_height + 1)
Beispiel #8
0
    async def process_message(self, msg):
        response = None
        mn_logger.debug('Got a msg')
        if primatives.dict_has_keys(msg, keys={'name', 'arg'}):
            if msg['name'] == base.GET_BLOCK:
                response = self.get_block(msg)
            elif msg['name'] == base.GET_HEIGHT:
                response = get_latest_block_height(self.driver)

        return response
Beispiel #9
0
    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)
Beispiel #10
0
    def test_process_new_block_updates_state(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        node.process_new_block(block)

        self.assertEqual(storage.get_latest_block_height(node.driver), 1)
        self.assertEqual(storage.get_latest_block_hash(node.driver),
                         block['hash'])
Beispiel #11
0
    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
Beispiel #12
0
 async def get_latest_block(self, request):
     num = storage.get_latest_block_height(self.driver)
     block = self.blocks.get_block(int(num))
     return response.json(block,
                          dumps=ByteEncoder().encode,
                          headers={'Access-Control-Allow-Origin': '*'})
Beispiel #13
0
    def test_masternode_delegate_single_loop_updates_block_num(self):
        ips = [
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002'
        ]

        dw = Wallet()
        mw = Wallet()

        self.authenticator.add_verifying_key(mw.verifying_key)
        self.authenticator.add_verifying_key(dw.verifying_key)
        self.authenticator.configure()

        mnd = ContractDriver(driver=InMemDriver())
        mn = masternode.Masternode(
            socket_base=ips[0],
            ctx=self.ctx,
            wallet=mw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=mnd
        )
        sender = Wallet()
        mnd.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)

        dld = ContractDriver(driver=InMemDriver())
        dld.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)
        dl = delegate.Delegate(
            socket_base=ips[1],
            ctx=self.ctx,
            wallet=dw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=dld
        )

        tx = transaction.build_transaction(
            wallet=sender,
            contract='currency',
            function='transfer',
            kwargs={
                'amount': 1338,
                'to': 'jeff'
            },
            stamps=5000,
            nonce=0,
            processor=mw.verifying_key
        )

        tx_decoded = decode(tx)
        mn.tx_batcher.queue.append(tx_decoded)

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1]
        }

        mn.network.peers = peers
        dl.network.peers = peers

        tasks = asyncio.gather(
            mn.router.serve(),
            dl.router.serve(),
            mn.loop(),
            dl.loop(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        self.loop.run_until_complete(tasks)

        dh = storage.get_latest_block_height(dld)
        mh = storage.get_latest_block_height(mnd)

        self.assertEqual(dh, 1)
        self.assertEqual(mh, 1)
Beispiel #14
0
 def test_get_latest_block_height_correct_after_set(self):
     storage.set_latest_block_height(123, self.driver)
     h = storage.get_latest_block_height(self.driver)
     self.assertEqual(h, 123)
Beispiel #15
0
 def test_get_latest_block_height_0_if_none(self):
     h = storage.get_latest_block_height(self.driver)
     self.assertEqual(h, 0)
Beispiel #16
0
    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'])