def __get_test_block():
     block_builder = BlockBuilder.new("0.1a", TransactionVersioner())
     block_builder.height = 0
     block_builder.prev_hash = None
     block = block_builder.build(
     )  # It does not have commit state. It will be rebuilt.
     return block
Пример #2
0
    def __add_genesis_block(self, tx_info: dict, reps: List[ExternalAddress]):
        """
        :param tx_info: Transaction data for making genesis block from an initial file
        :return:
        """
        logging.info("Make Genesis Block....")
        tx_builder = TransactionBuilder.new("genesis", self.tx_versioner)

        nid = tx_info.get("nid")
        if nid is not None:
            nid = int(nid, 16)
        tx_builder.nid = nid  # Optional. It will be 0x3 except for mainnet and testnet if not defined
        tx_builder.accounts = tx_info["accounts"]
        tx_builder.message = tx_info["message"]
        tx = tx_builder.build()

        block_version = self.block_versioner.get_version(0)
        block_builder = BlockBuilder.new(block_version, self.tx_versioner)
        block_builder.height = 0
        block_builder.fixed_timestamp = 0
        block_builder.prev_hash = None
        block_builder.next_leader = ExternalAddress.fromhex(self.__peer_id)
        block_builder.transactions[tx.hash] = tx
        block_builder.reps = reps
        block = block_builder.build(
        )  # It does not have commit state. It will be rebuilt.

        block, invoke_results = ObjectManager().channel_service.genesis_invoke(
            block)
        self.set_invoke_results(block.header.hash.hex(), invoke_results)
        self.add_block(block)
Пример #3
0
    def _makeup_block(self):
        block_builder = BlockBuilder.new("0.1a")

        tx_versions = TransactionVersions()
        while self._txQueue:
            if len(block_builder) >= conf.MAX_TX_SIZE_IN_BLOCK:
                logging.debug(
                    f"consensus_base total size({len(block_builder)}) "
                    f"count({len(block_builder.transactions)}) "
                    f"_txQueue size ({len(self._txQueue)})")
                break

            tx: 'Transaction' = self._txQueue.get_item_in_status(
                TransactionStatusInQueue.normal,
                TransactionStatusInQueue.added_to_block)
            if tx is None:
                break

            tx_hash_version = tx_versions.get_hash_generator_version(
                tx.version)
            tv = TransactionVerifier.new(tx.version, tx_hash_version)

            try:
                tv.verify(tx, self._blockchain)
            except Exception as e:
                logging.warning(f"tx hash invalid. tx: {tx}")
            else:
                block_builder.transactions[tx.hash] = tx

        return block_builder
Пример #4
0
    def __add_genesis_block(self, tx_info: dict = None):
        """
        :param tx_info: Transaction data for making genesis block from an initial file
        :return:
        """
        logging.info("Make Genesis Block....")
        genesis_hash_version = conf.CHANNEL_OPTION[
            self.__channel_name]["genesis_tx_hash_version"]
        tx_builder = TransactionBuilder.new("genesis", genesis_hash_version)

        nid = tx_info.get("nid")
        if nid is not None:
            nid = int(nid, 16)
        tx_builder.nid = nid  # Optional. It will be 0x3 except for mainnet and testnet if not defined
        tx_builder.accounts = tx_info["accounts"]
        tx_builder.message = tx_info["message"]
        tx = tx_builder.build()

        block_builder = BlockBuilder.new("0.1a")
        block_builder.height = 0
        block_builder.fixed_timestamp = 0
        block_builder.prev_hash = None
        block_builder.transactions[tx.hash] = tx
        block = block_builder.build(
        )  # It does not have commit state. It will be rebuilt.

        block, invoke_results = ObjectManager().channel_service.genesis_invoke(
            block)
        self.set_invoke_results(block.header.hash.hex(), invoke_results)
        self.add_block(block)
Пример #5
0
    def makeup_block(self, complained_result: str):
        # self._check_unconfirmed_block(
        last_block = self.__blockchain.last_unconfirmed_block or self.__blockchain.last_block
        block_height = last_block.header.height + 1
        block_version = self.__blockchain.block_versioner.get_version(block_height)
        block_builder = BlockBuilder.new(block_version, self.__blockchain.tx_versioner)
        if not complained_result:
            self.__add_tx_to_block(block_builder)

        return block_builder
Пример #6
0
    def _makeup_block(self):
        # self._check_unconfirmed_block()
        block_height = self._blockchain.last_block.header.height + 1
        block_version = self._blockchain.block_versioner.get_version(
            block_height)
        block_builder = BlockBuilder.new(block_version,
                                         self._blockchain.tx_versioner)

        tx_versioner = self._blockchain.tx_versioner
        while self._txQueue:
            if block_builder.size() >= conf.MAX_TX_SIZE_IN_BLOCK:
                logging.debug(
                    f"consensus_base total size({block_builder.size()}) "
                    f"count({len(block_builder.transactions)}) "
                    f"_txQueue size ({len(self._txQueue)})")
                break

            tx: 'Transaction' = self._txQueue.get_item_in_status(
                TransactionStatusInQueue.normal,
                TransactionStatusInQueue.added_to_block)
            if tx is None:
                break

            tv = TransactionVerifier.new(tx.version, tx_versioner)

            try:
                tv.verify(tx, self._blockchain)
            except Exception as e:
                logging.warning(f"tx hash invalid.\n"
                                f"tx: {tx}\n"
                                f"exception: {e}")
                traceback.print_exc()
            else:
                block_builder.transactions[tx.hash] = tx

        return block_builder
Пример #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)
Пример #8
0
    def test_block_v0_3(self):
        private_auth = test_util.create_default_peer_auth()
        tx_versioner = TransactionVersioner()

        dummy_receipts = {}
        block_builder = BlockBuilder.new("0.3", tx_versioner)
        for i in range(1000):
            tx_builder = TransactionBuilder.new("0x3", tx_versioner)
            tx_builder.private_key = private_auth.private_key
            tx_builder.to_address = ExternalAddress.new()
            tx_builder.step_limit = random.randint(0, 10000)
            tx_builder.value = random.randint(0, 10000)
            tx_builder.nid = 2
            tx = tx_builder.build()

            tx_serializer = TransactionSerializer.new(tx.version, tx_versioner)
            block_builder.transactions[tx.hash] = tx
            dummy_receipts[tx.hash.hex()] = {
                "dummy_receipt": "dummy",
                "tx_dumped": tx_serializer.to_full_data(tx)
            }

        block_builder.peer_private_key = private_auth.private_key
        block_builder.height = 0
        block_builder.state_hash = Hash32(bytes(Hash32.size))
        block_builder.receipts = dummy_receipts
        block_builder.reps = [
            ExternalAddress.fromhex_address(private_auth.address)
        ]
        block_builder.next_leader = ExternalAddress.fromhex(
            "hx00112233445566778899aabbccddeeff00112233")

        block = block_builder.build()
        block_verifier = BlockVerifier.new("0.3", tx_versioner)
        block_verifier.invoke_func = lambda b: (block, dummy_receipts)
        block_verifier.verify(block,
                              None,
                              None,
                              block.header.peer_id,
                              reps=block_builder.reps)

        block_serializer = BlockSerializer.new("0.3", tx_versioner)
        block_serialized = block_serializer.serialize(block)
        block_deserialized = block_serializer.deserialize(block_serialized)

        assert block.header == block_deserialized.header
        # FIXME : confirm_prev_block not serialized
        # assert block.body == block_deserialized.body

        tx_hashes = list(block.body.transactions)
        tx_index = random.randrange(0, len(tx_hashes))

        block_prover = BlockProver.new(block.header.version, tx_hashes,
                                       BlockProverType.Transaction)
        tx_proof = block_prover.get_proof(tx_index)
        assert block_prover.prove(tx_hashes[tx_index],
                                  block.header.transaction_hash, tx_proof)

        block_prover = BlockProver.new(block.header.version,
                                       block_builder.receipts,
                                       BlockProverType.Receipt)
        receipt_proof = block_prover.get_proof(tx_index)
        receipt_hash = block_prover.to_hash32(block_builder.receipts[tx_index])
        assert block_prover.prove(receipt_hash, block.header.receipt_hash,
                                  receipt_proof)