async def get_coin_records_by_parent_ids(
        self,
        include_spent_coins: bool,
        parent_ids: List[bytes32],
        start_height: uint32 = uint32(0),
        end_height: uint32 = uint32((2 ** 32) - 1),
    ) -> List[CoinRecord]:
        if len(parent_ids) == 0:
            return []

        coins = set()
        parent_ids_db = tuple([pid.hex() for pid in parent_ids])
        cursor = await self.coin_record_db.execute(
            f'SELECT * from coin_record WHERE coin_parent in ({"?," * (len(parent_ids_db) - 1)}?) '
            f"AND confirmed_index>=? AND confirmed_index<? "
            f"{'' if include_spent_coins else 'AND spent=0'}",
            parent_ids_db + (start_height, end_height),
        )

        rows = await cursor.fetchall()

        await cursor.close()
        for row in rows:
            coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7]))
            coins.add(CoinRecord(coin, row[1], row[2], row[3], row[4], row[8]))
        return list(coins)
Exemple #2
0
def do_inspect_coin_cmd(ctx, coins, print_results=True, **kwargs):
    if kwargs and all([kwargs[key] for key in kwargs.keys()]):
        coin_objs = [
            Coin(bytes.fromhex(kwargs['parent_id']),
                 bytes.fromhex(kwargs['puzzle_hash']),
                 uint64(kwargs['amount']))
        ]
    elif not kwargs or not any([kwargs[key] for key in kwargs.keys()]):
        coin_objs = []
        try:
            if type(coins[0]) == str:
                coin_objs = streamable_load(Coin, coins)
            else:
                coin_objs = coins
        except:
            print("One or more of the specified objects was not a coin")
    else:
        print("Invalid arguments specified.")
        return

    if print_results:
        inspect_callback(coin_objs,
                         ctx,
                         id_calc=(lambda e: e.name()),
                         type='Coin')
    else:
        return coin_objs
Exemple #3
0
    def to_spend_bundle(self) -> SpendBundle:
        # Before we serialze this as a SpendBundle, we need to serialze the `requested_payments` as dummy CoinSpends
        additional_coin_spends: List[CoinSpend] = []
        for tail_hash, payments in self.requested_payments.items():
            puzzle_reveal: Program = construct_cat_puzzle(
                CAT_MOD, tail_hash, OFFER_MOD) if tail_hash else OFFER_MOD
            inner_solutions = []
            nonces: List[bytes32] = [p.nonce for p in payments]
            for nonce in list(
                    dict.fromkeys(nonces)):  # dedup without messing with order
                nonce_payments: List[NotarizedPayment] = list(
                    filter(lambda p: p.nonce == nonce, payments))
                inner_solutions.append(
                    (nonce, [np.as_condition_args() for np in nonce_payments]))

            additional_coin_spends.append(
                CoinSpend(
                    Coin(
                        ZERO_32,
                        puzzle_reveal.get_tree_hash(),
                        uint64(0),
                    ),
                    puzzle_reveal,
                    Program.to(inner_solutions),
                ))

        return SpendBundle.aggregate([
            SpendBundle(additional_coin_spends, G2Element()),
            self.bundle,
        ])
Exemple #4
0
def create_spend_for_message(parent_of_message, recovering_coin, newpuz,
                             pubkey):
    puzzle = create_recovery_message_puzzle(recovering_coin, newpuz, pubkey)
    coin = Coin(parent_of_message, puzzle.get_tree_hash(), uint64(0))
    solution = Program.to([])
    coinsol = CoinSolution(coin, puzzle, solution)
    return coinsol
Exemple #5
0
    async def get_unspent_coins_for_wallet(
            self, wallet_id: int) -> Set[WalletCoinRecord]:
        """ Returns set of CoinRecords that have not been spent yet for a wallet. """
        async with self.wallet_cache_lock:
            if wallet_id in self.coin_wallet_record_cache:
                wallet_coins: Dict[
                    bytes32, WalletCoinRecord] = self.coin_wallet_record_cache[
                        wallet_id]
                return set(wallet_coins.values())

            coin_set = set()

            cursor = await self.db_connection.execute(
                "SELECT * from coin_record WHERE spent=0 and wallet_id=?",
                (wallet_id, ),
            )
            rows = await cursor.fetchall()
            await cursor.close()
            cache_dict = {}
            for row in rows:
                coin = Coin(bytes32(bytes.fromhex(row[6])),
                            bytes32(bytes.fromhex(row[5])),
                            uint64.from_bytes(row[7]))
                coin_record = WalletCoinRecord(coin, row[1], row[2],
                                               row[3], row[4],
                                               WalletType(row[8]), row[9])
                coin_set.add(coin_record)
                cache_dict[coin.name()] = coin_record

            self.coin_wallet_record_cache[wallet_id] = cache_dict
            return coin_set
Exemple #6
0
def launcher_conditions_and_spend_bundle(
    parent_coin_id: bytes32,
    launcher_amount: uint64,
    initial_singleton_inner_puzzle: Program,
    metadata: List[Tuple[str, str]],
    launcher_puzzle: Program = LAUNCHER_PUZZLE,
) -> Tuple[Program, bytes32, List[Program], SpendBundle]:
    launcher_puzzle_hash = launcher_puzzle.get_tree_hash()
    launcher_coin = Coin(parent_coin_id, launcher_puzzle_hash, launcher_amount)
    singleton_full_puzzle = SINGLETON_MOD.curry(
        SINGLETON_MOD_HASH, launcher_coin.name(), launcher_puzzle_hash,
        initial_singleton_inner_puzzle)
    singleton_full_puzzle_hash = singleton_full_puzzle.get_tree_hash()
    message_program = Program.to(
        [singleton_full_puzzle_hash, launcher_amount, metadata])
    expected_announcement = Announcement(launcher_coin.name(),
                                         message_program.get_tree_hash())
    expected_conditions = []
    expected_conditions.append(
        Program.to(
            binutils.assemble(
                f"(0x{ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT.hex()} 0x{expected_announcement.name()})"
            )))
    expected_conditions.append(
        Program.to(
            binutils.assemble(
                f"(0x{ConditionOpcode.CREATE_COIN.hex()} 0x{launcher_puzzle_hash} {launcher_amount})"
            )))
    launcher_solution = Program.to(
        [singleton_full_puzzle_hash, launcher_amount, metadata])
    coin_spend = CoinSpend(launcher_coin, launcher_puzzle, launcher_solution)
    spend_bundle = SpendBundle([coin_spend], G2Element())
    lineage_proof = Program.to([parent_coin_id, launcher_amount])
    return lineage_proof, launcher_coin.name(
    ), expected_conditions, spend_bundle
Exemple #7
0
 def farm_coin(self,
               puzzle_hash: bytes32,
               birthday: CoinTimestamp,
               amount: int = 1024) -> Coin:
     parent = birthday.height.to_bytes(32, "big")
     coin = Coin(parent, puzzle_hash, uint64(amount))
     self._add_coin_entry(coin, birthday)
     return coin
    async def test_store(self):
        db_filename = Path("wallet_store_test.db")

        if db_filename.exists():
            db_filename.unlink()

        db_connection = await aiosqlite.connect(db_filename)
        db_wrapper = DBWrapper(db_connection)
        store = await WalletInterestedStore.create(db_wrapper)
        try:
            coin_1 = Coin(token_bytes(32), token_bytes(32), uint64(12312))
            coin_2 = Coin(token_bytes(32), token_bytes(32), uint64(12312))
            assert (await store.get_interested_coin_ids()) == []
            await store.add_interested_coin_id(coin_1.name())
            assert (await store.get_interested_coin_ids()) == [coin_1.name()]
            await store.add_interested_coin_id(coin_1.name())
            assert (await store.get_interested_coin_ids()) == [coin_1.name()]
            await store.add_interested_coin_id(coin_2.name())
            assert set(await store.get_interested_coin_ids()) == {
                coin_1.name(), coin_2.name()
            }
            puzzle_hash = token_bytes(32)
            assert len(await store.get_interested_puzzle_hashes()) == 0

            await store.add_interested_puzzle_hash(puzzle_hash, 2)
            assert len(await store.get_interested_puzzle_hashes()) == 1
            await store.add_interested_puzzle_hash(puzzle_hash, 2)
            assert len(await store.get_interested_puzzle_hashes()) == 1
            assert (
                await
                store.get_interested_puzzle_hash_wallet_id(puzzle_hash)) == 2
            await store.add_interested_puzzle_hash(puzzle_hash, 3)
            assert len(await store.get_interested_puzzle_hashes()) == 1

            assert (
                await
                store.get_interested_puzzle_hash_wallet_id(puzzle_hash)) == 3
            await store.remove_interested_puzzle_hash(puzzle_hash)
            assert (await store.get_interested_puzzle_hash_wallet_id(
                puzzle_hash)) is None
            assert len(await store.get_interested_puzzle_hashes()) == 0

        finally:
            await db_connection.close()
            db_filename.unlink()
Exemple #9
0
def coin_spend_for_lock_coin(
    prev_coin: Coin,
    subtotal: int,
    coin: Coin,
) -> CoinSpend:
    puzzle_reveal = LOCK_INNER_PUZZLE.curry(prev_coin.as_list(), subtotal)
    coin = Coin(coin.name(), puzzle_reveal.get_tree_hash(), uint64(0))
    coin_spend = CoinSpend(coin, puzzle_reveal, Program.to(0))
    return coin_spend
 async def get_coins_added_at_height(self, height: uint32) -> List[CoinRecord]:
     cursor = await self.coin_record_db.execute("SELECT * from coin_record WHERE confirmed_index=?", (height,))
     rows = await cursor.fetchall()
     await cursor.close()
     coins = []
     for row in rows:
         coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7]))
         coins.append(CoinRecord(coin, row[1], row[2], row[3], row[4], row[8]))
     return coins
Exemple #11
0
def make_fake_coin(index: int, puzzle_hash_db: dict) -> Coin:
    """
    Make a fake coin with parent id equal to the index (ie. a genesis block coin)

    """
    parent = index.to_bytes(32, "big")
    puzzle_hash = puzzle_hash_for_index(index, puzzle_hash_db)
    amount = 100000
    return Coin(parent, puzzle_hash, uint64(amount))
Exemple #12
0
 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"""
     coins = set()
     cursor = await self.db_connection.execute("SELECT * from coin_record WHERE puzzle_hash=?", (puzzle_hash.hex(),))
     rows = await cursor.fetchall()
     await cursor.close()
     for row in rows:
         coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7]))
         coins.add(WalletCoinRecord(coin, row[1], row[2], row[3], row[4], WalletType(row[8]), row[9]))
     return list(coins)
Exemple #13
0
def generate_farmed_coin(
    block_index: int,
    puzzle_hash: bytes32,
    amount: int,
) -> Coin:
    """
    Generate a (fake) coin which can be used as a starting point for a chain
    of coin tests.
    """
    return Coin(int_as_bytes32(block_index), puzzle_hash, uint64(amount))
 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
Exemple #15
0
    async def get_coin_record_by_coin_id(self, coin_id: bytes32) -> Optional[WalletCoinRecord]:
        """Returns a coin records with the given name, if it exists"""
        cursor = await self.db_connection.execute("SELECT * from coin_record WHERE coin_name=?", (coin_id.hex(),))
        row = await cursor.fetchone()
        await cursor.close()
        if row is None:
            return None

        coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7]))
        coin_record = WalletCoinRecord(coin, row[1], row[2], row[3], row[4], WalletType(row[8]), row[9])
        return coin_record
Exemple #16
0
def created_outputs_for_conditions_dict(
    conditions_dict: Dict[ConditionOpcode, List[ConditionWithArgs]],
    input_coin_name: bytes32,
) -> List[Coin]:
    output_coins = []
    for cvp in conditions_dict.get(ConditionOpcode.CREATE_COIN, []):
        puzzle_hash, amount_bin = cvp.vars[0], cvp.vars[1]
        amount = int_from_bytes(amount_bin)
        coin = Coin(input_coin_name, bytes32(puzzle_hash), uint64(amount))
        output_coins.append(coin)
    return output_coins
Exemple #17
0
    async def get_all_coins(self) -> Set[WalletCoinRecord]:
        """ Returns set of all CoinRecords."""
        coins = set()

        cursor = await self.db_connection.execute("SELECT * from coin_record")
        rows = await cursor.fetchall()
        await cursor.close()
        for row in rows:
            coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7]))
            coins.add(WalletCoinRecord(coin, row[1], row[2], row[3], row[4], WalletType(row[8]), row[9]))
        return coins
 async def check_all_there():
     spendable = await cc_wallet.get_cc_spendable_coins()
     spendable_name_set = set()
     for record in spendable:
         spendable_name_set.add(record.coin.name())
     puzzle_hash = cc_puzzle_hash_for_inner_puzzle_hash(CC_MOD, cc_wallet.cc_info.my_genesis_checker, cc_2_hash)
     for i in range(1, 50):
         coin = Coin(spent_coint.name(), puzzle_hash, i)
         if coin.name() not in spendable_name_set:
             return False
     return True
Exemple #19
0
 async def get_coin_record(self, coin_name: bytes32) -> Optional[WalletCoinRecord]:
     """ Returns CoinRecord with specified coin id. """
     if coin_name in self.coin_record_cache:
         return self.coin_record_cache[coin_name]
     cursor = await self.db_connection.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 WalletCoinRecord(coin, row[1], row[2], row[3], row[4], WalletType(row[8]), row[9])
     return None
def test_only_odd_coins_0():
    blocks = initial_blocks()
    farmed_coin = list(blocks[-1].get_included_reward_coins())[0]

    metadata = [("foo", "bar")]
    ANYONE_CAN_SPEND_PUZZLE = Program.to(1)
    launcher_amount = uint64(1)
    launcher_puzzle = LAUNCHER_PUZZLE
    launcher_puzzle_hash = launcher_puzzle.get_tree_hash()
    initial_singleton_puzzle = adaptor_for_singleton_inner_puzzle(
        ANYONE_CAN_SPEND_PUZZLE)
    lineage_proof, launcher_id, condition_list, launcher_spend_bundle = launcher_conditions_and_spend_bundle(
        farmed_coin.name(), launcher_amount, initial_singleton_puzzle,
        metadata, launcher_puzzle)

    conditions = Program.to(condition_list)
    coin_solution = CoinSolution(farmed_coin, ANYONE_CAN_SPEND_PUZZLE,
                                 conditions)
    spend_bundle = SpendBundle.aggregate(
        [launcher_spend_bundle,
         SpendBundle([coin_solution], G2Element())])
    run = asyncio.get_event_loop().run_until_complete
    coins_added, coins_removed = run(
        check_spend_bundle_validity(bt.constants, blocks, spend_bundle))

    coin_set_added = set([_.coin for _ in coins_added])
    coin_set_removed = set([_.coin for _ in coins_removed])

    launcher_coin = launcher_spend_bundle.coin_solutions[0].coin

    assert launcher_coin in coin_set_added
    assert launcher_coin in coin_set_removed

    assert farmed_coin in coin_set_removed
    # breakpoint()

    singleton_expected_puzzle_hash = singleton_puzzle_hash(
        launcher_id, launcher_puzzle_hash, initial_singleton_puzzle)
    expected_singleton_coin = Coin(launcher_coin.name(),
                                   singleton_expected_puzzle_hash,
                                   launcher_amount)
    assert expected_singleton_coin in coin_set_added

    # next up: spend the expected_singleton_coin
    # it's an adapted `ANYONE_CAN_SPEND_PUZZLE`

    # then try a bad lineage proof
    # then try writing two odd coins
    # then try writing zero odd coins

    # then, destroy the singleton with the -113 hack

    return 0
Exemple #21
0
    async def all_non_reward_coins(self) -> List[Coin]:
        coins = set()
        cursor = await self.mempool_manager.coin_store.coin_record_db.execute(
            "SELECT * from coin_record WHERE coinbase=0 AND spent=0 ",
        )
        rows = await cursor.fetchall()

        await cursor.close()
        for row in rows:
            coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7]))
            coins.add(coin)
        return list(coins)
Exemple #22
0
def make_fake_coin(index: int, puzzle_hash_db: dict) -> Coin:
    """
    Make a fake coin with parent id equal to the index (ie. a genesis block coin)

    """
    parent = index.to_bytes(32, "big")
    puzzle_hash = puzzle_hash_for_index(index, puzzle_hash_db)
    amount = 100000
    # TODO: address hint error and remove ignore
    #       error: Argument 1 to "Coin" has incompatible type "bytes"; expected "bytes32"  [arg-type]
    #       error: Argument 2 to "Coin" has incompatible type "bytes"; expected "bytes32"  [arg-type]
    return Coin(parent, puzzle_hash, uint64(amount))  # type: ignore[arg-type]
Exemple #23
0
    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()

        did_inner: Program = await self.get_new_innerpuz()
        did_inner_hash = did_inner.get_tree_hash()
        did_puz = did_wallet_puzzles.create_fullpuz(did_inner,
                                                    origin.puzzle_hash)
        did_puzzle_hash = did_puz.get_tree_hash()

        tx_record: Optional[
            TransactionRecord] = await self.standard_wallet.generate_signed_transaction(
                amount, did_puzzle_hash, uint64(0), origin.name(), coins)
        eve_coin = Coin(origin.name(), did_puzzle_hash, amount)
        future_parent = CCParent(
            eve_coin.parent_coin_info,
            did_inner_hash,
            eve_coin.amount,
        )
        eve_parent = CCParent(
            origin.parent_coin_info,
            origin.puzzle_hash,
            origin.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(
            origin,
            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_puz, did_inner)
        full_spend = SpendBundle.aggregate([tx_record.spend_bundle, eve_spend])
        return full_spend
 async def check_all_there():
     spendable = await cat_wallet.get_cat_spendable_coins()
     spendable_name_set = set()
     for record in spendable:
         spendable_name_set.add(record.coin.name())
     puzzle_hash = construct_cat_puzzle(
         CAT_MOD, cat_wallet.cat_info.limitations_program_hash,
         cat_2).get_tree_hash()
     for i in range(1, 50):
         coin = Coin(spent_coint.name(), puzzle_hash, i)
         if coin.name() not in spendable_name_set:
             return False
     return True
 async def get_coin_record(self, coin_name: bytes32) -> Optional[CoinRecord]:
     cached = self.coin_record_cache.get(coin_name)
     if cached is not None:
         return cached
     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]))
         record = CoinRecord(coin, row[1], row[2], row[3], row[4], row[8])
         self.coin_record_cache.put(record.coin.name(), record)
         return record
     return None
Exemple #26
0
        def check_messages_for_hint(messages):
            notified_state = None

            for message in messages:
                if message.type == ProtocolMessageTypes.coin_state_update.value:
                    data_response: CoinStateUpdate = CoinStateUpdate.from_bytes(
                        message.data)
                    notified_state = data_response
                    break

            assert notified_state is not None
            assert notified_state.items[0].coin == Coin(
                coin_spent.name(), hint_puzzle_hash, amount)
def spend_coin_to_singleton(
        puzzle_db: PuzzleDB, launcher_puzzle: Program, coin_store: CoinStore,
        now: CoinTimestamp) -> Tuple[List[Coin], List[CoinSpend]]:

    farmed_coin_amount = 100000
    metadata = [("foo", "bar")]

    now = CoinTimestamp(10012300, 1)
    farmed_coin = coin_store.farm_coin(ANYONE_CAN_SPEND_PUZZLE.get_tree_hash(),
                                       now,
                                       amount=farmed_coin_amount)
    now.seconds += 500
    now.height += 1

    launcher_amount: uint64 = uint64(1)
    launcher_puzzle = LAUNCHER_PUZZLE
    launcher_puzzle_hash = launcher_puzzle.get_tree_hash()
    initial_singleton_puzzle = adaptor_for_singleton_inner_puzzle(
        ANYONE_CAN_SPEND_PUZZLE)
    launcher_id, condition_list, launcher_spend_bundle = launcher_conditions_and_spend_bundle(
        puzzle_db, farmed_coin.name(), launcher_amount,
        initial_singleton_puzzle, metadata, launcher_puzzle)

    conditions = Program.to(condition_list)
    coin_spend = CoinSpend(farmed_coin, ANYONE_CAN_SPEND_PUZZLE, conditions)
    spend_bundle = SpendBundle.aggregate(
        [launcher_spend_bundle,
         SpendBundle([coin_spend], G2Element())])

    additions, removals = coin_store.update_coin_store_for_spend_bundle(
        spend_bundle, now, MAX_BLOCK_COST_CLVM, COST_PER_BYTE)

    launcher_coin = launcher_spend_bundle.coin_spends[0].coin

    assert_coin_spent(coin_store, launcher_coin)
    assert_coin_spent(coin_store, farmed_coin)

    # TODO: address hint error and remove ignore
    #       error: Argument 1 to "singleton_puzzle" has incompatible type "bytes32"; expected "Program"  [arg-type]
    singleton_expected_puzzle = singleton_puzzle(
        launcher_id,  # type: ignore[arg-type]
        launcher_puzzle_hash,
        initial_singleton_puzzle,
    )
    singleton_expected_puzzle_hash = singleton_expected_puzzle.get_tree_hash()
    expected_singleton_coin = Coin(launcher_coin.name(),
                                   singleton_expected_puzzle_hash,
                                   launcher_amount)
    assert_coin_spent(coin_store, expected_singleton_coin, is_spent=False)

    return additions, removals
Exemple #28
0
def created_outputs_for_conditions_dict(
    conditions_dict: Dict[ConditionOpcode, List[ConditionWithArgs]],
    input_coin_name: bytes32,
) -> List[Coin]:
    output_coins = []
    for cvp in conditions_dict.get(ConditionOpcode.CREATE_COIN, []):
        puzzle_hash, amount_bin = cvp.vars[0], cvp.vars[1]
        amount = int_from_bytes(amount_bin)
        # TODO: address hint error and remove ignore
        #       error: Argument 2 to "Coin" has incompatible type "bytes"; expected "bytes32"  [arg-type]
        coin = Coin(input_coin_name, puzzle_hash,
                    uint64(amount))  # type: ignore[arg-type]
        output_coins.append(coin)
    return output_coins
Exemple #29
0
def get_name_puzzle_conditions(
    block_program: SerializedProgram, safe_mode: bool
) -> Tuple[Optional[str], Optional[List[NPC]], Optional[uint64]]:
    # TODO: allow generator mod to take something (future)
    # TODO: write more tests
    block_program_args = SerializedProgram.from_bytes(b"\x80")

    try:
        if safe_mode:
            cost, result = GENERATOR_MOD.run_safe_with_cost(
                block_program, block_program_args)
        else:
            cost, result = GENERATOR_MOD.run_with_cost(block_program,
                                                       block_program_args)
        npc_list: List[NPC] = []
        opcodes: Set[bytes] = set(item.value for item in ConditionOpcode)

        for res in result.as_iter():
            conditions_list: List[ConditionWithArgs] = []

            spent_coin_parent_id: bytes32 = res.first().first().as_atom()
            spent_coin_puzzle_hash: bytes32 = res.first().rest().first(
            ).as_atom()
            spent_coin_amount: uint64 = uint64(
                res.first().rest().rest().first().as_int())
            spent_coin: Coin = Coin(spent_coin_parent_id,
                                    spent_coin_puzzle_hash, spent_coin_amount)

            for cond in res.rest().first().as_iter():
                if cond.first().as_atom() in opcodes:
                    opcode: ConditionOpcode = ConditionOpcode(
                        cond.first().as_atom())
                elif not safe_mode:
                    opcode = ConditionOpcode.UNKNOWN
                else:
                    return "Unknown operator in safe mode.", None, None
                conditions_list.append(
                    ConditionWithArgs(opcode,
                                      cond.rest().as_atom_list()))
            conditions_dict = conditions_by_opcode(conditions_list)
            if conditions_dict is None:
                conditions_dict = {}
            npc_list.append(
                NPC(spent_coin.name(), spent_coin.puzzle_hash,
                    [(a, b) for a, b in conditions_dict.items()]))
        return None, npc_list, uint64(cost)
    except Exception:
        tb = traceback.format_exc()
        return tb, None, None
Exemple #30
0
def created_outputs_for_conditions_dict(
    conditions_dict: Dict[ConditionOpcode, List[ConditionWithArgs]],
    input_coin_name: bytes32,
) -> List[Coin]:
    output_coins = []
    for cvp in conditions_dict.get(ConditionOpcode.CREATE_COIN, []):
        # TODO: check condition very carefully
        # (ensure there are the correct number and type of parameters)
        # maybe write a type-checking framework for conditions
        # and don't just fail with asserts
        puzzle_hash, amount_bin = cvp.vars[0], cvp.vars[1]
        amount = int_from_bytes(amount_bin)
        coin = Coin(input_coin_name, puzzle_hash, amount)
        output_coins.append(coin)
    return output_coins