mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-20 16:08:51 +03:00
Rename coin solution to coin spend (#6841)
* Rename `CoinSolution` as `CoinSpend` everywhere. * Run `black` everywhere.
This commit is contained in:
parent
efd401ee35
commit
6cf29102f9
@ -6,21 +6,21 @@ from clvm_tools import binutils
|
||||
|
||||
from chia.full_node.generator import create_compressed_generator
|
||||
from chia.types.blockchain_format.program import SerializedProgram, Program
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.generator_types import BlockGenerator, CompressorArg
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.byte_types import hexstr_to_bytes
|
||||
from chia.util.ints import uint32, uint64
|
||||
|
||||
|
||||
def spend_bundle_to_serialized_coin_solution_entry_list(bundle: SpendBundle) -> bytes:
|
||||
def spend_bundle_to_serialized_coin_spend_entry_list(bundle: SpendBundle) -> bytes:
|
||||
r = b""
|
||||
for coin_solution in bundle.coin_solutions:
|
||||
for coin_spend in bundle.coin_spends:
|
||||
r += b"\xff"
|
||||
r += b"\xff" + SExp.to(coin_solution.coin.parent_coin_info).as_bin()
|
||||
r += b"\xff" + bytes(coin_solution.puzzle_reveal)
|
||||
r += b"\xff" + SExp.to(coin_solution.coin.amount).as_bin()
|
||||
r += b"\xff" + bytes(coin_solution.solution)
|
||||
r += b"\xff" + SExp.to(coin_spend.coin.parent_coin_info).as_bin()
|
||||
r += b"\xff" + bytes(coin_spend.puzzle_reveal)
|
||||
r += b"\xff" + SExp.to(coin_spend.coin.amount).as_bin()
|
||||
r += b"\xff" + bytes(coin_spend.solution)
|
||||
r += b"\x80"
|
||||
r += b"\x80"
|
||||
return r
|
||||
@ -30,7 +30,7 @@ def simple_solution_generator(bundle: SpendBundle) -> BlockGenerator:
|
||||
"""
|
||||
Simply quotes the solutions we know.
|
||||
"""
|
||||
cse_list = spend_bundle_to_serialized_coin_solution_entry_list(bundle)
|
||||
cse_list = spend_bundle_to_serialized_coin_spend_entry_list(bundle)
|
||||
block_program = b"\xff"
|
||||
|
||||
block_program += SExp.to(binutils.assemble("#q")).as_bin()
|
||||
@ -72,11 +72,11 @@ def compress_cse_puzzle(puzzle: SerializedProgram) -> Optional[bytes]:
|
||||
return match_standard_transaction_exactly_and_return_pubkey(puzzle)
|
||||
|
||||
|
||||
def compress_coin_solution(coin_solution: CoinSolution):
|
||||
compressed_puzzle = compress_cse_puzzle(coin_solution.puzzle_reveal)
|
||||
def compress_coin_spend(coin_spend: CoinSpend):
|
||||
compressed_puzzle = compress_cse_puzzle(coin_spend.puzzle_reveal)
|
||||
return [
|
||||
[coin_solution.coin.parent_coin_info, coin_solution.coin.amount],
|
||||
[compressed_puzzle, Program.from_bytes(bytes(coin_solution.solution))],
|
||||
[coin_spend.coin.parent_coin_info, coin_spend.coin.amount],
|
||||
[compressed_puzzle, Program.from_bytes(bytes(coin_spend.solution))],
|
||||
]
|
||||
|
||||
|
||||
@ -86,20 +86,20 @@ def puzzle_suitable_for_compression(puzzle: SerializedProgram) -> bool:
|
||||
|
||||
def bundle_suitable_for_compression(bundle: SpendBundle):
|
||||
ok = []
|
||||
for coin_solution in bundle.coin_solutions:
|
||||
ok.append(puzzle_suitable_for_compression(coin_solution.puzzle_reveal))
|
||||
for coin_spend in bundle.coin_spends:
|
||||
ok.append(puzzle_suitable_for_compression(coin_spend.puzzle_reveal))
|
||||
return all(ok)
|
||||
|
||||
|
||||
def compressed_coin_solution_entry_list(bundle: SpendBundle) -> List:
|
||||
def compressed_coin_spend_entry_list(bundle: SpendBundle) -> List:
|
||||
compressed_cse_list: List[List[Union[List[uint64], List[Union[bytes, None, Program]]]]] = []
|
||||
for coin_solution in bundle.coin_solutions:
|
||||
compressed_cse_list.append(compress_coin_solution(coin_solution))
|
||||
for coin_spend in bundle.coin_spends:
|
||||
compressed_cse_list.append(compress_coin_spend(coin_spend))
|
||||
return compressed_cse_list
|
||||
|
||||
|
||||
def compressed_spend_bundle_solution(original_generator_params: CompressorArg, bundle: SpendBundle) -> BlockGenerator:
|
||||
compressed_cse_list = compressed_coin_solution_entry_list(bundle)
|
||||
compressed_cse_list = compressed_coin_spend_entry_list(bundle)
|
||||
return create_compressed_generator(original_generator_params, compressed_cse_list)
|
||||
|
||||
|
||||
|
@ -10,10 +10,10 @@ GENERATOR_MOD = get_generator()
|
||||
|
||||
DECOMPRESS_BLOCK = load_clvm("block_program_zero.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
DECOMPRESS_PUZZLE = load_clvm("decompress_puzzle.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
# DECOMPRESS_CSE = load_clvm("decompress_coin_solution_entry.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
# DECOMPRESS_CSE = load_clvm("decompress_coin_spend_entry.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
|
||||
DECOMPRESS_CSE_WITH_PREFIX = load_clvm(
|
||||
"decompress_coin_solution_entry_with_prefix.clvm", package_or_requirement="chia.wallet.puzzles"
|
||||
"decompress_coin_spend_entry_with_prefix.clvm", package_or_requirement="chia.wallet.puzzles"
|
||||
)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -12,7 +12,7 @@ from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program, SerializedProgram
|
||||
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.wallet.puzzles.load_clvm import load_clvm
|
||||
from chia.wallet.puzzles.singleton_top_layer import puzzle_for_singleton
|
||||
|
||||
@ -94,7 +94,7 @@ def launcher_id_to_p2_puzzle_hash(launcher_id: bytes32, seconds_delay: uint64, d
|
||||
).get_tree_hash()
|
||||
|
||||
|
||||
def get_delayed_puz_info_from_launcher_spend(coinsol: CoinSolution) -> Tuple[uint64, bytes32]:
|
||||
def get_delayed_puz_info_from_launcher_spend(coinsol: CoinSpend) -> Tuple[uint64, bytes32]:
|
||||
extra_data = Program.from_bytes(bytes(coinsol.solution)).rest().rest().first()
|
||||
# Extra data is (pool_state delayed_puz_info)
|
||||
# Delayed puz info is (seconds delayed_puzzle_hash)
|
||||
@ -151,14 +151,14 @@ def is_pool_member_inner_puzzle(inner_puzzle: Program) -> bool:
|
||||
# If you are currently a waiting inner puzzle, then it will look at your target_state to determine the next
|
||||
# inner puzzle hash to go to. The member inner puzzle is already committed to its next puzzle hash.
|
||||
def create_travel_spend(
|
||||
last_coin_solution: CoinSolution,
|
||||
last_coin_spend: CoinSpend,
|
||||
launcher_coin: Coin,
|
||||
current: PoolState,
|
||||
target: PoolState,
|
||||
genesis_challenge: bytes32,
|
||||
delay_time: uint64,
|
||||
delay_ph: bytes32,
|
||||
) -> Tuple[CoinSolution, Program]:
|
||||
) -> Tuple[CoinSpend, Program]:
|
||||
inner_puzzle: Program = pool_state_to_inner_puzzle(
|
||||
current,
|
||||
launcher_coin.name(),
|
||||
@ -187,27 +187,27 @@ def create_travel_spend(
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
current_singleton: Optional[Coin] = get_most_recent_singleton_coin_from_coin_solution(last_coin_solution)
|
||||
current_singleton: Optional[Coin] = get_most_recent_singleton_coin_from_coin_spend(last_coin_spend)
|
||||
assert current_singleton is not None
|
||||
|
||||
if current_singleton.parent_coin_info == launcher_coin.name():
|
||||
parent_info_list = Program.to([launcher_coin.parent_coin_info, launcher_coin.amount])
|
||||
else:
|
||||
p = Program.from_bytes(bytes(last_coin_solution.puzzle_reveal))
|
||||
last_coin_solution_inner_puzzle: Optional[Program] = get_inner_puzzle_from_puzzle(p)
|
||||
assert last_coin_solution_inner_puzzle is not None
|
||||
p = Program.from_bytes(bytes(last_coin_spend.puzzle_reveal))
|
||||
last_coin_spend_inner_puzzle: Optional[Program] = get_inner_puzzle_from_puzzle(p)
|
||||
assert last_coin_spend_inner_puzzle is not None
|
||||
parent_info_list = Program.to(
|
||||
[
|
||||
last_coin_solution.coin.parent_coin_info,
|
||||
last_coin_solution_inner_puzzle.get_tree_hash(),
|
||||
last_coin_solution.coin.amount,
|
||||
last_coin_spend.coin.parent_coin_info,
|
||||
last_coin_spend_inner_puzzle.get_tree_hash(),
|
||||
last_coin_spend.coin.amount,
|
||||
]
|
||||
)
|
||||
full_solution: Program = Program.to([parent_info_list, current_singleton.amount, inner_sol])
|
||||
full_puzzle: Program = create_full_puzzle(inner_puzzle, launcher_coin.name())
|
||||
|
||||
return (
|
||||
CoinSolution(
|
||||
CoinSpend(
|
||||
current_singleton,
|
||||
SerializedProgram.from_program(full_puzzle),
|
||||
SerializedProgram.from_program(full_solution),
|
||||
@ -217,14 +217,14 @@ def create_travel_spend(
|
||||
|
||||
|
||||
def create_absorb_spend(
|
||||
last_coin_solution: CoinSolution,
|
||||
last_coin_spend: CoinSpend,
|
||||
current_state: PoolState,
|
||||
launcher_coin: Coin,
|
||||
height: uint32,
|
||||
genesis_challenge: bytes32,
|
||||
delay_time: uint64,
|
||||
delay_ph: bytes32,
|
||||
) -> List[CoinSolution]:
|
||||
) -> List[CoinSpend]:
|
||||
inner_puzzle: Program = pool_state_to_inner_puzzle(
|
||||
current_state, launcher_coin.name(), genesis_challenge, delay_time, delay_ph
|
||||
)
|
||||
@ -238,24 +238,24 @@ def create_absorb_spend(
|
||||
else:
|
||||
raise ValueError
|
||||
# full sol = (parent_info, my_amount, inner_solution)
|
||||
coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_solution(last_coin_solution)
|
||||
coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_spend(last_coin_spend)
|
||||
assert coin is not None
|
||||
|
||||
if coin.parent_coin_info == launcher_coin.name():
|
||||
parent_info: Program = Program.to([launcher_coin.parent_coin_info, launcher_coin.amount])
|
||||
else:
|
||||
p = Program.from_bytes(bytes(last_coin_solution.puzzle_reveal))
|
||||
last_coin_solution_inner_puzzle: Optional[Program] = get_inner_puzzle_from_puzzle(p)
|
||||
assert last_coin_solution_inner_puzzle is not None
|
||||
p = Program.from_bytes(bytes(last_coin_spend.puzzle_reveal))
|
||||
last_coin_spend_inner_puzzle: Optional[Program] = get_inner_puzzle_from_puzzle(p)
|
||||
assert last_coin_spend_inner_puzzle is not None
|
||||
parent_info = Program.to(
|
||||
[
|
||||
last_coin_solution.coin.parent_coin_info,
|
||||
last_coin_solution_inner_puzzle.get_tree_hash(),
|
||||
last_coin_solution.coin.amount,
|
||||
last_coin_spend.coin.parent_coin_info,
|
||||
last_coin_spend_inner_puzzle.get_tree_hash(),
|
||||
last_coin_spend.coin.amount,
|
||||
]
|
||||
)
|
||||
full_solution: SerializedProgram = SerializedProgram.from_program(
|
||||
Program.to([parent_info, last_coin_solution.coin.amount, inner_sol])
|
||||
Program.to([parent_info, last_coin_spend.coin.amount, inner_sol])
|
||||
)
|
||||
full_puzzle: SerializedProgram = SerializedProgram.from_program(
|
||||
create_full_puzzle(inner_puzzle, launcher_coin.name())
|
||||
@ -274,14 +274,14 @@ def create_absorb_spend(
|
||||
assert full_puzzle.get_tree_hash() == coin.puzzle_hash
|
||||
assert get_inner_puzzle_from_puzzle(Program.from_bytes(bytes(full_puzzle))) is not None
|
||||
|
||||
coin_solutions = [
|
||||
CoinSolution(coin, full_puzzle, full_solution),
|
||||
CoinSolution(reward_coin, p2_singleton_puzzle, p2_singleton_solution),
|
||||
coin_spends = [
|
||||
CoinSpend(coin, full_puzzle, full_solution),
|
||||
CoinSpend(reward_coin, p2_singleton_puzzle, p2_singleton_solution),
|
||||
]
|
||||
return coin_solutions
|
||||
return coin_spends
|
||||
|
||||
|
||||
def get_most_recent_singleton_coin_from_coin_solution(coin_sol: CoinSolution) -> Optional[Coin]:
|
||||
def get_most_recent_singleton_coin_from_coin_spend(coin_sol: CoinSpend) -> Optional[Coin]:
|
||||
additions: List[Coin] = coin_sol.additions()
|
||||
for coin in additions:
|
||||
if coin.amount % 2 == 1:
|
||||
@ -367,7 +367,7 @@ def pool_state_from_extra_data(extra_data: Program) -> Optional[PoolState]:
|
||||
return None
|
||||
|
||||
|
||||
def solution_to_extra_data(full_spend: CoinSolution) -> Optional[PoolState]:
|
||||
def solution_to_extra_data(full_spend: CoinSpend) -> Optional[PoolState]:
|
||||
full_solution_ser: SerializedProgram = full_spend.solution
|
||||
full_solution: Program = Program.from_bytes(bytes(full_solution_ser))
|
||||
|
||||
|
@ -22,7 +22,7 @@ from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.blockchain_format.program import Program, SerializedProgram
|
||||
from chia.types.coin_record import CoinRecord
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
|
||||
from chia.pools.pool_puzzles import (
|
||||
@ -32,7 +32,7 @@ from chia.pools.pool_puzzles import (
|
||||
create_pooling_inner_puzzle,
|
||||
solution_to_extra_data,
|
||||
pool_state_to_inner_puzzle,
|
||||
get_most_recent_singleton_coin_from_coin_solution,
|
||||
get_most_recent_singleton_coin_from_coin_spend,
|
||||
launcher_id_to_p2_puzzle_hash,
|
||||
create_travel_spend,
|
||||
uncurry_pool_member_inner_puzzle,
|
||||
@ -48,7 +48,7 @@ from chia.wallet.derive_keys import (
|
||||
master_sk_to_pooling_authentication_sk,
|
||||
find_owner_sk,
|
||||
)
|
||||
from chia.wallet.sign_coin_solutions import sign_coin_solutions
|
||||
from chia.wallet.sign_coin_spends import sign_coin_spends
|
||||
from chia.wallet.transaction_record import TransactionRecord
|
||||
from chia.wallet.util.wallet_types import WalletType
|
||||
from chia.wallet.wallet import Wallet
|
||||
@ -175,19 +175,19 @@ class PoolWallet:
|
||||
if err:
|
||||
raise ValueError(f"Invalid internal Pool State: {err}: {initial_target_state}")
|
||||
|
||||
async def get_spend_history(self) -> List[Tuple[uint32, CoinSolution]]:
|
||||
async def get_spend_history(self) -> List[Tuple[uint32, CoinSpend]]:
|
||||
return self.wallet_state_manager.pool_store.get_spends_for_wallet(self.wallet_id)
|
||||
|
||||
async def get_current_state(self) -> PoolWalletInfo:
|
||||
history: List[Tuple[uint32, CoinSolution]] = await self.get_spend_history()
|
||||
all_spends: List[CoinSolution] = [cs for _, cs in history]
|
||||
history: List[Tuple[uint32, CoinSpend]] = await self.get_spend_history()
|
||||
all_spends: List[CoinSpend] = [cs for _, cs in history]
|
||||
|
||||
# We must have at least the launcher spend
|
||||
assert len(all_spends) >= 1
|
||||
|
||||
launcher_coin: Coin = all_spends[0].coin
|
||||
delayed_seconds, delayed_puzhash = get_delayed_puz_info_from_launcher_spend(all_spends[0])
|
||||
tip_singleton_coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_solution(all_spends[-1])
|
||||
tip_singleton_coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_spend(all_spends[-1])
|
||||
launcher_id: bytes32 = launcher_coin.name()
|
||||
p2_singleton_puzzle_hash = launcher_id_to_p2_puzzle_hash(launcher_id, delayed_seconds, delayed_puzhash)
|
||||
assert tip_singleton_coin is not None
|
||||
@ -196,7 +196,7 @@ class PoolWallet:
|
||||
extra_data: Optional[PoolState] = None
|
||||
last_singleton_spend_height = uint32(0)
|
||||
while extra_data is None:
|
||||
full_spend: CoinSolution = all_spends[curr_spend_i]
|
||||
full_spend: CoinSpend = all_spends[curr_spend_i]
|
||||
extra_data = solution_to_extra_data(full_spend)
|
||||
last_singleton_spend_height = uint32(history[curr_spend_i][0])
|
||||
curr_spend_i -= 1
|
||||
@ -223,7 +223,7 @@ class PoolWallet:
|
||||
async def get_unconfirmed_transactions(self) -> List[TransactionRecord]:
|
||||
return await self.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(self.wallet_id)
|
||||
|
||||
async def get_tip(self) -> Tuple[uint32, CoinSolution]:
|
||||
async def get_tip(self) -> Tuple[uint32, CoinSpend]:
|
||||
return self.wallet_state_manager.pool_store.get_spends_for_wallet(self.wallet_id)[-1]
|
||||
|
||||
async def update_pool_config(self, make_new_authentication_key: bool):
|
||||
@ -255,34 +255,34 @@ class PoolWallet:
|
||||
await update_pool_config(self.wallet_state_manager.root_path, list(pool_config_dict.values()))
|
||||
|
||||
@staticmethod
|
||||
def get_next_interesting_coin_ids(spend: CoinSolution) -> List[bytes32]:
|
||||
# CoinSolution of one of the coins that we cared about. This coin was spent in a block, but might be in a reorg
|
||||
def get_next_interesting_coin_ids(spend: CoinSpend) -> List[bytes32]:
|
||||
# CoinSpend of one of the coins that we cared about. This coin was spent in a block, but might be in a reorg
|
||||
# If we return a value, it is a coin ID that we are also interested in (to support two transitions per block)
|
||||
coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_solution(spend)
|
||||
coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_spend(spend)
|
||||
if coin is not None:
|
||||
return [coin.name()]
|
||||
return []
|
||||
|
||||
async def apply_state_transitions(self, block_spends: List[CoinSolution], block_height: uint32):
|
||||
async def apply_state_transitions(self, block_spends: List[CoinSpend], block_height: uint32):
|
||||
"""
|
||||
Updates the Pool state (including DB) with new singleton spends. The block spends can contain many spends
|
||||
that we are not interested in, and can contain many ephemeral spends. They must all be in the same block.
|
||||
The DB must be committed after calling this method. All validation should be done here.
|
||||
"""
|
||||
coin_name_to_spend: Dict[bytes32, CoinSolution] = {cs.coin.name(): cs for cs in block_spends}
|
||||
coin_name_to_spend: Dict[bytes32, CoinSpend] = {cs.coin.name(): cs for cs in block_spends}
|
||||
|
||||
tip: Tuple[uint32, CoinSolution] = await self.get_tip()
|
||||
tip: Tuple[uint32, CoinSpend] = await self.get_tip()
|
||||
tip_height = tip[0]
|
||||
tip_spend = tip[1]
|
||||
assert block_height >= tip_height # We should not have a spend with a lesser block height
|
||||
|
||||
while True:
|
||||
tip_coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_solution(tip_spend)
|
||||
tip_coin: Optional[Coin] = get_most_recent_singleton_coin_from_coin_spend(tip_spend)
|
||||
assert tip_coin is not None
|
||||
spent_coin_name: bytes32 = tip_coin.name()
|
||||
if spent_coin_name not in coin_name_to_spend:
|
||||
break
|
||||
spend: CoinSolution = coin_name_to_spend[spent_coin_name]
|
||||
spend: CoinSpend = coin_name_to_spend[spent_coin_name]
|
||||
await self.wallet_state_manager.pool_store.add_spend(self.wallet_id, spend, block_height)
|
||||
tip_spend = (await self.get_tip())[1]
|
||||
self.log.info(f"New PoolWallet singleton tip_coin: {tip_spend}")
|
||||
@ -303,7 +303,7 @@ class PoolWallet:
|
||||
Returns True if the wallet should be removed.
|
||||
"""
|
||||
try:
|
||||
history: List[Tuple[uint32, CoinSolution]] = self.wallet_state_manager.pool_store.get_spends_for_wallet(
|
||||
history: List[Tuple[uint32, CoinSpend]] = self.wallet_state_manager.pool_store.get_spends_for_wallet(
|
||||
self.wallet_id
|
||||
).copy()
|
||||
prev_state: PoolWalletInfo = await self.get_current_state()
|
||||
@ -329,7 +329,7 @@ class PoolWallet:
|
||||
wallet_state_manager: Any,
|
||||
wallet: Wallet,
|
||||
launcher_coin_id: bytes32,
|
||||
block_spends: List[CoinSolution],
|
||||
block_spends: List[CoinSpend],
|
||||
block_height: uint32,
|
||||
in_transaction: bool,
|
||||
name: str = None,
|
||||
@ -349,7 +349,7 @@ class PoolWallet:
|
||||
self.target_state = None
|
||||
self.log = logging.getLogger(name if name else __name__)
|
||||
|
||||
launcher_spend: Optional[CoinSolution] = None
|
||||
launcher_spend: Optional[CoinSpend] = None
|
||||
for spend in block_spends:
|
||||
if spend.coin.name() == launcher_coin_id:
|
||||
launcher_spend = spend
|
||||
@ -458,14 +458,14 @@ class PoolWallet:
|
||||
)
|
||||
return standard_wallet_record, p2_singleton_puzzle_hash, launcher_coin_id
|
||||
|
||||
async def sign(self, coin_solution: CoinSolution) -> SpendBundle:
|
||||
async def sign(self, coin_spend: CoinSpend) -> SpendBundle:
|
||||
async def pk_to_sk(pk: G1Element) -> PrivateKey:
|
||||
owner_sk: Optional[PrivateKey] = await find_owner_sk([self.wallet_state_manager.private_key], pk)
|
||||
assert owner_sk is not None
|
||||
return owner_sk
|
||||
|
||||
return await sign_coin_solutions(
|
||||
[coin_solution],
|
||||
return await sign_coin_spends(
|
||||
[coin_spend],
|
||||
pk_to_sk,
|
||||
self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA,
|
||||
self.wallet_state_manager.constants.MAX_BLOCK_COST_CLVM,
|
||||
@ -476,7 +476,7 @@ class PoolWallet:
|
||||
pool_wallet_info: PoolWalletInfo = await self.get_current_state()
|
||||
|
||||
spend_history = await self.get_spend_history()
|
||||
last_coin_solution: CoinSolution = spend_history[-1][1]
|
||||
last_coin_spend: CoinSpend = spend_history[-1][1]
|
||||
delayed_seconds, delayed_puzhash = get_delayed_puz_info_from_launcher_spend(spend_history[0][1])
|
||||
assert pool_wallet_info.target is not None
|
||||
next_state = pool_wallet_info.target
|
||||
@ -500,8 +500,8 @@ class PoolWallet:
|
||||
create_full_puzzle(new_inner_puzzle, pool_wallet_info.launcher_coin.name())
|
||||
)
|
||||
|
||||
outgoing_coin_solution, inner_puzzle = create_travel_spend(
|
||||
last_coin_solution,
|
||||
outgoing_coin_spend, inner_puzzle = create_travel_spend(
|
||||
last_coin_spend,
|
||||
pool_wallet_info.launcher_coin,
|
||||
pool_wallet_info.current,
|
||||
next_state,
|
||||
@ -514,8 +514,8 @@ class PoolWallet:
|
||||
tip_coin = tip.coin
|
||||
singleton = tip.additions()[0]
|
||||
singleton_id = singleton.name()
|
||||
assert outgoing_coin_solution.coin.parent_coin_info == tip_coin.name()
|
||||
assert outgoing_coin_solution.coin.name() == singleton_id
|
||||
assert outgoing_coin_spend.coin.parent_coin_info == tip_coin.name()
|
||||
assert outgoing_coin_spend.coin.name() == singleton_id
|
||||
assert new_inner_puzzle != inner_puzzle
|
||||
if is_pool_member_inner_puzzle(inner_puzzle):
|
||||
(
|
||||
@ -543,7 +543,7 @@ class PoolWallet:
|
||||
else:
|
||||
raise RuntimeError("Invalid state")
|
||||
|
||||
signed_spend_bundle = await self.sign(outgoing_coin_solution)
|
||||
signed_spend_bundle = await self.sign(outgoing_coin_spend)
|
||||
|
||||
assert signed_spend_bundle.removals()[0].puzzle_hash == singleton.puzzle_hash
|
||||
assert signed_spend_bundle.removals()[0].name() == singleton.name()
|
||||
@ -641,7 +641,7 @@ class PoolWallet:
|
||||
|
||||
genesis_launcher_solution: Program = Program.to([puzzle_hash, amount, extra_data_bytes])
|
||||
|
||||
launcher_cs: CoinSolution = CoinSolution(
|
||||
launcher_cs: CoinSpend = CoinSpend(
|
||||
launcher_coin,
|
||||
SerializedProgram.from_program(genesis_launcher_puz),
|
||||
SerializedProgram.from_program(genesis_launcher_solution),
|
||||
@ -676,7 +676,7 @@ class PoolWallet:
|
||||
)
|
||||
PoolWallet._verify_initial_target_state(target_state)
|
||||
if current_state.current.state == LEAVING_POOL:
|
||||
history: List[Tuple[uint32, CoinSolution]] = await self.get_spend_history()
|
||||
history: List[Tuple[uint32, CoinSpend]] = await self.get_spend_history()
|
||||
last_height: uint32 = history[-1][0]
|
||||
if self.wallet_state_manager.get_peak().height <= last_height + current_state.current.relative_lock_height:
|
||||
raise ValueError(
|
||||
@ -708,7 +708,7 @@ class PoolWallet:
|
||||
current_state: PoolWalletInfo = await self.get_current_state()
|
||||
|
||||
if current_state.current.state == LEAVING_POOL:
|
||||
history: List[Tuple[uint32, CoinSolution]] = await self.get_spend_history()
|
||||
history: List[Tuple[uint32, CoinSpend]] = await self.get_spend_history()
|
||||
last_height: uint32 = history[-1][0]
|
||||
if self.wallet_state_manager.get_peak().height <= last_height + current_state.current.relative_lock_height:
|
||||
raise ValueError(
|
||||
@ -742,19 +742,19 @@ class PoolWallet:
|
||||
)
|
||||
assert height_farmed is not None
|
||||
coin_to_height_farmed[tx_record.additions[0]] = height_farmed
|
||||
history: List[Tuple[uint32, CoinSolution]] = await self.get_spend_history()
|
||||
history: List[Tuple[uint32, CoinSpend]] = await self.get_spend_history()
|
||||
assert len(history) > 0
|
||||
delayed_seconds, delayed_puzhash = get_delayed_puz_info_from_launcher_spend(history[0][1])
|
||||
current_state: PoolWalletInfo = await self.get_current_state()
|
||||
last_solution: CoinSolution = history[-1][1]
|
||||
last_solution: CoinSpend = history[-1][1]
|
||||
|
||||
all_spends: List[CoinSolution] = []
|
||||
all_spends: List[CoinSpend] = []
|
||||
total_amount = 0
|
||||
for coin_record in unspent_coin_records:
|
||||
if len(all_spends) >= 100:
|
||||
# Limit the total number of spends, so it fits into the block
|
||||
break
|
||||
absorb_spend: List[CoinSolution] = create_absorb_spend(
|
||||
absorb_spend: List[CoinSpend] = create_absorb_spend(
|
||||
last_solution,
|
||||
current_state.current,
|
||||
current_state.launcher_coin,
|
||||
@ -822,7 +822,7 @@ class PoolWallet:
|
||||
unconfirmed: List[
|
||||
TransactionRecord
|
||||
] = await self.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(self.wallet_id)
|
||||
next_tip: Optional[Coin] = get_most_recent_singleton_coin_from_coin_solution(tip_spend)
|
||||
next_tip: Optional[Coin] = get_most_recent_singleton_coin_from_coin_spend(tip_spend)
|
||||
assert next_tip is not None
|
||||
|
||||
if any([rem.name() == next_tip.name() for tx_rec in unconfirmed for rem in tx_rec.removals]):
|
||||
|
@ -102,7 +102,7 @@ def create_pool_state(
|
||||
class PoolWalletInfo(Streamable):
|
||||
"""
|
||||
Internal Pool Wallet state, not destined for the blockchain. This can be completely derived with
|
||||
the Singleton's CoinSolutions list, or with the information from the WalletPoolStore.
|
||||
the Singleton's CoinSpends list, or with the information from the WalletPoolStore.
|
||||
"""
|
||||
|
||||
current: PoolState
|
||||
|
@ -7,7 +7,7 @@ from chia.full_node.mempool_check_conditions import get_puzzle_and_solution_for_
|
||||
from chia.types.blockchain_format.program import Program, SerializedProgram
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_record import CoinRecord
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.full_block import FullBlock
|
||||
from chia.types.generator_types import BlockGenerator
|
||||
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
||||
@ -511,7 +511,7 @@ class FullNodeRpcApi:
|
||||
|
||||
puzzle_ser: SerializedProgram = SerializedProgram.from_program(Program.to(puzzle))
|
||||
solution_ser: SerializedProgram = SerializedProgram.from_program(Program.to(solution))
|
||||
return {"coin_solution": CoinSolution(coin_record.coin, puzzle_ser, solution_ser)}
|
||||
return {"coin_solution": CoinSpend(coin_record.coin, puzzle_ser, solution_ser)}
|
||||
|
||||
async def get_additions_and_removals(self, request: Dict) -> Optional[Dict]:
|
||||
if "header_hash" not in request:
|
||||
|
@ -5,7 +5,7 @@ from chia.full_node.signage_point import SignagePoint
|
||||
from chia.rpc.rpc_client import RpcClient
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_record import CoinRecord
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
|
||||
from chia.types.full_block import FullBlock
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
@ -146,7 +146,7 @@ class FullNodeRpcClient(RpcClient):
|
||||
async def get_puzzle_and_solution(self, coin_id: bytes32, height: uint32) -> Optional[CoinRecord]:
|
||||
try:
|
||||
response = await self.fetch("get_puzzle_and_solution", {"coin_id": coin_id.hex(), "height": height})
|
||||
return CoinSolution.from_json_dict(response["coin_solution"])
|
||||
return CoinSpend.from_json_dict(response["coin_solution"])
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
@ -1,24 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
import warnings
|
||||
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import SerializedProgram, INFINITE_COST
|
||||
from chia.util.chain_utils import additions_for_solution
|
||||
from chia.util.streamable import Streamable, streamable
|
||||
from .coin_spend import CoinSpend as CoinSolution # noqa
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@streamable
|
||||
class CoinSolution(Streamable):
|
||||
"""
|
||||
This is a rather disparate data structure that validates coin transfers. It's generally populated
|
||||
with data from different sources, since burned coins are identified by name, so it is built up
|
||||
more often that it is streamed.
|
||||
"""
|
||||
|
||||
coin: Coin
|
||||
puzzle_reveal: SerializedProgram
|
||||
solution: SerializedProgram
|
||||
|
||||
def additions(self) -> List[Coin]:
|
||||
return additions_for_solution(self.coin.name(), self.puzzle_reveal, self.solution, INFINITE_COST)
|
||||
warnings.warn("`CoinSolution` is now `CoinSpend`")
|
||||
|
24
chia/types/coin_spend.py
Normal file
24
chia/types/coin_spend.py
Normal file
@ -0,0 +1,24 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import SerializedProgram, INFINITE_COST
|
||||
from chia.util.chain_utils import additions_for_solution
|
||||
from chia.util.streamable import Streamable, streamable
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@streamable
|
||||
class CoinSpend(Streamable):
|
||||
"""
|
||||
This is a rather disparate data structure that validates coin transfers. It's generally populated
|
||||
with data from different sources, since burned coins are identified by name, so it is built up
|
||||
more often that it is streamed.
|
||||
"""
|
||||
|
||||
coin: Coin
|
||||
puzzle_reveal: SerializedProgram
|
||||
solution: SerializedProgram
|
||||
|
||||
def additions(self) -> List[Coin]:
|
||||
return additions_for_solution(self.coin.name(), self.puzzle_reveal, self.solution, INFINITE_COST)
|
@ -8,7 +8,7 @@ from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.util.streamable import Streamable, streamable
|
||||
from chia.wallet.util.debug_spend_bundle import debug_spend_bundle
|
||||
|
||||
from .coin_solution import CoinSolution
|
||||
from .coin_spend import CoinSpend
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@ -21,28 +21,28 @@ class SpendBundle(Streamable):
|
||||
between transactions are more flexible than in bitcoin).
|
||||
"""
|
||||
|
||||
coin_solutions: List[CoinSolution]
|
||||
coin_spends: List[CoinSpend]
|
||||
aggregated_signature: G2Element
|
||||
|
||||
@classmethod
|
||||
def aggregate(cls, spend_bundles) -> "SpendBundle":
|
||||
coin_solutions: List[CoinSolution] = []
|
||||
coin_spends: List[CoinSpend] = []
|
||||
sigs: List[G2Element] = []
|
||||
for bundle in spend_bundles:
|
||||
coin_solutions += bundle.coin_solutions
|
||||
coin_spends += bundle.coin_spends
|
||||
sigs.append(bundle.aggregated_signature)
|
||||
aggregated_signature = AugSchemeMPL.aggregate(sigs)
|
||||
return cls(coin_solutions, aggregated_signature)
|
||||
return cls(coin_spends, aggregated_signature)
|
||||
|
||||
def additions(self) -> List[Coin]:
|
||||
items: List[Coin] = []
|
||||
for coin_solution in self.coin_solutions:
|
||||
items.extend(coin_solution.additions())
|
||||
for coin_spend in self.coin_spends:
|
||||
items.extend(coin_spend.additions())
|
||||
return items
|
||||
|
||||
def removals(self) -> List[Coin]:
|
||||
"""This should be used only by wallet"""
|
||||
return [_.coin for _ in self.coin_solutions]
|
||||
return [_.coin for _ in self.coin_spends]
|
||||
|
||||
def fees(self) -> int:
|
||||
"""Unsafe to use for fees validation!!!"""
|
||||
|
@ -13,7 +13,7 @@ def additions_for_solution(
|
||||
coin_name: bytes32, puzzle_reveal: SerializedProgram, solution: SerializedProgram, max_cost: int
|
||||
) -> List[Coin]:
|
||||
"""
|
||||
Checks the conditions created by CoinSolution and returns the list of all coins created
|
||||
Checks the conditions created by CoinSpend and returns the list of all coins created
|
||||
"""
|
||||
err, dic, cost = conditions_dict_for_solution(puzzle_reveal, solution, max_cost)
|
||||
if err or dic is None:
|
||||
|
@ -7,7 +7,7 @@ from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program, INFINITE_COST
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.spend_bundle import CoinSolution, SpendBundle
|
||||
from chia.types.spend_bundle import CoinSpend, SpendBundle
|
||||
from chia.util.condition_tools import conditions_dict_for_solution
|
||||
from chia.util.ints import uint64
|
||||
from chia.wallet.puzzles.cc_loader import CC_MOD, LOCK_INNER_PUZZLE
|
||||
@ -81,15 +81,15 @@ def subtotals_for_deltas(deltas) -> List[int]:
|
||||
return subtotals
|
||||
|
||||
|
||||
def coin_solution_for_lock_coin(
|
||||
def coin_spend_for_lock_coin(
|
||||
prev_coin: Coin,
|
||||
subtotal: int,
|
||||
coin: Coin,
|
||||
) -> CoinSolution:
|
||||
) -> CoinSpend:
|
||||
puzzle_reveal = LOCK_INNER_PUZZLE.curry(prev_coin.as_list(), subtotal)
|
||||
coin = Coin(coin.name(), puzzle_reveal.get_tree_hash(), uint64(0))
|
||||
coin_solution = CoinSolution(coin, puzzle_reveal, Program.to(0))
|
||||
return coin_solution
|
||||
coin_spend = CoinSpend(coin, puzzle_reveal, Program.to(0))
|
||||
return coin_spend
|
||||
|
||||
|
||||
def bundle_for_spendable_cc_list(spendable_cc: SpendableCC) -> Program:
|
||||
@ -129,7 +129,7 @@ def spend_bundle_for_spendable_ccs(
|
||||
total += Program.to(_.vars[1]).as_int()
|
||||
output_amounts.append(total)
|
||||
|
||||
coin_solutions = []
|
||||
coin_spends = []
|
||||
|
||||
deltas = [input_coins[_].amount - output_amounts[_] for _ in range(N)]
|
||||
subtotals = subtotals_for_deltas(deltas)
|
||||
@ -157,13 +157,13 @@ def spend_bundle_for_spendable_ccs(
|
||||
next_bundle,
|
||||
subtotals[index],
|
||||
]
|
||||
coin_solution = CoinSolution(input_coins[index], puzzle_reveal, Program.to(solution))
|
||||
coin_solutions.append(coin_solution)
|
||||
coin_spend = CoinSpend(input_coins[index], puzzle_reveal, Program.to(solution))
|
||||
coin_spends.append(coin_spend)
|
||||
|
||||
if sigs is None or sigs == []:
|
||||
return SpendBundle(coin_solutions, NULL_SIGNATURE)
|
||||
return SpendBundle(coin_spends, NULL_SIGNATURE)
|
||||
else:
|
||||
return SpendBundle(coin_solutions, AugSchemeMPL.aggregate(sigs))
|
||||
return SpendBundle(coin_spends, AugSchemeMPL.aggregate(sigs))
|
||||
|
||||
|
||||
def is_cc_mod(inner_f: Program):
|
||||
@ -210,10 +210,10 @@ def get_lineage_proof_from_coin_and_puz(parent_coin, parent_puzzle):
|
||||
return lineage_proof
|
||||
|
||||
|
||||
def spendable_cc_list_from_coin_solution(coin_solution: CoinSolution, hash_to_puzzle_f) -> List[SpendableCC]:
|
||||
def spendable_cc_list_from_coin_spend(coin_spend: CoinSpend, hash_to_puzzle_f) -> List[SpendableCC]:
|
||||
|
||||
"""
|
||||
Given a `CoinSolution`, extract out a list of `SpendableCC` objects.
|
||||
Given a `CoinSpend`, extract out a list of `SpendableCC` objects.
|
||||
|
||||
Since `SpendableCC` needs to track the inner puzzles and a `Coin` only includes
|
||||
puzzle hash, we also need a `hash_to_puzzle_f` function that turns puzzle hashes into
|
||||
@ -223,8 +223,8 @@ def spendable_cc_list_from_coin_solution(coin_solution: CoinSolution, hash_to_pu
|
||||
|
||||
spendable_cc_list = []
|
||||
|
||||
coin = coin_solution.coin
|
||||
puzzle = Program.from_bytes(bytes(coin_solution.puzzle_reveal))
|
||||
coin = coin_spend.coin
|
||||
puzzle = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
|
||||
r = uncurry_cc(puzzle)
|
||||
if r:
|
||||
mod_hash, genesis_coin_checker, inner_puzzle = r
|
||||
@ -232,7 +232,7 @@ def spendable_cc_list_from_coin_solution(coin_solution: CoinSolution, hash_to_pu
|
||||
else:
|
||||
lineage_proof = lineage_proof_for_coin(coin)
|
||||
|
||||
for new_coin in coin_solution.additions():
|
||||
for new_coin in coin_spend.additions():
|
||||
puzzle = hash_to_puzzle_f(new_coin.puzzle_hash)
|
||||
if puzzle is None:
|
||||
# we don't recognize this puzzle hash, skip it
|
||||
|
@ -15,7 +15,7 @@ from chia.protocols.wallet_protocol import PuzzleSolutionResponse
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.generator_types import BlockGenerator
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.byte_types import hexstr_to_bytes
|
||||
@ -730,7 +730,7 @@ class CCWallet:
|
||||
sigs = sigs + await self.get_sigs(innerpuz, innersol, coin.name())
|
||||
lineage_proof = await self.get_lineage_proof_for_coin(coin)
|
||||
puzzle_reveal = cc_puzzle_for_inner_puzzle(CC_MOD, self.cc_info.my_genesis_checker, innerpuz)
|
||||
# Use coin info to create solution and add coin and solution to list of CoinSolutions
|
||||
# Use coin info to create solution and add coin and solution to list of CoinSpends
|
||||
solution = [
|
||||
innersol,
|
||||
coin.as_list(),
|
||||
@ -741,7 +741,7 @@ class CCWallet:
|
||||
None,
|
||||
None,
|
||||
]
|
||||
list_of_solutions.append(CoinSolution(coin, puzzle_reveal, Program.to(solution)))
|
||||
list_of_solutions.append(CoinSpend(coin, puzzle_reveal, Program.to(solution)))
|
||||
|
||||
aggsig = AugSchemeMPL.aggregate(sigs)
|
||||
return SpendBundle(list_of_solutions, aggsig)
|
||||
|
@ -9,14 +9,14 @@ from secrets import token_bytes
|
||||
from chia.protocols import wallet_protocol
|
||||
from chia.protocols.wallet_protocol import RespondAdditions, RejectAdditionsRequest
|
||||
from chia.server.outbound_message import NodeType
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.wallet.util.transaction_type import TransactionType
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.ints import uint64, uint32, uint8
|
||||
from chia.wallet.util.transaction_type import TransactionType
|
||||
|
||||
from chia.wallet.did_wallet.did_info import DIDInfo
|
||||
from chia.wallet.lineage_proof import LineageProof
|
||||
@ -454,7 +454,7 @@ class DIDWallet:
|
||||
innersol,
|
||||
]
|
||||
)
|
||||
list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
|
||||
list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
|
||||
# sign for AGG_SIG_ME
|
||||
message = (
|
||||
Program.to([new_puzhash, coin.amount, []]).get_tree_hash()
|
||||
@ -521,7 +521,7 @@ class DIDWallet:
|
||||
innersol,
|
||||
]
|
||||
)
|
||||
list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
|
||||
list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
|
||||
# sign for AGG_SIG_ME
|
||||
# new_inner_puzhash amount message
|
||||
message = (
|
||||
@ -588,7 +588,7 @@ class DIDWallet:
|
||||
innersol,
|
||||
]
|
||||
)
|
||||
list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
|
||||
list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
|
||||
# sign for AGG_SIG_ME
|
||||
message = (
|
||||
Program.to([amount, puzhash]).get_tree_hash()
|
||||
@ -659,7 +659,7 @@ class DIDWallet:
|
||||
innersol,
|
||||
]
|
||||
)
|
||||
list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
|
||||
list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
|
||||
message_spend = did_wallet_puzzles.create_spend_for_message(coin.name(), recovering_coin_name, newpuz, pubkey)
|
||||
message_spend_bundle = SpendBundle([message_spend], AugSchemeMPL.aggregate([]))
|
||||
# sign for AGG_SIG_ME
|
||||
@ -793,7 +793,7 @@ class DIDWallet:
|
||||
innersol,
|
||||
]
|
||||
)
|
||||
list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
|
||||
list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
|
||||
|
||||
index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(pubkey)
|
||||
if index is None:
|
||||
@ -801,7 +801,7 @@ class DIDWallet:
|
||||
private = master_sk_to_wallet_sk(self.wallet_state_manager.private_key, index)
|
||||
message = bytes(puzhash)
|
||||
sigs = [AugSchemeMPL.sign(private, message)]
|
||||
for _ in spend_bundle.coin_solutions:
|
||||
for _ in spend_bundle.coin_spends:
|
||||
sigs.append(AugSchemeMPL.sign(private, message))
|
||||
aggsig = AugSchemeMPL.aggregate(sigs)
|
||||
# assert AugSchemeMPL.verify(pubkey, message, aggsig)
|
||||
@ -900,7 +900,7 @@ class DIDWallet:
|
||||
|
||||
genesis_launcher_solution = Program.to([did_puzzle_hash, amount, bytes(0x80)])
|
||||
|
||||
launcher_cs = CoinSolution(launcher_coin, genesis_launcher_puz, genesis_launcher_solution)
|
||||
launcher_cs = CoinSpend(launcher_coin, genesis_launcher_puz, genesis_launcher_solution)
|
||||
launcher_sb = SpendBundle([launcher_cs], AugSchemeMPL.aggregate([]))
|
||||
eve_coin = Coin(launcher_coin.name(), did_puzzle_hash, amount)
|
||||
future_parent = LineageProof(
|
||||
@ -947,7 +947,7 @@ class DIDWallet:
|
||||
innersol,
|
||||
]
|
||||
)
|
||||
list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
|
||||
list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
|
||||
# sign for AGG_SIG_ME
|
||||
message = (
|
||||
Program.to([innerpuz.get_tree_hash(), coin.amount, []]).get_tree_hash()
|
||||
|
@ -4,7 +4,7 @@ from chia.types.blockchain_format.program import Program
|
||||
from typing import List, Optional, Tuple
|
||||
from blspy import G1Element
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.util.ints import uint64
|
||||
from chia.wallet.puzzles.load_clvm import load_clvm
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
@ -85,7 +85,7 @@ 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)
|
||||
coinsol = CoinSpend(coin, puzzle, solution)
|
||||
return coinsol
|
||||
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
|
||||
; TODO convert generators arg to list of generators
|
||||
|
||||
(mod (decompress_puzzle decompress_coin_solution_entry start end compressed_cses deserialize gen_list reserved_arg)
|
||||
(mod (decompress_puzzle decompress_coin_spend_entry start end compressed_cses deserialize gen_list reserved_arg)
|
||||
|
||||
(defun decompress_cses (decompress_puzzle decompress_coin_solution_entry cses deserialize puzzle_prefix)
|
||||
(defun decompress_cses (decompress_puzzle decompress_coin_spend_entry cses deserialize puzzle_prefix)
|
||||
(if cses
|
||||
(c (a decompress_coin_solution_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_solution_entry (r cses) deserialize puzzle_prefix ))
|
||||
(c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix ))
|
||||
()) )
|
||||
|
||||
(list (decompress_cses decompress_puzzle decompress_coin_solution_entry compressed_cses deserialize (substr (f gen_list) start end)))
|
||||
(list (decompress_cses decompress_puzzle decompress_coin_spend_entry compressed_cses deserialize (substr (f gen_list) start end)))
|
||||
|
||||
)
|
||||
|
@ -16,15 +16,15 @@
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)))
|
||||
|
||||
(defun check_coin_solution ((parent puzzle amount solution) coinname)
|
||||
(defun check_coin_spend ((parent puzzle amount solution) coinname)
|
||||
(= (sha256 parent (sha256tree1 puzzle) amount) coinname)
|
||||
)
|
||||
|
||||
(defun check_for_coinname (coin_solutions coinname)
|
||||
(if coin_solutions
|
||||
(if (check_coin_solution (f coin_solutions) coinname)
|
||||
(list (f (r (f coin_solutions))) (f (r (r (r (f coin_solutions))))))
|
||||
(check_for_coinname (r coin_solutions) coinname)
|
||||
(defun check_for_coinname (coin_spends coinname)
|
||||
(if coin_spends
|
||||
(if (check_coin_spend (f coin_spends) coinname)
|
||||
(list (f (r (f coin_spends))) (f (r (r (r (f coin_spends))))))
|
||||
(check_for_coinname (r coin_spends) coinname)
|
||||
)
|
||||
(x)
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ from clvm_tools import binutils
|
||||
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
|
||||
from chia.rpc.full_node_rpc_client import FullNodeRpcClient
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.bech32m import decode_puzzle_hash
|
||||
@ -18,10 +18,8 @@ from chia.util.ints import uint32, uint16
|
||||
|
||||
def print_conditions(spend_bundle: SpendBundle):
|
||||
print("\nConditions:")
|
||||
for coin_solution in spend_bundle.coin_solutions:
|
||||
result = Program.from_bytes(bytes(coin_solution.puzzle_reveal)).run(
|
||||
Program.from_bytes(bytes(coin_solution.solution))
|
||||
)
|
||||
for coin_spend in spend_bundle.coin_spends:
|
||||
result = Program.from_bytes(bytes(coin_spend.puzzle_reveal)).run(Program.from_bytes(bytes(coin_spend.solution)))
|
||||
error, result_human = parse_sexp_to_conditions(result)
|
||||
assert error is None
|
||||
assert result_human is not None
|
||||
@ -65,8 +63,8 @@ async def main() -> None:
|
||||
|
||||
p_solution = Program.to(binutils.assemble("()"))
|
||||
|
||||
sb_farmer = SpendBundle([CoinSolution(farmer_prefarm, p_farmer_2, p_solution)], G2Element())
|
||||
sb_pool = SpendBundle([CoinSolution(pool_prefarm, p_pool_2, p_solution)], G2Element())
|
||||
sb_farmer = SpendBundle([CoinSpend(farmer_prefarm, p_farmer_2, p_solution)], G2Element())
|
||||
sb_pool = SpendBundle([CoinSpend(pool_prefarm, p_pool_2, p_solution)], G2Element())
|
||||
|
||||
print("\n\n\nConditions")
|
||||
print_conditions(sb_pool)
|
||||
|
@ -18,19 +18,19 @@
|
||||
)
|
||||
)
|
||||
|
||||
(defun process_coin_solution ((parent puzzle amount solution . spend_level_extras))
|
||||
(defun process_coin_spend ((parent puzzle amount solution . spend_level_extras))
|
||||
(c parent (c (sha256tree puzzle) (c amount (c (a puzzle solution) spend_level_extras))))
|
||||
)
|
||||
|
||||
(defun recurse (coin_solutions)
|
||||
(if coin_solutions
|
||||
(c (process_coin_solution (f coin_solutions)) (recurse (r coin_solutions)))
|
||||
(defun recurse (coin_spends)
|
||||
(if coin_spends
|
||||
(c (process_coin_spend (f coin_spends)) (recurse (r coin_spends)))
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
(defun process-decompressor ((coin_solutions . block-level-extras))
|
||||
(c (recurse coin_solutions) block-level-extras)
|
||||
(defun process-decompressor ((coin_spends . block-level-extras))
|
||||
(c (recurse coin_spends) block-level-extras)
|
||||
)
|
||||
|
||||
(process-decompressor (a block_decompresser_program (list local_deserialize_mod historical_blocks_tree))))
|
||||
|
@ -4,7 +4,7 @@ from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.wallet.puzzles.load_clvm import load_clvm
|
||||
from chia.wallet.lineage_proof import LineageProof
|
||||
from chia.util.ints import uint64
|
||||
@ -37,7 +37,7 @@ def launch_conditions_and_coinsol(
|
||||
inner_puzzle: Program,
|
||||
comment: List[Tuple[str, str]],
|
||||
amount: uint64,
|
||||
) -> Tuple[List[Program], CoinSolution]:
|
||||
) -> Tuple[List[Program], CoinSpend]:
|
||||
if (amount % 2) == 0:
|
||||
raise ValueError("Coin amount cannot be even. Subtract one mojo.")
|
||||
|
||||
@ -70,29 +70,29 @@ def launch_conditions_and_coinsol(
|
||||
|
||||
conditions = [create_launcher, assert_launcher_announcement]
|
||||
|
||||
launcher_coin_solution = CoinSolution(
|
||||
launcher_coin_spend = CoinSpend(
|
||||
launcher_coin,
|
||||
SINGLETON_LAUNCHER,
|
||||
launcher_solution,
|
||||
)
|
||||
|
||||
return conditions, launcher_coin_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_solution: CoinSolution) -> LineageProof:
|
||||
parent_name = coin_solution.coin.parent_coin_info
|
||||
def lineage_proof_for_coinsol(coin_spend: CoinSpend) -> LineageProof:
|
||||
parent_name = coin_spend.coin.parent_coin_info
|
||||
|
||||
inner_puzzle_hash = None
|
||||
if coin_solution.coin.puzzle_hash != SINGLETON_LAUNCHER_HASH:
|
||||
full_puzzle = Program.from_bytes(bytes(coin_solution.puzzle_reveal))
|
||||
if coin_spend.coin.puzzle_hash != SINGLETON_LAUNCHER_HASH:
|
||||
full_puzzle = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
|
||||
r = full_puzzle.uncurry()
|
||||
if r is not None:
|
||||
_, args = r
|
||||
_, inner_puzzle = list(args.as_iter())
|
||||
inner_puzzle_hash = inner_puzzle.get_tree_hash()
|
||||
|
||||
amount = coin_solution.coin.amount
|
||||
amount = coin_spend.coin.amount
|
||||
|
||||
return LineageProof(
|
||||
parent_name,
|
||||
@ -156,15 +156,15 @@ def solution_for_p2_delayed_puzzle(output_amount: uint64) -> Program:
|
||||
return Program.to([output_amount, []])
|
||||
|
||||
|
||||
# Get announcement conditions for singleton solution and full CoinSolution for the claimed coin
|
||||
# Get announcement conditions for singleton solution and full CoinSpend for the claimed coin
|
||||
def claim_p2_singleton(
|
||||
p2_singleton_coin: Coin,
|
||||
singleton_inner_puzhash: bytes32,
|
||||
launcher_id: bytes32,
|
||||
) -> Tuple[Program, Program, CoinSolution]:
|
||||
) -> Tuple[Program, Program, CoinSpend]:
|
||||
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()])
|
||||
claim_coinsol = CoinSolution(
|
||||
claim_coinsol = CoinSpend(
|
||||
p2_singleton_coin,
|
||||
pay_to_singleton_puzzle(launcher_id),
|
||||
solution_for_p2_singleton(p2_singleton_coin, singleton_inner_puzhash),
|
||||
@ -172,15 +172,15 @@ def claim_p2_singleton(
|
||||
return assertion, announcement, claim_coinsol
|
||||
|
||||
|
||||
# Get the CoinSolution for spending to a delayed puzzle
|
||||
# Get the CoinSpend for spending to a delayed puzzle
|
||||
def spend_to_delayed_puzzle(
|
||||
p2_singleton_coin: Coin,
|
||||
output_amount: uint64,
|
||||
launcher_id: bytes32,
|
||||
delay_time: uint64,
|
||||
delay_ph: bytes32,
|
||||
) -> CoinSolution:
|
||||
claim_coinsol = CoinSolution(
|
||||
) -> CoinSpend:
|
||||
claim_coinsol = CoinSpend(
|
||||
p2_singleton_coin,
|
||||
pay_to_singleton_or_delay_puzzle(launcher_id, delay_time, delay_ph),
|
||||
solution_for_p2_delayed_puzzle(output_amount),
|
||||
|
@ -9,14 +9,14 @@ from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.spend_bundle import CoinSolution, SpendBundle
|
||||
from chia.types.spend_bundle import CoinSpend, SpendBundle
|
||||
from chia.util.ints import uint64
|
||||
from chia.wallet.cc_wallet.cc_utils import (
|
||||
CC_MOD,
|
||||
cc_puzzle_for_inner_puzzle,
|
||||
cc_puzzle_hash_for_inner_puzzle_hash,
|
||||
spend_bundle_for_spendable_ccs,
|
||||
spendable_cc_list_from_coin_solution,
|
||||
spendable_cc_list_from_coin_spend,
|
||||
)
|
||||
from chia.wallet.puzzles.genesis_by_coin_id_with_0 import create_genesis_or_zero_coin_checker
|
||||
from chia.wallet.puzzles.genesis_by_puzzle_hash_with_0 import create_genesis_puzzle_or_zero_coin_checker
|
||||
@ -83,8 +83,8 @@ def issue_cc_from_farmed_coin(
|
||||
# this is just a coincidence... for more complicated puzzles, you'll likely have to do some real work
|
||||
|
||||
solution = Program.to(output_conditions)
|
||||
coin_solution = CoinSolution(farmed_coin, farmed_puzzle, solution)
|
||||
spend_bundle = SpendBundle([coin_solution], NULL_SIGNATURE)
|
||||
coin_spend = CoinSpend(farmed_coin, farmed_puzzle, solution)
|
||||
spend_bundle = SpendBundle([coin_spend], NULL_SIGNATURE)
|
||||
return genesis_coin_checker, spend_bundle
|
||||
|
||||
|
||||
@ -130,8 +130,8 @@ def test_spend_through_n(mod_code, coin_checker_for_farmed_coin, n):
|
||||
# collect up the spendable coins
|
||||
|
||||
spendable_cc_list = []
|
||||
for coin_solution in spend_bundle.coin_solutions:
|
||||
spendable_cc_list.extend(spendable_cc_list_from_coin_solution(coin_solution, hash_to_puzzle_f))
|
||||
for coin_spend in spend_bundle.coin_spends:
|
||||
spendable_cc_list.extend(spendable_cc_list_from_coin_spend(coin_spend, hash_to_puzzle_f))
|
||||
|
||||
# now spend the genesis coin cc to N outputs
|
||||
|
||||
@ -152,8 +152,8 @@ def test_spend_through_n(mod_code, coin_checker_for_farmed_coin, n):
|
||||
# collect up the spendable coins
|
||||
|
||||
spendable_cc_list = []
|
||||
for coin_solution in spend_bundle.coin_solutions:
|
||||
spendable_cc_list.extend(spendable_cc_list_from_coin_solution(coin_solution, hash_to_puzzle_f))
|
||||
for coin_spend in spend_bundle.coin_spends:
|
||||
spendable_cc_list.extend(spendable_cc_list_from_coin_spend(coin_spend, hash_to_puzzle_f))
|
||||
|
||||
# now spend N inputs to two outputs
|
||||
|
||||
@ -192,8 +192,8 @@ def test_spend_zero_coin(mod_code: Program, coin_checker_for_farmed_coin):
|
||||
add_puzzles_to_puzzle_preimage_db(puzzles_for_db)
|
||||
|
||||
eve_cc_list = []
|
||||
for _ in spend_bundle.coin_solutions:
|
||||
eve_cc_list.extend(spendable_cc_list_from_coin_solution(_, hash_to_puzzle_f))
|
||||
for _ in spend_bundle.coin_spends:
|
||||
eve_cc_list.extend(spendable_cc_list_from_coin_spend(_, hash_to_puzzle_f))
|
||||
assert len(eve_cc_list) == 1
|
||||
eve_cc_spendable = eve_cc_list[0]
|
||||
|
||||
@ -206,8 +206,8 @@ def test_spend_zero_coin(mod_code: Program, coin_checker_for_farmed_coin):
|
||||
wrapped_cc_puzzle_hash = cc_puzzle_hash_for_inner_puzzle_hash(mod_code, genesis_coin_checker, eve_inner_puzzle_hash)
|
||||
|
||||
solution = solution_for_pay_to_any([(wrapped_cc_puzzle_hash, 0)])
|
||||
coin_solution = CoinSolution(farmed_coin, ANYONE_CAN_SPEND_PUZZLE, solution)
|
||||
spendable_cc_list = spendable_cc_list_from_coin_solution(coin_solution, hash_to_puzzle_f)
|
||||
coin_spend = CoinSpend(farmed_coin, ANYONE_CAN_SPEND_PUZZLE, solution)
|
||||
spendable_cc_list = spendable_cc_list_from_coin_spend(coin_spend, hash_to_puzzle_f)
|
||||
assert len(spendable_cc_list) == 1
|
||||
zero_cc_spendable = spendable_cc_list[0]
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
|
||||
(mod (decompress_puzzle decompress_coin_solution_entry start1 end1 start2 end2 compressed_cses deserialize gen_list reserved_arg)
|
||||
(mod (decompress_puzzle decompress_coin_spend_entry start1 end1 start2 end2 compressed_cses deserialize gen_list reserved_arg)
|
||||
|
||||
(defun decompress_cses (decompress_puzzle decompress_coin_solution_entry cses deserialize puzzle_prefix)
|
||||
(defun decompress_cses (decompress_puzzle decompress_coin_spend_entry cses deserialize puzzle_prefix)
|
||||
(if cses
|
||||
(c (a decompress_coin_solution_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_solution_entry (r cses) deserialize puzzle_prefix ))
|
||||
(c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix ))
|
||||
()) )
|
||||
|
||||
(defun join_gen_args (generators start1 end1 start2 end2)
|
||||
@ -14,6 +14,6 @@
|
||||
)
|
||||
)
|
||||
|
||||
(list (decompress_cses decompress_puzzle decompress_coin_solution_entry compressed_cses deserialize (join_gen_args gen_list start1 end1 start2 end2)))
|
||||
(list (decompress_cses decompress_puzzle decompress_coin_spend_entry compressed_cses deserialize (join_gen_args gen_list start1 end1 start2 end2)))
|
||||
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ from blspy import AugSchemeMPL, G1Element, PrivateKey
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.byte_types import hexstr_to_bytes
|
||||
from chia.util.ints import uint8, uint32, uint64, uint128
|
||||
@ -475,7 +475,7 @@ class RLWallet:
|
||||
|
||||
return rl_parent.coin
|
||||
|
||||
async def rl_generate_unsigned_transaction(self, to_puzzlehash, amount, fee) -> List[CoinSolution]:
|
||||
async def rl_generate_unsigned_transaction(self, to_puzzlehash, amount, fee) -> List[CoinSpend]:
|
||||
spends = []
|
||||
assert self.rl_coin_record is not None
|
||||
coin = self.rl_coin_record.coin
|
||||
@ -514,7 +514,7 @@ class RLWallet:
|
||||
fee,
|
||||
)
|
||||
|
||||
spends.append(CoinSolution(coin, puzzle, solution))
|
||||
spends.append(CoinSpend(coin, puzzle, solution))
|
||||
return spends
|
||||
|
||||
async def generate_signed_transaction(self, amount, to_puzzle_hash, fee: uint64 = uint64(0)) -> TransactionRecord:
|
||||
@ -544,11 +544,11 @@ class RLWallet:
|
||||
name=spend_bundle.name(),
|
||||
)
|
||||
|
||||
async def rl_sign_transaction(self, spends: List[CoinSolution]) -> SpendBundle:
|
||||
async def rl_sign_transaction(self, spends: List[CoinSpend]) -> SpendBundle:
|
||||
sigs = []
|
||||
for coin_solution in spends:
|
||||
pubkey, secretkey = await self.get_keys(coin_solution.coin.puzzle_hash)
|
||||
signature = AugSchemeMPL.sign(secretkey, coin_solution.solution.get_tree_hash())
|
||||
for coin_spend in spends:
|
||||
pubkey, secretkey = await self.get_keys(coin_spend.coin.puzzle_hash)
|
||||
signature = AugSchemeMPL.sign(secretkey, coin_spend.solution.get_tree_hash())
|
||||
sigs.append(signature)
|
||||
|
||||
aggsig = AugSchemeMPL.aggregate(sigs)
|
||||
@ -575,12 +575,10 @@ class RLWallet:
|
||||
self.rl_info.admin_pubkey,
|
||||
)
|
||||
solution = make_clawback_solution(clawback_puzzle_hash, clawback_coin.amount, fee)
|
||||
spends.append((puzzle, CoinSolution(coin, puzzle, solution)))
|
||||
spends.append((puzzle, CoinSpend(coin, puzzle, solution)))
|
||||
return spends
|
||||
|
||||
async def sign_clawback_transaction(
|
||||
self, spends: List[Tuple[Program, CoinSolution]], clawback_pubkey
|
||||
) -> SpendBundle:
|
||||
async def sign_clawback_transaction(self, spends: List[Tuple[Program, CoinSpend]], clawback_pubkey) -> SpendBundle:
|
||||
sigs = []
|
||||
for puzzle, solution in spends:
|
||||
pubkey, secretkey = await self.get_keys_pk(clawback_pubkey)
|
||||
@ -588,8 +586,8 @@ class RLWallet:
|
||||
sigs.append(signature)
|
||||
aggsig = AugSchemeMPL.aggregate(sigs)
|
||||
solution_list = []
|
||||
for puzzle, coin_solution in spends:
|
||||
solution_list.append(coin_solution)
|
||||
for puzzle, coin_spend in spends:
|
||||
solution_list.append(coin_spend)
|
||||
|
||||
return SpendBundle(solution_list, aggsig)
|
||||
|
||||
@ -634,7 +632,7 @@ class RLWallet:
|
||||
if self.rl_coin_record is None:
|
||||
raise ValueError("Rl coin record is None")
|
||||
|
||||
list_of_coin_solutions = []
|
||||
list_of_coin_spends = []
|
||||
self.rl_coin_record = await self._get_rl_coin_record()
|
||||
pubkey, secretkey = await self.get_keys(self.rl_coin_record.coin.puzzle_hash)
|
||||
# Spend wallet coin
|
||||
@ -657,9 +655,9 @@ class RLWallet:
|
||||
rl_parent.parent_coin_info,
|
||||
)
|
||||
signature = AugSchemeMPL.sign(secretkey, solution.get_tree_hash())
|
||||
rl_spend = CoinSolution(self.rl_coin_record.coin, puzzle, solution)
|
||||
rl_spend = CoinSpend(self.rl_coin_record.coin, puzzle, solution)
|
||||
|
||||
list_of_coin_solutions.append(rl_spend)
|
||||
list_of_coin_spends.append(rl_spend)
|
||||
|
||||
# Spend consolidating coin
|
||||
puzzle = rl_make_aggregation_puzzle(self.rl_coin_record.coin.puzzle_hash)
|
||||
@ -668,12 +666,12 @@ class RLWallet:
|
||||
self.rl_coin_record.coin.parent_coin_info,
|
||||
self.rl_coin_record.coin.amount,
|
||||
)
|
||||
agg_spend = CoinSolution(consolidating_coin, puzzle, solution)
|
||||
agg_spend = CoinSpend(consolidating_coin, puzzle, solution)
|
||||
|
||||
list_of_coin_solutions.append(agg_spend)
|
||||
list_of_coin_spends.append(agg_spend)
|
||||
aggsig = AugSchemeMPL.aggregate([signature])
|
||||
|
||||
return SpendBundle(list_of_coin_solutions, aggsig)
|
||||
return SpendBundle(list_of_coin_spends, aggsig)
|
||||
|
||||
def rl_get_aggregation_puzzlehash(self, wallet_puzzle):
|
||||
puzzle_hash = rl_make_aggregation_puzzle(wallet_puzzle).get_tree_hash()
|
||||
|
@ -4,13 +4,13 @@ from typing import List, Any
|
||||
import blspy
|
||||
from blspy import AugSchemeMPL
|
||||
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.condition_tools import conditions_dict_for_solution, pkm_pairs_for_conditions_dict
|
||||
|
||||
|
||||
async def sign_coin_solutions(
|
||||
coin_solutions: List[CoinSolution],
|
||||
async def sign_coin_spends(
|
||||
coin_spends: List[CoinSpend],
|
||||
secret_key_for_public_key_f: Any, # Potentially awaitable function from G1Element => Optional[PrivateKey]
|
||||
additional_data: bytes,
|
||||
max_cost: int,
|
||||
@ -18,19 +18,17 @@ async def sign_coin_solutions(
|
||||
signatures: List[blspy.G2Element] = []
|
||||
pk_list: List[blspy.G1Element] = []
|
||||
msg_list: List[bytes] = []
|
||||
for coin_solution in coin_solutions:
|
||||
for coin_spend in coin_spends:
|
||||
# Get AGG_SIG conditions
|
||||
err, conditions_dict, cost = conditions_dict_for_solution(
|
||||
coin_solution.puzzle_reveal, coin_solution.solution, max_cost
|
||||
coin_spend.puzzle_reveal, coin_spend.solution, max_cost
|
||||
)
|
||||
if err or conditions_dict is None:
|
||||
error_msg = f"Sign transaction failed, con:{conditions_dict}, error: {err}"
|
||||
raise ValueError(error_msg)
|
||||
|
||||
# Create signature
|
||||
for pk, msg in pkm_pairs_for_conditions_dict(
|
||||
conditions_dict, bytes(coin_solution.coin.name()), additional_data
|
||||
):
|
||||
for pk, msg in pkm_pairs_for_conditions_dict(conditions_dict, bytes(coin_spend.coin.name()), additional_data):
|
||||
pk_list.append(pk)
|
||||
msg_list.append(msg)
|
||||
if inspect.iscoroutinefunction(secret_key_for_public_key_f):
|
||||
@ -48,4 +46,4 @@ async def sign_coin_solutions(
|
||||
# Aggregate signatures
|
||||
aggsig = AugSchemeMPL.aggregate(signatures)
|
||||
assert AugSchemeMPL.aggregate_verify(pk_list, msg_list, aggsig)
|
||||
return SpendBundle(coin_solutions, aggsig)
|
||||
return SpendBundle(coin_spends, aggsig)
|
@ -11,7 +11,7 @@ from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.util.byte_types import hexstr_to_bytes
|
||||
from chia.util.db_wrapper import DBWrapper
|
||||
from chia.util.hash import std_hash
|
||||
@ -360,14 +360,14 @@ class TradeManager:
|
||||
if trade_offer is not None:
|
||||
offer_spend_bundle: SpendBundle = trade_offer.spend_bundle
|
||||
|
||||
coinsols: List[CoinSolution] = [] # [] of CoinSolutions
|
||||
cc_coinsol_outamounts: Dict[bytes32, List[Tuple[CoinSolution, int]]] = dict()
|
||||
coinsols: List[CoinSpend] = [] # [] of CoinSpends
|
||||
cc_coinsol_outamounts: Dict[bytes32, List[Tuple[CoinSpend, int]]] = dict()
|
||||
aggsig = offer_spend_bundle.aggregated_signature
|
||||
cc_discrepancies: Dict[bytes32, int] = dict()
|
||||
chia_discrepancy = None
|
||||
wallets: Dict[bytes32, Any] = dict() # colour to wallet dict
|
||||
|
||||
for coinsol in offer_spend_bundle.coin_solutions:
|
||||
for coinsol in offer_spend_bundle.coin_spends:
|
||||
puzzle: Program = Program.from_bytes(bytes(coinsol.puzzle_reveal))
|
||||
solution: Program = Program.from_bytes(bytes(coinsol.solution))
|
||||
|
||||
@ -414,7 +414,7 @@ class TradeManager:
|
||||
)
|
||||
if chia_spend_bundle is not None:
|
||||
for coinsol in coinsols:
|
||||
chia_spend_bundle.coin_solutions.append(coinsol)
|
||||
chia_spend_bundle.coin_spends.append(coinsol)
|
||||
|
||||
zero_spend_list: List[SpendBundle] = []
|
||||
spend_bundle = None
|
||||
|
@ -55,15 +55,15 @@ def debug_spend_bundle(spend_bundle, agg_sig_additional_data=bytes([3] * 32)) ->
|
||||
asserted_puzzle_announcements = []
|
||||
|
||||
print("=" * 80)
|
||||
for coin_solution in spend_bundle.coin_solutions:
|
||||
coin = coin_solution.coin
|
||||
puzzle_reveal = Program.from_bytes(bytes(coin_solution.puzzle_reveal))
|
||||
solution = Program.from_bytes(bytes(coin_solution.solution))
|
||||
for coin_spend in spend_bundle.coin_spends:
|
||||
coin = coin_spend.coin
|
||||
puzzle_reveal = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
|
||||
solution = Program.from_bytes(bytes(coin_spend.solution))
|
||||
coin_name = coin.name()
|
||||
|
||||
if puzzle_reveal.get_tree_hash() != coin_solution.coin.puzzle_hash:
|
||||
if puzzle_reveal.get_tree_hash() != coin_spend.coin.puzzle_hash:
|
||||
print("*** BAD PUZZLE REVEAL")
|
||||
print(f"{puzzle_reveal.get_tree_hash().hex()} vs {coin_solution.coin.puzzle_hash.hex()}")
|
||||
print(f"{puzzle_reveal.get_tree_hash().hex()} vs {coin_spend.coin.puzzle_hash.hex()}")
|
||||
print("*" * 80)
|
||||
breakpoint()
|
||||
continue
|
||||
|
@ -63,7 +63,7 @@ def get_discrepancies_for_spend_bundle(
|
||||
) -> Tuple[bool, Optional[Dict], Optional[Exception]]:
|
||||
try:
|
||||
cc_discrepancies: Dict[str, int] = dict()
|
||||
for coinsol in trade_offer.coin_solutions:
|
||||
for coinsol in trade_offer.coin_spends:
|
||||
puzzle: Program = Program.from_bytes(bytes(coinsol.puzzle_reveal))
|
||||
solution: Program = Program.from_bytes(bytes(coinsol.solution))
|
||||
# work out the deficits between coin amount and expected output for each
|
||||
|
@ -11,7 +11,7 @@ from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program, SerializedProgram
|
||||
from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.generator_types import BlockGenerator
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.ints import uint8, uint32, uint64, uint128
|
||||
@ -34,7 +34,7 @@ from chia.wallet.puzzles.puzzle_utils import (
|
||||
make_reserve_fee_condition,
|
||||
)
|
||||
from chia.wallet.secret_key_store import SecretKeyStore
|
||||
from chia.wallet.sign_coin_solutions import sign_coin_solutions
|
||||
from chia.wallet.sign_coin_spends import sign_coin_spends
|
||||
from chia.wallet.transaction_record import TransactionRecord
|
||||
from chia.wallet.util.transaction_type import TransactionType
|
||||
from chia.wallet.util.wallet_types import WalletType
|
||||
@ -163,13 +163,13 @@ class Wallet:
|
||||
|
||||
return public_key
|
||||
|
||||
async def hack_populate_secret_keys_for_coin_solutions(self, coin_solutions: List[CoinSolution]) -> None:
|
||||
async def hack_populate_secret_keys_for_coin_spends(self, coin_spends: List[CoinSpend]) -> None:
|
||||
"""
|
||||
This hack forces secret keys into the `_pk2sk` lookup. This should eventually be replaced
|
||||
by a persistent DB table that can do this look-up directly.
|
||||
"""
|
||||
for coin_solution in coin_solutions:
|
||||
await self.hack_populate_secret_key_for_puzzle_hash(coin_solution.coin.puzzle_hash)
|
||||
for coin_spend in coin_spends:
|
||||
await self.hack_populate_secret_key_for_puzzle_hash(coin_spend.coin.puzzle_hash)
|
||||
|
||||
async def puzzle_for_puzzle_hash(self, puzzle_hash: bytes32) -> Program:
|
||||
public_key = await self.hack_populate_secret_key_for_puzzle_hash(puzzle_hash)
|
||||
@ -293,7 +293,7 @@ class Wallet:
|
||||
primaries_input: Optional[List[Dict[str, Any]]] = None,
|
||||
ignore_max_send_amount: bool = False,
|
||||
announcements_to_consume: Set[Announcement] = None,
|
||||
) -> List[CoinSolution]:
|
||||
) -> List[CoinSpend]:
|
||||
"""
|
||||
Generates a unsigned transaction in form of List(Puzzle, Solutions)
|
||||
Note: this must be called under a wallet state manager lock
|
||||
@ -322,7 +322,7 @@ class Wallet:
|
||||
change = spend_value - total_amount
|
||||
assert change >= 0
|
||||
|
||||
spends: List[CoinSolution] = []
|
||||
spends: List[CoinSpend] = []
|
||||
primary_announcement_hash: Optional[bytes32] = None
|
||||
|
||||
# Check for duplicates
|
||||
@ -359,7 +359,7 @@ class Wallet:
|
||||
solution = self.make_solution(coin_announcements_to_assert={primary_announcement_hash})
|
||||
|
||||
spends.append(
|
||||
CoinSolution(
|
||||
CoinSpend(
|
||||
coin, SerializedProgram.from_bytes(bytes(puzzle)), SerializedProgram.from_bytes(bytes(solution))
|
||||
)
|
||||
)
|
||||
@ -367,9 +367,9 @@ class Wallet:
|
||||
self.log.info(f"Spends is {spends}")
|
||||
return spends
|
||||
|
||||
async def sign_transaction(self, coin_solutions: List[CoinSolution]) -> SpendBundle:
|
||||
return await sign_coin_solutions(
|
||||
coin_solutions,
|
||||
async def sign_transaction(self, coin_spends: List[CoinSpend]) -> SpendBundle:
|
||||
return await sign_coin_spends(
|
||||
coin_spends,
|
||||
self.secret_key_store.secret_key_for_public_key,
|
||||
self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA,
|
||||
self.wallet_state_manager.constants.MAX_BLOCK_COST_CLVM,
|
||||
@ -401,8 +401,8 @@ class Wallet:
|
||||
assert len(transaction) > 0
|
||||
|
||||
self.log.info("About to sign a transaction")
|
||||
await self.hack_populate_secret_keys_for_coin_solutions(transaction)
|
||||
spend_bundle: SpendBundle = await sign_coin_solutions(
|
||||
await self.hack_populate_secret_keys_for_coin_spends(transaction)
|
||||
spend_bundle: SpendBundle = await sign_coin_spends(
|
||||
transaction,
|
||||
self.secret_key_store.secret_key_for_public_key,
|
||||
self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA,
|
||||
@ -463,10 +463,10 @@ class Wallet:
|
||||
primaries = [{"puzzlehash": newpuzhash, "amount": chia_amount}]
|
||||
solution = self.make_solution(primaries=primaries)
|
||||
output_created = coin
|
||||
list_of_solutions.append(CoinSolution(coin, puzzle, solution))
|
||||
list_of_solutions.append(CoinSpend(coin, puzzle, solution))
|
||||
|
||||
await self.hack_populate_secret_keys_for_coin_solutions(list_of_solutions)
|
||||
spend_bundle = await sign_coin_solutions(
|
||||
await self.hack_populate_secret_keys_for_coin_spends(list_of_solutions)
|
||||
spend_bundle = await sign_coin_spends(
|
||||
list_of_solutions,
|
||||
self.secret_key_store.secret_key_for_public_key,
|
||||
self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA,
|
||||
|
@ -6,7 +6,7 @@ import aiosqlite
|
||||
from chia.consensus.block_record import BlockRecord
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.header_block import HeaderBlock
|
||||
from chia.util.db_wrapper import DBWrapper
|
||||
from chia.util.ints import uint32, uint64
|
||||
@ -18,7 +18,7 @@ from chia.wallet.block_record import HeaderBlockRecord
|
||||
@dataclass(frozen=True)
|
||||
@streamable
|
||||
class AdditionalCoinSpends(Streamable):
|
||||
coin_spends_list: List[CoinSolution]
|
||||
coin_spends_list: List[CoinSpend]
|
||||
|
||||
|
||||
class WalletBlockStore:
|
||||
@ -79,7 +79,7 @@ class WalletBlockStore:
|
||||
self,
|
||||
header_block_record: HeaderBlockRecord,
|
||||
block_record: BlockRecord,
|
||||
additional_coin_spends: List[CoinSolution],
|
||||
additional_coin_spends: List[CoinSpend],
|
||||
):
|
||||
"""
|
||||
Adds a block record to the database. This block record is assumed to be connected
|
||||
@ -157,7 +157,7 @@ class WalletBlockStore:
|
||||
else:
|
||||
return None
|
||||
|
||||
async def get_additional_coin_spends(self, header_hash: bytes32) -> Optional[List[CoinSolution]]:
|
||||
async def get_additional_coin_spends(self, header_hash: bytes32) -> Optional[List[CoinSpend]]:
|
||||
cursor = await self.db.execute(
|
||||
"SELECT spends_list_blob from additional_coin_spends WHERE header_hash=?", (header_hash.hex(),)
|
||||
)
|
||||
|
@ -16,7 +16,7 @@ from chia.consensus.full_block_to_block_record import block_to_block_record
|
||||
from chia.consensus.multiprocess_validation import PreValidationResult, pre_validate_blocks_multiprocessing
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.header_block import HeaderBlock
|
||||
from chia.types.unfinished_header_block import UnfinishedHeaderBlock
|
||||
from chia.util.errors import Err, ValidationError
|
||||
@ -156,7 +156,7 @@ class WalletBlockchain(BlockchainInterface):
|
||||
pre_validation_result: Optional[PreValidationResult] = None,
|
||||
trusted: bool = False,
|
||||
fork_point_with_peak: Optional[uint32] = None,
|
||||
additional_coin_spends: List[CoinSolution] = None,
|
||||
additional_coin_spends: List[CoinSpend] = None,
|
||||
) -> Tuple[ReceiveBlockResult, Optional[Err], Optional[uint32]]:
|
||||
"""
|
||||
Adds a new block into the blockchain, if it's valid and connected to the current
|
||||
@ -268,7 +268,7 @@ class WalletBlockchain(BlockchainInterface):
|
||||
block_record: BlockRecord,
|
||||
genesis: bool,
|
||||
fork_point_with_peak: Optional[uint32],
|
||||
additional_coin_spends_from_wallet: Optional[List[CoinSolution]],
|
||||
additional_coin_spends_from_wallet: Optional[List[CoinSpend]],
|
||||
heights_changed: Set[Tuple[uint32, Optional[bytes32]]],
|
||||
) -> Tuple[Optional[uint32], List[BlockRecord]]:
|
||||
"""
|
||||
@ -318,7 +318,7 @@ class WalletBlockchain(BlockchainInterface):
|
||||
del self.__sub_epoch_summaries[height]
|
||||
|
||||
# Collect all blocks from fork point to new peak
|
||||
blocks_to_add: List[Tuple[HeaderBlockRecord, BlockRecord, List[CoinSolution]]] = []
|
||||
blocks_to_add: List[Tuple[HeaderBlockRecord, BlockRecord, List[CoinSpend]]] = []
|
||||
curr = block_record.header_hash
|
||||
while fork_h < 0 or curr != self.height_to_hash(uint32(fork_h)):
|
||||
fetched_header_block: Optional[HeaderBlockRecord] = await self.block_store.get_header_block_record(curr)
|
||||
|
@ -32,7 +32,7 @@ from chia.server.server import ChiaServer
|
||||
from chia.server.ws_connection import WSChiaConnection
|
||||
from chia.types.blockchain_format.coin import Coin, hash_coin_list
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.header_block import HeaderBlock
|
||||
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
||||
from chia.types.peer_info import PeerInfo
|
||||
@ -405,7 +405,7 @@ class WalletNode:
|
||||
raise ValueError("Failed to fetch removals")
|
||||
|
||||
# If there is a launcher created, or we have a singleton spent, fetches the required solutions
|
||||
additional_coin_spends: List[CoinSolution] = await self.get_additional_coin_spends(
|
||||
additional_coin_spends: List[CoinSpend] = await self.get_additional_coin_spends(
|
||||
peer, block, added_coins, removed_coins
|
||||
)
|
||||
|
||||
@ -715,7 +715,7 @@ class WalletNode:
|
||||
raise ValueError("Failed to fetch removals")
|
||||
|
||||
# If there is a launcher created, or we have a singleton spent, fetches the required solutions
|
||||
additional_coin_spends: List[CoinSolution] = await self.get_additional_coin_spends(
|
||||
additional_coin_spends: List[CoinSpend] = await self.get_additional_coin_spends(
|
||||
peer, header_block, added_coins, removed_coins
|
||||
)
|
||||
|
||||
@ -860,19 +860,19 @@ class WalletNode:
|
||||
return False
|
||||
return True
|
||||
|
||||
async def fetch_puzzle_solution(self, peer, height: uint32, coin: Coin) -> CoinSolution:
|
||||
async def fetch_puzzle_solution(self, peer, height: uint32, coin: Coin) -> CoinSpend:
|
||||
solution_response = await peer.request_puzzle_solution(
|
||||
wallet_protocol.RequestPuzzleSolution(coin.name(), height)
|
||||
)
|
||||
if solution_response is None or not isinstance(solution_response, wallet_protocol.RespondPuzzleSolution):
|
||||
raise ValueError(f"Was not able to obtain solution {solution_response}")
|
||||
return CoinSolution(coin, solution_response.response.puzzle, solution_response.response.solution)
|
||||
return CoinSpend(coin, solution_response.response.puzzle, solution_response.response.solution)
|
||||
|
||||
async def get_additional_coin_spends(
|
||||
self, peer, block, added_coins: List[Coin], removed_coins: List[Coin]
|
||||
) -> List[CoinSolution]:
|
||||
) -> List[CoinSpend]:
|
||||
assert self.wallet_state_manager is not None
|
||||
additional_coin_spends: List[CoinSolution] = []
|
||||
additional_coin_spends: List[CoinSpend] = []
|
||||
if len(removed_coins) > 0:
|
||||
removed_coin_ids = set([coin.name() for coin in removed_coins])
|
||||
all_added_coins = await self.get_additions(peer, block, [], get_all_additions=True)
|
||||
@ -882,7 +882,7 @@ class WalletNode:
|
||||
for coin in all_added_coins:
|
||||
# This searches specifically for a launcher being created, and adds the solution of the launcher
|
||||
if coin.puzzle_hash == SINGLETON_LAUNCHER_HASH and coin.parent_coin_info in removed_coin_ids:
|
||||
cs: CoinSolution = await self.fetch_puzzle_solution(peer, block.height, coin)
|
||||
cs: CoinSpend = await self.fetch_puzzle_solution(peer, block.height, coin)
|
||||
additional_coin_spends.append(cs)
|
||||
# Apply this coin solution, which might add things to interested list
|
||||
await self.wallet_state_manager.get_next_interesting_coin_ids(cs, False)
|
||||
|
@ -3,7 +3,7 @@ from typing import List, Tuple, Dict, Optional
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.util.db_wrapper import DBWrapper
|
||||
from chia.util.ints import uint32
|
||||
|
||||
@ -13,7 +13,7 @@ log = logging.getLogger(__name__)
|
||||
class WalletPoolStore:
|
||||
db_connection: aiosqlite.Connection
|
||||
db_wrapper: DBWrapper
|
||||
_state_transitions_cache: Dict[int, List[Tuple[uint32, CoinSolution]]]
|
||||
_state_transitions_cache: Dict[int, List[Tuple[uint32, CoinSpend]]]
|
||||
|
||||
@classmethod
|
||||
async def create(cls, wrapper: DBWrapper):
|
||||
@ -40,7 +40,7 @@ class WalletPoolStore:
|
||||
async def add_spend(
|
||||
self,
|
||||
wallet_id: int,
|
||||
spend: CoinSolution,
|
||||
spend: CoinSpend,
|
||||
height: uint32,
|
||||
) -> None:
|
||||
"""
|
||||
@ -51,7 +51,7 @@ class WalletPoolStore:
|
||||
"""
|
||||
if wallet_id not in self._state_transitions_cache:
|
||||
self._state_transitions_cache[wallet_id] = []
|
||||
all_state_transitions: List[Tuple[uint32, CoinSolution]] = self.get_spends_for_wallet(wallet_id)
|
||||
all_state_transitions: List[Tuple[uint32, CoinSpend]] = self.get_spends_for_wallet(wallet_id)
|
||||
|
||||
if (height, spend) in all_state_transitions:
|
||||
return
|
||||
@ -75,7 +75,7 @@ class WalletPoolStore:
|
||||
)
|
||||
await cursor.close()
|
||||
|
||||
def get_spends_for_wallet(self, wallet_id: int) -> List[Tuple[uint32, CoinSolution]]:
|
||||
def get_spends_for_wallet(self, wallet_id: int) -> List[Tuple[uint32, CoinSpend]]:
|
||||
"""
|
||||
Retrieves all entries for a wallet ID from the cache, works even if commit is not called yet.
|
||||
"""
|
||||
@ -91,11 +91,11 @@ class WalletPoolStore:
|
||||
await cursor.close()
|
||||
self._state_transitions_cache = {}
|
||||
for row in rows:
|
||||
_, wallet_id, height, coin_solution_bytes = row
|
||||
coin_solution: CoinSolution = CoinSolution.from_bytes(coin_solution_bytes)
|
||||
_, wallet_id, height, coin_spend_bytes = row
|
||||
coin_spend: CoinSpend = CoinSpend.from_bytes(coin_spend_bytes)
|
||||
if wallet_id not in self._state_transitions_cache:
|
||||
self._state_transitions_cache[wallet_id] = []
|
||||
self._state_transitions_cache[wallet_id].append((height, coin_solution))
|
||||
self._state_transitions_cache[wallet_id].append((height, coin_spend))
|
||||
|
||||
async def rollback(self, height: int, wallet_id_arg: int) -> None:
|
||||
"""
|
||||
|
@ -24,7 +24,7 @@ from chia.protocols.wallet_protocol import PuzzleSolutionResponse, RespondPuzzle
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.full_block import FullBlock
|
||||
from chia.types.header_block import HeaderBlock
|
||||
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
||||
@ -567,7 +567,7 @@ class WalletStateManager:
|
||||
removals: List[Coin],
|
||||
additions: List[Coin],
|
||||
block: BlockRecord,
|
||||
additional_coin_spends: List[CoinSolution],
|
||||
additional_coin_spends: List[CoinSpend],
|
||||
):
|
||||
height: uint32 = block.height
|
||||
for coin in additions:
|
||||
@ -1213,7 +1213,7 @@ class WalletStateManager:
|
||||
def get_peak(self) -> Optional[BlockRecord]:
|
||||
return self.blockchain.get_peak()
|
||||
|
||||
async def get_next_interesting_coin_ids(self, spend: CoinSolution, in_transaction: bool) -> List[bytes32]:
|
||||
async def get_next_interesting_coin_ids(self, spend: CoinSpend, in_transaction: bool) -> List[bytes32]:
|
||||
pool_wallet_interested: List[bytes32] = PoolWallet.get_next_interesting_coin_ids(spend)
|
||||
for coin_id in pool_wallet_interested:
|
||||
await self.interested_store.add_interested_coin_id(coin_id, in_transaction)
|
||||
|
@ -67,10 +67,10 @@ class CoinStore:
|
||||
puzzle_announcements: Set[bytes32] = set()
|
||||
|
||||
conditions_dicts = []
|
||||
for coin_solution in spend_bundle.coin_solutions:
|
||||
assert isinstance(coin_solution.coin, Coin)
|
||||
for coin_spend in spend_bundle.coin_spends:
|
||||
assert isinstance(coin_spend.coin, Coin)
|
||||
err, conditions_dict, cost = conditions_dict_for_solution(
|
||||
coin_solution.puzzle_reveal, coin_solution.solution, max_cost
|
||||
coin_spend.puzzle_reveal, coin_spend.solution, max_cost
|
||||
)
|
||||
if conditions_dict is None:
|
||||
raise BadSpendBundleError(f"clvm validation failure {err}")
|
||||
@ -78,13 +78,13 @@ class CoinStore:
|
||||
coin_announcements.update(
|
||||
coin_announcement_names_for_conditions_dict(
|
||||
conditions_dict,
|
||||
coin_solution.coin,
|
||||
coin_spend.coin,
|
||||
)
|
||||
)
|
||||
puzzle_announcements.update(
|
||||
puzzle_announcement_names_for_conditions_dict(
|
||||
conditions_dict,
|
||||
coin_solution.coin,
|
||||
coin_spend.coin,
|
||||
)
|
||||
)
|
||||
|
||||
@ -100,12 +100,12 @@ class CoinStore:
|
||||
uint64(now.seconds),
|
||||
)
|
||||
|
||||
for coin_solution, conditions_dict in zip(spend_bundle.coin_solutions, conditions_dicts): # noqa
|
||||
for coin_spend, conditions_dict in zip(spend_bundle.coin_spends, conditions_dicts): # noqa
|
||||
prev_transaction_block_height = now.height
|
||||
timestamp = now.seconds
|
||||
coin_record = ephemeral_db.get(coin_solution.coin.name())
|
||||
coin_record = ephemeral_db.get(coin_spend.coin.name())
|
||||
if coin_record is None:
|
||||
raise BadSpendBundleError(f"coin not found for id 0x{coin_solution.coin.name().hex()}") # noqa
|
||||
raise BadSpendBundleError(f"coin not found for id 0x{coin_spend.coin.name().hex()}") # noqa
|
||||
err = mempool_check_conditions_dict(
|
||||
coin_record,
|
||||
coin_announcements,
|
||||
@ -136,7 +136,7 @@ class CoinStore:
|
||||
coin_name = spent_coin.name()
|
||||
coin_record = self._db[coin_name]
|
||||
self._db[coin_name] = replace(coin_record, spent_block_index=now.height, spent=True)
|
||||
return additions, spend_bundle.coin_solutions
|
||||
return additions, spend_bundle.coin_spends
|
||||
|
||||
def coins_for_puzzle_hash(self, puzzle_hash: bytes32) -> Iterator[Coin]:
|
||||
for coin_name in self._ph_index[puzzle_hash]:
|
||||
|
@ -27,8 +27,8 @@ wallet_program_files = set(
|
||||
"chia/wallet/puzzles/singleton_top_layer.clvm",
|
||||
"chia/wallet/puzzles/did_innerpuz.clvm",
|
||||
"chia/wallet/puzzles/decompress_puzzle.clvm",
|
||||
"chia/wallet/puzzles/decompress_coin_solution_entry_with_prefix.clvm",
|
||||
"chia/wallet/puzzles/decompress_coin_solution_entry.clvm",
|
||||
"chia/wallet/puzzles/decompress_coin_spend_entry_with_prefix.clvm",
|
||||
"chia/wallet/puzzles/decompress_coin_spend_entry.clvm",
|
||||
"chia/wallet/puzzles/block_program_zero.clvm",
|
||||
"chia/wallet/puzzles/test_generator_deserialize.clvm",
|
||||
"chia/wallet/puzzles/test_multiple_generator_input_arguments.clvm",
|
||||
|
@ -5,7 +5,7 @@ from blspy import AugSchemeMPL, BasicSchemeMPL, G1Element, G2Element
|
||||
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.condition_tools import ConditionOpcode
|
||||
from chia.util.hash import std_hash
|
||||
@ -69,9 +69,9 @@ def do_test_spend(
|
||||
coin = coin_db.farm_coin(puzzle_hash, farm_time)
|
||||
|
||||
# spend it
|
||||
coin_solution = CoinSolution(coin, puzzle_reveal, solution)
|
||||
coin_spend = CoinSpend(coin, puzzle_reveal, solution)
|
||||
|
||||
spend_bundle = SpendBundle([coin_solution], G2Element())
|
||||
spend_bundle = SpendBundle([coin_spend], G2Element())
|
||||
coin_db.update_coin_store_for_spend_bundle(spend_bundle, spend_time, MAX_BLOCK_COST_CLVM)
|
||||
|
||||
# ensure all outputs are there
|
||||
@ -84,10 +84,10 @@ def do_test_spend(
|
||||
|
||||
# make sure we can actually sign the solution
|
||||
signatures = []
|
||||
for coin_solution in spend_bundle.coin_solutions:
|
||||
signature = key_lookup.signature_for_solution(coin_solution, bytes([2] * 32))
|
||||
for coin_spend in spend_bundle.coin_spends:
|
||||
signature = key_lookup.signature_for_solution(coin_spend, bytes([2] * 32))
|
||||
signatures.append(signature)
|
||||
return SpendBundle(spend_bundle.coin_solutions, AugSchemeMPL.aggregate(signatures))
|
||||
return SpendBundle(spend_bundle.coin_spends, AugSchemeMPL.aggregate(signatures))
|
||||
|
||||
|
||||
def default_payments_and_conditions(
|
||||
|
@ -8,7 +8,7 @@ from blspy import AugSchemeMPL, G1Element, G2Element, PrivateKey
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.condition_tools import ConditionOpcode
|
||||
from chia.util.ints import uint64
|
||||
@ -57,7 +57,7 @@ def make_and_spend_bundle(
|
||||
db: CoinStore,
|
||||
coin: Coin,
|
||||
delegated_puzzle: Program,
|
||||
coinsols: List[CoinSolution],
|
||||
coinsols: List[CoinSpend],
|
||||
exception: Optional[Exception] = None,
|
||||
ex_msg: str = "",
|
||||
fail_msg: str = "",
|
||||
@ -119,7 +119,7 @@ class TestSingleton(TestCase):
|
||||
delegated_puzzle: Program = p2_conditions.puzzle_for_conditions(conditions) # noqa
|
||||
full_solution: Program = p2_delegated_puzzle_or_hidden_puzzle.solution_for_conditions(conditions) # noqa
|
||||
|
||||
starting_coinsol = CoinSolution(
|
||||
starting_coinsol = CoinSpend(
|
||||
starting_coin,
|
||||
starting_puzzle,
|
||||
full_solution,
|
||||
@ -165,7 +165,7 @@ class TestSingleton(TestCase):
|
||||
inner_solution,
|
||||
)
|
||||
|
||||
singleton_eve_coinsol = CoinSolution(
|
||||
singleton_eve_coinsol = CoinSpend(
|
||||
singleton_eve,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -189,7 +189,7 @@ class TestSingleton(TestCase):
|
||||
inner_solution,
|
||||
)
|
||||
|
||||
singleton_coinsol = CoinSolution(
|
||||
singleton_coinsol = CoinSpend(
|
||||
singleton,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -240,7 +240,7 @@ class TestSingleton(TestCase):
|
||||
singleton_eve.amount,
|
||||
inner_solution,
|
||||
)
|
||||
singleton_claim_coinsol = CoinSolution(
|
||||
singleton_claim_coinsol = CoinSpend(
|
||||
singleton_child,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -292,7 +292,7 @@ class TestSingleton(TestCase):
|
||||
singleton_eve.amount,
|
||||
inner_solution,
|
||||
)
|
||||
delay_claim_coinsol = CoinSolution(
|
||||
delay_claim_coinsol = CoinSpend(
|
||||
singleton_child,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -348,7 +348,7 @@ class TestSingleton(TestCase):
|
||||
lineage_proof, singleton_child.amount, inner_solution
|
||||
)
|
||||
|
||||
multi_odd_coinsol = CoinSolution(
|
||||
multi_odd_coinsol = CoinSpend(
|
||||
singleton_child,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -384,7 +384,7 @@ class TestSingleton(TestCase):
|
||||
lineage_proof, singleton_child.amount, inner_solution
|
||||
)
|
||||
|
||||
no_odd_coinsol = CoinSolution(
|
||||
no_odd_coinsol = CoinSpend(
|
||||
singleton_child,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -426,7 +426,7 @@ class TestSingleton(TestCase):
|
||||
lineage_proof, singleton_child.amount, inner_solution
|
||||
)
|
||||
|
||||
singleton_even_coinsol = CoinSolution(
|
||||
singleton_even_coinsol = CoinSpend(
|
||||
singleton_child,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -465,7 +465,7 @@ class TestSingleton(TestCase):
|
||||
inner_solution,
|
||||
)
|
||||
|
||||
evil_coinsol = CoinSolution(
|
||||
evil_coinsol = CoinSpend(
|
||||
evil_coin,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
@ -502,7 +502,7 @@ class TestSingleton(TestCase):
|
||||
lineage_proof, singleton_child.amount, inner_solution
|
||||
)
|
||||
|
||||
melt_coinsol = CoinSolution(
|
||||
melt_coinsol = CoinSpend(
|
||||
singleton_child,
|
||||
puzzle_reveal,
|
||||
full_solution,
|
||||
|
@ -19,7 +19,7 @@ from chia.consensus.constants import ConsensusConstants
|
||||
from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.coin_record import CoinRecord
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.full_block import FullBlock
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
@ -112,8 +112,8 @@ async def check_conditions(
|
||||
blocks = initial_blocks()
|
||||
coin = list(blocks[spend_reward_index].get_included_reward_coins())[0]
|
||||
|
||||
coin_solution = CoinSolution(coin, EASY_PUZZLE, condition_solution)
|
||||
spend_bundle = SpendBundle([coin_solution], G2Element())
|
||||
coin_spend = CoinSpend(coin, EASY_PUZZLE, condition_solution)
|
||||
spend_bundle = SpendBundle([coin_spend], G2Element())
|
||||
|
||||
# now let's try to create a block with the spend bundle and ensure that it doesn't validate
|
||||
|
||||
|
@ -15,7 +15,7 @@ from chia.protocols import full_node_protocol
|
||||
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
|
||||
from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.condition_with_args import ConditionWithArgs
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
@ -1246,22 +1246,22 @@ class TestMempoolManager:
|
||||
|
||||
coin = list(blocks[-1].get_included_reward_coins())[0]
|
||||
spend_bundle_0 = generate_test_spend_bundle(coin)
|
||||
unsigned: List[CoinSolution] = spend_bundle_0.coin_solutions
|
||||
unsigned: List[CoinSpend] = spend_bundle_0.coin_spends
|
||||
|
||||
assert len(unsigned) == 1
|
||||
coin_solution: CoinSolution = unsigned[0]
|
||||
coin_spend: CoinSpend = unsigned[0]
|
||||
|
||||
err, con, cost = conditions_for_solution(coin_solution.puzzle_reveal, coin_solution.solution, INFINITE_COST)
|
||||
err, con, cost = conditions_for_solution(coin_spend.puzzle_reveal, coin_spend.solution, INFINITE_COST)
|
||||
assert con is not None
|
||||
|
||||
# TODO(straya): fix this test
|
||||
# puzzle, solution = list(coin_solution.solution.as_iter())
|
||||
# puzzle, solution = list(coin_spend.solution.as_iter())
|
||||
# conditions_dict = conditions_by_opcode(con)
|
||||
|
||||
# pkm_pairs = pkm_pairs_for_conditions_dict(conditions_dict, coin_solution.coin.name())
|
||||
# pkm_pairs = pkm_pairs_for_conditions_dict(conditions_dict, coin_spend.coin.name())
|
||||
# assert len(pkm_pairs) == 1
|
||||
#
|
||||
# assert pkm_pairs[0][1] == solution.rest().first().get_tree_hash() + coin_solution.coin.name()
|
||||
# assert pkm_pairs[0][1] == solution.rest().first().get_tree_hash() + coin_spend.coin.name()
|
||||
#
|
||||
# spend_bundle = WALLET_A.sign_transaction(unsigned)
|
||||
# assert spend_bundle is not None
|
||||
|
@ -5,7 +5,7 @@ import blspy
|
||||
from chia.full_node.bundle_tools import simple_solution_generator
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.generator_types import BlockGenerator
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
@ -50,15 +50,15 @@ def make_spend_bundle(count: int) -> SpendBundle:
|
||||
puzzle_hash_db: Dict = dict()
|
||||
coins = [make_fake_coin(_, puzzle_hash_db) for _ in range(count)]
|
||||
|
||||
coin_solutions = []
|
||||
coin_spends = []
|
||||
for coin in coins:
|
||||
puzzle_reveal = puzzle_hash_db[coin.puzzle_hash]
|
||||
conditions = conditions_for_payment(coin)
|
||||
solution = solution_for_conditions(conditions)
|
||||
coin_solution = CoinSolution(coin, puzzle_reveal, solution)
|
||||
coin_solutions.append(coin_solution)
|
||||
coin_spend = CoinSpend(coin, puzzle_reveal, solution)
|
||||
coin_spends.append(coin_spend)
|
||||
|
||||
spend_bundle = SpendBundle(coin_solutions, blspy.G2Element())
|
||||
spend_bundle = SpendBundle(coin_spends, blspy.G2Element())
|
||||
return spend_bundle
|
||||
|
||||
|
||||
|
@ -5,11 +5,11 @@ from unittest import TestCase
|
||||
|
||||
from chia.full_node.bundle_tools import (
|
||||
bundle_suitable_for_compression,
|
||||
compressed_coin_solution_entry_list,
|
||||
compressed_coin_spend_entry_list,
|
||||
compressed_spend_bundle_solution,
|
||||
match_standard_transaction_at_any_index,
|
||||
simple_solution_generator,
|
||||
spend_bundle_to_serialized_coin_solution_entry_list,
|
||||
spend_bundle_to_serialized_coin_spend_entry_list,
|
||||
)
|
||||
from chia.full_node.generator import run_generator, create_generator_args
|
||||
from chia.types.blockchain_format.program import Program, SerializedProgram, INFINITE_COST
|
||||
@ -31,10 +31,10 @@ TEST_GEN_DESERIALIZE = load_clvm("test_generator_deserialize.clvm", package_or_r
|
||||
DESERIALIZE_MOD = load_clvm("chialisp_deserialisation.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
|
||||
DECOMPRESS_PUZZLE = load_clvm("decompress_puzzle.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
DECOMPRESS_CSE = load_clvm("decompress_coin_solution_entry.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
DECOMPRESS_CSE = load_clvm("decompress_coin_spend_entry.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
|
||||
DECOMPRESS_CSE_WITH_PREFIX = load_clvm(
|
||||
"decompress_coin_solution_entry_with_prefix.clvm", package_or_requirement="chia.wallet.puzzles"
|
||||
"decompress_coin_spend_entry_with_prefix.clvm", package_or_requirement="chia.wallet.puzzles"
|
||||
)
|
||||
DECOMPRESS_BLOCK = load_clvm("block_program_zero.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
TEST_MULTIPLE = load_clvm("test_multiple_generator_input_arguments.clvm", package_or_requirement="chia.wallet.puzzles")
|
||||
@ -61,7 +61,7 @@ def create_multiple_ref_generator(args: MultipleCompressorArg, spend_bundle: Spe
|
||||
"""
|
||||
Decompress a transaction by referencing bytes from multiple input generator references
|
||||
"""
|
||||
compressed_cse_list = compressed_coin_solution_entry_list(spend_bundle)
|
||||
compressed_cse_list = compressed_coin_spend_entry_list(spend_bundle)
|
||||
program = TEST_MULTIPLE.curry(
|
||||
DECOMPRESS_PUZZLE,
|
||||
DECOMPRESS_CSE_WITH_PREFIX,
|
||||
@ -80,14 +80,14 @@ def create_multiple_ref_generator(args: MultipleCompressorArg, spend_bundle: Spe
|
||||
return BlockGenerator(program, generator_args)
|
||||
|
||||
|
||||
def spend_bundle_to_coin_solution_entry_list(bundle: SpendBundle) -> List[Any]:
|
||||
def spend_bundle_to_coin_spend_entry_list(bundle: SpendBundle) -> List[Any]:
|
||||
r = []
|
||||
for coin_solution in bundle.coin_solutions:
|
||||
for coin_spend in bundle.coin_spends:
|
||||
entry = [
|
||||
coin_solution.coin.parent_coin_info,
|
||||
sexp_from_stream(io.BytesIO(bytes(coin_solution.puzzle_reveal)), SExp.to),
|
||||
coin_solution.coin.amount,
|
||||
sexp_from_stream(io.BytesIO(bytes(coin_solution.solution)), SExp.to),
|
||||
coin_spend.coin.parent_coin_info,
|
||||
sexp_from_stream(io.BytesIO(bytes(coin_spend.puzzle_reveal)), SExp.to),
|
||||
coin_spend.coin.amount,
|
||||
sexp_from_stream(io.BytesIO(bytes(coin_spend.solution)), SExp.to),
|
||||
]
|
||||
r.append(entry)
|
||||
return r
|
||||
@ -136,11 +136,11 @@ class TestCompression(TestCase):
|
||||
assert result_s is not None
|
||||
assert result_c == result_s
|
||||
|
||||
def test_spend_byndle_coin_solution(self):
|
||||
def test_spend_byndle_coin_spend(self):
|
||||
for i in range(0, 10):
|
||||
sb: SpendBundle = make_spend_bundle(i)
|
||||
cs1 = SExp.to(spend_bundle_to_coin_solution_entry_list(sb)).as_bin()
|
||||
cs2 = spend_bundle_to_serialized_coin_solution_entry_list(sb)
|
||||
cs1 = SExp.to(spend_bundle_to_coin_spend_entry_list(sb)).as_bin()
|
||||
cs2 = spend_bundle_to_serialized_coin_spend_entry_list(sb)
|
||||
assert cs1 == cs2
|
||||
|
||||
|
||||
@ -180,7 +180,7 @@ class TestDecompression(TestCase):
|
||||
# print(out)
|
||||
|
||||
def test_decompress_cse(self):
|
||||
"""Decompress a single CSE / CoinSolutionEntry"""
|
||||
"""Decompress a single CSE / CoinSpendEntry"""
|
||||
cse0 = binutils.assemble(
|
||||
"((0x0000000000000000000000000000000000000000000000000000000000000000 0x0186a0) (0xb081963921826355dcb6c355ccf9c2637c18adf7d38ee44d803ea9ca41587e48c913d8d46896eb830aeadfc13144a8eac3 (() (q (51 0x6b7a83babea1eec790c947db4464ab657dbe9b887fe9acc247062847b8c2a8a9 0x0186a0)) ())))"
|
||||
) # noqa
|
||||
@ -232,7 +232,7 @@ class TestDecompression(TestCase):
|
||||
start = 2 + 44
|
||||
end = start + 238
|
||||
|
||||
# (mod (decompress_puzzle decompress_coin_solution_entry start end compressed_cses deserialize generator_list reserved_arg)
|
||||
# (mod (decompress_puzzle decompress_coin_spend_entry start end compressed_cses deserialize generator_list reserved_arg)
|
||||
# cost, out = DECOMPRESS_BLOCK.run_with_cost(INFINITE_COST, [DECOMPRESS_PUZZLE, DECOMPRESS_CSE, start, Program.to(end), cse0, DESERIALIZE_MOD, bytes(original_generator)])
|
||||
cost, out = DECOMPRESS_BLOCK.run_with_cost(
|
||||
INFINITE_COST,
|
||||
@ -274,7 +274,7 @@ class TestDecompression(TestCase):
|
||||
start = 2 + 44
|
||||
end = start + 238
|
||||
|
||||
# (mod (decompress_puzzle decompress_coin_solution_entry start end compressed_cses deserialize generator_list reserved_arg)
|
||||
# (mod (decompress_puzzle decompress_coin_spend_entry start end compressed_cses deserialize generator_list reserved_arg)
|
||||
# cost, out = DECOMPRESS_BLOCK.run_with_cost(INFINITE_COST, [DECOMPRESS_PUZZLE, DECOMPRESS_CSE, start, Program.to(end), cse0, DESERIALIZE_MOD, bytes(original_generator)])
|
||||
p = DECOMPRESS_BLOCK.curry(DECOMPRESS_PUZZLE, DECOMPRESS_CSE_WITH_PREFIX, start, Program.to(end))
|
||||
cost, out = p.run_with_cost(INFINITE_COST, [cse2, DESERIALIZE_MOD, [bytes(original_generator)]])
|
||||
|
@ -8,7 +8,7 @@ from blspy import AugSchemeMPL, G1Element, G2Element, PrivateKey
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.ints import uint64, uint32
|
||||
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
||||
@ -27,7 +27,7 @@ from chia.pools.pool_puzzles import (
|
||||
create_p2_singleton_puzzle,
|
||||
create_absorb_spend,
|
||||
create_travel_spend,
|
||||
get_most_recent_singleton_coin_from_coin_solution,
|
||||
get_most_recent_singleton_coin_from_coin_spend,
|
||||
get_delayed_puz_info_from_launcher_spend,
|
||||
SINGLETON_MOD_HASH,
|
||||
launcher_id_to_p2_puzzle_hash,
|
||||
@ -147,7 +147,7 @@ class TestPoolPuzzles(TestCase):
|
||||
# Creating solution for standard transaction
|
||||
delegated_puzzle: Program = puzzle_for_conditions(conditions)
|
||||
full_solution: Program = solution_for_conditions(conditions)
|
||||
starting_coinsol = CoinSolution(
|
||||
starting_coinsol = CoinSpend(
|
||||
starting_coin,
|
||||
starting_puzzle,
|
||||
full_solution,
|
||||
@ -206,7 +206,7 @@ class TestPoolPuzzles(TestCase):
|
||||
assert launcher_id_to_p2_puzzle_hash(launcher_id, DELAY_TIME, DELAY_PH) == p2_singleton_ph
|
||||
assert get_seconds_and_delayed_puzhash_from_p2_singleton_puzzle(p2_singleton_puz) == (DELAY_TIME, DELAY_PH)
|
||||
coin_db.farm_coin(p2_singleton_ph, time, 1750000000000)
|
||||
coin_sols: List[CoinSolution] = create_absorb_spend(
|
||||
coin_sols: List[CoinSpend] = create_absorb_spend(
|
||||
launcher_coinsol,
|
||||
pool_state,
|
||||
launcher_coin,
|
||||
@ -223,13 +223,13 @@ class TestPoolPuzzles(TestCase):
|
||||
)
|
||||
|
||||
# ABSORB A NON EXISTENT REWARD (Negative test)
|
||||
last_coinsol: CoinSolution = list(
|
||||
last_coinsol: CoinSpend = list(
|
||||
filter(
|
||||
lambda e: e.coin.amount == START_AMOUNT,
|
||||
coin_sols,
|
||||
)
|
||||
)[0]
|
||||
coin_sols: List[CoinSolution] = create_absorb_spend(
|
||||
coin_sols: List[CoinSpend] = create_absorb_spend(
|
||||
last_coinsol,
|
||||
pool_state,
|
||||
launcher_coin,
|
||||
@ -239,7 +239,7 @@ class TestPoolPuzzles(TestCase):
|
||||
DELAY_PH, # height
|
||||
)
|
||||
# filter for only the singleton solution
|
||||
singleton_coinsol: CoinSolution = list(
|
||||
singleton_coinsol: CoinSpend = list(
|
||||
filter(
|
||||
lambda e: e.coin.amount == START_AMOUNT,
|
||||
coin_sols,
|
||||
@ -264,7 +264,7 @@ class TestPoolPuzzles(TestCase):
|
||||
)
|
||||
coin_db._add_coin_entry(non_reward_p2_singleton, time)
|
||||
# construct coin solution for the p2_singleton coin
|
||||
bad_coinsol = CoinSolution(
|
||||
bad_coinsol = CoinSpend(
|
||||
non_reward_p2_singleton,
|
||||
p2_singleton_puz,
|
||||
Program.to(
|
||||
@ -286,7 +286,7 @@ class TestPoolPuzzles(TestCase):
|
||||
|
||||
# ENTER WAITING ROOM
|
||||
# find the singleton
|
||||
singleton = get_most_recent_singleton_coin_from_coin_solution(last_coinsol)
|
||||
singleton = get_most_recent_singleton_coin_from_coin_spend(last_coinsol)
|
||||
# get the relevant coin solution
|
||||
travel_coinsol, _ = create_travel_spend(
|
||||
last_coinsol,
|
||||
@ -314,7 +314,7 @@ class TestPoolPuzzles(TestCase):
|
||||
|
||||
# ESCAPE TOO FAST (Negative test)
|
||||
# find the singleton
|
||||
singleton = get_most_recent_singleton_coin_from_coin_solution(travel_coinsol)
|
||||
singleton = get_most_recent_singleton_coin_from_coin_spend(travel_coinsol)
|
||||
# get the relevant coin solution
|
||||
return_coinsol, _ = create_travel_spend(
|
||||
travel_coinsol,
|
||||
@ -345,7 +345,7 @@ class TestPoolPuzzles(TestCase):
|
||||
# create the farming reward
|
||||
coin_db.farm_coin(p2_singleton_ph, time, 1750000000000)
|
||||
# generate relevant coin solutions
|
||||
coin_sols: List[CoinSolution] = create_absorb_spend(
|
||||
coin_sols: List[CoinSpend] = create_absorb_spend(
|
||||
travel_coinsol,
|
||||
target_pool_state,
|
||||
launcher_coin,
|
||||
@ -364,13 +364,13 @@ class TestPoolPuzzles(TestCase):
|
||||
# LEAVE THE WAITING ROOM
|
||||
time = CoinTimestamp(20000000, 10000)
|
||||
# find the singleton
|
||||
singleton_coinsol: CoinSolution = list(
|
||||
singleton_coinsol: CoinSpend = list(
|
||||
filter(
|
||||
lambda e: e.coin.amount == START_AMOUNT,
|
||||
coin_sols,
|
||||
)
|
||||
)[0]
|
||||
singleton: Coin = get_most_recent_singleton_coin_from_coin_solution(singleton_coinsol)
|
||||
singleton: Coin = get_most_recent_singleton_coin_from_coin_spend(singleton_coinsol)
|
||||
# get the relevant coin solution
|
||||
return_coinsol, _ = create_travel_spend(
|
||||
singleton_coinsol,
|
||||
@ -400,7 +400,7 @@ class TestPoolPuzzles(TestCase):
|
||||
time = CoinTimestamp(20000000, 10005)
|
||||
# create the farming reward
|
||||
coin_db.farm_coin(p2_singleton_ph, time, 1750000000000)
|
||||
coin_sols: List[CoinSolution] = create_absorb_spend(
|
||||
coin_sols: List[CoinSpend] = create_absorb_spend(
|
||||
return_coinsol,
|
||||
pool_state,
|
||||
launcher_coin,
|
||||
|
@ -8,7 +8,7 @@ from blspy import PrivateKey
|
||||
from chia.pools.pool_wallet import PoolWallet
|
||||
from chia.pools.pool_wallet_info import PoolState, FARMING_TO_POOL
|
||||
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.full_block import FullBlock
|
||||
from chia.types.peer_info import PeerInfo
|
||||
from chia.util.ints import uint16, uint32
|
||||
@ -55,11 +55,11 @@ class TestPoolWallet2:
|
||||
initial_state = PoolState(1, FARMING_TO_POOL, ph, owner_sk.get_g1(), "pool.com", uint32(10))
|
||||
tx_record, _, _ = await PoolWallet.create_new_pool_wallet_transaction(wsm, wallet_0, initial_state)
|
||||
|
||||
launcher_spend: CoinSolution = tx_record.spend_bundle.coin_solutions[1]
|
||||
launcher_spend: CoinSpend = tx_record.spend_bundle.coin_spends[1]
|
||||
|
||||
async with wsm.db_wrapper.lock:
|
||||
pw = await PoolWallet.create(
|
||||
wsm, wallet_0, launcher_spend.coin.name(), tx_record.spend_bundle.coin_solutions, h, True
|
||||
wsm, wallet_0, launcher_spend.coin.name(), tx_record.spend_bundle.coin_spends, h, True
|
||||
)
|
||||
|
||||
log.warning(await pw.get_current_state())
|
||||
|
@ -11,7 +11,7 @@ from clvm_tools import binutils
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program, SerializedProgram
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.util.db_wrapper import DBWrapper
|
||||
from chia.util.ints import uint64
|
||||
|
||||
@ -26,15 +26,15 @@ def event_loop():
|
||||
yield loop
|
||||
|
||||
|
||||
def make_child_solution(coin_solution: CoinSolution, new_coin: Optional[Coin] = None) -> CoinSolution:
|
||||
def make_child_solution(coin_spend: CoinSpend, new_coin: Optional[Coin] = None) -> CoinSpend:
|
||||
new_puzzle_hash: bytes32 = token_bytes(32)
|
||||
solution = "()"
|
||||
puzzle = f"(q . ((51 0x{new_puzzle_hash.hex()} 1)))"
|
||||
puzzle_prog = Program.to(binutils.assemble(puzzle))
|
||||
solution_prog = Program.to(binutils.assemble(solution))
|
||||
if new_coin is None:
|
||||
new_coin = coin_solution.additions()[0]
|
||||
sol: CoinSolution = CoinSolution(
|
||||
new_coin = coin_spend.additions()[0]
|
||||
sol: CoinSpend = CoinSpend(
|
||||
new_coin,
|
||||
SerializedProgram.from_program(puzzle_prog),
|
||||
SerializedProgram.from_program(solution_prog),
|
||||
@ -59,9 +59,9 @@ class TestWalletPoolStore:
|
||||
await db_wrapper.begin_transaction()
|
||||
coin_0 = Coin(token_bytes(32), token_bytes(32), uint64(12312))
|
||||
coin_0_alt = Coin(token_bytes(32), token_bytes(32), uint64(12312))
|
||||
solution_0: CoinSolution = make_child_solution(None, coin_0)
|
||||
solution_0_alt: CoinSolution = make_child_solution(None, coin_0_alt)
|
||||
solution_1: CoinSolution = make_child_solution(solution_0)
|
||||
solution_0: CoinSpend = make_child_solution(None, coin_0)
|
||||
solution_0_alt: CoinSpend = make_child_solution(None, coin_0_alt)
|
||||
solution_1: CoinSpend = make_child_solution(solution_0)
|
||||
|
||||
assert store.get_spends_for_wallet(0) == []
|
||||
assert store.get_spends_for_wallet(1) == []
|
||||
@ -85,19 +85,19 @@ class TestWalletPoolStore:
|
||||
await store.add_spend(1, solution_1, 100)
|
||||
assert store.get_spends_for_wallet(1) == [(100, solution_1)]
|
||||
|
||||
solution_1_alt: CoinSolution = make_child_solution(solution_0_alt)
|
||||
solution_1_alt: CoinSpend = make_child_solution(solution_0_alt)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await store.add_spend(1, solution_1_alt, 100)
|
||||
|
||||
assert store.get_spends_for_wallet(1) == [(100, solution_1)]
|
||||
|
||||
solution_2: CoinSolution = make_child_solution(solution_1)
|
||||
solution_2: CoinSpend = make_child_solution(solution_1)
|
||||
await store.add_spend(1, solution_2, 100)
|
||||
await store.rebuild_cache()
|
||||
solution_3: CoinSolution = make_child_solution(solution_2)
|
||||
solution_3: CoinSpend = make_child_solution(solution_2)
|
||||
await store.add_spend(1, solution_3, 100)
|
||||
solution_4: CoinSolution = make_child_solution(solution_3)
|
||||
solution_4: CoinSpend = make_child_solution(solution_3)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await store.add_spend(1, solution_4, 99)
|
||||
@ -125,7 +125,7 @@ class TestWalletPoolStore:
|
||||
await store.add_spend(1, solution_1, 105)
|
||||
|
||||
await store.add_spend(1, solution_4, 105)
|
||||
solution_5: CoinSolution = make_child_solution(solution_4)
|
||||
solution_5: CoinSpend = make_child_solution(solution_4)
|
||||
await store.add_spend(1, solution_5, 105)
|
||||
await store.rollback(99, 1)
|
||||
assert store.get_spends_for_wallet(1) == []
|
||||
|
@ -3,7 +3,7 @@ from typing import List
|
||||
from blspy import AugSchemeMPL, G2Element, PrivateKey
|
||||
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.util.condition_tools import conditions_by_opcode, conditions_for_solution, pkm_pairs_for_conditions_dict
|
||||
from tests.core.make_block_generator import GROUP_ORDER, int_to_public_key
|
||||
from tests.block_tools import test_constants
|
||||
@ -25,15 +25,15 @@ class KeyTool(dict):
|
||||
bls_private_key = PrivateKey.from_bytes(secret_exponent.to_bytes(32, "big"))
|
||||
return AugSchemeMPL.sign(bls_private_key, message_hash)
|
||||
|
||||
def signature_for_solution(self, coin_solution: CoinSolution, additional_data: bytes) -> AugSchemeMPL:
|
||||
def signature_for_solution(self, coin_spend: CoinSpend, additional_data: bytes) -> AugSchemeMPL:
|
||||
signatures = []
|
||||
err, conditions, cost = conditions_for_solution(
|
||||
coin_solution.puzzle_reveal, coin_solution.solution, test_constants.MAX_BLOCK_COST_CLVM
|
||||
coin_spend.puzzle_reveal, coin_spend.solution, test_constants.MAX_BLOCK_COST_CLVM
|
||||
)
|
||||
assert conditions is not None
|
||||
conditions_dict = conditions_by_opcode(conditions)
|
||||
for public_key, message_hash in pkm_pairs_for_conditions_dict(
|
||||
conditions_dict, coin_solution.coin.name(), additional_data
|
||||
conditions_dict, coin_spend.coin.name(), additional_data
|
||||
):
|
||||
signature = self.sign(bytes(public_key), message_hash)
|
||||
signatures.append(signature)
|
||||
|
@ -11,7 +11,7 @@ from chia.wallet.did_wallet import did_wallet_puzzles
|
||||
from clvm_tools import binutils
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.wallet.derivation_record import DerivationRecord
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from blspy import AugSchemeMPL
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.wallet.transaction_record import TransactionRecord
|
||||
@ -589,7 +589,7 @@ class XTestDIDWallet:
|
||||
]
|
||||
)
|
||||
|
||||
list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
|
||||
list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
|
||||
# sign for AGG_SIG_ME
|
||||
message = coin.puzzle_hash + coin.name() + did_wallet.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA
|
||||
pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
|
||||
|
@ -9,7 +9,7 @@ from chia.types.blockchain_format.program import Program, INFINITE_COST
|
||||
from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.condition_tools import ConditionOpcode
|
||||
|
||||
@ -31,10 +31,10 @@ SINGLETON_MOD_HASH = SINGLETON_MOD.get_tree_hash()
|
||||
POOL_REWARD_PREFIX_MAINNET = bytes32.fromhex("ccd5bb71183532bff220ba46c268991a00000000000000000000000000000000")
|
||||
|
||||
|
||||
def check_coin_solution(coin_solution: CoinSolution):
|
||||
def check_coin_spend(coin_spend: CoinSpend):
|
||||
# breakpoint()
|
||||
try:
|
||||
cost, result = coin_solution.puzzle_reveal.run_with_cost(INFINITE_COST, coin_solution.solution)
|
||||
cost, result = coin_spend.puzzle_reveal.run_with_cost(INFINITE_COST, coin_spend.solution)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
# breakpoint()
|
||||
@ -73,8 +73,8 @@ def launcher_conditions_and_spend_bundle(
|
||||
)
|
||||
)
|
||||
launcher_solution = Program.to([singleton_full_puzzle_hash, launcher_amount, metadata])
|
||||
coin_solution = CoinSolution(launcher_coin, launcher_puzzle, launcher_solution)
|
||||
spend_bundle = SpendBundle([coin_solution], G2Element())
|
||||
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
|
||||
|
||||
@ -114,15 +114,15 @@ def test_only_odd_coins_0():
|
||||
)
|
||||
|
||||
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())])
|
||||
coin_spend = CoinSpend(farmed_coin, ANYONE_CAN_SPEND_PUZZLE, conditions)
|
||||
spend_bundle = SpendBundle.aggregate([launcher_spend_bundle, SpendBundle([coin_spend], 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
|
||||
launcher_coin = launcher_spend_bundle.coin_spends[0].coin
|
||||
|
||||
assert launcher_coin in coin_set_added
|
||||
assert launcher_coin in coin_set_removed
|
||||
|
@ -8,7 +8,7 @@ from chia.types.blockchain_format.program import Program, SerializedProgram
|
||||
from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution as CoinSpend
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.util.condition_tools import ConditionOpcode
|
||||
from chia.util.ints import uint64
|
||||
@ -419,7 +419,7 @@ def spend_coin_to_singleton(
|
||||
|
||||
additions, removals = coin_store.update_coin_store_for_spend_bundle(spend_bundle, now, MAX_BLOCK_COST_CLVM)
|
||||
|
||||
launcher_coin = launcher_spend_bundle.coin_solutions[0].coin
|
||||
launcher_coin = launcher_spend_bundle.coin_spends[0].coin
|
||||
|
||||
assert_coin_spent(coin_store, launcher_coin)
|
||||
assert_coin_spent(coin_store, farmed_coin)
|
||||
|
@ -499,8 +499,8 @@ class TestWalletSimulator:
|
||||
tx_fee,
|
||||
)
|
||||
|
||||
# extract coin_solution from generated spend_bundle
|
||||
for cs in tx.spend_bundle.coin_solutions:
|
||||
# extract coin_spend from generated spend_bundle
|
||||
for cs in tx.spend_bundle.coin_spends:
|
||||
if cs.additions() == []:
|
||||
stolen_cs = cs
|
||||
# get a legit signature
|
||||
|
@ -8,7 +8,7 @@ from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
from chia.types.coin_spend import CoinSpend
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
from chia.types.condition_with_args import ConditionWithArgs
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
@ -98,7 +98,7 @@ class WalletTool:
|
||||
fee: int = 0,
|
||||
secret_key: Optional[PrivateKey] = None,
|
||||
additional_outputs: Optional[List[Tuple[bytes32, int]]] = None,
|
||||
) -> List[CoinSolution]:
|
||||
) -> List[CoinSpend]:
|
||||
spends = []
|
||||
|
||||
spend_value = sum([c.amount for c in coins])
|
||||
@ -143,32 +143,32 @@ class WalletTool:
|
||||
ConditionWithArgs(ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, [primary_announcement_hash])
|
||||
)
|
||||
main_solution = self.make_solution(condition_dic)
|
||||
spends.append(CoinSolution(coin, puzzle, main_solution))
|
||||
spends.append(CoinSpend(coin, puzzle, main_solution))
|
||||
else:
|
||||
spends.append(CoinSolution(coin, puzzle, self.make_solution(secondary_coins_cond_dic)))
|
||||
spends.append(CoinSpend(coin, puzzle, self.make_solution(secondary_coins_cond_dic)))
|
||||
return spends
|
||||
|
||||
def sign_transaction(self, coin_solutions: List[CoinSolution]) -> SpendBundle:
|
||||
def sign_transaction(self, coin_spends: List[CoinSpend]) -> SpendBundle:
|
||||
signatures = []
|
||||
solution: Program
|
||||
puzzle: Program
|
||||
for coin_solution in coin_solutions: # type: ignore # noqa
|
||||
secret_key = self.get_private_key_for_puzzle_hash(coin_solution.coin.puzzle_hash)
|
||||
for coin_spend in coin_spends: # type: ignore # noqa
|
||||
secret_key = self.get_private_key_for_puzzle_hash(coin_spend.coin.puzzle_hash)
|
||||
synthetic_secret_key = calculate_synthetic_secret_key(secret_key, DEFAULT_HIDDEN_PUZZLE_HASH)
|
||||
err, con, cost = conditions_for_solution(
|
||||
coin_solution.puzzle_reveal, coin_solution.solution, self.constants.MAX_BLOCK_COST_CLVM
|
||||
coin_spend.puzzle_reveal, coin_spend.solution, self.constants.MAX_BLOCK_COST_CLVM
|
||||
)
|
||||
if not con:
|
||||
raise ValueError(err)
|
||||
conditions_dict = conditions_by_opcode(con)
|
||||
|
||||
for _, msg in pkm_pairs_for_conditions_dict(
|
||||
conditions_dict, bytes(coin_solution.coin.name()), self.constants.AGG_SIG_ME_ADDITIONAL_DATA
|
||||
conditions_dict, bytes(coin_spend.coin.name()), self.constants.AGG_SIG_ME_ADDITIONAL_DATA
|
||||
):
|
||||
signature = AugSchemeMPL.sign(synthetic_secret_key, msg)
|
||||
signatures.append(signature)
|
||||
aggsig = AugSchemeMPL.aggregate(signatures)
|
||||
spend_bundle = SpendBundle(coin_solutions, aggsig)
|
||||
spend_bundle = SpendBundle(coin_spends, aggsig)
|
||||
return spend_bundle
|
||||
|
||||
def generate_signed_transaction(
|
||||
|
Loading…
Reference in New Issue
Block a user