async def add_full_block(self, header_hash: bytes32, block: FullBlock, block_record: BlockRecord) -> None: self.block_cache.put(header_hash, block) cursor_1 = await self.db.execute( "INSERT OR REPLACE INTO full_blocks VALUES(?, ?, ?, ?, ?)", ( header_hash.hex(), block.height, int(block.is_transaction_block()), int(block.is_fully_compactified()), bytes(block), ), ) await cursor_1.close() cursor_2 = await self.db.execute( "INSERT OR REPLACE INTO block_records VALUES(?, ?, ?, ?,?, ?, ?)", ( header_hash.hex(), block.prev_header_hash.hex(), block.height, bytes(block_record), None if block_record.sub_epoch_summary_included is None else bytes(block_record.sub_epoch_summary_included), False, block.is_transaction_block(), ), ) await cursor_2.close()
def solution_for_rl( my_parent_id: bytes32, my_puzzlehash: bytes32, my_amount: uint64, out_puzzlehash: bytes32, out_amount: uint64, my_parent_parent_id: bytes32, parent_amount: uint64, interval, limit, fee, ): """ Solution is (1 my_parent_id, my_puzzlehash, my_amount, outgoing_puzzle_hash, outgoing_amount, min_block_time, parent_parent_id, parent_amount, fee) min block time = Math.ceil((new_amount * self.interval) / self.limit) """ min_block_count = math.ceil((out_amount * interval) / limit) solution = sexp( RATE_LIMITED_MODE, "0x" + my_parent_id.hex(), "0x" + my_puzzlehash.hex(), my_amount, "0x" + out_puzzlehash.hex(), out_amount, min_block_count, "0x" + my_parent_parent_id.hex(), parent_amount, fee, ) return Program.to(binutils.assemble(solution))
async def get_coin_record(self, coin_name: bytes32) -> Optional[CoinRecord]: if coin_name.hex() in self.coin_record_cache: return self.coin_record_cache[coin_name.hex()] cursor = await self.coin_record_db.execute("SELECT * from coin_record WHERE coin_name=?", (coin_name.hex(),)) row = await cursor.fetchone() await cursor.close() if row is not None: coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7])) return CoinRecord(coin, row[1], row[2], row[3], row[4], row[8]) return None
async def add_partial(self, launcher_id: bytes32, timestamp: uint64, difficulty: uint64): cursor = await self.connection.execute( "INSERT into partial VALUES(?, ?, ?)", (launcher_id.hex(), timestamp, difficulty), ) await cursor.close() cursor = await self.connection.execute( f"UPDATE farmer SET points=points+? WHERE launcher_id=?", (difficulty, launcher_id.hex())) await cursor.close() await self.connection.commit()
async def add_full_block( self, header_hash: bytes32, block: FullBlock, block_record: BlockRecord, in_main_chain: bool ) -> None: self.block_cache.put(header_hash, block) if self.db_wrapper.db_version == 2: ses: Optional[bytes] = ( None if block_record.sub_epoch_summary_included is None else bytes(block_record.sub_epoch_summary_included) ) await self.db.execute( "INSERT OR REPLACE INTO full_blocks VALUES(?, ?, ?, ?, ?, ?, ?, ?)", ( header_hash, block.prev_header_hash, block.height, ses, int(block.is_fully_compactified()), in_main_chain, # in_main_chain self.compress(block), bytes(block_record), ), ) else: await self.db.execute( "INSERT OR REPLACE INTO full_blocks VALUES(?, ?, ?, ?, ?)", ( header_hash.hex(), block.height, int(block.is_transaction_block()), int(block.is_fully_compactified()), bytes(block), ), ) await self.db.execute( "INSERT OR REPLACE INTO block_records VALUES(?, ?, ?, ?,?, ?, ?)", ( header_hash.hex(), block.prev_header_hash.hex(), block.height, bytes(block_record), None if block_record.sub_epoch_summary_included is None else bytes(block_record.sub_epoch_summary_included), False, block.is_transaction_block(), ), )
async def get_network_space( self, newer_block_header_hash: bytes32, older_block_header_hash: bytes32) -> Optional[uint64]: try: network_space_bytes_estimate = await self.fetch( "get_network_space", { "newer_block_header_hash": newer_block_header_hash.hex(), "older_block_header_hash": older_block_header_hash.hex(), }, ) except Exception: return None return network_space_bytes_estimate["space"]
async def add_partial(self, launcher_id: bytes32, timestamp: uint64, difficulty: uint64): cursor = await self.connection.execute( "INSERT into partial VALUES(?, ?, ?)", (launcher_id.hex(), timestamp, difficulty), ) await cursor.close() cursor = await self.connection.execute(f"SELECT points from farmer where launcher_id=?", (launcher_id.hex(),)) row = await cursor.fetchone() points = row[0] await cursor.close() cursor = await self.connection.execute( f"UPDATE farmer set points=? where launcher_id=?", (points + difficulty, launcher_id.hex()) ) await cursor.close() await self.connection.commit()
async def get_pool_login_link(self, launcher_id: bytes32) -> Optional[str]: try: return (await self.fetch( "get_pool_login_link", {"launcher_id": launcher_id.hex()}))["login_link"] except ValueError: return None
async def set_payout_instructions(self, launcher_id: bytes32, payout_instructions: str) -> Dict: request = { "launcher_id": launcher_id.hex(), "payout_instructions": payout_instructions } return await self.fetch("set_payout_instructions", request)
async def add_partial(self, launcher_id: bytes32, timestamp: uint64, difficulty: uint64): with (await self.pool) as connection: cursor = await connection.cursor() await cursor.execute( "INSERT INTO partial VALUES(%s, %s, %s)", (launcher_id.hex(), timestamp, difficulty), ) await connection.commit() with (await self.pool) as connection: cursor = await connection.cursor() await cursor.execute( f"UPDATE farmer SET points=points+%s WHERE launcher_id=%s", (difficulty, launcher_id.hex())) await connection.commit() await cursor.close()
async def update_difficulty(self, launcher_id: bytes32, difficulty: uint64): cursor = await self.connection.execute( f"UPDATE farmer SET difficulty=? WHERE launcher_id=?", (difficulty, launcher_id.hex())) await cursor.close() await self.connection.commit()
async def get_mempool_item_by_tx_id(self, tx_id: bytes32) -> Optional[Dict]: try: response = await self.fetch("get_mempool_item_by_tx_id", {"tx_id": tx_id.hex()}) return response["mempool_item"] except Exception: return None
async def set_peak(self, header_hash: bytes32) -> None: cursor_1 = await self.db.execute("UPDATE block_records SET is_peak=0 WHERE is_peak=1") await cursor_1.close() cursor_2 = await self.db.execute( "UPDATE block_records SET is_peak=1 WHERE header_hash=?", (header_hash.hex(),), ) await cursor_2.close()
async def get_recent_partials(self, launcher_id: bytes32, count: int) -> List[Tuple[uint64, uint64]]: cursor = await self.connection.execute( "SELECT timestamp, difficulty from partial WHERE launcher_id=? ORDER BY timestamp DESC LIMIT ?", (launcher_id.hex(), count), ) rows = await cursor.fetchall() ret: List[Tuple[uint64, uint64]] = [(uint64(timestamp), uint64(difficulty)) for timestamp, difficulty in rows] return ret
async def get_interested_puzzle_hash_wallet_id(self, puzzle_hash: bytes32) -> Optional[int]: cursor = await self.db_connection.execute( "SELECT wallet_id FROM interested_puzzle_hashes WHERE puzzle_hash=?", (puzzle_hash.hex(),) ) row = await cursor.fetchone() if row is None: return None return row[0]
async def update_singleton( self, launcher_id: bytes32, singleton_tip: CoinSolution, singleton_tip_state: PoolState, is_pool_member: bool, ): if is_pool_member: entry = (bytes(singleton_tip), bytes(singleton_tip_state), 1, launcher_id.hex()) else: entry = (bytes(singleton_tip), bytes(singleton_tip_state), 0, launcher_id.hex()) cursor = await self.connection.execute( f"UPDATE farmer SET singleton_tip=?, singleton_tip_state=?, is_pool_member=? WHERE launcher_id=?", entry, ) await cursor.close() await self.connection.commit()
async def get_coin_record_by_name( self, coin_id: bytes32) -> Optional[CoinRecord]: try: response = await self.fetch("get_coin_record_by_name", {"name": coin_id.hex()}) except Exception: return None return CoinRecord.from_json_dict(response["coin_record"])
async def update_difficulty(self, launcher_id: bytes32, difficulty: uint64): with (await self.pool) as connection: connection = await self.pool.acquire() cursor = await connection.cursor() await cursor.execute( f"UPDATE farmer SET difficulty=%s WHERE launcher_id=%s", (difficulty, launcher_id.hex())) await connection.commit()
async def cancel_offer(self, trade_id: bytes32, fee=uint64(0), secure: bool = True): await self.fetch("cancel_offer", { "trade_id": trade_id.hex(), "secure": secure, "fee": fee })
async def is_fully_compactified(self, header_hash: bytes32) -> Optional[bool]: cursor = await self.db.execute( "SELECT is_fully_compactified from full_blocks WHERE header_hash=?", (header_hash.hex(),) ) row = await cursor.fetchone() await cursor.close() if row is None: return None return bool(row[0])
async def inner_puzzle_for_did_puzzle(self, did_hash: bytes32) -> Program: record: DerivationRecord = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash( did_hash.hex()) inner_puzzle: Program = did_wallet_puzzles.create_innerpuz( bytes(record.pubkey), self.did_info.backup_ids, self.did_info.num_of_backup_ids_needed, ) return inner_puzzle
async def get_coin_records_by_parent_id( self, parent_coin_info: bytes32) -> List[WalletCoinRecord]: """Returns a list of all coin records with the given parent id""" cursor = await self.db_connection.execute( "SELECT * from coin_record WHERE coin_parent=?", (parent_coin_info.hex(), )) rows = await cursor.fetchall() await cursor.close() return [self.coin_record_from_row(row) for row in rows]
async def get_puzzle_and_solution(self, coin_id: bytes32, height: uint32) -> Optional[CoinRecord]: try: response = await self.fetch("get_puzzle_and_solution", { "coin_id": coin_id.hex(), "height": height }) return CoinSolution.from_json_dict(response["coin_solution"]) except Exception: return None
async def persist_sub_epoch_challenge_segments( self, ses_block_hash: bytes32, segments: List[SubEpochChallengeSegment] ) -> None: async with self.db_wrapper.lock: cursor_1 = await self.db.execute( "INSERT OR REPLACE INTO sub_epoch_segments_v3 VALUES(?, ?)", (ses_block_hash.hex(), bytes(SubEpochSegments(segments))), ) await cursor_1.close() await self.db.commit()
async def get_coin_records_by_puzzle_hash( self, puzzle_hash: bytes32) -> List[WalletCoinRecord]: """Returns a list of all coin records with the given puzzle hash""" cursor = await self.db_connection.execute( "SELECT * from coin_record WHERE puzzle_hash=?", (puzzle_hash.hex(), )) rows = await cursor.fetchall() await cursor.close() return [self.coin_record_from_row(row) for row in rows]
async def get_block_record(self, header_hash: bytes32) -> Optional[BlockRecord]: cursor = await self.db.execute( "SELECT block from block_records WHERE header_hash=?", (header_hash.hex(),), ) row = await cursor.fetchone() await cursor.close() if row is not None: return BlockRecord.from_bytes(row[0]) return None
async def set_peak(self, header_hash: bytes32) -> None: # We need to be in a sqlite transaction here. # Note: we do not commit this to the database yet, as we need to also change the coin store cursor_1 = await self.db.execute("UPDATE block_records SET is_peak=0 WHERE is_peak=1") await cursor_1.close() cursor_2 = await self.db.execute( "UPDATE block_records SET is_peak=1 WHERE header_hash=?", (header_hash.hex(),), ) await cursor_2.close()
async def is_transaction_confirmed(user_wallet_id, api, tx_id: bytes32) -> bool: try: val = await api.get_transaction({ "wallet_id": user_wallet_id, "transaction_id": tx_id.hex() }) except ValueError: return False return val["transaction"].confirmed
async def get_farmer_record(self, launcher_id: bytes32) -> Optional[FarmerRecord]: # TODO(pool): use cache cursor = await self.connection.execute( "SELECT * from farmer where launcher_id=?", (launcher_id.hex(),), ) row = await cursor.fetchone() if row is None: return None return self._row_to_farmer_record(row)
async def pw_join_pool( self, wallet_id: str, target_puzzlehash: bytes32, pool_url: str, relative_lock_height: uint32 ) -> TransactionRecord: request = { "wallet_id": int(wallet_id), "target_puzzlehash": target_puzzlehash.hex(), "relative_lock_height": relative_lock_height, "pool_url": pool_url, } return TransactionRecord.from_json_dict((await self.fetch("pw_join_pool", request))["transaction"])