async def get_sub_block_records_close_to_peak( self, blocks_n: int ) -> Tuple[Dict[bytes32, SubBlockRecord], Optional[bytes32]]: """ Returns a dictionary with all sub blocks, as well as the header hash of the peak, if present. """ res = await self.db.execute( "SELECT header_hash, height from block_records WHERE is_peak = 1") row = await res.fetchone() await res.close() if row is None: return {}, None header_hash_bytes, peak_height = row peak: bytes32 = bytes32(bytes.fromhex(header_hash_bytes)) formatted_str = f"SELECT header_hash, block from block_records WHERE height >= {peak_height - blocks_n}" cursor = await self.db.execute(formatted_str) rows = await cursor.fetchall() await cursor.close() ret: Dict[bytes32, SubBlockRecord] = {} for row in rows: header_hash_bytes, sub_block_bytes = row header_hash = bytes.fromhex(header_hash_bytes) ret[header_hash] = SubBlockRecord.from_bytes(sub_block_bytes) return ret, peak
async def get_sub_block_record(self, header_hash: bytes32) -> Optional[SubBlockRecord]: cursor = await self.db.execute( "SELECT sub_block from sub_block_records WHERE header_hash=?", (header_hash.hex(),), ) row = await cursor.fetchone() await cursor.close() if row is not None: return SubBlockRecord.from_bytes(row[0]) return None
def batch_pre_validate_sub_blocks( constants_dict: Dict, sub_blocks_pickled: Dict[bytes, bytes], header_blocks_pickled: List[bytes], transaction_generators: List[Optional[bytes]], check_filter: bool, expected_difficulty: List[uint64], expected_sub_slot_iters: List[uint64], ) -> List[bytes]: assert len(header_blocks_pickled) == len(transaction_generators) sub_blocks = {} for k, v in sub_blocks_pickled.items(): sub_blocks[k] = SubBlockRecord.from_bytes(v) results: List[PreValidationResult] = [] constants: ConsensusConstants = dataclass_from_dict( ConsensusConstants, constants_dict) for i in range(len(header_blocks_pickled)): try: header_block: HeaderBlock = HeaderBlock.from_bytes( header_blocks_pickled[i]) generator: Optional[bytes] = transaction_generators[i] required_iters, error = validate_finished_header_block( constants, sub_blocks, header_block, check_filter, expected_difficulty[i], expected_sub_slot_iters[i], ) cost_result = None error_int: Optional[uint16] = None if error is not None: error_int = uint16(error.code.value) if not error and generator is not None: cost_result = calculate_cost_of_program( Program.from_bytes(generator), constants.CLVM_COST_RATIO_CONSTANT) results.append( PreValidationResult(error_int, required_iters, cost_result)) except Exception: error_stack = traceback.format_exc() log.error(f"Exception: {error_stack}") results.append( PreValidationResult(uint16(Err.UNKNOWN.value), None, None)) return [bytes(r) for r in results]
async def get_sub_block_records( self, ) -> Tuple[Dict[bytes32, SubBlockRecord], Optional[bytes32]]: """ Returns a dictionary with all sub blocks, as well as the header hash of the peak, if present. """ cursor = await self.db.execute("SELECT * from block_records") rows = await cursor.fetchall() await cursor.close() ret: Dict[bytes32, SubBlockRecord] = {} peak: Optional[bytes32] = None for row in rows: header_hash = bytes.fromhex(row[0]) ret[header_hash] = SubBlockRecord.from_bytes(row[3]) if row[5]: assert peak is None # Sanity check, only one peak peak = header_hash return ret, peak
async def get_sub_block_records_in_range( self, start: int, stop: int, ) -> Dict[bytes32, SubBlockRecord]: """ Returns a dictionary with all sub blocks in range between start and stop if present. """ formatted_str = f"SELECT header_hash, block from block_records WHERE height >= {start} and height <= {stop}" cursor = await self.db.execute(formatted_str) rows = await cursor.fetchall() await cursor.close() ret: Dict[bytes32, SubBlockRecord] = {} for row in rows: header_hash = bytes.fromhex(row[0]) ret[header_hash] = SubBlockRecord.from_bytes(row[1]) return ret
async def get_sub_block_records_close_to_peak( self, blocks_n: int ) -> Tuple[Dict[bytes32, SubBlockRecord], Optional[bytes32]]: """ Returns a dictionary with all sub_blocks that have height >= peak height - blocks_n, as well as the peak header hash. """ res = await self.db.execute( "SELECT * from block_records WHERE is_peak = 1") peak_row = await res.fetchone() await res.close() if peak_row is None: return {}, None formatted_str = f"SELECT header_hash, block from block_records WHERE height >= {peak_row[2] - blocks_n}" cursor = await self.db.execute(formatted_str) rows = await cursor.fetchall() await cursor.close() ret: Dict[bytes32, SubBlockRecord] = {} for row in rows: header_hash = bytes.fromhex(row[0]) ret[header_hash] = SubBlockRecord.from_bytes(row[1]) return ret, bytes.fromhex(peak_row[0])