Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHIA-907 Augment uncurry_puzzle to accept both types of programs #18286

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion chia/_tests/wallet/did_wallet/test_did.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ async def test_get_info(self, self_hostname, two_wallet_nodes, trusted):
response = await api_0.did_get_info({"coin_id": did_wallet_1.did_info.origin_coin.name().hex()})
assert response["did_id"] == encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value)
assert response["launcher_id"] == did_wallet_1.did_info.origin_coin.name().hex()
assert response["full_puzzle"] == create_singleton_puzzle(
assert response["full_puzzle"].to_program() == create_singleton_puzzle(
did_wallet_1.did_info.current_inner, did_wallet_1.did_info.origin_coin.name()
)
assert response["metadata"]["twitter"] == "twitter"
Expand Down
2 changes: 1 addition & 1 deletion chia/_tests/wallet/rpc/test_wallet_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ async def test_cat_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment):

spend_bundle = tx_res.transaction.spend_bundle
assert spend_bundle is not None
assert uncurry_puzzle(spend_bundle.coin_spends[0].puzzle_reveal.to_program()).mod == CAT_MOD
assert uncurry_puzzle(spend_bundle.coin_spends[0].puzzle_reveal).mod == CAT_MOD
await farm_transaction(full_node_api, wallet_node, spend_bundle)

await farm_transaction_block(full_node_api, wallet_node)
Expand Down
8 changes: 3 additions & 5 deletions chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ async def test_vc_lifecycle(test_syncing: bool, cost_logger: CostLogger) -> None
assert result == (MempoolInclusionStatus.SUCCESS, None)
if test_syncing:
vc = VerifiedCredential.get_next_from_coin_spend(coin_spends[1])
assert VerifiedCredential.is_vc(uncurry_puzzle(coin_spends[1].puzzle_reveal.to_program()))[0]
assert VerifiedCredential.is_vc(uncurry_puzzle(coin_spends[1].puzzle_reveal))[0]
assert vc.construct_puzzle().get_tree_hash() == vc.coin.puzzle_hash
assert len(await client.get_coin_records_by_puzzle_hashes([vc.coin.puzzle_hash], include_spent_coins=False)) > 0

Expand Down Expand Up @@ -585,7 +585,7 @@ async def test_vc_lifecycle(test_syncing: bool, cost_logger: CostLogger) -> None
await sim.farm_block()
if test_syncing:
vc = VerifiedCredential.get_next_from_coin_spend(update_spend)
assert VerifiedCredential.is_vc(uncurry_puzzle(update_spend.puzzle_reveal.to_program()))[0]
assert VerifiedCredential.is_vc(uncurry_puzzle(update_spend.puzzle_reveal))[0]

# Now lets farm a funds for some CR-CATs
await sim.farm_block(RUN_PUZ_PUZ_PH)
Expand Down Expand Up @@ -749,9 +749,7 @@ async def test_vc_lifecycle(test_syncing: bool, cost_logger: CostLogger) -> None
if error is None:
assert result == (MempoolInclusionStatus.SUCCESS, None)
if test_syncing:
assert all(
CRCAT.is_cr_cat(uncurry_puzzle(spend.puzzle_reveal.to_program()))[0] for spend in cr_cat_spends
)
assert all(CRCAT.is_cr_cat(uncurry_puzzle(spend.puzzle_reveal))[0] for spend in cr_cat_spends)
new_crcats = [crcat for spend in cr_cat_spends for crcat in CRCAT.get_next_from_coin_spend(spend)]
vc = VerifiedCredential.get_next_from_coin_spend(auth_spend)
else:
Expand Down
8 changes: 3 additions & 5 deletions chia/rpc/wallet_rpc_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2281,8 +2281,7 @@ async def did_get_info(self, request: Dict[str, Any]) -> EndpointResult:
# Get coin state
peer = self.service.get_full_node_peer()
coin_spend, coin_state = await self.get_latest_singleton_coin_spend(peer, coin_id, request.get("latest", True))
full_puzzle: Program = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
uncurried = uncurry_puzzle(full_puzzle)
uncurried = uncurry_puzzle(coin_spend.puzzle_reveal)
curried_args = match_did_puzzle(uncurried.mod, uncurried.args)
if curried_args is None:
return {"success": False, "error": "The coin is not a DID."}
Expand All @@ -2306,7 +2305,7 @@ async def did_get_info(self, request: Dict[str, Any]) -> EndpointResult:
"num_verification": num_verification.as_int(),
"metadata": did_program_to_metadata(metadata),
"launcher_id": launcher_id.hex(),
"full_puzzle": full_puzzle,
"full_puzzle": coin_spend.puzzle_reveal,
"solution": coin_spend.solution.to_program().as_python(),
"hints": hints,
}
Expand All @@ -2329,8 +2328,7 @@ async def did_find_lost_did(self, request: Dict[str, Any]) -> EndpointResult:
# Get coin state
peer = self.service.get_full_node_peer()
coin_spend, coin_state = await self.get_latest_singleton_coin_spend(peer, coin_id)
full_puzzle: Program = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
uncurried = uncurry_puzzle(full_puzzle)
uncurried = uncurry_puzzle(coin_spend.puzzle_reveal)
curried_args = match_did_puzzle(uncurried.mod, uncurried.args)
if curried_args is None:
return {"success": False, "error": "The coin is not a DID."}
Expand Down
2 changes: 1 addition & 1 deletion chia/wallet/cat_wallet/cat_outer_puzzle.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def solve(self, constructor: PuzzleInfo, solver: Solver, inner_puzzle: Program,
if also is not None:
solution = self._solve(also, solver, puzzle, solution)
puzzle = self._construct(also, puzzle)
args = match_cat_puzzle(uncurry_puzzle(parent_spend.puzzle_reveal.to_program()))
args = match_cat_puzzle(uncurry_puzzle(parent_spend.puzzle_reveal))
assert args is not None
_, _, parent_inner_puzzle = args
spendable_cats.append(
Expand Down
2 changes: 1 addition & 1 deletion chia/wallet/cat_wallet/cat_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ async def coin_added(
)
assert coin_state[0].coin.name() == coin.parent_coin_info
coin_spend = await fetch_coin_spend_for_coin_state(coin_state[0], peer)
cat_curried_args = match_cat_puzzle(uncurry_puzzle(coin_spend.puzzle_reveal.to_program()))
cat_curried_args = match_cat_puzzle(uncurry_puzzle(coin_spend.puzzle_reveal))
if cat_curried_args is not None:
cat_mod_hash, tail_program_hash, cat_inner_puzzle = cat_curried_args
parent_coin_data = CATCoinData(
Expand Down
8 changes: 4 additions & 4 deletions chia/wallet/dao_wallet/dao_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,10 +422,10 @@ async def coin_added(self, coin: Coin, height: uint32, peer: WSChiaConnection, c
cs = (await wallet_node.get_coin_state([coin.parent_coin_info], peer, height))[0]
parent_spend = await fetch_coin_spend(cs.spent_height, cs.coin, peer)

puzzle = Program.from_bytes(bytes(parent_spend.puzzle_reveal))
solution = Program.from_bytes(bytes(parent_spend.solution))
uncurried = uncurry_puzzle(puzzle)
matched_funding_puz = match_funding_puzzle(uncurried, solution, coin, [self.dao_info.treasury_id])
uncurried = uncurry_puzzle(parent_spend.puzzle_reveal)
matched_funding_puz = match_funding_puzzle(
uncurried, parent_spend.solution.to_program(), coin, [self.dao_info.treasury_id]
)
if matched_funding_puz:
# funding coin
xch_funds_puzhash = get_p2_singleton_puzhash(self.dao_info.treasury_id, asset_id=None)
Expand Down
2 changes: 1 addition & 1 deletion chia/wallet/did_wallet/did_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ async def coin_added(self, coin: Coin, _: uint32, peer: WSChiaConnection, parent
)
)[0]
coin_spend = await fetch_coin_spend_for_coin_state(parent_state, peer)
uncurried = uncurry_puzzle(coin_spend.puzzle_reveal.to_program())
uncurried = uncurry_puzzle(coin_spend.puzzle_reveal)
did_curried_args = match_did_puzzle(uncurried.mod, uncurried.args)
assert did_curried_args is not None
p2_puzzle, recovery_list_hash, num_verification, singleton_struct, metadata = did_curried_args
Expand Down
2 changes: 1 addition & 1 deletion chia/wallet/nft_wallet/singleton_outer_puzzle.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def solve(self, constructor: PuzzleInfo, solver: Solver, inner_puzzle: Program,
also = constructor.also()
if also is not None:
inner_solution = self._solve(also, solver, inner_puzzle, inner_solution)
matched, curried_args = match_singleton_puzzle(uncurry_puzzle(parent_spend.puzzle_reveal.to_program()))
matched, curried_args = match_singleton_puzzle(uncurry_puzzle(parent_spend.puzzle_reveal))
assert matched
_, parent_inner_puzzle = curried_args
return solution_for_singleton(
Expand Down
4 changes: 2 additions & 2 deletions chia/wallet/trading/offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def _get_offered_coins(self) -> Dict[Optional[bytes32], List[Coin]]:
for parent_spend in self._bundle.coin_spends:
coins_for_this_spend: List[Coin] = []

parent_puzzle: UncurriedPuzzle = uncurry_puzzle(parent_spend.puzzle_reveal.to_program())
parent_puzzle: UncurriedPuzzle = uncurry_puzzle(parent_spend.puzzle_reveal)
parent_solution: Program = parent_spend.solution.to_program()
additions: List[Coin] = self._additions[parent_spend.coin]

Expand Down Expand Up @@ -617,7 +617,7 @@ def from_spend_bundle(cls, bundle: SpendBundle) -> Offer:
driver_dict: Dict[bytes32, PuzzleInfo] = {}
leftover_coin_spends: List[CoinSpend] = []
for coin_spend in bundle.coin_spends:
driver = match_puzzle(uncurry_puzzle(coin_spend.puzzle_reveal.to_program()))
driver = match_puzzle(uncurry_puzzle(coin_spend.puzzle_reveal))
if driver is not None:
asset_id = create_asset_id(driver)
assert asset_id is not None
Expand Down
4 changes: 3 additions & 1 deletion chia/wallet/uncurried_puzzle.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from __future__ import annotations

from dataclasses import dataclass
from typing import Union

from chia.types.blockchain_format.program import Program
from chia.types.blockchain_format.serialized_program import SerializedProgram


@dataclass(frozen=True)
Expand All @@ -11,5 +13,5 @@ class UncurriedPuzzle:
args: Program


def uncurry_puzzle(puzzle: Program) -> UncurriedPuzzle:
def uncurry_puzzle(puzzle: Union[Program, SerializedProgram]) -> UncurriedPuzzle:
arvidn marked this conversation as resolved.
Show resolved Hide resolved
return UncurriedPuzzle(*puzzle.uncurry())
4 changes: 2 additions & 2 deletions chia/wallet/vc_wallet/cr_cat_drivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def get_inner_solution(solution: Program) -> Program: # pragma: no cover

@classmethod
def get_current_from_coin_spend(cls: Type[_T_CRCAT], spend: CoinSpend) -> CRCAT: # pragma: no cover
uncurried_puzzle: UncurriedPuzzle = uncurry_puzzle(spend.puzzle_reveal.to_program())
uncurried_puzzle: UncurriedPuzzle = uncurry_puzzle(spend.puzzle_reveal)
first_uncurried_cr_layer: UncurriedPuzzle = uncurry_puzzle(uncurried_puzzle.args.at("rrf"))
second_uncurried_cr_layer: UncurriedPuzzle = uncurry_puzzle(first_uncurried_cr_layer.mod)
lineage_proof = LineageProof.from_program(
Expand Down Expand Up @@ -611,7 +611,7 @@ class CRCATSpend:

@classmethod
def from_coin_spend(cls, spend: CoinSpend) -> CRCATSpend: # pragma: no cover
inner_puzzle: Program = CRCAT.get_inner_puzzle(uncurry_puzzle(spend.puzzle_reveal.to_program()))
inner_puzzle: Program = CRCAT.get_inner_puzzle(uncurry_puzzle(spend.puzzle_reveal))
inner_solution: Program = CRCAT.get_inner_solution(spend.solution.to_program())
inner_conditions: Program = inner_puzzle.run(inner_solution)
return cls(
Expand Down
3 changes: 1 addition & 2 deletions chia/wallet/vc_wallet/vc_drivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,10 +566,9 @@ def get_next_from_coin_spend(cls: Type[_T_VerifiedCredential], parent_spend: Coi

# BEGIN CODE
parent_coin: Coin = parent_spend.coin
puzzle: Program = parent_spend.puzzle_reveal.to_program()
solution: Program = parent_spend.solution.to_program()

singleton: UncurriedPuzzle = uncurry_puzzle(puzzle)
singleton: UncurriedPuzzle = uncurry_puzzle(parent_spend.puzzle_reveal)
launcher_id: bytes32 = bytes32(singleton.args.at("frf").as_atom())
layer_below_singleton: Program = singleton.args.at("rf")
singleton_lineage_proof: LineageProof = LineageProof(
Expand Down
2 changes: 1 addition & 1 deletion chia/wallet/vc_wallet/vc_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ async def add_vc_authorization(
other_spends: List[CoinSpend] = []
spends_to_fix: Dict[bytes32, CoinSpend] = {}
for spend in offer.to_valid_spend().coin_spends:
if CRCAT.is_cr_cat(uncurry_puzzle(spend.puzzle_reveal.to_program()))[0]:
if CRCAT.is_cr_cat(uncurry_puzzle(spend.puzzle_reveal))[0]:
crcat_spend: CRCATSpend = CRCATSpend.from_coin_spend(spend)
if crcat_spend.incomplete:
crcat_spends.append(crcat_spend)
Expand Down
25 changes: 11 additions & 14 deletions chia/wallet/wallet_state_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,18 +803,17 @@ async def determine_coin_type(

coin_spend = await fetch_coin_spend_for_coin_state(parent_coin_state, peer)

puzzle = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
solution = Program.from_bytes(bytes(coin_spend.solution))

uncurried = uncurry_puzzle(puzzle)
uncurried = uncurry_puzzle(coin_spend.puzzle_reveal)

dao_ids = []
wallets = self.wallets.values()
for wallet in wallets:
if wallet.type() == WalletType.DAO.value:
assert isinstance(wallet, DAOWallet)
dao_ids.append(wallet.dao_info.treasury_id)
funding_puzzle_check = match_funding_puzzle(uncurried, solution, coin_state.coin, dao_ids)
funding_puzzle_check = match_funding_puzzle(
uncurried, coin_spend.solution.to_program(), coin_state.coin, dao_ids
)
if funding_puzzle_check:
return await self.get_dao_wallet_from_coinspend_hint(coin_spend, coin_state), None

Expand Down Expand Up @@ -887,8 +886,7 @@ async def determine_coin_type(
return await self.handle_did(did_data, parent_coin_state, coin_state, coin_spend, peer), did_data

# Check if the coin is clawback
solution = coin_spend.solution.to_program()
clawback_coin_data = match_clawback_puzzle(uncurried, puzzle, solution)
clawback_coin_data = match_clawback_puzzle(uncurried, coin_spend.puzzle_reveal, coin_spend.solution)
if clawback_coin_data is not None:
return await self.handle_clawback(clawback_coin_data, coin_state, coin_spend, peer), clawback_coin_data

Expand Down Expand Up @@ -1167,7 +1165,7 @@ async def handle_cat(
is_crcat: bool = False
if cat_puzzle.get_tree_hash() != coin_state.coin.puzzle_hash:
# Check if it is a CRCAT
if CRCAT.is_cr_cat(uncurry_puzzle(Program.from_bytes(bytes(coin_spend.puzzle_reveal)))):
if CRCAT.is_cr_cat(uncurry_puzzle(coin_spend.puzzle_reveal)):
is_crcat = True
else:
return None # pragma: no cover
Expand Down Expand Up @@ -1370,8 +1368,7 @@ async def get_minter_did(self, launcher_coin: Coin, peer: WSChiaConnection) -> O
)
assert did_coin is not None and len(did_coin) == 1 and did_coin[0].spent_height is not None
did_spend = await fetch_coin_spend_for_coin_state(did_coin[0], peer)
puzzle = Program.from_bytes(bytes(did_spend.puzzle_reveal))
uncurried = uncurry_puzzle(puzzle)
uncurried = uncurry_puzzle(did_spend.puzzle_reveal)
did_curried_args = match_did_puzzle(uncurried.mod, uncurried.args)
if did_curried_args is not None:
p2_puzzle, recovery_list_hash, num_verification, singleton_struct, metadata = did_curried_args
Expand Down Expand Up @@ -1884,10 +1881,10 @@ async def _add_coin_states(
# if there is a child coin that is not owned by the wallet.
coin_spend = await fetch_coin_spend_for_coin_state(coin_state, peer)
# Check if the parent coin is a Clawback coin
puzzle: Program = coin_spend.puzzle_reveal.to_program()
solution: Program = coin_spend.solution.to_program()
uncurried = uncurry_puzzle(puzzle)
clawback_metadata = match_clawback_puzzle(uncurried, puzzle, solution)
uncurried = uncurry_puzzle(coin_spend.puzzle_reveal)
clawback_metadata = match_clawback_puzzle(
uncurried, coin_spend.puzzle_reveal, coin_spend.solution
)
if clawback_metadata is not None:
# Add the Clawback coin as the interested coin for the sender
await self.add_interested_coin_ids([coin.name()])
Expand Down
Loading