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
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
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()