mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2026-08-24 10:05:29 -05:00
[CHIA-3608] Port take_offer to @marshal (#20061)
* Port `take_offer` to `@marshal` * `TransactionEndpointRequest` misses
This commit is contained in:
@@ -75,6 +75,7 @@ from chia.wallet.wallet_request_types import (
|
||||
SendTransactionResponse,
|
||||
SpendClawbackCoins,
|
||||
SpendClawbackCoinsResponse,
|
||||
TakeOffer,
|
||||
TakeOfferResponse,
|
||||
TransactionRecordWithMetadata,
|
||||
WalletInfoResponse,
|
||||
@@ -1055,18 +1056,19 @@ def test_take_offer(capsys: object, get_test_cli_clients: tuple[TestRpcClients,
|
||||
class TakeOfferRpcClient(TestWalletRpcClient):
|
||||
async def take_offer(
|
||||
self,
|
||||
offer: Offer,
|
||||
request: TakeOffer,
|
||||
tx_config: TXConfig,
|
||||
solver: Optional[dict[str, Any]] = None,
|
||||
fee: uint64 = uint64(0),
|
||||
push: bool = True,
|
||||
extra_conditions: tuple[Condition, ...] = tuple(),
|
||||
timelock_info: ConditionValidTimes = ConditionValidTimes(),
|
||||
) -> TakeOfferResponse:
|
||||
self.add_to_log("take_offer", (offer, tx_config, solver, fee, push, timelock_info))
|
||||
self.add_to_log(
|
||||
"take_offer",
|
||||
(request.parsed_offer, tx_config, request.solver, request.fee, request.push, timelock_info),
|
||||
)
|
||||
return TakeOfferResponse(
|
||||
[STD_UTX],
|
||||
[STD_TX],
|
||||
offer,
|
||||
request.parsed_offer,
|
||||
TradeRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
accepted_at_time=uint64(123456789),
|
||||
@@ -1074,10 +1076,10 @@ def test_take_offer(capsys: object, get_test_cli_clients: tuple[TestRpcClients,
|
||||
is_my_offer=False,
|
||||
sent=uint32(1),
|
||||
sent_to=[("aaaaa", uint8(1), None)],
|
||||
offer=bytes(offer),
|
||||
offer=bytes(request.parsed_offer),
|
||||
taken_offer=None,
|
||||
coins_of_interest=offer.get_involved_coins(),
|
||||
trade_id=offer.name(),
|
||||
coins_of_interest=request.parsed_offer.get_involved_coins(),
|
||||
trade_id=request.parsed_offer.name(),
|
||||
status=uint32(TradeStatus.PENDING_ACCEPT.value),
|
||||
valid_times=ConditionValidTimes(),
|
||||
),
|
||||
|
||||
@@ -160,6 +160,7 @@ from chia.wallet.wallet_request_types import (
|
||||
SetWalletResyncOnStartup,
|
||||
SpendClawbackCoins,
|
||||
SplitCoins,
|
||||
TakeOffer,
|
||||
VerifySignature,
|
||||
VerifySignatureResponse,
|
||||
)
|
||||
@@ -1647,7 +1648,16 @@ async def test_offer_endpoints(wallet_environments: WalletTestFramework, wallet_
|
||||
assert offer_count.my_offers_count == 1
|
||||
assert offer_count.taken_offers_count == 0
|
||||
|
||||
trade_record = (await env_2.rpc_client.take_offer(offer, wallet_environments.tx_config, fee=uint64(1))).trade_record
|
||||
trade_record = (
|
||||
await env_2.rpc_client.take_offer(
|
||||
TakeOffer(
|
||||
offer=offer.to_bech32(),
|
||||
fee=uint64(1),
|
||||
push=True,
|
||||
),
|
||||
wallet_environments.tx_config,
|
||||
)
|
||||
).trade_record
|
||||
assert TradeStatus(trade_record.status) == TradeStatus.PENDING_CONFIRM
|
||||
|
||||
await env_1.rpc_client.cancel_offer(offer.name(), wallet_environments.tx_config, secure=False)
|
||||
|
||||
@@ -88,6 +88,7 @@ from chia.wallet.wallet_request_types import (
|
||||
SignMessageByID,
|
||||
SignMessageByIDResponse,
|
||||
SpendClawbackCoins,
|
||||
TakeOffer,
|
||||
VCAddProofs,
|
||||
VCGet,
|
||||
VCGetList,
|
||||
@@ -892,11 +893,9 @@ async def take_offer(
|
||||
print()
|
||||
cli_confirm("Would you like to take this offer? (y/n): ")
|
||||
res = await wallet_client.take_offer(
|
||||
offer,
|
||||
fee=fee,
|
||||
tx_config=CMDTXConfigLoader().to_tx_config(units["chia"], config, fingerprint),
|
||||
push=push,
|
||||
TakeOffer(offer=offer.to_bech32(), fee=fee, push=push),
|
||||
timelock_info=condition_valid_times,
|
||||
tx_config=CMDTXConfigLoader().to_tx_config(units["chia"], config, fingerprint),
|
||||
)
|
||||
if push:
|
||||
print(f"Accepted offer with ID {res.trade_record.trade_id}")
|
||||
|
||||
@@ -81,6 +81,7 @@ from chia.wallet.wallet_request_types import (
|
||||
DLUpdateRoot,
|
||||
LauncherRootPair,
|
||||
LogIn,
|
||||
TakeOffer,
|
||||
)
|
||||
from chia.wallet.wallet_rpc_client import WalletRpcClient
|
||||
|
||||
@@ -1241,22 +1242,26 @@ class DataLayer:
|
||||
)
|
||||
)
|
||||
|
||||
solver: dict[str, Any] = {
|
||||
"proofs_of_inclusion": proofs_of_inclusion,
|
||||
**{
|
||||
"0x" + our_offer_store.store_id.hex(): {
|
||||
"new_root": "0x" + root.hex(),
|
||||
"dependencies": [
|
||||
{
|
||||
"launcher_id": "0x" + their_offer_store.store_id.hex(),
|
||||
"values_to_prove": ["0x" + entry.node_hash.hex() for entry in their_offer_store.proofs],
|
||||
}
|
||||
for their_offer_store in maker
|
||||
],
|
||||
}
|
||||
for our_offer_store in taker
|
||||
},
|
||||
}
|
||||
solver = Solver(
|
||||
{
|
||||
"proofs_of_inclusion": proofs_of_inclusion,
|
||||
**{
|
||||
"0x" + our_offer_store.store_id.hex(): {
|
||||
"new_root": "0x" + root.hex(),
|
||||
"dependencies": [
|
||||
{
|
||||
"launcher_id": "0x" + their_offer_store.store_id.hex(),
|
||||
"values_to_prove": [
|
||||
"0x" + entry.node_hash.hex() for entry in their_offer_store.proofs
|
||||
],
|
||||
}
|
||||
for their_offer_store in maker
|
||||
],
|
||||
}
|
||||
for our_offer_store in taker
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
# Excluding wallet from transaction since failures in the wallet may occur
|
||||
# after the transaction is submitted to the chain. If we roll back data we
|
||||
@@ -1264,9 +1269,7 @@ class DataLayer:
|
||||
|
||||
trade_record = (
|
||||
await self.wallet_rpc.take_offer(
|
||||
offer=offer,
|
||||
solver=solver,
|
||||
fee=fee,
|
||||
TakeOffer(offer=offer.to_bech32(), solver=solver, fee=fee, push=True),
|
||||
# TODO: probably shouldn't be default but due to peculiarities in the RPC, we're using a stop gap.
|
||||
# This is not a change in behavior, the default was already implicit.
|
||||
tx_config=DEFAULT_TX_CONFIG,
|
||||
|
||||
@@ -1930,6 +1930,17 @@ class CreateOfferForIDsResponse(_OfferEndpointResponse):
|
||||
pass
|
||||
|
||||
|
||||
@streamable
|
||||
@dataclass(frozen=True)
|
||||
class TakeOffer(TransactionEndpointRequest):
|
||||
offer: str = field(default_factory=default_raise)
|
||||
solver: Optional[Solver] = None
|
||||
|
||||
@cached_property
|
||||
def parsed_offer(self) -> Offer:
|
||||
return Offer.from_bech32(self.offer)
|
||||
|
||||
|
||||
@streamable
|
||||
@dataclass(frozen=True)
|
||||
class TakeOfferResponse(_OfferEndpointResponse): # Inheriting for de-dup sake
|
||||
|
||||
@@ -70,7 +70,7 @@ from chia.wallet.nft_wallet.nft_wallet import NFTWallet
|
||||
from chia.wallet.nft_wallet.uncurry_nft import UncurriedNFT
|
||||
from chia.wallet.notification_store import Notification
|
||||
from chia.wallet.outer_puzzles import AssetType
|
||||
from chia.wallet.puzzle_drivers import PuzzleInfo, Solver
|
||||
from chia.wallet.puzzle_drivers import PuzzleInfo
|
||||
from chia.wallet.puzzles import p2_delegated_conditions
|
||||
from chia.wallet.puzzles.clawback.metadata import AutoClaimSettings, ClawbackMetadata
|
||||
from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_hash_for_synthetic_public_key
|
||||
@@ -283,6 +283,8 @@ from chia.wallet.wallet_request_types import (
|
||||
StrayCAT,
|
||||
SubmitTransactions,
|
||||
SubmitTransactionsResponse,
|
||||
TakeOffer,
|
||||
TakeOfferResponse,
|
||||
TransactionRecordWithMetadata,
|
||||
VCAddProofs,
|
||||
VCGet,
|
||||
@@ -2322,44 +2324,34 @@ class WalletRpcApi:
|
||||
)
|
||||
|
||||
@tx_endpoint(push=True)
|
||||
@marshal
|
||||
async def take_offer(
|
||||
self,
|
||||
request: dict[str, Any],
|
||||
request: TakeOffer,
|
||||
action_scope: WalletActionScope,
|
||||
extra_conditions: tuple[Condition, ...] = tuple(),
|
||||
) -> EndpointResult:
|
||||
offer_hex: str = request["offer"]
|
||||
|
||||
offer = Offer.from_bech32(offer_hex)
|
||||
fee: uint64 = uint64(request.get("fee", 0))
|
||||
maybe_marshalled_solver: Optional[dict[str, Any]] = request.get("solver")
|
||||
solver: Optional[Solver]
|
||||
if maybe_marshalled_solver is None:
|
||||
solver = None
|
||||
else:
|
||||
solver = Solver(info=maybe_marshalled_solver)
|
||||
|
||||
) -> TakeOfferResponse:
|
||||
peer = self.service.get_full_node_peer()
|
||||
trade_record = await self.service.wallet_state_manager.trade_manager.respond_to_offer(
|
||||
offer,
|
||||
request.parsed_offer,
|
||||
peer,
|
||||
action_scope,
|
||||
fee=fee,
|
||||
solver=solver,
|
||||
fee=request.fee,
|
||||
solver=request.solver,
|
||||
extra_conditions=extra_conditions,
|
||||
)
|
||||
|
||||
async with action_scope.use() as interface:
|
||||
interface.side_effects.signing_responses.append(
|
||||
SigningResponse(bytes(offer._bundle.aggregated_signature), trade_record.trade_id)
|
||||
SigningResponse(bytes(request.parsed_offer._bundle.aggregated_signature), trade_record.trade_id)
|
||||
)
|
||||
|
||||
return {
|
||||
"trade_record": trade_record.to_json_dict_convenience(),
|
||||
"offer": Offer.from_bytes(trade_record.offer).to_bech32(),
|
||||
"transactions": None, # tx_endpoint wrapper will take care of this
|
||||
"signing_responses": None, # tx_endpoint wrapper will take care of this
|
||||
}
|
||||
return TakeOfferResponse(
|
||||
[], # tx_endpoint will fill in this default value
|
||||
[], # tx_endpoint will fill in this default value
|
||||
Offer.from_bytes(trade_record.offer),
|
||||
trade_record,
|
||||
)
|
||||
|
||||
async def get_offer(self, request: dict[str, Any]) -> EndpointResult:
|
||||
trade_mgr = self.service.wallet_state_manager.trade_manager
|
||||
|
||||
@@ -192,6 +192,7 @@ from chia.wallet.wallet_request_types import (
|
||||
SplitCoinsResponse,
|
||||
SubmitTransactions,
|
||||
SubmitTransactionsResponse,
|
||||
TakeOffer,
|
||||
TakeOfferResponse,
|
||||
VCAddProofs,
|
||||
VCGet,
|
||||
@@ -690,26 +691,16 @@ class WalletRpcClient(RpcClient):
|
||||
|
||||
async def take_offer(
|
||||
self,
|
||||
offer: Offer,
|
||||
request: TakeOffer,
|
||||
tx_config: TXConfig,
|
||||
solver: Optional[dict[str, Any]] = None,
|
||||
fee: int = 0,
|
||||
extra_conditions: tuple[Condition, ...] = tuple(),
|
||||
timelock_info: ConditionValidTimes = ConditionValidTimes(),
|
||||
push: bool = True,
|
||||
) -> TakeOfferResponse:
|
||||
req = {
|
||||
"offer": offer.to_bech32(),
|
||||
"fee": fee,
|
||||
"extra_conditions": conditions_to_json_dicts(extra_conditions),
|
||||
"push": push,
|
||||
**tx_config.to_json_dict(),
|
||||
**timelock_info.to_json_dict(),
|
||||
}
|
||||
if solver is not None:
|
||||
req["solver"] = solver
|
||||
res = await self.fetch("take_offer", req)
|
||||
return json_deserialize_with_clvm_streamable(res, TakeOfferResponse)
|
||||
return TakeOfferResponse.from_json_dict(
|
||||
await self.fetch(
|
||||
"take_offer", request.json_serialize_for_transport(tx_config, extra_conditions, timelock_info)
|
||||
)
|
||||
)
|
||||
|
||||
async def get_offer(self, trade_id: bytes32, file_contents: bool = False) -> TradeRecord:
|
||||
res = await self.fetch("get_offer", {"trade_id": trade_id.hex(), "file_contents": file_contents})
|
||||
|
||||
Reference in New Issue
Block a user