mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-11-29 05:18:11 +03:00
first pass at updating cc_wallet
trades do not work
This commit is contained in:
parent
42e47749c0
commit
0882821c4c
4
.gitignore
vendored
4
.gitignore
vendored
@ -77,6 +77,10 @@ vdf_bench
|
||||
# Offer Files
|
||||
*.offer
|
||||
|
||||
# Compiled CLVM
|
||||
*.hex
|
||||
main.sym
|
||||
|
||||
# Dev config react
|
||||
electron-react/src/dev_config.js
|
||||
# React built app
|
||||
|
@ -4,19 +4,11 @@ from typing import List, Optional, Tuple
|
||||
from src.types.program import Program
|
||||
from src.types.sized_bytes import bytes32
|
||||
from src.util.streamable import streamable, Streamable
|
||||
from src.wallet.cc_wallet import cc_wallet_puzzles
|
||||
from src.wallet.cc_wallet.ccparent import CCParent
|
||||
from src.types.program import Program
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@streamable
|
||||
class CCInfo(Streamable):
|
||||
parent_info: List[Tuple[bytes32, Optional[CCParent]]] # {coin.name(): CCParent}
|
||||
my_colour_name: str
|
||||
|
||||
def puzzle_for_inner_puzzle(self, inner_puzzle: Program) -> Program:
|
||||
genesis_id = bytes.fromhex(self.my_colour_name) if self.my_colour_name else 0
|
||||
return cc_wallet_puzzles.puzzle_for_inner_puzzle(inner_puzzle, genesis_id)
|
||||
|
||||
def genesis_id(self):
|
||||
return self.my_colour_name
|
||||
my_genesis_checker: Optional[Program] # this is the program
|
||||
lineage_proofs: List[Tuple[bytes32, Optional[Program]]] # {coin.name(): lineage_proof}
|
||||
|
@ -2,7 +2,7 @@ import dataclasses
|
||||
|
||||
from typing import Any, List, Optional, Tuple
|
||||
|
||||
from blspy import G2Element
|
||||
from blspy import G2Element, AugSchemeMPL
|
||||
|
||||
from clvm_tools.curry import curry as ct_curry, uncurry
|
||||
|
||||
@ -24,6 +24,9 @@ CC_MOD = load_clvm("cc.clvm", package_or_requirement=__name__)
|
||||
|
||||
ZERO_GENESIS_MOD = load_clvm("zero-genesis.clvm", package_or_requirement=__name__)
|
||||
|
||||
NULL_SIGNATURE = G2Element.generator() * 0
|
||||
|
||||
ANYONE_CAN_SPEND_PUZZLE = Program.to(1) # simply return the conditions
|
||||
|
||||
# information needed to spend a cc
|
||||
# if we ever support more genesis conditions, like a re-issuable coin,
|
||||
@ -164,6 +167,7 @@ def spend_bundle_for_spendable_ccs(
|
||||
genesis_coin_checker: Program,
|
||||
spendable_cc_list: List[SpendableCC],
|
||||
inner_solutions: List[Program],
|
||||
sigs: Optional[List[G2Element]] = []
|
||||
) -> SpendBundle:
|
||||
"""
|
||||
Given a list of `SpendableCC` objects and inner solutions for those objects, create a `SpendBundle`
|
||||
@ -239,8 +243,10 @@ def spend_bundle_for_spendable_ccs(
|
||||
parent_coin, next_coin, output_amount, subtotal
|
||||
)
|
||||
coin_solutions.append(coin_solution)
|
||||
|
||||
return SpendBundle(coin_solutions, NULL_SIGNATURE)
|
||||
if sigs is None or sigs == []:
|
||||
return SpendBundle(coin_solutions, NULL_SIGNATURE)
|
||||
else:
|
||||
return SpendBundle(coin_solutions, AugSchemeMPL.aggregate(sigs))
|
||||
|
||||
|
||||
def is_cc_mod(inner_f: Program):
|
||||
@ -266,6 +272,19 @@ def uncurry_cc(puzzle: Program) -> Optional[Tuple[Program, Program, Program]]:
|
||||
return mod_hash, genesis_coin_checker, inner_puzzle
|
||||
|
||||
|
||||
def get_lineage_proof_from_coin_and_puz(parent_coin, parent_puzzle):
|
||||
r = uncurry_cc(parent_puzzle)
|
||||
if r:
|
||||
mod_hash, genesis_checker, inner_puzzle = r
|
||||
lineage_proof = lineage_proof_for_cc_parent(parent_coin, inner_puzzle.get_tree_hash())
|
||||
else:
|
||||
if parent_coin.amount == 0:
|
||||
lineage_proof = lineage_proof_for_zero(parent_coin)
|
||||
else:
|
||||
lineage_proof = lineage_proof_for_genesis(parent_coin)
|
||||
return lineage_proof
|
||||
|
||||
|
||||
def spendable_cc_list_from_coin_solution(
|
||||
coin_solution: CoinSolution, hash_to_puzzle_f
|
||||
) -> List[SpendableCC]:
|
||||
|
@ -19,13 +19,6 @@ from src.util.json_util import dict_to_json_str
|
||||
from src.util.ints import uint64, uint32
|
||||
from src.wallet.block_record import BlockRecord
|
||||
from src.wallet.cc_wallet.cc_info import CCInfo
|
||||
from src.wallet.cc_wallet.cc_wallet_puzzles import (
|
||||
get_inner_puzzle_hash_from_puzzle,
|
||||
cc_generate_eve_spend,
|
||||
create_spend_for_auditor,
|
||||
create_spend_for_ephemeral,
|
||||
)
|
||||
from src.wallet.cc_wallet.ccparent import CCParent
|
||||
from src.wallet.transaction_record import TransactionRecord
|
||||
from src.wallet.util.wallet_types import WalletType
|
||||
from src.wallet.wallet import Wallet
|
||||
@ -33,13 +26,24 @@ from src.wallet.wallet_coin_record import WalletCoinRecord
|
||||
from src.wallet.wallet_info import WalletInfo
|
||||
from src.wallet.derivation_record import DerivationRecord
|
||||
from src.wallet.cc_wallet import cc_wallet_puzzles
|
||||
from src.wallet.cc_wallet.cc_utils import (
|
||||
SpendableCC,
|
||||
cc_puzzle_for_inner_puzzle,
|
||||
create_genesis_or_zero_coin_checker,
|
||||
cc_puzzle_hash_for_inner_puzzle_hash,
|
||||
cc_puzzle_for_inner_puzzle,
|
||||
spend_bundle_for_spendable_ccs,
|
||||
genesis_coin_id_for_genesis_coin_checker,
|
||||
coin_as_list,
|
||||
lineage_proof_for_genesis,
|
||||
get_lineage_proof_from_coin_and_puz,
|
||||
uncurry_cc,
|
||||
CC_MOD,
|
||||
ZERO_GENESIS_MOD,
|
||||
ANYONE_CAN_SPEND_PUZZLE
|
||||
)
|
||||
from dataclasses import replace
|
||||
|
||||
# TODO: write tests based on wallet tests
|
||||
# TODO: {Matt} compatibility based on deriving innerpuzzle from derivation record
|
||||
# TODO: {Matt} convert this into wallet_state_manager.puzzle_store
|
||||
# TODO: {Matt} add hooks in WebSocketServer for all UI functions
|
||||
|
||||
|
||||
class CCWallet:
|
||||
wallet_state_manager: Any
|
||||
@ -69,7 +73,7 @@ class CCWallet:
|
||||
|
||||
self.wallet_state_manager = wallet_state_manager
|
||||
|
||||
self.cc_info = CCInfo([], "")
|
||||
self.cc_info = CCInfo(None, [])
|
||||
info_as_string = bytes(self.cc_info).hex()
|
||||
self.wallet_info = await wallet_state_manager.user_store.create_wallet(
|
||||
"CC Wallet", WalletType.COLOURED_COIN.value, info_as_string
|
||||
@ -138,7 +142,7 @@ class CCWallet:
|
||||
|
||||
@staticmethod
|
||||
async def create_wallet_for_cc(
|
||||
wallet_state_manager: Any, wallet: Wallet, colour: str, name: str = None
|
||||
wallet_state_manager: Any, wallet: Wallet, genesis_checker_hex: str, name: str = None
|
||||
):
|
||||
|
||||
self = CCWallet()
|
||||
@ -152,7 +156,7 @@ class CCWallet:
|
||||
|
||||
self.wallet_state_manager = wallet_state_manager
|
||||
|
||||
self.cc_info = CCInfo([], colour)
|
||||
self.cc_info = CCInfo(Program.from_bytes(bytes.fromhex(genesis_checker_hex)), [])
|
||||
info_as_string = bytes(self.cc_info).hex()
|
||||
self.wallet_info = await wallet_state_manager.user_store.create_wallet(
|
||||
"CC Wallet", WalletType.COLOURED_COIN.value, info_as_string
|
||||
@ -194,8 +198,8 @@ class CCWallet:
|
||||
|
||||
amount: uint64 = uint64(0)
|
||||
for record in record_list:
|
||||
parent = await self.get_parent_for_coin(record.coin)
|
||||
if parent is not None:
|
||||
lineage = await self.get_lineage_proof_for_coin(record.coin)
|
||||
if lineage is not None:
|
||||
amount = uint64(amount + record.coin.amount)
|
||||
|
||||
self.log.info(
|
||||
@ -235,7 +239,7 @@ class CCWallet:
|
||||
await self.wallet_state_manager.user_store.update_wallet(self.wallet_info)
|
||||
|
||||
def get_colour(self):
|
||||
return self.cc_info.my_colour_name
|
||||
return bytes(self.cc_info.my_genesis_checker).hex()
|
||||
|
||||
async def coin_added(
|
||||
self, coin: Coin, height: int, header_hash: bytes32, removals: List[Coin]
|
||||
@ -245,14 +249,20 @@ class CCWallet:
|
||||
|
||||
search_for_parent: bool = True
|
||||
|
||||
inner_puzzle = await self.inner_puzzle_for_cc_puzzle(coin.puzzle_hash)
|
||||
future_parent = CCParent(
|
||||
coin.parent_coin_info, inner_puzzle.get_tree_hash(), coin.amount
|
||||
inner_puzzle = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash)
|
||||
lineage_proof = Program.to(
|
||||
(
|
||||
1,
|
||||
[
|
||||
coin.parent_coin_info,
|
||||
inner_puzzle.get_tree_hash(),
|
||||
coin.amount,
|
||||
],
|
||||
)
|
||||
)
|
||||
await self.add_lineage(coin.name(), lineage_proof)
|
||||
|
||||
await self.add_parent(coin.name(), future_parent)
|
||||
|
||||
for name, ccparent in self.cc_info.parent_info:
|
||||
for name, lineage_proofs in self.cc_info.lineage_proofs:
|
||||
if coin.parent_coin_info == name:
|
||||
search_for_parent = False
|
||||
break
|
||||
@ -339,20 +349,15 @@ class CCWallet:
|
||||
break
|
||||
|
||||
if coin is not None:
|
||||
if cc_wallet_puzzles.check_is_cc_puzzle(puzzle_program):
|
||||
inner_puzzle_hash = get_inner_puzzle_hash_from_puzzle(
|
||||
puzzle_program
|
||||
)
|
||||
|
||||
mod_hash, genesis_coin_checker, inner_puzzle = uncurry_cc(puzzle_program)
|
||||
if inner_puzzle is not None:
|
||||
self.log.info(
|
||||
f"parent: {coin_name} inner_puzzle for parent is {inner_puzzle_hash.hex()}"
|
||||
f"parent: {coin_name} inner_puzzle for parent is {inner_puzzle}"
|
||||
)
|
||||
|
||||
await self.add_parent(
|
||||
lineage_proof = get_lineage_proof_from_coin_and_puz(coin, puzzle_program)
|
||||
await self.add_lineage(
|
||||
coin_name,
|
||||
CCParent(
|
||||
coin.parent_coin_info, inner_puzzle_hash, coin.amount
|
||||
),
|
||||
lineage_proof
|
||||
)
|
||||
|
||||
return True
|
||||
@ -382,27 +387,15 @@ class CCWallet:
|
||||
async def get_new_puzzlehash(self) -> bytes32:
|
||||
return await self.standard_wallet.get_new_puzzlehash()
|
||||
|
||||
def do_replace(self, sexp, magic, magic_replacement):
|
||||
""" Generic way to replace anything inside a SEXP, not used currentyl """
|
||||
if sexp.listp():
|
||||
return self.do_replace(sexp.first(), magic, magic_replacement).cons(
|
||||
self.do_replace(sexp.rest(), magic, magic_replacement)
|
||||
)
|
||||
if sexp.as_atom() == magic:
|
||||
return sexp.to(magic_replacement)
|
||||
return sexp
|
||||
|
||||
def specific_replace(self, old, magic, magic_replacement):
|
||||
"""binutil.assemble is slow, using this hack to swap inner_puzzle_hash. """
|
||||
new = old.replace(magic, magic_replacement)
|
||||
return new
|
||||
|
||||
def puzzle_for_pk(self, pubkey) -> Program:
|
||||
inner_puzzle = self.standard_wallet.puzzle_for_pk(bytes(pubkey))
|
||||
inner_puzzle_hash = inner_puzzle.get_tree_hash()
|
||||
cc_puzzle: Program = self.cc_info.puzzle_for_inner_puzzle(inner_puzzle)
|
||||
inner_puzzle = self.standard_wallet.puzzle_for_pk(
|
||||
bytes(pubkey)
|
||||
)
|
||||
cc_puzzle: Program = cc_puzzle_for_inner_puzzle(
|
||||
CC_MOD, self.cc_info.my_genesis_checker, inner_puzzle
|
||||
)
|
||||
self.base_puzzle_program = bytes(cc_puzzle)
|
||||
self.base_inner_puzzle_hash = inner_puzzle_hash
|
||||
self.base_inner_puzzle_hash = inner_puzzle.get_tree_hash()
|
||||
return cc_puzzle
|
||||
|
||||
async def get_new_cc_puzzle_hash(self):
|
||||
@ -416,6 +409,8 @@ class CCWallet:
|
||||
async def generate_zero_val_coin(
|
||||
self, send=True, exclude: List[Coin] = None
|
||||
) -> Optional[SpendBundle]:
|
||||
if self.cc_info.my_genesis_checker is None:
|
||||
return None
|
||||
if exclude is None:
|
||||
exclude = []
|
||||
coins = await self.standard_wallet.select_coins(0, exclude)
|
||||
@ -425,33 +420,31 @@ class CCWallet:
|
||||
origin = coins.copy().pop()
|
||||
origin_id = origin.name()
|
||||
|
||||
cc_inner_puzzle = await self.get_new_inner_puzzle()
|
||||
cc_inner_puzzle_hash = cc_inner_puzzle.get_tree_hash()
|
||||
|
||||
cc_puzzle = self.cc_info.puzzle_for_inner_puzzle(cc_inner_puzzle)
|
||||
cc_puzzle_hash = cc_puzzle.get_tree_hash()
|
||||
cc_inner = await self.get_new_inner_hash()
|
||||
cc_puzzle_hash: Program = cc_puzzle_hash_for_inner_puzzle_hash(
|
||||
CC_MOD, self.cc_info.my_genesis_checker, cc_inner
|
||||
)
|
||||
|
||||
tx = await self.standard_wallet.generate_signed_transaction(
|
||||
uint64(0), cc_puzzle_hash, uint64(0), origin_id, coins
|
||||
)
|
||||
full_spend = tx.spend_bundle
|
||||
self.log.info(f"Generate zero val coin: cc_puzzle_hash is {cc_puzzle_hash}")
|
||||
|
||||
# generate eve coin so we can add future lineage_proofs even if we don't eve spend
|
||||
eve_coin = Coin(origin_id, cc_puzzle_hash, uint64(0))
|
||||
if tx is None or tx.spend_bundle is None:
|
||||
return None
|
||||
|
||||
genesis_id = bytes.fromhex(self.cc_info.my_colour_name)
|
||||
eve_spend = cc_generate_eve_spend(eve_coin, cc_inner_puzzle, genesis_id)
|
||||
full_spend = SpendBundle.aggregate([tx.spend_bundle, eve_spend])
|
||||
|
||||
future_parent = CCParent(
|
||||
eve_coin.parent_coin_info, cc_inner_puzzle_hash, eve_coin.amount
|
||||
)
|
||||
eve_parent = CCParent(
|
||||
origin.parent_coin_info, origin.puzzle_hash, origin.amount
|
||||
)
|
||||
|
||||
await self.add_parent(eve_coin.name(), future_parent)
|
||||
await self.add_parent(eve_coin.parent_coin_info, eve_parent)
|
||||
await self.add_lineage(eve_coin.name(), Program.to(
|
||||
(
|
||||
1,
|
||||
[
|
||||
eve_coin.parent_coin_info,
|
||||
cc_inner,
|
||||
eve_coin.amount
|
||||
],
|
||||
)
|
||||
))
|
||||
await self.add_lineage(eve_coin.parent_coin_info, Program.to((0, [coin_as_list(origin), 1])))
|
||||
|
||||
if send:
|
||||
regular_record = TransactionRecord(
|
||||
@ -540,8 +533,8 @@ class CCWallet:
|
||||
)
|
||||
|
||||
for record in record_list:
|
||||
parent = await self.get_parent_for_coin(record.coin)
|
||||
if parent is not None:
|
||||
lineage = await self.get_lineage_proof_for_coin(record.coin)
|
||||
if lineage is not None:
|
||||
result.append(record)
|
||||
|
||||
return result
|
||||
@ -607,20 +600,18 @@ class CCWallet:
|
||||
sigs.append(signature)
|
||||
return sigs
|
||||
|
||||
async def inner_puzzle_for_cc_puzzle(self, cc_hash: bytes32) -> Program:
|
||||
async def inner_puzzle_for_cc_puzhash(self, cc_hash: bytes32) -> Program:
|
||||
record: DerivationRecord = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(
|
||||
cc_hash.hex()
|
||||
)
|
||||
inner_puzzle: Program = self.standard_wallet.puzzle_for_pk(bytes(record.pubkey))
|
||||
return inner_puzzle
|
||||
|
||||
async def get_parent_for_coin(self, coin) -> Optional[CCParent]:
|
||||
parent_info = None
|
||||
for name, ccparent in self.cc_info.parent_info:
|
||||
async def get_lineage_proof_for_coin(self, coin) -> Optional[Program]:
|
||||
for name, proof in self.cc_info.lineage_proofs:
|
||||
if name == coin.parent_coin_info:
|
||||
parent_info = ccparent
|
||||
|
||||
return parent_info
|
||||
return proof
|
||||
return None
|
||||
|
||||
async def generate_signed_transaction(
|
||||
self,
|
||||
@ -643,122 +634,31 @@ class CCWallet:
|
||||
total_amount = sum([x.amount for x in selected_coins])
|
||||
change = total_amount - amount
|
||||
|
||||
# first coin becomes the auditor special case
|
||||
auditor = selected_coins.pop()
|
||||
puzzle_hash = auditor.puzzle_hash
|
||||
inner_puzzle: Program = await self.inner_puzzle_for_cc_puzzle(puzzle_hash)
|
||||
|
||||
auditor_info = (
|
||||
auditor.parent_coin_info,
|
||||
inner_puzzle.get_tree_hash(),
|
||||
auditor.amount,
|
||||
)
|
||||
list_of_solutions = []
|
||||
|
||||
# auditees should be (primary_input, innerpuzhash, coin_amount, output_amount)
|
||||
auditees = [
|
||||
(
|
||||
auditor.parent_coin_info,
|
||||
inner_puzzle.get_tree_hash(),
|
||||
auditor.amount,
|
||||
total_amount,
|
||||
)
|
||||
]
|
||||
for coin in selected_coins:
|
||||
coin_inner_puzzle: Program = await self.inner_puzzle_for_cc_puzzle(
|
||||
coin.puzzle_hash
|
||||
)
|
||||
auditees.append(
|
||||
(
|
||||
coin.parent_coin_info,
|
||||
coin_inner_puzzle[coin],
|
||||
coin.amount,
|
||||
0,
|
||||
)
|
||||
)
|
||||
|
||||
primaries = [{"puzzlehash": to_address, "amount": amount}]
|
||||
if change > 0:
|
||||
changepuzzlehash = await self.get_new_inner_hash()
|
||||
primaries.append({"puzzlehash": changepuzzlehash, "amount": change})
|
||||
|
||||
innersol = self.standard_wallet.make_solution(primaries=primaries)
|
||||
coin = selected_coins.pop()
|
||||
inner_puzzle = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash)
|
||||
genesis_id = genesis_coin_id_for_genesis_coin_checker(self.cc_info.my_genesis_checker)
|
||||
innersol_list = [innersol]
|
||||
|
||||
sigs = sigs + await self.get_sigs(inner_puzzle, innersol)
|
||||
parent_info = await self.get_parent_for_coin(auditor)
|
||||
assert parent_info is not None
|
||||
lineage_proof = await self.get_lineage_proof_for_coin(coin)
|
||||
assert lineage_proof is not None
|
||||
spendable_cc_list = [SpendableCC(coin, genesis_id, inner_puzzle, lineage_proof)]
|
||||
assert self.cc_info.my_genesis_checker is not None
|
||||
|
||||
solution = cc_wallet_puzzles.cc_make_solution(
|
||||
self.cc_info.my_colour_name,
|
||||
(
|
||||
parent_info.parent_name,
|
||||
parent_info.inner_puzzle_hash,
|
||||
parent_info.amount,
|
||||
),
|
||||
auditor.amount,
|
||||
inner_puzzle,
|
||||
innersol,
|
||||
auditor_info,
|
||||
auditees,
|
||||
False,
|
||||
)
|
||||
|
||||
puzzle = self.cc_info.puzzle_for_inner_puzzle(inner_puzzle)
|
||||
|
||||
main_coin_solution = CoinSolution(
|
||||
auditor,
|
||||
Program.to([puzzle, solution]),
|
||||
)
|
||||
list_of_solutions.append(main_coin_solution)
|
||||
# main = SpendBundle([main_coin_solution], ZERO96)
|
||||
|
||||
ephemeral_coin_solution = create_spend_for_ephemeral(
|
||||
auditor, auditor, total_amount
|
||||
)
|
||||
list_of_solutions.append(ephemeral_coin_solution)
|
||||
# eph = SpendBundle([ephemeral_coin_solution], ZERO96)
|
||||
|
||||
auditor_coin_colution = create_spend_for_auditor(auditor, auditor)
|
||||
list_of_solutions.append(auditor_coin_colution)
|
||||
# aud = SpendBundle([auditor_coin_colution], ZERO96)
|
||||
|
||||
# loop through remaining spends, treating them as aggregatees
|
||||
for coin in selected_coins:
|
||||
coin_inner_puzzle = await self.inner_puzzle_for_cc_puzzle(coin.puzzle_hash)
|
||||
coin_inner_puzzle = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash)
|
||||
innersol = self.standard_wallet.make_solution()
|
||||
innersol_list.append(innersol)
|
||||
parent_info = await self.get_parent_for_coin(coin)
|
||||
assert parent_info is not None
|
||||
sigs = sigs + await self.get_sigs(coin_inner_puzzle, innersol)
|
||||
|
||||
solution = cc_wallet_puzzles.cc_make_solution(
|
||||
self.cc_info.my_colour_name,
|
||||
(
|
||||
parent_info.parent_name,
|
||||
parent_info.inner_puzzle_hash,
|
||||
parent_info.amount,
|
||||
),
|
||||
coin.amount,
|
||||
coin_inner_puzzle,
|
||||
innersol,
|
||||
auditor_info,
|
||||
None,
|
||||
)
|
||||
list_of_solutions.append(
|
||||
CoinSolution(
|
||||
coin,
|
||||
Program.to(
|
||||
[
|
||||
self.cc_info.puzzle_for_inner_puzzle(coin_inner_puzzle),
|
||||
solution,
|
||||
]
|
||||
),
|
||||
)
|
||||
)
|
||||
list_of_solutions.append(create_spend_for_ephemeral(coin, auditor, 0))
|
||||
list_of_solutions.append(create_spend_for_auditor(auditor, coin))
|
||||
|
||||
aggsig = AugSchemeMPL.aggregate(sigs)
|
||||
spend_bundle = SpendBundle(list_of_solutions, aggsig)
|
||||
|
||||
spend_bundle = spend_bundle_for_spendable_ccs(CC_MOD, self.cc_info.my_genesis_checker, spendable_cc_list, innersol_list, sigs)
|
||||
tx_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=uint64(int(time.time())),
|
||||
@ -778,11 +678,13 @@ class CCWallet:
|
||||
|
||||
return tx_record
|
||||
|
||||
async def add_parent(self, name: bytes32, parent: Optional[CCParent]):
|
||||
self.log.info(f"Adding parent {name}: {parent}")
|
||||
current_list = self.cc_info.parent_info.copy()
|
||||
current_list.append((name, parent))
|
||||
cc_info: CCInfo = CCInfo(current_list, self.cc_info.my_colour_name)
|
||||
async def add_lineage(self, name: bytes32, lineage: Optional[Program]):
|
||||
self.log.info(f"Adding parent {name}: {lineage}")
|
||||
current_list = self.cc_info.lineage_proofs.copy()
|
||||
current_list.append((name, lineage))
|
||||
cc_info: CCInfo = CCInfo(
|
||||
self.cc_info.my_genesis_checker, current_list
|
||||
)
|
||||
await self.save_info(cc_info)
|
||||
|
||||
async def save_info(self, cc_info: CCInfo):
|
||||
@ -803,32 +705,27 @@ class CCWallet:
|
||||
|
||||
origin = coins.copy().pop()
|
||||
origin_id = origin.name()
|
||||
# self.add_parent(origin_id, origin_id)
|
||||
|
||||
cc_info: CCInfo = CCInfo([], origin_id.hex())
|
||||
await self.save_info(cc_info)
|
||||
cc_inner_hash = await self.get_new_inner_hash()
|
||||
await self.add_lineage(origin_id, Program.to((0, [coin_as_list(origin), 0])))
|
||||
genesis_coin_checker = create_genesis_or_zero_coin_checker(origin_id)
|
||||
|
||||
cc_inner_puzzle = await self.get_new_inner_puzzle()
|
||||
cc_puzzle = cc_wallet_puzzles.puzzle_for_inner_puzzle(
|
||||
cc_inner_puzzle, origin_id
|
||||
minted_cc_puzzle_hash = cc_puzzle_hash_for_inner_puzzle_hash(
|
||||
CC_MOD, genesis_coin_checker, cc_inner_hash
|
||||
)
|
||||
cc_puzzle_hash = cc_puzzle.get_tree_hash()
|
||||
|
||||
tx_record: Optional[
|
||||
TransactionRecord
|
||||
] = await self.standard_wallet.generate_signed_transaction(
|
||||
amount, cc_puzzle_hash, uint64(0), origin_id, coins
|
||||
amount, minted_cc_puzzle_hash, uint64(0), origin_id, coins
|
||||
)
|
||||
self.log.info(f"cc_puzzle_hash is {cc_puzzle_hash}")
|
||||
eve_coin = Coin(origin_id, cc_puzzle_hash, amount)
|
||||
if tx_record is None or tx_record.spend_bundle is None:
|
||||
return None
|
||||
|
||||
eve_spend = cc_generate_eve_spend(eve_coin, cc_inner_puzzle, origin_id)
|
||||
|
||||
full_spend = SpendBundle.aggregate([tx_record.spend_bundle, eve_spend])
|
||||
return full_spend
|
||||
lineage_proofs = [(origin_id, lineage_proof_for_genesis(origin))]
|
||||
cc_info: CCInfo = CCInfo(genesis_coin_checker, lineage_proofs)
|
||||
await self.save_info(cc_info)
|
||||
return tx_record.spend_bundle
|
||||
|
||||
"""
|
||||
async def create_spend_bundle_relative_amount(
|
||||
self, cc_amount, zero_coin: Coin = None
|
||||
):
|
||||
@ -862,7 +759,7 @@ class CCWallet:
|
||||
output_created = coin
|
||||
else:
|
||||
innersol = self.standard_wallet.make_solution()
|
||||
innerpuz: Program = await self.inner_puzzle_for_cc_puzzle(coin.puzzle_hash)
|
||||
innerpuz: Program = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash)
|
||||
|
||||
parent_info = await self.get_parent_for_coin(coin)
|
||||
assert parent_info is not None
|
||||
@ -894,8 +791,4 @@ class CCWallet:
|
||||
spend_bundle = SpendBundle(list_of_solutions, aggsig)
|
||||
return spend_bundle
|
||||
|
||||
# Create an offer spend bundle for chia given an amount of relative change (i.e -400 or 1000)
|
||||
# This is to be aggregated together with a coloured coin offer to ensure that the trade happens
|
||||
async def create_spend_bundle_relative_chia(self, chia_amount: uint64):
|
||||
self.log.error("Not implemented")
|
||||
# TODO MATT: Implement
|
||||
"""
|
||||
|
@ -1450,7 +1450,7 @@ class WalletStateManager:
|
||||
for wallet_id in self.wallets:
|
||||
wallet = self.wallets[wallet_id]
|
||||
if wallet.wallet_info.type == WalletType.COLOURED_COIN.value:
|
||||
if wallet.cc_info.genesis_id() == colour:
|
||||
if bytes(wallet.cc_info.my_genesis_checker).hex() == colour:
|
||||
return wallet
|
||||
return None
|
||||
|
||||
|
@ -103,13 +103,14 @@ class TestCCWallet:
|
||||
await time_out_assert(15, cc_wallet.get_confirmed_balance, 100)
|
||||
await time_out_assert(15, cc_wallet.get_unconfirmed_balance, 100)
|
||||
|
||||
colour = cc_wallet.cc_info.genesis_id()
|
||||
assert cc_wallet.cc_info.my_genesis_checker is not None
|
||||
colour = cc_wallet.get_colour()
|
||||
|
||||
cc_wallet_2: CCWallet = await CCWallet.create_wallet_for_cc(
|
||||
wallet_node_2.wallet_state_manager, wallet2, colour
|
||||
)
|
||||
|
||||
assert cc_wallet.cc_info.genesis_id() == cc_wallet_2.cc_info.genesis_id()
|
||||
assert cc_wallet.cc_info.my_genesis_checker == cc_wallet_2.cc_info.my_genesis_checker
|
||||
|
||||
cc_2_hash = await cc_wallet_2.get_new_inner_hash()
|
||||
tx_record = await cc_wallet.generate_signed_transaction(uint64(60), cc_2_hash)
|
||||
@ -206,13 +207,14 @@ class TestCCWallet:
|
||||
await time_out_assert(15, cc_wallet.get_confirmed_balance, 100)
|
||||
await time_out_assert(15, cc_wallet.get_unconfirmed_balance, 100)
|
||||
|
||||
colour = cc_wallet.cc_info.genesis_id()
|
||||
assert cc_wallet.cc_info.my_genesis_checker is not None
|
||||
colour = cc_wallet.get_colour()
|
||||
|
||||
cc_wallet_2: CCWallet = await CCWallet.create_wallet_for_cc(
|
||||
wallet_node_2.wallet_state_manager, wallet2, colour
|
||||
)
|
||||
|
||||
assert cc_wallet.cc_info.genesis_id() == cc_wallet_2.cc_info.genesis_id()
|
||||
assert cc_wallet.cc_info.my_genesis_checker == cc_wallet_2.cc_info.my_genesis_checker
|
||||
|
||||
await cc_wallet_2.generate_zero_val_coin()
|
||||
|
||||
@ -264,14 +266,14 @@ class TestCCWallet:
|
||||
await time_out_assert(15, cc_wallet.get_confirmed_balance, 100)
|
||||
await time_out_assert(15, cc_wallet.get_unconfirmed_balance, 100)
|
||||
|
||||
assert cc_wallet.cc_info.genesis_id() is not None
|
||||
colour = cc_wallet.cc_info.genesis_id()
|
||||
assert cc_wallet.cc_info.my_genesis_checker is not None
|
||||
colour = cc_wallet.get_colour()
|
||||
|
||||
cc_wallet_2: CCWallet = await CCWallet.create_wallet_for_cc(
|
||||
wallet_node_2.wallet_state_manager, wallet2, colour
|
||||
)
|
||||
|
||||
assert cc_wallet.cc_info.genesis_id() == cc_wallet_2.cc_info.genesis_id()
|
||||
assert cc_wallet.cc_info.my_genesis_checker == cc_wallet_2.cc_info.my_genesis_checker
|
||||
|
||||
cc_2_hash = await cc_wallet_2.get_new_inner_hash()
|
||||
tx_record = await cc_wallet.generate_signed_transaction(uint64(60), cc_2_hash)
|
||||
|
Loading…
Reference in New Issue
Block a user