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 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.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"
def adapt_inner_to_singleton(inner_puzzle: Program) -> Program:
# (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:
@ -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
def launch_conditions_and_coinsol(
coin: Coin,
inner_puzzle: Program,
comment: List[Tuple[str, str]],
amount: uint64,
coin: Coin, inner_puzzle: Program, comment: List[Tuple[str, str]], amount: uint64
) -> Tuple[List[Program], CoinSpend]:
if (amount % 2) == 0:
raise ValueError("Coin amount cannot be even. Subtract one mojo.")
launcher_coin: Coin = generate_launcher_coin(coin, amount)
curried_singleton: Program = SINGLETON_MOD.curry(
(SINGLETON_MOD_HASH, (launcher_coin.name(), SINGLETON_LAUNCHER_HASH)),
inner_puzzle,
launcher_coin = generate_launcher_coin(coin, amount)
curried_singleton = SINGLETON_MOD.curry(
(SINGLETON_MOD_HASH, (launcher_coin.name(), SINGLETON_LAUNCHER_HASH)), inner_puzzle
)
launcher_solution = Program.to(
[
curried_singleton.get_tree_hash(),
amount,
comment,
]
)
create_launcher = Program.to(
[
ConditionOpcode.CREATE_COIN,
SINGLETON_LAUNCHER_HASH,
amount,
],
)
launcher_solution = Program.to([curried_singleton.get_tree_hash(), amount, comment])
create_launcher = Program.to([ConditionOpcode.CREATE_COIN, SINGLETON_LAUNCHER_HASH, amount])
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]
launcher_coin_spend = make_spend(
launcher_coin,
SINGLETON_LAUNCHER,
launcher_solution,
)
launcher_coin_spend = make_spend(launcher_coin, SINGLETON_LAUNCHER, launcher_solution)
return conditions, launcher_coin_spend
# Take a coin solution, return a lineage proof for their child to use in spends
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:
full_puzzle = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
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_hash = inner_puzzle.get_tree_hash()
amount: uint64 = uint64(coin_spend.coin.amount)
amount = uint64(coin_spend.coin.amount)
return LineageProof(
parent_name,
inner_puzzle_hash,
amount,
)
return LineageProof(parent_name, inner_puzzle_hash, amount)
# Return the puzzle reveal of a singleton with specific ID and innerpuz
def puzzle_for_singleton(
launcher_id: bytes32, inner_puz: Program, launcher_hash: bytes32 = SINGLETON_LAUNCHER_HASH
) -> Program:
return SINGLETON_MOD.curry(
(SINGLETON_MOD_HASH, (launcher_id, launcher_hash)),
inner_puz,
)
return SINGLETON_MOD.curry((SINGLETON_MOD_HASH, (launcher_id, launcher_hash)), inner_puz)
# Return a solution to spend a singleton
def solution_for_singleton(
lineage_proof: LineageProof,
amount: uint64,
inner_solution: Program,
) -> Program:
def solution_for_singleton(lineage_proof: LineageProof, amount: uint64, inner_solution: Program) -> Program:
if lineage_proof.inner_puzzle_hash is None:
parent_info = [
lineage_proof.parent_name,
lineage_proof.amount,
]
parent_info = [lineage_proof.parent_name, lineage_proof.amount]
else:
parent_info = [
lineage_proof.parent_name,
lineage_proof.inner_puzzle_hash,
lineage_proof.amount,
]
return Program.to([parent_info, amount, inner_solution])
parent_info = [lineage_proof.parent_name, lineage_proof.inner_puzzle_hash, lineage_proof.amount]
# TODO: Remove cast when we improve typing
return cast(Program, Program.to([parent_info, amount, inner_solution]))
# 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
def pay_to_singleton_or_delay_puzzle(launcher_id: bytes32, delay_time: uint64, delay_ph: bytes32) -> Program:
return P2_SINGLETON_OR_DELAYED_MOD.curry(
SINGLETON_MOD_HASH,
launcher_id,
SINGLETON_LAUNCHER_HASH,
delay_time,
delay_ph,
SINGLETON_MOD_HASH, 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
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
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
@ -321,17 +279,11 @@ def claim_p2_singleton(
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()])
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:
puzzle = pay_to_singleton_or_delay_puzzle(
launcher_id,
delay_time,
delay_ph,
)
puzzle = pay_to_singleton_or_delay_puzzle(launcher_id, delay_time, delay_ph)
claim_coinsol = make_spend(
p2_singleton_coin,
puzzle,
solution_for_p2_singleton(p2_singleton_coin, singleton_inner_puzhash),
p2_singleton_coin, puzzle, solution_for_p2_singleton(p2_singleton_coin, singleton_inner_puzhash)
)
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_m_of_n_delegate_direct
chia.wallet.puzzles.p2_puzzle_hash
chia.wallet.puzzles.singleton_top_layer
chia.wallet.puzzles.tails
chia.wallet.trading.trade_store
chia.wallet.transaction_record