Exemple #1
0
    def test_fail_vote(self):
        # GIVEN
        peer_manager = PeerManager(conf.LOOPCHAIN_DEFAULT_CHANNEL)
        self.__add_peer_to_peer_manager(peer_manager, 3)
        peer_manager.add_peer(
            PeerInfo("peerid-4",
                     "groupid-3",
                     "peerid-4_target",
                     cert=self.__cert))
        peer_manager.add_peer(
            PeerInfo("peerid-5",
                     "groupid-3",
                     "peerid-5_target",
                     cert=self.__cert))

        vote = Vote("block_hash", peer_manager)
        logging.debug("votes: " + str(vote.votes))

        # WHEN
        vote.add_vote("groupid-1", "peerid-1", conf.TEST_FAIL_VOTE_SIGN)
        vote.add_vote("groupid-3", "peerid-4", conf.TEST_FAIL_VOTE_SIGN)
        vote.add_vote("groupid-3", "peerid-5", conf.TEST_FAIL_VOTE_SIGN)
        vote.get_result("block_hash", 0.51)

        # THEN
        self.assertTrue(vote.is_failed_vote("block_hash", 0.51))
Exemple #2
0
    def test_add_vote_fail_before_add_peer(self):
        # GIVEN
        peer_manager = PeerManager(conf.LOOPCHAIN_DEFAULT_CHANNEL)
        self.__add_peer_to_peer_manager(peer_manager, 3)
        peer_manager.add_peer(
            PeerInfo("peerid-4",
                     "groupid-3",
                     "peerid-4_target",
                     cert=self.__cert))
        peer_manager.add_peer(
            PeerInfo("peerid-5",
                     "groupid-3",
                     "peerid-5_target",
                     cert=self.__cert))

        vote = Vote("block_hash", peer_manager)
        logging.debug("votes: " + str(vote.votes))

        # WHEN
        vote.add_vote("groupid-1", "peerid-1", None)
        vote.add_vote("groupid-3", "peerid-4", None)
        ret1 = vote.add_vote("groupid-4", "peerid-1", None)
        ret2 = vote.add_vote("groupid-1", "peerid-9", None)
        self.assertFalse(ret1)
        self.assertFalse(ret2)

        # THEN
        ret = vote.get_result_detail("block_hash", 0.51)
        self.assertEqual(ret[5], 5)
    def add_unconfirmed_block(self, block):
        """Block Manager 가 주기적으로 생성한 블럭을 등록한다. 이 블럭은 각 Peer 로 전송되어 Validate vote 를 받아야 한다.

        :param block: Block Manager 가 tx 를 수집하여 주기적으로 생성한 블럭, 아직 Block Chain 의 멤버가 아니다.
        :return: unconfirmed block 을 식별하기 위한 block_hash (str)
        """
        # block 생성자의 peer_id 를 지정한다. (새로 네트워크에 참여하는 피어는 마지막 블럭의 peer_id 를 리더로 간주한다.)
        block.peer_id = self.__peer_id

        # leader 가 block 에 담을 때 이미 1 투표한 내용으로 생성한다.
        vote = Vote(block.block_hash, ObjectManager().peer_service.peer_list)
        vote.add_vote(ObjectManager().peer_service.group_id,
                      ObjectManager().peer_service.peer_id, None)

        self.__unconfirmed_blocks[block.block_hash] = [vote, block]
        self.__candidate_last_block = block
        return block.block_hash
Exemple #4
0
    def test_add_vote(self):
        # GIVEN
        peer_manager = PeerManager()
        self.__add_peer_to_peer_manager(peer_manager, 3)
        peer_manager.add_peer(PeerInfo("peerid-4", "groupid-3", "peerid-4_target", cert=self.__cert))
        peer_manager.add_peer(PeerInfo("peerid-5", "groupid-3", "peerid-5_target", cert=self.__cert))

        vote = Vote("block_hash", peer_manager)
        logging.debug("votes: " + str(vote.votes))

        # WHEN
        vote.add_vote("groupid-1", "peerid-1", None)
        self.assertFalse(vote.get_result("block_hash", 0.51))

        # THEN
        vote.add_vote("groupid-2", "peerid-2", None)
        self.assertTrue(vote.get_result("block_hash", 0.51))
Exemple #5
0
    def test_fail_vote(self):
        # GIVEN
        peer_manager = PeerManager()
        peer_manager.add_peer("peerid-1", "groupid-1", "peerid-1_target")
        peer_manager.add_peer("peerid-2", "groupid-2", "peerid-2_target")
        peer_manager.add_peer("peerid-3", "groupid-3", "peerid-3_target")
        peer_manager.add_peer("peerid-4", "groupid-3", "peerid-4_target")
        peer_manager.add_peer("peerid-5", "groupid-3", "peerid-5_target")
        vote = Vote("block_hash", peer_manager)
        logging.debug("votes: " + str(vote.votes))

        # WHEN
        vote.add_vote("groupid-1", "peerid-1", conf.TEST_FAIL_VOTE_SIGN)
        vote.add_vote("groupid-3", "peerid-4", conf.TEST_FAIL_VOTE_SIGN)
        vote.add_vote("groupid-3", "peerid-5", conf.TEST_FAIL_VOTE_SIGN)
        vote.get_result("block_hash", 0.51)

        # THEN
        self.assertTrue(vote.is_failed_vote("block_hash", 0.51))
Exemple #6
0
    def test_add_vote_fail_before_add_peer(self):
        # GIVEN
        peer_manager = PeerManager()
        peer_manager.add_peer("peerid-1", "groupid-1", "peerid-1_target")
        peer_manager.add_peer("peerid-2", "groupid-2", "peerid-2_target")
        peer_manager.add_peer("peerid-3", "groupid-3", "peerid-3_target")
        peer_manager.add_peer("peerid-4", "groupid-3", "peerid-4_target")
        peer_manager.add_peer("peerid-5", "groupid-3", "peerid-5_target")
        vote = Vote("block_hash", peer_manager)
        logging.debug("votes: " + str(vote.votes))

        # WHEN
        vote.add_vote("groupid-1", "peerid-1", None)
        vote.add_vote("groupid-3", "peerid-4", None)
        ret1 = vote.add_vote("groupid-4", "peerid-1", None)
        ret2 = vote.add_vote("groupid-1", "peerid-9", None)
        self.assertFalse(ret1)
        self.assertFalse(ret2)

        # THEN
        ret = vote.get_result_detail("block_hash", 0.51)
        self.assertEqual(ret[5], 5)
Exemple #7
0
    async def consensus(self):
        start_time = time.time()
        empty_block: Block = None

        try:
            self._loop = asyncio.get_event_loop()
            self._vote_queue = asyncio.Queue(loop=self._loop)

            block_builder = self._makeup_block()

            if len(block_builder.transactions
                   ) == 0 and not conf.ALLOW_MAKE_EMPTY_BLOCK:
                return

            peer_manager = ObjectManager().channel_service.peer_manager

            last_block = self._blockchain.last_block
            block_builder.height = last_block.header.height + 1
            block_builder.prev_hash = last_block.header.hash
            block_builder.next_leader = Address.fromhex(
                peer_manager.get_next_leader_peer().peer_id)
            block_builder.peer_private_key = ObjectManager(
            ).channel_service.peer_auth.peer_private_key
            block_builder.confirm_prev_block = (self._made_block_count > 0)

            candidate_block = block_builder.build()
            candidate_block, invoke_results = ObjectManager(
            ).channel_service.score_invoke(candidate_block)

            block_verifier = BlockVerifier.new("0.1a")
            block_verifier.verify(candidate_block, self._blockchain.last_block,
                                  self._blockchain)

            logging.info(
                f"candidate block height: {candidate_block.header.height}")
            logging.info(
                f"candidate block hash: {candidate_block.header.hash.hex()}")
            logging.info(
                f"candidate block next leader: {candidate_block.header.next_leader.hex()}"
            )
            logging.info(
                f"candidate block confirm_prev_block: {candidate_block.body.confirm_prev_block}"
            )

            vote = Vote(candidate_block.header.hash.hex(),
                        ObjectManager().channel_service.peer_manager)
            vote.add_vote(ChannelProperty().group_id,
                          ChannelProperty().peer_id, True)

            self._blockmanager.broadcast_send_unconfirmed_block(
                candidate_block)
            success = await self._wait_for_voting(candidate_block, vote)
            if not success:
                return

            self._blockmanager.set_invoke_results(
                candidate_block.header.hash.hex(), invoke_results)
            self._blockmanager.add_block(candidate_block)
            self._made_block_count += 1

            pending_tx = self._txQueue.get_item_in_status(
                TransactionStatusInQueue.normal,
                TransactionStatusInQueue.normal)
            if not pending_tx and not conf.ALLOW_MAKE_EMPTY_BLOCK:
                block_builder = BlockBuilder.new("0.1a")
                block_builder.prev_hash = candidate_block.header.hash
                block_builder.height = candidate_block.header.height + 1
                block_builder.next_leader = candidate_block.header.next_leader
                block_builder.peer_private_key = ObjectManager(
                ).channel_service.peer_auth.peer_private_key
                block_builder.confirm_prev_block = True
                empty_block = block_builder.build()

                self._blockmanager.broadcast_send_unconfirmed_block(
                    empty_block)

                ObjectManager().channel_service.state_machine.turn_to_peer()
        finally:
            if not empty_block:
                elapsed_time = time.time() - start_time
                delay_time = conf.INTERVAL_BLOCKGENERATION - elapsed_time
                self._start_consensus_timer(delay_time)