Skip to content

Commit 11696e4

Browse files
authored
[CHIA-3600] Port send_transaction to @marshal (#19960)
* Port `send_transaction` * Have I mentioned this framework is suboptimal? * Fix tests
1 parent 8463909 commit 11696e4

File tree

8 files changed

+176
-109
lines changed

8 files changed

+176
-109
lines changed

chia/_tests/cmds/wallet/test_wallet.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from chia.types.blockchain_format.program import Program
3030
from chia.types.signing_mode import SigningMode
3131
from chia.util.bech32m import encode_puzzle_hash
32-
from chia.wallet.conditions import ConditionValidTimes
32+
from chia.wallet.conditions import Condition, ConditionValidTimes
3333
from chia.wallet.trade_record import TradeRecord
3434
from chia.wallet.trading.offer import Offer
3535
from chia.wallet.trading.trade_status import TradeStatus
@@ -44,6 +44,7 @@
4444
BalanceResponse,
4545
CancelOfferResponse,
4646
CATSpendResponse,
47+
ClawbackPuzzleDecoratorOverride,
4748
CreateOfferForIDsResponse,
4849
DeleteUnconfirmedTransactions,
4950
ExtendDerivationIndex,
@@ -64,6 +65,7 @@
6465
NFTGetWalletDID,
6566
NFTGetWalletDIDResponse,
6667
RoyaltyAsset,
68+
SendTransaction,
6769
SendTransactionResponse,
6870
TakeOfferResponse,
6971
TransactionRecordWithMetadata,
@@ -333,19 +335,24 @@ def test_send(capsys: object, get_test_cli_clients: tuple[TestRpcClients, Path])
333335
class SendWalletRpcClient(TestWalletRpcClient):
334336
async def send_transaction(
335337
self,
336-
wallet_id: int,
337-
amount: uint64,
338-
address: str,
338+
request: SendTransaction,
339339
tx_config: TXConfig,
340-
fee: uint64 = uint64(0),
341-
memos: Optional[list[str]] = None,
342-
puzzle_decorator_override: Optional[list[dict[str, Union[str, int, bool]]]] = None,
343-
push: bool = True,
340+
extra_conditions: tuple[Condition, ...] = tuple(),
344341
timelock_info: ConditionValidTimes = ConditionValidTimes(),
345342
) -> SendTransactionResponse:
346343
self.add_to_log(
347344
"send_transaction",
348-
(wallet_id, amount, address, tx_config, fee, memos, puzzle_decorator_override, push, timelock_info),
345+
(
346+
request.wallet_id,
347+
request.amount,
348+
request.address,
349+
tx_config,
350+
request.fee,
351+
request.memos,
352+
request.puzzle_decorator,
353+
request.push,
354+
timelock_info,
355+
),
349356
)
350357
name = get_bytes32(2)
351358
tx_rec = TransactionRecord(
@@ -463,7 +470,7 @@ async def cat_spend(
463470
),
464471
500000000000,
465472
["0x6262626262626262626262626262626262626262626262626262626262626262"],
466-
[{"decorator": "CLAWBACK", "clawback_timelock": 60}],
473+
[ClawbackPuzzleDecoratorOverride(decorator="CLAWBACK", clawback_timelock=uint64(60))],
467474
True,
468475
test_condition_valid_times,
469476
)

chia/_tests/pools/test_pool_rpc.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
PWJoinPool,
5050
PWSelfPool,
5151
PWStatus,
52+
SendTransaction,
5253
)
5354
from chia.wallet.wallet_rpc_client import WalletRpcClient
5455
from chia.wallet.wallet_service import WalletService
@@ -591,7 +592,13 @@ async def test_absorb_self(
591592

592593
tr: TransactionRecord = (
593594
await client.send_transaction(
594-
1, uint64(100), encode_puzzle_hash(status.p2_singleton_puzzle_hash, "txch"), DEFAULT_TX_CONFIG
595+
SendTransaction(
596+
wallet_id=uint32(1),
597+
amount=uint64(100),
598+
address=encode_puzzle_hash(status.p2_singleton_puzzle_hash, "txch"),
599+
push=True,
600+
),
601+
DEFAULT_TX_CONFIG,
595602
)
596603
).transaction
597604

chia/_tests/wallet/cat_wallet/test_cat_wallet.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
from chia.wallet.wallet_info import WalletInfo
4545
from chia.wallet.wallet_interested_store import WalletInterestedStore
4646
from chia.wallet.wallet_node import WalletNode
47-
from chia.wallet.wallet_request_types import GetTransactionMemo, PushTX
47+
from chia.wallet.wallet_request_types import GetTransactionMemo, PushTX, SendTransaction
4848
from chia.wallet.wallet_state_manager import WalletStateManager
4949

5050

@@ -1429,7 +1429,12 @@ async def test_cat_change_detection(wallet_environments: WalletTestFramework, wa
14291429
cat_amount_0 = uint64(100)
14301430
cat_amount_1 = uint64(5)
14311431

1432-
tx = (await env.rpc_client.send_transaction(1, cat_amount_0, addr, wallet_environments.tx_config)).transaction
1432+
tx = (
1433+
await env.rpc_client.send_transaction(
1434+
SendTransaction(wallet_id=uint32(1), amount=cat_amount_0, address=addr, push=True),
1435+
wallet_environments.tx_config,
1436+
)
1437+
).transaction
14331438
spend_bundle = tx.spend_bundle
14341439
assert spend_bundle is not None
14351440

chia/_tests/wallet/rpc/test_wallet_rpc.py

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
from chia.wallet.wallet_request_types import (
106106
AddKey,
107107
CheckDeleteKey,
108+
ClawbackPuzzleDecoratorOverride,
108109
CombineCoins,
109110
DefaultCAT,
110111
DeleteKey,
@@ -140,6 +141,7 @@
140141
PushTransactions,
141142
PushTX,
142143
RoyaltyAsset,
144+
SendTransaction,
143145
SetWalletResyncOnStartup,
144146
SplitCoins,
145147
VerifySignature,
@@ -382,24 +384,25 @@ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment
382384
addr = encode_puzzle_hash(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager), "txch")
383385
tx_amount = uint64(15600000)
384386
with pytest.raises(ValueError):
385-
await client.send_transaction(1, uint64(100000000000000001), addr, DEFAULT_TX_CONFIG)
387+
await client.send_transaction(
388+
SendTransaction(wallet_id=uint32(1), amount=uint64(100000000000000001), address=addr, push=True),
389+
DEFAULT_TX_CONFIG,
390+
)
386391

387392
# Tests sending a basic transaction
388393
extra_conditions = (Remark(Program.to(("test", None))),)
389394
non_existent_coin = Coin(bytes32.zeros, bytes32.zeros, uint64(0))
390395
tx_no_push = (
391396
await client.send_transaction(
392-
1,
393-
tx_amount,
394-
addr,
395-
memos=["this is a basic tx"],
397+
SendTransaction(
398+
wallet_id=uint32(1), amount=tx_amount, address=addr, memos=["this is a basic tx"], push=False
399+
),
396400
tx_config=DEFAULT_TX_CONFIG.override(
397401
excluded_coin_amounts=[uint64(250000000000)],
398402
excluded_coin_ids=[non_existent_coin.name()],
399403
reuse_puzhash=True,
400404
),
401405
extra_conditions=extra_conditions,
402-
push=False,
403406
)
404407
).transaction
405408
response = await client.fetch(
@@ -841,12 +844,14 @@ async def test_spend_clawback_coins(wallet_rpc_environment: WalletRpcTestEnviron
841844
wallet_2_puzhash = await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)
842845
tx = (
843846
await wallet_1_rpc.send_transaction(
844-
wallet_id=1,
845-
amount=uint64(500),
846-
address=encode_puzzle_hash(wallet_2_puzhash, "txch"),
847+
SendTransaction(
848+
wallet_id=uint32(1),
849+
amount=uint64(500),
850+
address=encode_puzzle_hash(wallet_2_puzhash, "txch"),
851+
puzzle_decorator=[ClawbackPuzzleDecoratorOverride(decorator="CLAWBACK", clawback_timelock=uint64(5))],
852+
push=True,
853+
),
847854
tx_config=DEFAULT_TX_CONFIG,
848-
fee=uint64(0),
849-
puzzle_decorator_override=[{"decorator": "CLAWBACK", "clawback_timelock": 5}],
850855
)
851856
).transaction
852857
clawback_coin_id_1 = tx.additions[0].name()
@@ -855,12 +860,14 @@ async def test_spend_clawback_coins(wallet_rpc_environment: WalletRpcTestEnviron
855860
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_2_node, timeout=20)
856861
tx = (
857862
await wallet_2_rpc.send_transaction(
858-
wallet_id=1,
859-
amount=uint64(500),
860-
address=encode_puzzle_hash(wallet_1_puzhash, "txch"),
863+
SendTransaction(
864+
wallet_id=uint32(1),
865+
amount=uint64(500),
866+
address=encode_puzzle_hash(wallet_1_puzhash, "txch"),
867+
puzzle_decorator=[ClawbackPuzzleDecoratorOverride(decorator="CLAWBACK", clawback_timelock=uint64(5))],
868+
push=True,
869+
),
861870
tx_config=DEFAULT_TX_CONFIG,
862-
fee=uint64(0),
863-
puzzle_decorator_override=[{"decorator": "CLAWBACK", "clawback_timelock": 5}],
864871
)
865872
).transaction
866873
assert tx.spend_bundle is not None
@@ -1023,7 +1030,8 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
10231030
puzhash = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
10241031
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
10251032
await client.send_transaction(
1026-
1, uint64(1), encode_puzzle_hash(puzhash, "txch"), DEFAULT_TX_CONFIG
1033+
SendTransaction(wallet_id=uint32(1), amount=uint64(1), address=encode_puzzle_hash(puzhash, "txch"), push=True),
1034+
DEFAULT_TX_CONFIG,
10271035
) # Create a pending tx
10281036

10291037
with pytest.raises(ValueError, match="There is no known sort foo"):
@@ -1049,7 +1057,12 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
10491057
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
10501058
ph_by_addr = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
10511059
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
1052-
await client.send_transaction(1, uint64(1), encode_puzzle_hash(ph_by_addr, "txch"), DEFAULT_TX_CONFIG)
1060+
await client.send_transaction(
1061+
SendTransaction(
1062+
wallet_id=uint32(1), amount=uint64(1), address=encode_puzzle_hash(ph_by_addr, "txch"), push=True
1063+
),
1064+
DEFAULT_TX_CONFIG,
1065+
)
10531066
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
10541067
tx_for_address = (
10551068
await client.get_transactions(GetTransactions(uint32(1), to_address=encode_puzzle_hash(ph_by_addr, "txch")))
@@ -1801,7 +1814,12 @@ async def test_get_coin_records_by_names(wallet_rpc_environment: WalletRpcTestEn
18011814
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
18021815

18031816
# Spend half of it back to the same wallet get some spent coins in the wallet
1804-
tx = (await client.send_transaction(1, uint64(generated_funds / 2), address, DEFAULT_TX_CONFIG)).transaction
1817+
tx = (
1818+
await client.send_transaction(
1819+
SendTransaction(wallet_id=uint32(1), amount=uint64(generated_funds / 2), address=address, push=True),
1820+
DEFAULT_TX_CONFIG,
1821+
)
1822+
).transaction
18051823
assert tx.spend_bundle is not None
18061824
await time_out_assert(20, tx_in_mempool, True, client, tx.name)
18071825
await farm_transaction(full_node_api, wallet_node, tx.spend_bundle)
@@ -2167,7 +2185,11 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
21672185
addr = encode_puzzle_hash(ph, "txch")
21682186
tx_amount = uint64(15600000)
21692187
await env.full_node.api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
2170-
created_tx = (await client.send_transaction(1, tx_amount, addr, DEFAULT_TX_CONFIG)).transaction
2188+
created_tx = (
2189+
await client.send_transaction(
2190+
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True), DEFAULT_TX_CONFIG
2191+
)
2192+
).transaction
21712193

21722194
await time_out_assert(20, tx_in_mempool, True, client, created_tx.name)
21732195
assert len(await wallet.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(1)) == 1
@@ -2230,7 +2252,10 @@ async def test_key_and_address_endpoints(wallet_rpc_environment: WalletRpcTestEn
22302252
assert await get_unconfirmed_balance(client, int(wallets[0].id)) == 0
22312253

22322254
with pytest.raises(ValueError):
2233-
await client.send_transaction(wallets[0].id, uint64(100), addr, DEFAULT_TX_CONFIG)
2255+
await client.send_transaction(
2256+
SendTransaction(wallet_id=uint32(wallets[0].id), amount=uint64(100), address=addr, push=True),
2257+
DEFAULT_TX_CONFIG,
2258+
)
22342259

22352260
# Delete all keys
22362261
await client.delete_all_keys()
@@ -2256,7 +2281,11 @@ async def test_select_coins_rpc(wallet_rpc_environment: WalletRpcTestEnvironment
22562281
for tx_amount in tx_amounts:
22572282
funds -= tx_amount
22582283
# create coins for tests
2259-
tx = (await client.send_transaction(1, tx_amount, addr, DEFAULT_TX_CONFIG)).transaction
2284+
tx = (
2285+
await client.send_transaction(
2286+
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True), DEFAULT_TX_CONFIG
2287+
)
2288+
).transaction
22602289
spend_bundle = tx.spend_bundle
22612290
assert spend_bundle is not None
22622291
for coin in spend_bundle.additions():
@@ -2817,12 +2846,14 @@ async def test_set_wallet_resync_on_startup(wallet_rpc_environment: WalletRpcTes
28172846
# Test Clawback resync
28182847
tx = (
28192848
await wc.send_transaction(
2820-
wallet_id=1,
2821-
amount=uint64(500),
2822-
address=address,
2849+
SendTransaction(
2850+
wallet_id=uint32(1),
2851+
amount=uint64(500),
2852+
address=address,
2853+
puzzle_decorator=[ClawbackPuzzleDecoratorOverride(decorator="CLAWBACK", clawback_timelock=uint64(5))],
2854+
push=True,
2855+
),
28232856
tx_config=DEFAULT_TX_CONFIG,
2824-
fee=uint64(0),
2825-
puzzle_decorator_override=[{"decorator": "CLAWBACK", "clawback_timelock": 5}],
28262857
)
28272858
).transaction
28282859
clawback_coin_id = tx.additions[0].name()
@@ -2965,7 +2996,11 @@ async def test_cat_spend_run_tail(wallet_rpc_environment: WalletRpcTestEnvironme
29652996
)
29662997
tx_amount = uint64(100)
29672998

2968-
tx = (await client.send_transaction(1, tx_amount, addr, DEFAULT_TX_CONFIG)).transaction
2999+
tx = (
3000+
await client.send_transaction(
3001+
SendTransaction(wallet_id=uint32(1), amount=tx_amount, address=addr, push=True), DEFAULT_TX_CONFIG
3002+
)
3003+
).transaction
29693004
transaction_id = tx.name
29703005
spend_bundle = tx.spend_bundle
29713006
assert spend_bundle is not None

chia/cmds/wallet_funcs.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from chia.wallet.wallet_coin_store import GetCoinRecords
4646
from chia.wallet.wallet_request_types import (
4747
CATSpendResponse,
48+
ClawbackPuzzleDecoratorOverride,
4849
DeleteNotifications,
4950
DeleteUnconfirmedTransactions,
5051
DIDFindLostDID,
@@ -72,6 +73,7 @@
7273
NFTSetNFTDID,
7374
NFTTransferNFT,
7475
RoyaltyAsset,
76+
SendTransaction,
7577
SendTransactionResponse,
7678
SignMessageByAddress,
7779
SignMessageByAddressResponse,
@@ -335,7 +337,7 @@ async def send(
335337
) -> list[TransactionRecord]:
336338
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, config):
337339
if memo is None:
338-
memos = None
340+
memos = []
339341
else:
340342
memos = [memo]
341343

@@ -364,23 +366,29 @@ async def send(
364366
if typ == WalletType.STANDARD_WALLET:
365367
print("Submitting transaction...")
366368
res: Union[CATSpendResponse, SendTransactionResponse] = await wallet_client.send_transaction(
367-
wallet_id,
368-
final_amount,
369-
address.original_address,
370-
CMDTXConfigLoader(
369+
SendTransaction(
370+
wallet_id=uint32(wallet_id),
371+
amount=final_amount,
372+
address=address.original_address,
373+
fee=fee,
374+
memos=memos,
375+
push=push,
376+
puzzle_decorator=(
377+
[
378+
ClawbackPuzzleDecoratorOverride(
379+
PuzzleDecoratorType.CLAWBACK.name, clawback_timelock=uint64(clawback_time_lock)
380+
)
381+
]
382+
if clawback_time_lock > 0
383+
else None
384+
),
385+
),
386+
tx_config=CMDTXConfigLoader(
371387
min_coin_amount=min_coin_amount,
372388
max_coin_amount=max_coin_amount,
373389
excluded_coin_ids=list(excluded_coin_ids),
374390
reuse_puzhash=reuse_puzhash,
375391
).to_tx_config(mojo_per_unit, config, fingerprint),
376-
fee,
377-
memos,
378-
puzzle_decorator_override=(
379-
[{"decorator": PuzzleDecoratorType.CLAWBACK.name, "clawback_timelock": clawback_time_lock}]
380-
if clawback_time_lock > 0
381-
else None
382-
),
383-
push=push,
384392
timelock_info=condition_valid_times,
385393
)
386394
elif typ in {WalletType.CAT, WalletType.CRCAT, WalletType.RCAT}:

0 commit comments

Comments
 (0)