def test_signature(self): header = RootBlockHeader() private_key = KeyAPI.PrivateKey(Identity.create_random_identity().get_key()) self.assertEqual(header.signature, bytes(65)) self.assertFalse(header.is_signed()) self.assertFalse(header.verify_signature(private_key.public_key)) header.sign_with_private_key(private_key) self.assertNotEqual(header.signature, bytes(65)) self.assertTrue(header.is_signed()) self.assertTrue(header.verify_signature(private_key.public_key))
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 > 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") 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) if (block_header.difficulty + prev_block_header.total_difficulty != block_header.total_difficulty): raise ValueError("incorrect total difficulty") # Check PoW if applicable consensus_type = self.root_config.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 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 ) # lower the difficulty for root block signed by guardian if block_header.verify_signature( self.env.quark_chain_config.guardian_public_key ): diff = Guardian.adjust_difficulty(diff, block_header.height) if diff != block_header.difficulty: raise ValueError("incorrect difficulty") # Check PoW if applicable consensus_type = self.env.quark_chain_config.ROOT.CONSENSUS_TYPE validate_seal(block_header, consensus_type) return block_hash