예제 #1
0
    def validate_block_header(self,
                              block_header: RootBlockHeader,
                              block_hash=None):
        """ Validate the block header.
        """
        height = block_header.height
        if height < 1:
            raise ValueError("unexpected height")

        if not self.db.contain_root_block_by_hash(
                block_header.hash_prev_block):
            raise ValueError("previous hash block mismatch")
        prev_block_header = self.db.get_root_block_header_by_hash(
            block_header.hash_prev_block)

        if prev_block_header.height + 1 != height:
            raise ValueError("incorrect block height")

        if block_header.create_time <= prev_block_header.create_time:
            raise ValueError(
                "incorrect create time tip time {}, new block time {}".format(
                    block_header.create_time, prev_block_header.create_time))

        if (len(block_header.extra_data) >
                self.env.quark_chain_config.BLOCK_EXTRA_DATA_SIZE_LIMIT):
            raise ValueError("extra_data in block is too large")

        header_hash = block_header.get_hash()
        if block_hash is None:
            block_hash = header_hash

        # Check difficulty, potentially adjusted by guardian mechanism
        adjusted_diff = None  # type: Optional[int]
        if not self.env.quark_chain_config.SKIP_ROOT_DIFFICULTY_CHECK:
            diff = self.diff_calc.calculate_diff_with_parent(
                prev_block_header, block_header.create_time)
            if diff != block_header.difficulty:
                raise ValueError("incorrect difficulty")
            # lower the difficulty for root block signed by guardian
            if block_header.verify_signature(
                    self.env.quark_chain_config.guardian_public_key):
                adjusted_diff = Guardian.adjust_difficulty(
                    diff, block_header.height)

        # Check PoW if applicable
        consensus_type = self.env.quark_chain_config.ROOT.CONSENSUS_TYPE
        validate_seal(block_header,
                      consensus_type,
                      adjusted_diff=adjusted_diff)

        return block_hash
예제 #2
0
    def validate_block_header(self,
                              block_header: RootBlockHeader,
                              block_hash=None):
        """ Validate the block header.
        """
        height = block_header.height
        if height < 1:
            raise ValueError("unexpected height")

        if not self.db.contain_root_block_by_hash(
                block_header.hash_prev_block):
            raise ValueError("previous hash block mismatch")
        prev_block_header = self.db.get_root_block_header_by_hash(
            block_header.hash_prev_block)

        if prev_block_header.height + 1 != height:
            raise ValueError("incorrect block height")

        if block_header.create_time <= prev_block_header.create_time:
            raise ValueError(
                "incorrect create time tip time {}, new block time {}".format(
                    block_header.create_time, prev_block_header.create_time))

        if (len(block_header.extra_data) >
                self.env.quark_chain_config.BLOCK_EXTRA_DATA_SIZE_LIMIT):
            raise ValueError("extra_data in block is too large")

        header_hash = block_header.get_hash()
        if block_hash is None:
            block_hash = header_hash

        # Check difficulty
        curr_diff = block_header.difficulty
        if not self.env.quark_chain_config.SKIP_ROOT_DIFFICULTY_CHECK:
            if self.env.quark_chain_config.NETWORK_ID == NetworkId.MAINNET:
                diff = self.diff_calc.calculate_diff_with_parent(
                    prev_block_header, block_header.create_time)
                if diff != curr_diff:
                    raise ValueError("incorrect difficulty")
            elif (block_header.coinbase_address.recipient !=
                  self.env.quark_chain_config.testnet_master_address.recipient
                  ):
                raise ValueError("incorrect master to create the block")

        # Check PoW if applicable
        consensus_type = self.env.quark_chain_config.ROOT.CONSENSUS_TYPE
        validate_seal(block_header, consensus_type)

        return block_hash
예제 #3
0
    def __validate_block_header(
        self, block_header: RootBlockHeader, adjusted_diff: int = None
    ):
        """ Validate the block header.
        """
        height = block_header.height
        if height < 1:
            raise ValueError("unexpected height")

        if block_header.version != 0:
            raise ValueError("incorrect root block version")

        if not self.db.contain_root_block_by_hash(block_header.hash_prev_block):
            raise ValueError("previous hash block mismatch")
        prev_block_header = self.db.get_root_block_header_by_hash(
            block_header.hash_prev_block
        )

        if prev_block_header.height + 1 != height:
            raise ValueError("incorrect block height")

        if (
            block_header.create_time
            > time_ms() // 1000 + ALLOWED_FUTURE_BLOCKS_TIME_VALIDATION
        ):
            raise ValueError("block too far into future")

        if block_header.create_time <= prev_block_header.create_time:
            raise ValueError(
                "incorrect create time tip time {}, new block time {}".format(
                    block_header.create_time, prev_block_header.create_time
                )
            )

        if (
            len(block_header.extra_data)
            > self.env.quark_chain_config.BLOCK_EXTRA_DATA_SIZE_LIMIT
        ):
            raise ValueError("extra_data in block is too large")

        # Check difficulty, potentially adjusted by guardian mechanism
        if not self.env.quark_chain_config.SKIP_ROOT_DIFFICULTY_CHECK:
            diff = self.diff_calc.calculate_diff_with_parent(
                prev_block_header, block_header.create_time
            )
            if diff != block_header.difficulty:
                raise ValueError("incorrect difficulty")

        if (
            block_header.difficulty + prev_block_header.total_difficulty
            != block_header.total_difficulty
        ):
            raise ValueError("incorrect total difficulty")

        # Check PoW if applicable
        if not self.env.quark_chain_config.DISABLE_POW_CHECK:
            consensus_type = self.root_config.CONSENSUS_TYPE
            diff = (
                adjusted_diff if adjusted_diff is not None else block_header.difficulty
            )
            validate_seal(block_header, consensus_type, adjusted_diff=diff)

        return block_header.get_hash()