def puzzle_announcements_names_for_npc(npc_list) -> Set[bytes32]: output_announcements: Set[bytes32] = set() for npc in npc_list: for condition, cvp_list in npc.conditions: if condition == ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT: for cvp in cvp_list: message = cvp.vars[0] announcement = Announcement(npc.puzzle_hash, message) output_announcements.add(announcement.name()) return output_announcements
def coin_announcements_names_for_npc(npc_list) -> Set[bytes32]: output_announcements: Set[bytes32] = set() for npc in npc_list: for condition, cvp_list in npc.conditions: if condition == ConditionOpcode.CREATE_COIN_ANNOUNCEMENT: for cvp in cvp_list: message = cvp.vars[0] assert len(message) <= 1024 announcement = Announcement(npc.coin_name, message) output_announcements.add(announcement.name()) return output_announcements
def test_fun(coin_1: Coin, coin_2: Coin) -> SpendBundle: announce = Announcement(coin_2.name(), b"test") cvp = ConditionWithArgs(ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, [announce.name()]) dic = {cvp.opcode: [cvp]} cvp2 = ConditionWithArgs(ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, [b"test"]) dic2 = {cvp.opcode: [cvp2]} spend_bundle1 = generate_test_spend_bundle(coin_1, dic) spend_bundle2 = generate_test_spend_bundle(coin_2, dic2) bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2]) return bundle
async def test_invalid_announcement_consumed_two(self, two_nodes): reward_ph = WALLET_A.get_new_puzzlehash() full_node_1, full_node_2, server_1, server_2 = two_nodes blocks = await full_node_1.get_all_full_blocks() start_height = blocks[-1].height if len(blocks) > 0 else -1 blocks = bt.get_consecutive_blocks( 3, block_list_input=blocks, guarantee_transaction_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph, ) peer = await connect_and_get_peer(server_1, server_2) for block in blocks: await full_node_1.full_node.respond_block( full_node_protocol.RespondBlock(block)) await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3) coin_1 = list(blocks[-2].get_included_reward_coins())[0] coin_2 = list(blocks[-1].get_included_reward_coins())[0] announce = Announcement(coin_1.name(), bytes("test", "utf-8")) cvp = ConditionVarPair(ConditionOpcode.ASSERT_ANNOUNCEMENT, [announce.name()]) dic = {cvp.opcode: [cvp]} cvp2 = ConditionVarPair( ConditionOpcode.CREATE_ANNOUNCEMENT, [bytes("test", "utf-8")], ) dic2 = {cvp.opcode: [cvp2]} spend_bundle1 = generate_test_spend_bundle(coin_1, dic) spend_bundle2 = generate_test_spend_bundle(coin_2, dic2) bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2]) tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction( spend_bundle1) await full_node_1.respond_transaction(tx1, peer) mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle( bundle.name()) assert mempool_bundle is None
def test_fun(coin_1: Coin, coin_2: Coin): announce = Announcement(coin_2.puzzle_hash, bytes(0x80)) cvp = ConditionWithArgs(ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT, [announce.name()]) dic = {cvp.opcode: [cvp]} cvp2 = ConditionWithArgs(ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT, [bytes(0x80)]) dic2 = {cvp.opcode: [cvp2]} spend_bundle1 = generate_test_spend_bundle(coin_1, dic) spend_bundle2 = generate_test_spend_bundle(coin_2, dic2) return SpendBundle.aggregate([spend_bundle1, spend_bundle2])
def test_fun(coin_1: Coin, coin_2: Coin): announce = Announcement(coin_1.name(), b"test") cvp = ConditionWithArgs(ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, [announce.name()]) dic = {cvp.opcode: [cvp]} cvp2 = ConditionWithArgs( ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, [b"test"], ) dic2 = {cvp.opcode: [cvp2]} spend_bundle1 = generate_test_spend_bundle(coin_1, dic) # coin 2 is making the announcement, right message wrong coin spend_bundle2 = generate_test_spend_bundle(coin_2, dic2) return SpendBundle.aggregate([spend_bundle1, spend_bundle2])
async def generate_unsigned_spendbundle( self, payments: List[Payment], fee: uint64 = uint64(0), cat_discrepancy: Optional[Tuple[ int, Program]] = None, # (extra_delta, limitations_solution) coins: Set[Coin] = None, coin_announcements_to_consume: Optional[Set[Announcement]] = None, puzzle_announcements_to_consume: Optional[Set[Announcement]] = None, ) -> Tuple[SpendBundle, Optional[TransactionRecord]]: if coin_announcements_to_consume is not None: coin_announcements_bytes: Optional[Set[bytes32]] = { a.name() for a in coin_announcements_to_consume } else: coin_announcements_bytes = None if puzzle_announcements_to_consume is not None: puzzle_announcements_bytes: Optional[Set[bytes32]] = { a.name() for a in puzzle_announcements_to_consume } else: puzzle_announcements_bytes = None if cat_discrepancy is not None: extra_delta, limitations_solution = cat_discrepancy else: extra_delta, limitations_solution = 0, Program.to([]) payment_amount: int = sum([p.amount for p in payments]) starting_amount: int = payment_amount - extra_delta if coins is None: cat_coins = await self.select_coins(uint64(starting_amount)) else: cat_coins = coins selected_cat_amount = sum([c.amount for c in cat_coins]) assert selected_cat_amount >= starting_amount # Figure out if we need to absorb/melt some XCH as part of this regular_chia_to_claim: int = 0 if payment_amount > starting_amount: fee = uint64(fee + payment_amount - starting_amount) elif payment_amount < starting_amount: regular_chia_to_claim = payment_amount need_chia_transaction = (fee > 0 or regular_chia_to_claim > 0) and ( fee - regular_chia_to_claim != 0) # Calculate standard puzzle solutions change = selected_cat_amount - starting_amount primaries: List[AmountWithPuzzlehash] = [] for payment in payments: primaries.append({ "puzzlehash": payment.puzzle_hash, "amount": payment.amount, "memos": payment.memos }) if change > 0: changepuzzlehash = await self.get_new_inner_hash() primaries.append({ "puzzlehash": changepuzzlehash, "amount": uint64(change), "memos": [] }) limitations_program_reveal = Program.to([]) if self.cat_info.my_tail is None: assert cat_discrepancy is None elif cat_discrepancy is not None: limitations_program_reveal = self.cat_info.my_tail # Loop through the coins we've selected and gather the information we need to spend them spendable_cc_list = [] chia_tx = None first = True for coin in cat_coins: if first: first = False if need_chia_transaction: if fee > regular_chia_to_claim: announcement = Announcement(coin.name(), b"$", b"\xca") chia_tx, _ = await self.create_tandem_xch_tx( fee, uint64(regular_chia_to_claim), announcement_to_assert=announcement) innersol = self.standard_wallet.make_solution( primaries=primaries, coin_announcements={announcement.message}, coin_announcements_to_assert= coin_announcements_bytes, puzzle_announcements_to_assert= puzzle_announcements_bytes, ) elif regular_chia_to_claim > fee: chia_tx, _ = await self.create_tandem_xch_tx( fee, uint64(regular_chia_to_claim)) innersol = self.standard_wallet.make_solution( primaries=primaries, coin_announcements_to_assert={announcement.name()}) else: innersol = self.standard_wallet.make_solution( primaries=primaries, coin_announcements_to_assert=coin_announcements_bytes, puzzle_announcements_to_assert= puzzle_announcements_bytes, ) else: innersol = self.standard_wallet.make_solution(primaries=[]) inner_puzzle = await self.inner_puzzle_for_cc_puzhash( coin.puzzle_hash) lineage_proof = await self.get_lineage_proof_for_coin(coin) assert lineage_proof is not None new_spendable_cc = SpendableCAT( coin, self.cat_info.limitations_program_hash, inner_puzzle, innersol, limitations_solution=limitations_solution, extra_delta=extra_delta, lineage_proof=lineage_proof, limitations_program_reveal=limitations_program_reveal, ) spendable_cc_list.append(new_spendable_cc) cat_spend_bundle = unsigned_spend_bundle_for_spendable_cats( CAT_MOD, spendable_cc_list) chia_spend_bundle = SpendBundle([], G2Element()) if chia_tx is not None and chia_tx.spend_bundle is not None: chia_spend_bundle = chia_tx.spend_bundle return ( SpendBundle.aggregate([ cat_spend_bundle, chia_spend_bundle, ]), chia_tx, )