Annotate singleton_top_layer.py (#17358)

Annotate singleton_top_layer.py.
This commit is contained in:
Amine Khaldi 2024-01-25 18:59:33 +01:00 committed by GitHub
parent a3099b03c4
commit 41a09e92f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 78 deletions

View File

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Iterator, List, Optional, Tuple from typing import Iterator, List, Optional, Tuple, cast
from chia.types.blockchain_format.coin import Coin from chia.types.blockchain_format.coin import Coin
from chia.types.blockchain_format.program import Program from chia.types.blockchain_format.program import Program
@ -175,7 +175,8 @@ def generate_launcher_coin(coin: Coin, amount: uint64) -> Coin:
# Wrap inner puzzles that are not singleton specific to strip away "truths" # Wrap inner puzzles that are not singleton specific to strip away "truths"
def adapt_inner_to_singleton(inner_puzzle: Program) -> Program: def adapt_inner_to_singleton(inner_puzzle: Program) -> Program:
# (a (q . inner_puzzle) (r 1)) # (a (q . inner_puzzle) (r 1))
return Program.to([2, (1, inner_puzzle), [6, 1]]) # TODO: Remove cast when we improve typing
return cast(Program, Program.to([2, (1, inner_puzzle), [6, 1]]))
def adapt_inner_puzzle_hash_to_singleton(inner_puzzle_hash: bytes32) -> bytes32: def adapt_inner_puzzle_hash_to_singleton(inner_puzzle_hash: bytes32) -> bytes32:
@ -185,57 +186,34 @@ def adapt_inner_puzzle_hash_to_singleton(inner_puzzle_hash: bytes32) -> bytes32:
# Take standard coin and amount -> launch conditions & launcher coin solution # Take standard coin and amount -> launch conditions & launcher coin solution
def launch_conditions_and_coinsol( def launch_conditions_and_coinsol(
coin: Coin, coin: Coin, inner_puzzle: Program, comment: List[Tuple[str, str]], amount: uint64
inner_puzzle: Program,
comment: List[Tuple[str, str]],
amount: uint64,
) -> Tuple[List[Program], CoinSpend]: ) -> Tuple[List[Program], CoinSpend]:
if (amount % 2) == 0: if (amount % 2) == 0:
raise ValueError("Coin amount cannot be even. Subtract one mojo.") raise ValueError("Coin amount cannot be even. Subtract one mojo.")
launcher_coin: Coin = generate_launcher_coin(coin, amount) launcher_coin = generate_launcher_coin(coin, amount)
curried_singleton: Program = SINGLETON_MOD.curry( curried_singleton = SINGLETON_MOD.curry(
(SINGLETON_MOD_HASH, (launcher_coin.name(), SINGLETON_LAUNCHER_HASH)), (SINGLETON_MOD_HASH, (launcher_coin.name(), SINGLETON_LAUNCHER_HASH)), inner_puzzle
inner_puzzle,
) )
launcher_solution = Program.to( launcher_solution = Program.to([curried_singleton.get_tree_hash(), amount, comment])
[ create_launcher = Program.to([ConditionOpcode.CREATE_COIN, SINGLETON_LAUNCHER_HASH, amount])
curried_singleton.get_tree_hash(),
amount,
comment,
]
)
create_launcher = Program.to(
[
ConditionOpcode.CREATE_COIN,
SINGLETON_LAUNCHER_HASH,
amount,
],
)
assert_launcher_announcement = Program.to( assert_launcher_announcement = Program.to(
[ [ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, std_hash(launcher_coin.name() + launcher_solution.get_tree_hash())]
ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT,
std_hash(launcher_coin.name() + launcher_solution.get_tree_hash()),
],
) )
conditions = [create_launcher, assert_launcher_announcement] conditions = [create_launcher, assert_launcher_announcement]
launcher_coin_spend = make_spend( launcher_coin_spend = make_spend(launcher_coin, SINGLETON_LAUNCHER, launcher_solution)
launcher_coin,
SINGLETON_LAUNCHER,
launcher_solution,
)
return conditions, launcher_coin_spend return conditions, launcher_coin_spend
# Take a coin solution, return a lineage proof for their child to use in spends # Take a coin solution, return a lineage proof for their child to use in spends
def lineage_proof_for_coinsol(coin_spend: CoinSpend) -> LineageProof: def lineage_proof_for_coinsol(coin_spend: CoinSpend) -> LineageProof:
parent_name: bytes32 = coin_spend.coin.parent_coin_info parent_name = coin_spend.coin.parent_coin_info
inner_puzzle_hash: Optional[bytes32] = None inner_puzzle_hash = None
if coin_spend.coin.puzzle_hash != SINGLETON_LAUNCHER_HASH: if coin_spend.coin.puzzle_hash != SINGLETON_LAUNCHER_HASH:
full_puzzle = Program.from_bytes(bytes(coin_spend.puzzle_reveal)) full_puzzle = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
r = full_puzzle.uncurry() r = full_puzzle.uncurry()
@ -244,44 +222,26 @@ def lineage_proof_for_coinsol(coin_spend: CoinSpend) -> LineageProof:
_, inner_puzzle = list(args.as_iter()) _, inner_puzzle = list(args.as_iter())
inner_puzzle_hash = inner_puzzle.get_tree_hash() inner_puzzle_hash = inner_puzzle.get_tree_hash()
amount: uint64 = uint64(coin_spend.coin.amount) amount = uint64(coin_spend.coin.amount)
return LineageProof( return LineageProof(parent_name, inner_puzzle_hash, amount)
parent_name,
inner_puzzle_hash,
amount,
)
# Return the puzzle reveal of a singleton with specific ID and innerpuz # Return the puzzle reveal of a singleton with specific ID and innerpuz
def puzzle_for_singleton( def puzzle_for_singleton(
launcher_id: bytes32, inner_puz: Program, launcher_hash: bytes32 = SINGLETON_LAUNCHER_HASH launcher_id: bytes32, inner_puz: Program, launcher_hash: bytes32 = SINGLETON_LAUNCHER_HASH
) -> Program: ) -> Program:
return SINGLETON_MOD.curry( return SINGLETON_MOD.curry((SINGLETON_MOD_HASH, (launcher_id, launcher_hash)), inner_puz)
(SINGLETON_MOD_HASH, (launcher_id, launcher_hash)),
inner_puz,
)
# Return a solution to spend a singleton # Return a solution to spend a singleton
def solution_for_singleton( def solution_for_singleton(lineage_proof: LineageProof, amount: uint64, inner_solution: Program) -> Program:
lineage_proof: LineageProof,
amount: uint64,
inner_solution: Program,
) -> Program:
if lineage_proof.inner_puzzle_hash is None: if lineage_proof.inner_puzzle_hash is None:
parent_info = [ parent_info = [lineage_proof.parent_name, lineage_proof.amount]
lineage_proof.parent_name,
lineage_proof.amount,
]
else: else:
parent_info = [ parent_info = [lineage_proof.parent_name, lineage_proof.inner_puzzle_hash, lineage_proof.amount]
lineage_proof.parent_name, # TODO: Remove cast when we improve typing
lineage_proof.inner_puzzle_hash, return cast(Program, Program.to([parent_info, amount, inner_solution]))
lineage_proof.amount,
]
return Program.to([parent_info, amount, inner_solution])
# Create a coin that a singleton can claim # Create a coin that a singleton can claim
@ -292,22 +252,20 @@ def pay_to_singleton_puzzle(launcher_id: bytes32) -> Program:
# Create a coin that a singleton can claim or that can be sent to another puzzle after a specified time # Create a coin that a singleton can claim or that can be sent to another puzzle after a specified time
def pay_to_singleton_or_delay_puzzle(launcher_id: bytes32, delay_time: uint64, delay_ph: bytes32) -> Program: def pay_to_singleton_or_delay_puzzle(launcher_id: bytes32, delay_time: uint64, delay_ph: bytes32) -> Program:
return P2_SINGLETON_OR_DELAYED_MOD.curry( return P2_SINGLETON_OR_DELAYED_MOD.curry(
SINGLETON_MOD_HASH, SINGLETON_MOD_HASH, launcher_id, SINGLETON_LAUNCHER_HASH, delay_time, delay_ph
launcher_id,
SINGLETON_LAUNCHER_HASH,
delay_time,
delay_ph,
) )
# Solution for EITHER p2_singleton or the claiming spend case for p2_singleton_or_delayed_puzhash # Solution for EITHER p2_singleton or the claiming spend case for p2_singleton_or_delayed_puzhash
def solution_for_p2_singleton(p2_singleton_coin: Coin, singleton_inner_puzhash: bytes32) -> Program: def solution_for_p2_singleton(p2_singleton_coin: Coin, singleton_inner_puzhash: bytes32) -> Program:
return Program.to([singleton_inner_puzhash, p2_singleton_coin.name()]) # TODO: Remove cast when we improve typing
return cast(Program, Program.to([singleton_inner_puzhash, p2_singleton_coin.name()]))
# Solution for the delayed spend case for p2_singleton_or_delayed_puzhash # Solution for the delayed spend case for p2_singleton_or_delayed_puzhash
def solution_for_p2_delayed_puzzle(output_amount: uint64) -> Program: def solution_for_p2_delayed_puzzle(output_amount: uint64) -> Program:
return Program.to([output_amount, []]) # TODO: Remove cast when we improve typing
return cast(Program, Program.to([output_amount, []]))
# Get announcement conditions for singleton solution and full CoinSpend for the claimed coin # Get announcement conditions for singleton solution and full CoinSpend for the claimed coin
@ -321,17 +279,11 @@ def claim_p2_singleton(
assertion = Program.to([ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, std_hash(p2_singleton_coin.name() + b"$")]) assertion = Program.to([ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, std_hash(p2_singleton_coin.name() + b"$")])
announcement = Program.to([ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT, p2_singleton_coin.name()]) announcement = Program.to([ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT, p2_singleton_coin.name()])
if delay_time is None or delay_ph is None: if delay_time is None or delay_ph is None:
puzzle: Program = pay_to_singleton_puzzle(launcher_id) puzzle = pay_to_singleton_puzzle(launcher_id)
else: else:
puzzle = pay_to_singleton_or_delay_puzzle( puzzle = pay_to_singleton_or_delay_puzzle(launcher_id, delay_time, delay_ph)
launcher_id,
delay_time,
delay_ph,
)
claim_coinsol = make_spend( claim_coinsol = make_spend(
p2_singleton_coin, p2_singleton_coin, puzzle, solution_for_p2_singleton(p2_singleton_coin, singleton_inner_puzhash)
puzzle,
solution_for_p2_singleton(p2_singleton_coin, singleton_inner_puzhash),
) )
return assertion, announcement, claim_coinsol return assertion, announcement, claim_coinsol

View File

@ -30,7 +30,6 @@ chia.wallet.puzzles.p2_delegated_puzzle
chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle
chia.wallet.puzzles.p2_m_of_n_delegate_direct chia.wallet.puzzles.p2_m_of_n_delegate_direct
chia.wallet.puzzles.p2_puzzle_hash chia.wallet.puzzles.p2_puzzle_hash
chia.wallet.puzzles.singleton_top_layer
chia.wallet.puzzles.tails chia.wallet.puzzles.tails
chia.wallet.trading.trade_store chia.wallet.trading.trade_store
chia.wallet.transaction_record chia.wallet.transaction_record