Skip to content

Commit

Permalink
Return TXs from CATWallet and Offer creation (#17506)
Browse files Browse the repository at this point in the history
* Don't autopush transactions by default anywhere

* Remove ignore_max_send_amount

* Use TXConfig instead of pending_transactions for coin exclusion in spend_clawback_coins

* Unify transaction pushing into a single method

* Address offline comments by @emlowe

* Rework max send amount to be based on coin quantity rather than amount

* Return offer transactions from create_offer_for_ids

* Return transaction list from CATWallet.create_new_cat_wallet

* Missed an instance in a newer test

* Missed an instance in a newer test

* Simplify processing some transaction records.

---------

Co-authored-by: Amine Khaldi <amine.khaldi@reactos.org>
  • Loading branch information
Quexington and AmineKhaldi authored Feb 8, 2024
1 parent c932324 commit 76bb49c
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 110 deletions.
16 changes: 13 additions & 3 deletions chia/data_layer/data_layer_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ async def make_update_offer(
tx_config: TXConfig,
fee: uint64 = uint64(0),
extra_conditions: Tuple[Condition, ...] = tuple(),
) -> Offer:
) -> Tuple[Offer, List[TransactionRecord]]:
dl_wallet = None
for wallet in wallet_state_manager.wallets.values():
if wallet.type() == WalletType.DATA_LAYER.value:
Expand All @@ -1171,6 +1171,7 @@ async def make_update_offer(
offered_launchers: List[bytes32] = [k for k, v in offer_dict.items() if v < 0 and k is not None]
fee_left_to_pay: uint64 = fee
all_bundles: List[SpendBundle] = []
all_transactions: List[TransactionRecord] = []
for launcher in offered_launchers:
try:
this_solver: Solver = solver[launcher.hex()]
Expand Down Expand Up @@ -1213,15 +1214,24 @@ async def make_update_offer(
txs[0].spend_bundle,
coin_spends=all_other_spends,
)
all_bundles.append(SpendBundle.aggregate([signed_bundle, new_bundle]))
agg_bundle: SpendBundle = SpendBundle.aggregate([signed_bundle, new_bundle])
all_bundles.append(agg_bundle)
all_transactions.append(
dataclasses.replace(
txs[0],
spend_bundle=agg_bundle,
name=agg_bundle.name(),
)
)
all_transactions.extend(txs[1:])

# create some dummy requested payments
requested_payments = {
k: [NotarizedPayment(bytes32([0] * 32), uint64(v), [], bytes32([0] * 32))]
for k, v in offer_dict.items()
if v > 0
}
return Offer(requested_payments, SpendBundle.aggregate(all_bundles), driver_dict)
return Offer(requested_payments, SpendBundle.aggregate(all_bundles), driver_dict), all_transactions

@staticmethod
async def finish_graftroot_solutions(offer: Offer, solver: Solver) -> Offer:
Expand Down
12 changes: 9 additions & 3 deletions chia/rpc/wallet_rpc_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ async def create_new_wallet(
if not push:
raise ValueError("Test CAT minting must be pushed automatically") # pragma: no cover
async with self.service.wallet_state_manager.lock:
cat_wallet: CATWallet = await CATWallet.create_new_cat_wallet(
cat_wallet, txs = await CATWallet.create_new_cat_wallet(
wallet_state_manager,
main_wallet,
{"identifier": "genesis_by_id"},
Expand All @@ -706,7 +706,12 @@ async def create_new_wallet(
)
asset_id = cat_wallet.get_asset_id()
self.service.wallet_state_manager.state_changed("wallet_created")
return {"type": cat_wallet.type(), "asset_id": asset_id, "wallet_id": cat_wallet.id()}
return {
"type": cat_wallet.type(),
"asset_id": asset_id,
"wallet_id": cat_wallet.id(),
"transactions": [tx.to_json_dict_convenience(self.service.config) for tx in txs],
}
else:
raise ValueError(
"Support for this RPC mode has been dropped."
Expand Down Expand Up @@ -1847,10 +1852,11 @@ async def create_offer_for_ids(
extra_conditions=extra_conditions,
)
if result[0]:
success, trade_record, error = result
success, trade_record, tx_records, error = result
return {
"offer": Offer.from_bytes(trade_record.offer).to_bech32(),
"trade_record": trade_record.to_json_dict_convenience(),
"transactions": [tx.to_json_dict_convenience(self.service.config) for tx in tx_records],
}
raise ValueError(result[2])

Expand Down
4 changes: 2 additions & 2 deletions chia/wallet/cat_wallet/cat_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ async def create_new_cat_wallet(
tx_config: TXConfig,
fee: uint64 = uint64(0),
name: Optional[str] = None,
) -> CATWallet:
) -> Tuple[CATWallet, List[TransactionRecord]]:
self = CATWallet()
self.standard_wallet = wallet
self.log = logging.getLogger(__name__)
Expand Down Expand Up @@ -201,7 +201,7 @@ async def create_new_cat_wallet(
)
chia_tx = dataclasses.replace(chia_tx, spend_bundle=spend_bundle, name=spend_bundle.name())
await self.wallet_state_manager.add_pending_transactions([chia_tx, cat_record])
return self
return self, [chia_tx, cat_record]

@staticmethod
async def get_or_create_wallet_for_cat(
Expand Down
2 changes: 1 addition & 1 deletion chia/wallet/dao_wallet/dao_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ async def generate_new_dao(
"treasury_id": launcher_coin.name(),
"coins": different_coins,
}
new_cat_wallet = await CATWallet.create_new_cat_wallet(
new_cat_wallet, _ = await CATWallet.create_new_cat_wallet(
self.wallet_state_manager,
self.standard_wallet,
cat_tail_info,
Expand Down
4 changes: 2 additions & 2 deletions chia/wallet/nft_wallet/nft_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ async def make_nft1_offer(
tx_config: TXConfig,
fee: uint64,
extra_conditions: Tuple[Condition, ...],
) -> Offer:
) -> Tuple[Offer, List[TransactionRecord]]:
# First, let's take note of all the royalty enabled NFTs
royalty_nft_asset_dict: Dict[bytes32, int] = {}
for asset, amount in offer_dict.items():
Expand Down Expand Up @@ -1087,7 +1087,7 @@ async def make_nft1_offer(
txs_bundle = SpendBundle.aggregate([tx.spend_bundle for tx in all_transactions if tx.spend_bundle is not None])
aggregate_bundle = SpendBundle.aggregate([txs_bundle, *additional_bundles])
offer = Offer(notarized_payments, aggregate_bundle, driver_dict)
return offer
return offer, all_transactions

async def set_bulk_nft_did(
self,
Expand Down
28 changes: 17 additions & 11 deletions chia/wallet/trade_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import time
from typing import Any, Dict, List, Optional, Set, Tuple, Union, cast

from typing_extensions import Literal
from typing_extensions import Literal, Never

from chia.data_layer.data_layer_wallet import DataLayerWallet
from chia.protocols.wallet_protocol import CoinState
Expand Down Expand Up @@ -374,7 +374,9 @@ async def create_offer_for_ids(
validate_only: bool = False,
extra_conditions: Tuple[Condition, ...] = tuple(),
taking: bool = False,
) -> Union[Tuple[Literal[True], TradeRecord, None], Tuple[Literal[False], None, str]]:
) -> Union[
Tuple[Literal[True], TradeRecord, List[TransactionRecord], None], Tuple[Literal[False], None, List[Never], str]
]:
if driver_dict is None:
driver_dict = {}
if solver is None:
Expand All @@ -391,7 +393,7 @@ async def create_offer_for_ids(
if not result[0] or result[1] is None:
raise Exception(f"Error creating offer: {result[2]}")

success, created_offer, error = result
success, created_offer, tx_records, error = result

now = uint64(int(time.time()))
trade_offer: TradeRecord = TradeRecord(
Expand All @@ -412,7 +414,7 @@ async def create_offer_for_ids(
if success is True and trade_offer is not None and not validate_only:
await self.save_trade(trade_offer, created_offer)

return success, trade_offer, error
return success, trade_offer, tx_records, error

async def _create_offer_for_ids(
self,
Expand All @@ -423,7 +425,9 @@ async def _create_offer_for_ids(
fee: uint64 = uint64(0),
extra_conditions: Tuple[Condition, ...] = tuple(),
taking: bool = False,
) -> Union[Tuple[Literal[True], Offer, None], Tuple[Literal[False], None, str]]:
) -> Union[
Tuple[Literal[True], Offer, List[TransactionRecord], None], Tuple[Literal[False], None, List[Never], str]
]:
"""
Offer is dictionary of wallet ids and amount
"""
Expand Down Expand Up @@ -512,7 +516,9 @@ async def _create_offer_for_ids(
requested_payments, driver_dict, taking
)

potential_special_offer: Optional[Offer] = await self.check_for_special_offer_making(
potential_special_offer: Optional[
Tuple[Offer, List[TransactionRecord]]
] = await self.check_for_special_offer_making(
offer_dict_no_ints,
driver_dict,
tx_config,
Expand All @@ -522,7 +528,7 @@ async def _create_offer_for_ids(
)

if potential_special_offer is not None:
return True, potential_special_offer, None
return True, potential_special_offer[0], potential_special_offer[1], None

all_coins: List[Coin] = [c for coins in coins_to_offer.values() for c in coins]
notarized_payments: Dict[Optional[bytes32], List[NotarizedPayment]] = Offer.notarize_payments(
Expand Down Expand Up @@ -586,11 +592,11 @@ async def _create_offer_for_ids(
)

offer = Offer(notarized_payments, total_spend_bundle, driver_dict)
return True, offer, None
return True, offer, all_transactions, None

except Exception as e:
self.log.exception("Error creating trade offer")
return False, None, str(e)
return False, None, [], str(e)

async def maybe_create_wallets_for_offer(self, offer: Offer) -> None:
for key in offer.arbitrage():
Expand Down Expand Up @@ -786,7 +792,7 @@ async def respond_to_offer(
if not result[0] or result[1] is None:
raise ValueError(result[2])

success, take_offer, error = result
success, take_offer, _, error = result

complete_offer, valid_spend_solver = await self.check_for_final_modifications(
Offer.aggregate([offer, take_offer]), solver, tx_config
Expand Down Expand Up @@ -848,7 +854,7 @@ async def check_for_special_offer_making(
solver: Solver,
fee: uint64 = uint64(0),
extra_conditions: Tuple[Condition, ...] = tuple(),
) -> Optional[Offer]:
) -> Optional[Tuple[Offer, List[TransactionRecord]]]:
for puzzle_info in driver_dict.values():
if (
puzzle_info.check_type([AssetType.SINGLETON.value, AssetType.METADATA.value, AssetType.OWNERSHIP.value])
Expand Down
2 changes: 1 addition & 1 deletion chia/wallet/vc_wallet/cr_cat_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ async def create_new_cat_wallet(
tx_config: TXConfig,
fee: uint64 = uint64(0),
name: Optional[str] = None,
) -> CATWallet: # pragma: no cover
) -> Tuple[CATWallet, List[TransactionRecord]]: # pragma: no cover
raise NotImplementedError("create_new_cat_wallet is a legacy method and is not available on CR-CAT wallets")

@staticmethod
Expand Down
36 changes: 13 additions & 23 deletions tests/wallet/cat_wallet/test_cat_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ async def test_cat_creation(self_hostname: str, two_wallet_nodes: OldSimulatorsA
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)

async with wallet_node.wallet_state_manager.lock:
cat_wallet = await CATWallet.create_new_cat_wallet(
cat_wallet, tx_records = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager,
wallet,
{"identifier": "genesis_by_id"},
Expand All @@ -83,9 +83,7 @@ async def test_cat_creation(self_hostname: str, two_wallet_nodes: OldSimulatorsA
cat_wallet = await CATWallet.create(wallet_node.wallet_state_manager, wallet, cat_wallet.wallet_info)
await wallet_node.wallet_state_manager.add_new_wallet(cat_wallet)

tx_queue = await wallet_node.wallet_state_manager.tx_store.get_not_sent()
tx_record = tx_queue[0]
await full_node_api.process_transaction_records(records=[tx_record])
await full_node_api.process_transaction_records(records=tx_records)

await time_out_assert(20, cat_wallet.get_confirmed_balance, 100)
await time_out_assert(20, cat_wallet.get_spendable_balance, 100)
Expand Down Expand Up @@ -140,10 +138,10 @@ async def test_cat_creation_unique_lineage_store(self_hostname: str, two_wallet_
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)

async with wallet_node.wallet_state_manager.lock:
cat_wallet_1 = await CATWallet.create_new_cat_wallet(
cat_wallet_1, _ = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(100), DEFAULT_TX_CONFIG
)
cat_wallet_2 = await CATWallet.create_new_cat_wallet(
cat_wallet_2, _ = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(200), DEFAULT_TX_CONFIG
)

Expand Down Expand Up @@ -188,12 +186,10 @@ async def test_cat_spend(self_hostname: str, two_wallet_nodes: OldSimulatorsAndW
await time_out_assert(20, wallet.get_confirmed_balance, funds)

async with wallet_node.wallet_state_manager.lock:
cat_wallet = await CATWallet.create_new_cat_wallet(
cat_wallet, tx_records = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(100), DEFAULT_TX_CONFIG
)
tx_queue = await wallet_node.wallet_state_manager.tx_store.get_not_sent()
tx_record = tx_queue[0]
await full_node_api.process_transaction_records(records=[tx_record])
await full_node_api.process_transaction_records(records=tx_records)

await time_out_assert(20, cat_wallet.get_confirmed_balance, 100)
await time_out_assert(20, cat_wallet.get_unconfirmed_balance, 100)
Expand Down Expand Up @@ -293,12 +289,10 @@ async def test_cat_reuse_address(self_hostname: str, two_wallet_nodes: OldSimula
await time_out_assert(20, wallet.get_confirmed_balance, funds)

async with wallet_node.wallet_state_manager.lock:
cat_wallet = await CATWallet.create_new_cat_wallet(
cat_wallet, tx_records = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(100), DEFAULT_TX_CONFIG
)
tx_queue = await wallet_node.wallet_state_manager.tx_store.get_not_sent()
tx_record = tx_queue[0]
await full_node_api.process_transaction_records(records=[tx_record])
await full_node_api.process_transaction_records(records=tx_records)

await time_out_assert(20, cat_wallet.get_confirmed_balance, 100)
await time_out_assert(20, cat_wallet.get_unconfirmed_balance, 100)
Expand Down Expand Up @@ -390,7 +384,7 @@ async def test_get_wallet_for_asset_id(
await time_out_assert(20, wallet.get_confirmed_balance, funds)

async with wallet_node.wallet_state_manager.lock:
cat_wallet = await CATWallet.create_new_cat_wallet(
cat_wallet, _ = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(100), DEFAULT_TX_CONFIG
)

Expand Down Expand Up @@ -444,10 +438,9 @@ async def test_cat_doesnt_see_eve(self_hostname: str, two_wallet_nodes: OldSimul
await time_out_assert(20, wallet.get_confirmed_balance, funds)

async with wallet_node.wallet_state_manager.lock:
cat_wallet = await CATWallet.create_new_cat_wallet(
cat_wallet, tx_records = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(100), DEFAULT_TX_CONFIG
)
tx_records = await wallet_node.wallet_state_manager.tx_store.get_not_sent()
await full_node_api.process_transaction_records(records=tx_records)

await time_out_assert(20, cat_wallet.get_confirmed_balance, 100)
Expand Down Expand Up @@ -535,14 +528,13 @@ async def test_cat_spend_multiple(
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)

async with wallet_node_0.wallet_state_manager.lock:
cat_wallet_0 = await CATWallet.create_new_cat_wallet(
cat_wallet_0, tx_records = await CATWallet.create_new_cat_wallet(
wallet_node_0.wallet_state_manager,
wallet_0,
{"identifier": "genesis_by_id"},
uint64(100),
DEFAULT_TX_CONFIG,
)
tx_records = await wallet_node_0.wallet_state_manager.tx_store.get_not_sent()
await full_node_api.process_transaction_records(records=tx_records)

await time_out_assert(20, cat_wallet_0.get_confirmed_balance, 100)
Expand Down Expand Up @@ -652,10 +644,9 @@ async def test_cat_max_amount_send(
await time_out_assert(20, wallet.get_confirmed_balance, funds)

async with wallet_node.wallet_state_manager.lock:
cat_wallet = await CATWallet.create_new_cat_wallet(
cat_wallet, tx_records = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(100000), DEFAULT_TX_CONFIG
)
tx_records = await wallet_node.wallet_state_manager.tx_store.get_not_sent()
await full_node_api.process_transaction_records(records=tx_records)

await time_out_assert(20, cat_wallet.get_confirmed_balance, 100000)
Expand Down Expand Up @@ -751,10 +742,9 @@ async def test_cat_hint(
await time_out_assert(20, wallet.get_confirmed_balance, funds)

async with wallet_node.wallet_state_manager.lock:
cat_wallet = await CATWallet.create_new_cat_wallet(
cat_wallet, tx_records = await CATWallet.create_new_cat_wallet(
wallet_node.wallet_state_manager, wallet, {"identifier": "genesis_by_id"}, uint64(100), DEFAULT_TX_CONFIG
)
tx_records = await wallet_node.wallet_state_manager.tx_store.get_not_sent()
await full_node_api.process_transaction_records(records=tx_records)

await time_out_assert(20, cat_wallet.get_confirmed_balance, 100)
Expand Down
Loading

0 comments on commit 76bb49c

Please sign in to comment.