From fe64274cd20eeb10fb4326492b13815fb13d9fc1 Mon Sep 17 00:00:00 2001 From: Matt Hauff Date: Thu, 21 Jul 2022 09:40:49 -0500 Subject: [PATCH] Add offer summaries --- chia/data_layer/data_layer_wallet.py | 30 ++++++++++++++++++ chia/wallet/trade_manager.py | 14 +++++++-- tests/wallet/db_wallet/test_dl_offers.py | 40 ++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/chia/data_layer/data_layer_wallet.py b/chia/data_layer/data_layer_wallet.py index cc2347ce0932..d7a232485b6b 100644 --- a/chia/data_layer/data_layer_wallet.py +++ b/chia/data_layer/data_layer_wallet.py @@ -1076,3 +1076,33 @@ class DataLayerWallet: new_spends.append(spend) return Offer({}, SpendBundle(new_spends, offer.bundle.aggregated_signature), offer.driver_dict) + + @staticmethod + async def get_offer_summary(offer: Offer) -> Dict[str, Any]: + summary: Dict[str, Any] = {"offered": []} + for spend in offer.bundle.coin_spends: + solution = spend.solution.to_program() + matched, curried_args = match_dl_singleton(spend.puzzle_reveal.to_program()) + if matched: + graftroot: Program = solution.at("rrffrf") + mod, graftroot_curried_args = graftroot.uncurry() + if mod == GRAFTROOT_DL_OFFERS: + child_spend: CoinSpend = next( + cs for cs in offer.bundle.coin_spends if cs.coin.parent_coin_info == spend.coin.name() + ) + _, child_curried_args = match_dl_singleton(child_spend.puzzle_reveal.to_program()) + singleton_summary = { + "launcher_id": list(curried_args)[2].as_python().hex(), + "new_root": list(child_curried_args)[1].as_python().hex(), + "dependencies": [], + } + _, singleton_structs, _, values_to_prove = graftroot_curried_args.as_iter() + for struct, values in zip(singleton_structs.as_iter(), values_to_prove.as_iter()): + singleton_summary["dependencies"].append( + { + "launcher_id": struct.at("rf").as_python().hex(), + "values_to_prove": [value.as_python().hex() for value in values.as_iter()], + } + ) + summary["offered"].append(singleton_summary) + return summary diff --git a/chia/wallet/trade_manager.py b/chia/wallet/trade_manager.py index 50fc2b3fdcd7..4aff5a014ace 100644 --- a/chia/wallet/trade_manager.py +++ b/chia/wallet/trade_manager.py @@ -723,12 +723,22 @@ class TradeManager: return False async def get_offer_summary(self, offer: Offer) -> Dict[str, Any]: - # This looks silly right now since it's the same as the RPC but eventually there will be ifs here that do stuff + for puzzle_info in offer.driver_dict.values(): + if ( + puzzle_info.check_type( + [ + AssetType.SINGLETON.value, + AssetType.METADATA.value, + ] + ) + and puzzle_info.also()["updater_hash"] == ACS_MU_PH # type: ignore + ): + return await DataLayerWallet.get_offer_summary(offer) + # Otherwise just return the same thing as the RPC normally does offered, requested, infos = offer.summary() return {"offered": offered, "requested": requested, "fees": offer.bundle.fees(), "infos": infos} async def check_for_final_modifications(self, offer: Offer, solver: Solver) -> Offer: - # This looks silly right but eventually there will be ifs here that do stuff for puzzle_info in offer.driver_dict.values(): if ( puzzle_info.check_type( diff --git a/tests/wallet/db_wallet/test_dl_offers.py b/tests/wallet/db_wallet/test_dl_offers.py index 45262ee35867..0f569d2d43a1 100644 --- a/tests/wallet/db_wallet/test_dl_offers.py +++ b/tests/wallet/db_wallet/test_dl_offers.py @@ -103,6 +103,21 @@ async def test_dl_offers(wallets_prefarm: Any, trusted: bool) -> None: assert success is True assert offer_maker is not None + assert await trade_manager_taker.get_offer_summary(Offer.from_bytes(offer_maker.offer)) == { + "offered": [ + { + "launcher_id": launcher_id_maker.hex(), + "new_root": maker_root.hex(), + "dependencies": [ + { + "launcher_id": launcher_id_taker.hex(), + "values_to_prove": [taker_addition.hex()], + } + ], + } + ] + } + maker_proof: Tuple[int, List[bytes32]] = maker_proofs[maker_addition] taker_proof: Tuple[int, List[bytes32]] = taker_proofs[taker_addition] success, offer_taker, error = await trade_manager_taker.respond_to_offer( @@ -127,6 +142,31 @@ async def test_dl_offers(wallets_prefarm: Any, trusted: bool) -> None: assert success is True assert offer_taker is not None + assert await trade_manager_maker.get_offer_summary(Offer.from_bytes(offer_taker.offer)) == { + "offered": [ + { + "launcher_id": launcher_id_maker.hex(), + "new_root": maker_root.hex(), + "dependencies": [ + { + "launcher_id": launcher_id_taker.hex(), + "values_to_prove": [taker_addition.hex()], + } + ], + }, + { + "launcher_id": launcher_id_taker.hex(), + "new_root": taker_root.hex(), + "dependencies": [ + { + "launcher_id": launcher_id_maker.hex(), + "values_to_prove": [maker_addition.hex()], + } + ], + }, + ] + } + await time_out_assert(15, wallet_maker.get_unconfirmed_balance, funds - 2000000000000) await time_out_assert(15, wallet_taker.get_unconfirmed_balance, funds - 4000000000000)