async def coin_added(self, coin: Coin, _: uint32): """Notification from wallet state manager that wallet has been received.""" self.log.info("DID wallet has been notified that coin was added") inner_puzzle = await self.inner_puzzle_for_did_puzzle(coin.puzzle_hash) if self.did_info.temp_coin is not None: self.wallet_state_manager.state_changed("did_coin_added", self.wallet_info.id) new_info = DIDInfo( self.did_info.origin_coin, self.did_info.backup_ids, self.did_info.num_of_backup_ids_needed, self.did_info.parent_info, inner_puzzle, None, None, None, False, ) await self.save_info(new_info, True) future_parent = LineageProof( coin.parent_coin_info, inner_puzzle.get_tree_hash(), coin.amount, ) await self.add_parent(coin.name(), future_parent, True)
async def coin_added(self, coin: Coin, _: uint32): """Notification from wallet state manager that wallet has been received.""" self.log.info(f"DID wallet has been notified that coin was added: {coin.name()}:{coin}") inner_puzzle = await self.inner_puzzle_for_did_puzzle(coin.puzzle_hash) if self.did_info.temp_coin is not None: self.wallet_state_manager.state_changed("did_coin_added", self.wallet_info.id) new_info = DIDInfo( self.did_info.origin_coin, self.did_info.backup_ids, self.did_info.num_of_backup_ids_needed, self.did_info.parent_info, inner_puzzle, None, None, None, False, ) await self.save_info(new_info, True) future_parent = LineageProof( coin.parent_coin_info, inner_puzzle.get_tree_hash(), coin.amount, ) await self.add_parent(coin.name(), future_parent, True) parent = self.get_parent_for_coin(coin) if parent is None: parent_state: CoinState = ( await self.wallet_state_manager.wallet_node.get_coin_state([coin.parent_coin_info]) )[0] node = self.wallet_state_manager.wallet_node.get_full_node_peer() assert parent_state.spent_height is not None puzzle_solution_request = wallet_protocol.RequestPuzzleSolution( coin.parent_coin_info, parent_state.spent_height ) response = await node.request_puzzle_solution(puzzle_solution_request) req_puz_sol = response.response assert req_puz_sol.puzzle is not None parent_innerpuz = did_wallet_puzzles.get_innerpuzzle_from_puzzle(req_puz_sol.puzzle) assert parent_innerpuz is not None parent_info = LineageProof( parent_state.coin.parent_coin_info, parent_innerpuz.get_tree_hash(), parent_state.coin.amount, ) await self.add_parent(coin.parent_coin_info, parent_info, False)
class SpendableCAT: coin: Coin limitations_program_hash: bytes32 inner_puzzle: Program inner_solution: Program limitations_solution: Program = Program.to([]) lineage_proof: LineageProof = LineageProof() extra_delta: int = 0 limitations_program_reveal: Program = Program.to([])
async def generate_issuance_bundle( cls, wallet, _: Dict, amount: uint64) -> Tuple[TransactionRecord, SpendBundle]: coins = await wallet.standard_wallet.select_coins(amount) origin = coins.copy().pop() origin_id = origin.name() cc_inner: Program = await wallet.get_new_inner_puzzle() await wallet.add_lineage(origin_id, LineageProof()) genesis_coin_checker: Program = cls.construct([Program.to(origin_id)]) minted_cc_puzzle_hash: bytes32 = construct_cat_puzzle( CAT_MOD, genesis_coin_checker.get_tree_hash(), cc_inner).get_tree_hash() tx_record: TransactionRecord = await wallet.standard_wallet.generate_signed_transaction( amount, minted_cc_puzzle_hash, uint64(0), origin_id, coins) assert tx_record.spend_bundle is not None inner_solution = wallet.standard_wallet.add_condition_to_solution( Program.to([51, 0, -113, genesis_coin_checker, []]), wallet.standard_wallet.make_solution(primaries=[{ "puzzlehash": cc_inner.get_tree_hash(), "amount": amount }], ), ) eve_spend = unsigned_spend_bundle_for_spendable_cats( CAT_MOD, [ SpendableCAT( list( filter(lambda a: a.amount == amount, tx_record.additions))[0], genesis_coin_checker.get_tree_hash(), cc_inner, inner_solution, limitations_program_reveal=genesis_coin_checker, ) ], ) signed_eve_spend = await wallet.sign(eve_spend) if wallet.cat_info.my_tail is None: await wallet.save_info( CATInfo(genesis_coin_checker.get_tree_hash(), genesis_coin_checker, wallet.cat_info.lineage_proofs), False, ) return tx_record, SpendBundle.aggregate( [tx_record.spend_bundle, signed_eve_spend])
def lineage_proof_for_coinsol(coin_spend: CoinSpend) -> LineageProof: parent_name: bytes32 = coin_spend.coin.parent_coin_info inner_puzzle_hash: Optional[bytes32] = None if coin_spend.coin.puzzle_hash != SINGLETON_LAUNCHER_HASH: full_puzzle = Program.from_bytes(bytes(coin_spend.puzzle_reveal)) r = full_puzzle.uncurry() if r is not None: _, args = r _, inner_puzzle = list(args.as_iter()) inner_puzzle_hash = inner_puzzle.get_tree_hash() amount: uint64 = coin_spend.coin.amount return LineageProof( parent_name, inner_puzzle_hash, amount, )
async def puzzle_solution_received(self, response: PuzzleSolutionResponse, action_id: int): coin_name = response.coin_name puzzle: Program = response.puzzle matched, curried_args = match_cat_puzzle(puzzle) if matched: mod_hash, genesis_coin_checker_hash, inner_puzzle = curried_args self.log.info( f"parent: {coin_name} inner_puzzle for parent is {inner_puzzle}" ) parent_coin = None coin_record = await self.wallet_state_manager.coin_store.get_coin_record( coin_name) if coin_record is None: coin_states: Optional[List[ CoinState]] = await self.wallet_state_manager.wallet_node.get_coin_state( [coin_name]) if coin_states is not None: parent_coin = coin_states[0].coin if coin_record is not None: parent_coin = coin_record.coin if parent_coin is None: raise ValueError("Error in finding parent") await self.add_lineage( coin_name, LineageProof(parent_coin.parent_coin_info, inner_puzzle.get_tree_hash(), parent_coin.amount)) await self.wallet_state_manager.action_store.action_done(action_id) else: # The parent is not a CAT which means we need to scrub all of its children from our DB child_coin_records = await self.wallet_state_manager.coin_store.get_coin_records_by_parent_id( coin_name) if len(child_coin_records) > 0: for record in child_coin_records: if record.wallet_id == self.id(): await self.wallet_state_manager.coin_store.delete_coin_record( record.coin.name()) await self.remove_lineage(record.coin.name()) # We also need to make sure there's no record of the transaction await self.wallet_state_manager.tx_store.delete_transaction_record( record.coin.name())
async def coin_added(self, coin: Coin, height: uint32): """Notification from wallet state manager that wallet has been received.""" self.log.info(f"CC wallet has been notified that {coin} was added") search_for_parent: bool = True inner_puzzle = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash) lineage_proof = LineageProof(coin.parent_coin_info, inner_puzzle.get_tree_hash(), coin.amount) await self.add_lineage(coin.name(), lineage_proof, True) for name, lineage_proofs in self.cat_info.lineage_proofs: if coin.parent_coin_info == name: search_for_parent = False break if search_for_parent: data: Dict[str, Any] = { "data": { "action_data": { "api_name": "request_puzzle_solution", "height": height, "coin_name": coin.parent_coin_info, "received_coin": coin.name(), } } } data_str = dict_to_json_str(data) await self.wallet_state_manager.create_action( name="request_puzzle_solution", wallet_id=self.id(), wallet_type=self.type(), callback="puzzle_solution_received", done=False, data=data_str, in_transaction=True, )
def to_valid_spend(self, arbitrage_ph: Optional[bytes32] = None) -> SpendBundle: if not self.is_valid(): raise ValueError("Offer is currently incomplete") completion_spends: List[CoinSpend] = [] for tail_hash, payments in self.requested_payments.items(): offered_coins: List[Coin] = self.get_offered_coins()[tail_hash] # Because of CAT supply laws, we must specify a place for the leftovers to go arbitrage_amount: int = self.arbitrage()[tail_hash] all_payments: List[NotarizedPayment] = payments.copy() if arbitrage_amount > 0: assert arbitrage_amount is not None assert arbitrage_ph is not None all_payments.append( NotarizedPayment(arbitrage_ph, uint64(arbitrage_amount), [])) for coin in offered_coins: inner_solutions = [] if coin == offered_coins[0]: nonces: List[bytes32] = [p.nonce for p in all_payments] for nonce in list(dict.fromkeys( nonces)): # dedup without messing with order nonce_payments: List[NotarizedPayment] = list( filter(lambda p: p.nonce == nonce, all_payments)) inner_solutions.append( (nonce, [np.as_condition_args() for np in nonce_payments])) if tail_hash: # CATs have a special way to be solved so we have to do some calculation before getting the solution parent_spend: CoinSpend = list( filter( lambda cs: cs.coin.name() == coin.parent_coin_info, self.bundle.coin_spends))[0] parent_coin: Coin = parent_spend.coin matched, curried_args = match_cat_puzzle( parent_spend.puzzle_reveal.to_program()) assert matched _, _, inner_puzzle = curried_args spendable_cat = SpendableCAT( coin, tail_hash, OFFER_MOD, Program.to(inner_solutions), lineage_proof=LineageProof( parent_coin.parent_coin_info, inner_puzzle.get_tree_hash(), parent_coin.amount), ) solution: Program = ( unsigned_spend_bundle_for_spendable_cats( CAT_MOD, [spendable_cat ]).coin_spends[0].solution.to_program()) else: solution = Program.to(inner_solutions) completion_spends.append( CoinSpend( coin, construct_cat_puzzle(CAT_MOD, tail_hash, OFFER_MOD) if tail_hash else OFFER_MOD, solution, )) return SpendBundle.aggregate( [SpendBundle(completion_spends, G2Element()), self.bundle])
async def generate_new_decentralised_id( self, amount: uint64) -> Optional[SpendBundle]: """ This must be called under the wallet state manager lock """ coins = await self.standard_wallet.select_coins(amount) if coins is None: return None origin = coins.copy().pop() genesis_launcher_puz = did_wallet_puzzles.SINGLETON_LAUNCHER launcher_coin = Coin(origin.name(), genesis_launcher_puz.get_tree_hash(), amount) did_inner: Program = await self.get_new_innerpuz() did_inner_hash = did_inner.get_tree_hash() did_full_puz = did_wallet_puzzles.create_fullpuz( did_inner, launcher_coin.name()) did_puzzle_hash = did_full_puz.get_tree_hash() announcement_set: Set[Announcement] = set() announcement_message = Program.to( [did_puzzle_hash, amount, bytes(0x80)]).get_tree_hash() announcement_set.add( Announcement(launcher_coin.name(), announcement_message).name()) tx_record: Optional[ TransactionRecord] = await self.standard_wallet.generate_signed_transaction( amount, genesis_launcher_puz.get_tree_hash(), uint64(0), origin.name(), coins, None, False, announcement_set) genesis_launcher_solution = Program.to( [did_puzzle_hash, amount, bytes(0x80)]) launcher_cs = CoinSolution(launcher_coin, genesis_launcher_puz, genesis_launcher_solution) launcher_sb = SpendBundle([launcher_cs], AugSchemeMPL.aggregate([])) eve_coin = Coin(launcher_coin.name(), did_puzzle_hash, amount) future_parent = LineageProof( eve_coin.parent_coin_info, did_inner_hash, eve_coin.amount, ) eve_parent = LineageProof( launcher_coin.parent_coin_info, launcher_coin.puzzle_hash, launcher_coin.amount, ) await self.add_parent(eve_coin.parent_coin_info, eve_parent, False) await self.add_parent(eve_coin.name(), future_parent, False) if tx_record is None or tx_record.spend_bundle is None: return None # Only want to save this information if the transaction is valid did_info: DIDInfo = DIDInfo( launcher_coin, self.did_info.backup_ids, self.did_info.num_of_backup_ids_needed, self.did_info.parent_info, did_inner, None, None, None, ) await self.save_info(did_info, False) eve_spend = await self.generate_eve_spend(eve_coin, did_full_puz, did_inner) full_spend = SpendBundle.aggregate( [tx_record.spend_bundle, eve_spend, launcher_sb]) return full_spend
async def load_backup(self, filename: str): try: f = open(filename, "r") details = f.readline().split(":") f.close() origin = Coin(bytes.fromhex(details[0]), bytes.fromhex(details[1]), uint64(int(details[2]))) backup_ids = [] for d in details[3].split(","): backup_ids.append(bytes.fromhex(d)) num_of_backup_ids_needed = uint64(int(details[5])) if num_of_backup_ids_needed > len(backup_ids): raise Exception innerpuz = Program.from_bytes(bytes.fromhex(details[4])) did_info = DIDInfo( origin, backup_ids, num_of_backup_ids_needed, self.did_info.parent_info, innerpuz, None, None, None, ) await self.save_info(did_info, False) await self.wallet_state_manager.update_wallet_puzzle_hashes( self.wallet_info.id) full_puz = did_wallet_puzzles.create_fullpuz( innerpuz, origin.name()) full_puzzle_hash = full_puz.get_tree_hash() ( sub_height, header_hash, ) = await self.wallet_state_manager.search_blockrecords_for_puzzlehash( full_puzzle_hash) assert sub_height is not None assert header_hash is not None full_nodes = self.wallet_state_manager.server.connection_by_type[ NodeType.FULL_NODE] additions: Union[RespondAdditions, RejectAdditionsRequest, None] = None for id, node in full_nodes.items(): request = wallet_protocol.RequestAdditions( sub_height, header_hash, None) additions = await node.request_additions(request) if additions is not None: break if isinstance(additions, RejectAdditionsRequest): continue assert additions is not None assert isinstance(additions, RespondAdditions) # All additions in this block here: new_puzhash = (await self.get_new_puzzle()).get_tree_hash() new_pubkey = bytes( (await self.wallet_state_manager.get_unused_derivation_record( self.wallet_info.id)).pubkey) all_parents: bytes32 = set() for puzzle_list_coin in additions.coins: puzzle_hash, coins = puzzle_list_coin for coin in coins: all_parents.add(coin.parent_coin_info) for puzzle_list_coin in additions.coins: puzzle_hash, coins = puzzle_list_coin if puzzle_hash == full_puzzle_hash: # our coin for coin in coins: future_parent = LineageProof( coin.parent_coin_info, innerpuz.get_tree_hash(), coin.amount, ) await self.add_parent(coin.name(), future_parent, False) if coin.name() in all_parents: continue did_info = DIDInfo( origin, backup_ids, num_of_backup_ids_needed, self.did_info.parent_info, innerpuz, coin, new_puzhash, new_pubkey, ) await self.save_info(did_info, False) return None except Exception as e: raise e
async def load_backup(self, filename: str): try: f = open(filename, "r") details = f.readline().split(":") f.close() origin = Coin( bytes32.fromhex(details[0]), bytes32.fromhex(details[1]), uint64(int(details[2])), ) backup_ids = [] for d in details[3].split(","): backup_ids.append(bytes.fromhex(d)) num_of_backup_ids_needed = uint64(int(details[5])) if num_of_backup_ids_needed > len(backup_ids): raise Exception innerpuz: Program = Program.from_bytes(bytes.fromhex(details[4])) did_info: DIDInfo = DIDInfo( origin, backup_ids, num_of_backup_ids_needed, self.did_info.parent_info, innerpuz, None, None, None, False, ) await self.save_info(did_info, False) await self.wallet_state_manager.update_wallet_puzzle_hashes(self.wallet_info.id) # full_puz = did_wallet_puzzles.create_fullpuz(innerpuz, origin.name()) # All additions in this block here: new_puzhash = await self.get_new_inner_hash() new_pubkey = bytes( (await self.wallet_state_manager.get_unused_derivation_record(self.wallet_info.id)).pubkey ) parent_info = None node = self.wallet_state_manager.wallet_node.get_full_node_peer() children = await self.wallet_state_manager.wallet_node.fetch_children(node, origin.name()) while True: if len(children) == 0: break children_state: CoinState = children[0] coin = children_state.coin name = coin.name() children = await self.wallet_state_manager.wallet_node.fetch_children(node, name) future_parent = LineageProof( coin.parent_coin_info, innerpuz.get_tree_hash(), coin.amount, ) await self.add_parent(coin.name(), future_parent, False) if children_state.spent_height != children_state.created_height: did_info = DIDInfo( origin, backup_ids, num_of_backup_ids_needed, self.did_info.parent_info, innerpuz, coin, new_puzhash, new_pubkey, False, ) await self.save_info(did_info, False) assert children_state.created_height puzzle_solution_request = wallet_protocol.RequestPuzzleSolution( coin.parent_coin_info, children_state.created_height ) parent_state: CoinState = ( await self.wallet_state_manager.wallet_node.get_coin_state([coin.parent_coin_info]) )[0] response = await node.request_puzzle_solution(puzzle_solution_request) req_puz_sol = response.response assert req_puz_sol.puzzle is not None parent_innerpuz = did_wallet_puzzles.get_innerpuzzle_from_puzzle(req_puz_sol.puzzle) assert parent_innerpuz is not None parent_info = LineageProof( parent_state.coin.parent_coin_info, parent_innerpuz.get_tree_hash(), parent_state.coin.amount, ) await self.add_parent(coin.parent_coin_info, parent_info, False) assert parent_info is not None return None except Exception as e: raise e
async def test_complex_spend(self, setup_sim): sim, sim_client = setup_sim try: tail = Program.to([]) checker_solution = Program.to([]) cat_puzzle: Program = construct_cat_puzzle(CAT_MOD, tail.get_tree_hash(), acs) cat_ph: bytes32 = cat_puzzle.get_tree_hash() await sim.farm_block(cat_ph) await sim.farm_block(cat_ph) cat_records = await sim_client.get_coin_records_by_puzzle_hash(cat_ph, include_spent_coins=False) parent_of_mint = cat_records[0].coin parent_of_melt = cat_records[1].coin eve_to_mint = cat_records[2].coin eve_to_melt = cat_records[3].coin # Spend two of them to make them non-eve await self.do_spend( sim, sim_client, tail, [parent_of_mint, parent_of_melt], [NO_LINEAGE_PROOF, NO_LINEAGE_PROOF], [ Program.to( [ [51, acs.get_tree_hash(), parent_of_mint.amount], [51, 0, -113, tail, checker_solution], ] ), Program.to( [ [51, acs.get_tree_hash(), parent_of_melt.amount], [51, 0, -113, tail, checker_solution], ] ), ], (MempoolInclusionStatus.SUCCESS, None), limitations_solutions=[checker_solution] * 2, cost_str="Spend two eves", ) # Make the lineage proofs for the non-eves mint_lineage = LineageProof(parent_of_mint.parent_coin_info, acs_ph, parent_of_mint.amount) melt_lineage = LineageProof(parent_of_melt.parent_coin_info, acs_ph, parent_of_melt.amount) # Find the two new coins all_cats = await sim_client.get_coin_records_by_puzzle_hash(cat_ph, include_spent_coins=False) all_cat_coins = [cr.coin for cr in all_cats] standard_to_mint = list(filter(lambda cr: cr.parent_coin_info == parent_of_mint.name(), all_cat_coins))[0] standard_to_melt = list(filter(lambda cr: cr.parent_coin_info == parent_of_melt.name(), all_cat_coins))[0] # Do the complex spend # We have both and eve and non-eve doing both minting and melting await self.do_spend( sim, sim_client, tail, [eve_to_mint, eve_to_melt, standard_to_mint, standard_to_melt], [NO_LINEAGE_PROOF, NO_LINEAGE_PROOF, mint_lineage, melt_lineage], [ Program.to( [ [51, acs.get_tree_hash(), eve_to_mint.amount + 13], [51, 0, -113, tail, checker_solution], ] ), Program.to( [ [51, acs.get_tree_hash(), eve_to_melt.amount - 21], [51, 0, -113, tail, checker_solution], ] ), Program.to( [ [51, acs.get_tree_hash(), standard_to_mint.amount + 21], [51, 0, -113, tail, checker_solution], ] ), Program.to( [ [51, acs.get_tree_hash(), standard_to_melt.amount - 13], [51, 0, -113, tail, checker_solution], ] ), ], (MempoolInclusionStatus.SUCCESS, None), limitations_solutions=[checker_solution] * 4, extra_deltas=[13, -21, 21, -13], cost_str="Complex Spend", ) finally: await sim.close()
async def test_cat_mod(self, setup_sim): sim, sim_client = setup_sim try: tail = Program.to([]) checker_solution = Program.to([]) cat_puzzle: Program = construct_cat_puzzle(CAT_MOD, tail.get_tree_hash(), acs) cat_ph: bytes32 = cat_puzzle.get_tree_hash() await sim.farm_block(cat_ph) starting_coin: Coin = (await sim_client.get_coin_records_by_puzzle_hash(cat_ph))[0].coin # Testing the eve spend await self.do_spend( sim, sim_client, tail, [starting_coin], [NO_LINEAGE_PROOF], [ Program.to( [ [51, acs.get_tree_hash(), starting_coin.amount - 3, [b"memo"]], [51, acs.get_tree_hash(), 1], [51, acs.get_tree_hash(), 2], [51, 0, -113, tail, checker_solution], ] ) ], (MempoolInclusionStatus.SUCCESS, None), limitations_solutions=[checker_solution], cost_str="Eve Spend", ) # There's 4 total coins at this point. A farming reward and the three children of the spend above. # Testing a combination of two coins: List[Coin] = [ record.coin for record in (await sim_client.get_coin_records_by_puzzle_hash(cat_ph, include_spent_coins=False)) ] coins = [coins[0], coins[1]] await self.do_spend( sim, sim_client, tail, coins, [NO_LINEAGE_PROOF] * 2, [ Program.to( [ [51, acs.get_tree_hash(), coins[0].amount + coins[1].amount], [51, 0, -113, tail, checker_solution], ] ), Program.to([[51, 0, -113, tail, checker_solution]]), ], (MempoolInclusionStatus.SUCCESS, None), limitations_solutions=[checker_solution] * 2, cost_str="Two CATs", ) # Testing a combination of three coins = [ record.coin for record in (await sim_client.get_coin_records_by_puzzle_hash(cat_ph, include_spent_coins=False)) ] total_amount: uint64 = uint64(sum([c.amount for c in coins])) await self.do_spend( sim, sim_client, tail, coins, [NO_LINEAGE_PROOF] * 3, [ Program.to( [ [51, acs.get_tree_hash(), total_amount], [51, 0, -113, tail, checker_solution], ] ), Program.to([[51, 0, -113, tail, checker_solution]]), Program.to([[51, 0, -113, tail, checker_solution]]), ], (MempoolInclusionStatus.SUCCESS, None), limitations_solutions=[checker_solution] * 3, cost_str="Three CATs", ) # Spend with a standard lineage proof parent_coin: Coin = coins[0] # The first one is the one we didn't light on fire _, curried_args = cat_puzzle.uncurry() _, _, innerpuzzle = curried_args.as_iter() lineage_proof = LineageProof(parent_coin.parent_coin_info, innerpuzzle.get_tree_hash(), parent_coin.amount) await self.do_spend( sim, sim_client, tail, [(await sim_client.get_coin_records_by_puzzle_hash(cat_ph, include_spent_coins=False))[0].coin], [lineage_proof], [Program.to([[51, acs.get_tree_hash(), total_amount]])], (MempoolInclusionStatus.SUCCESS, None), reveal_limitations_program=False, cost_str="Standard Lineage Check", ) # Melt some value await self.do_spend( sim, sim_client, tail, [(await sim_client.get_coin_records_by_puzzle_hash(cat_ph, include_spent_coins=False))[0].coin], [NO_LINEAGE_PROOF], [ Program.to( [ [51, acs.get_tree_hash(), total_amount - 1], [51, 0, -113, tail, checker_solution], ] ) ], (MempoolInclusionStatus.SUCCESS, None), extra_deltas=[-1], limitations_solutions=[checker_solution], cost_str="Melting Value", ) # Mint some value temp_p = Program.to(1) temp_ph: bytes32 = temp_p.get_tree_hash() await sim.farm_block(temp_ph) acs_coin: Coin = (await sim_client.get_coin_records_by_puzzle_hash(temp_ph, include_spent_coins=False))[ 0 ].coin acs_bundle = SpendBundle( [ CoinSpend( acs_coin, temp_p, Program.to([]), ) ], G2Element(), ) await self.do_spend( sim, sim_client, tail, [(await sim_client.get_coin_records_by_puzzle_hash(cat_ph, include_spent_coins=False))[0].coin], [NO_LINEAGE_PROOF], [ Program.to( [ [51, acs.get_tree_hash(), total_amount], [51, 0, -113, tail, checker_solution], ] ) ], # We subtracted 1 last time so it's normal now (MempoolInclusionStatus.SUCCESS, None), extra_deltas=[1], additional_spends=[acs_bundle], limitations_solutions=[checker_solution], cost_str="Mint Value", ) finally: await sim.close()
construct_cat_puzzle, unsigned_spend_bundle_for_spendable_cats, ) from chia.wallet.puzzles.tails import ( GenesisById, GenesisByPuzhash, EverythingWithSig, DelegatedLimitations, ) from tests.clvm.test_puzzles import secret_exponent_for_index from tests.clvm.benchmark_costs import cost_of_spend_bundle acs = Program.to(1) acs_ph = acs.get_tree_hash() NO_LINEAGE_PROOF = LineageProof() class TestCATLifecycle: cost: Dict[str, int] = {} @pytest.fixture(scope="function") async def setup_sim(self): sim = await SpendSim.create() sim_client = SimClient(sim) await sim.farm_block() return sim, sim_client async def do_spend( self, sim: SpendSim,