async def submit_work(self, header_hash: bytes, nonce: int, mixhash: bytes) -> bool: if not self.remote: raise ValueError("Should only be used for remote miner") if header_hash not in self.work_map: return False block = self.work_map[header_hash] header = copy.copy(block.header) header.nonce, header.mixhash = nonce, mixhash # lower the difficulty for root block signed by guardian if self.guardian_private_key and isinstance(block, RootBlock): diff = Guardian.adjust_difficulty(header.difficulty, header.height) try: validate_seal(header, self.consensus_type, adjusted_diff=diff) except ValueError: return False # sign as a guardian header.sign_with_private_key(self.guardian_private_key) else: # minor block, or doesn't have guardian private key try: validate_seal(header, self.consensus_type) except ValueError: return False block.header = header # actual update try: await self.add_block_async_func(block) del self.work_map[header_hash] self.current_work = None return True except Exception as ex: Logger.error(ex) return False
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
async def add(block_to_add): h = block_to_add.header diff = h.difficulty if h.verify_signature(priv.public_key): diff = Guardian.adjust_difficulty(diff, h.height) validate_seal(block_to_add.header, doublesha, adjusted_diff=diff)
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
async def submit_work(self, header_hash: bytes, nonce: int, mixhash: bytes) -> bool: if not self.remote: raise ValueError("Should only be used for remote miner") if header_hash not in self.work_map: return False # this copy is necessary since there might be multiple submissions concurrently block = copy.deepcopy(self.work_map[header_hash]) header = block.header header.nonce, header.mixhash = nonce, mixhash # lower the difficulty for root block signed by guardian if self.guardian_private_key and isinstance(block, RootBlock): diff = Guardian.adjust_difficulty(header.difficulty, header.height) try: validate_seal(header, self.consensus_type, adjusted_diff=diff) except ValueError: return False # sign as a guardian header.sign_with_private_key(self.guardian_private_key) else: # minor block, or doesn't have guardian private key try: validate_seal(header, self.consensus_type) except ValueError: return False try: await self.add_block_async_func(block) # a previous submission of the same work could have removed the key if header_hash in self.work_map: del self.work_map[header_hash] self.current_work = None return True except Exception: Logger.error_exception() return False