Skip to content

Commit 0a0293f

Browse files
Quexingtonaltendky
andauthored
[CHIA-3297] Port get_transaction(s) to @marshal (#19775)
* Port `get_transaction(s)` * simplify class * undo simplification * Delete __eq__ and add test coverage * Less dunder access * small change Co-authored-by: Kyle Altendorf <[email protected]> --------- Co-authored-by: Kyle Altendorf <[email protected]>
1 parent 12712ea commit 0a0293f

File tree

11 files changed

+243
-154
lines changed

11 files changed

+243
-154
lines changed

chia/_tests/cmds/cmd_test_utils.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
from chia.wallet.util.wallet_types import WalletType
3636
from chia.wallet.wallet_request_types import (
3737
GetSyncStatusResponse,
38+
GetTransaction,
39+
GetTransactionResponse,
3840
GetWallets,
3941
GetWalletsResponse,
4042
NFTCalculateRoyalties,
@@ -115,27 +117,30 @@ async def get_wallets(self, request: GetWallets) -> GetWalletsResponse:
115117
raise ValueError(f"Invalid fingerprint: {self.fingerprint}")
116118
return GetWalletsResponse([WalletInfoResponse(id=uint32(1), name="", type=uint8(w_type.value), data="")])
117119

118-
async def get_transaction(self, transaction_id: bytes32) -> TransactionRecord:
119-
self.add_to_log("get_transaction", (transaction_id,))
120-
return TransactionRecord(
121-
confirmed_at_height=uint32(1),
122-
created_at_time=uint64(1234),
123-
to_puzzle_hash=bytes32([1] * 32),
124-
to_address=encode_puzzle_hash(bytes32([1] * 32), "xch"),
125-
amount=uint64(12345678),
126-
fee_amount=uint64(1234567),
127-
confirmed=False,
128-
sent=uint32(0),
129-
spend_bundle=WalletSpendBundle([], G2Element()),
130-
additions=[Coin(bytes32([1] * 32), bytes32([2] * 32), uint64(12345678))],
131-
removals=[Coin(bytes32([2] * 32), bytes32([4] * 32), uint64(12345678))],
132-
wallet_id=uint32(1),
133-
sent_to=[("aaaaa", uint8(1), None)],
134-
trade_id=None,
135-
type=uint32(TransactionType.OUTGOING_TX.value),
136-
name=bytes32([2] * 32),
137-
memos={bytes32([3] * 32): [bytes([4] * 32)]},
138-
valid_times=ConditionValidTimes(),
120+
async def get_transaction(self, request: GetTransaction) -> GetTransactionResponse:
121+
self.add_to_log("get_transaction", (request,))
122+
return GetTransactionResponse(
123+
TransactionRecord(
124+
confirmed_at_height=uint32(1),
125+
created_at_time=uint64(1234),
126+
to_puzzle_hash=bytes32([1] * 32),
127+
to_address=encode_puzzle_hash(bytes32([1] * 32), "xch"),
128+
amount=uint64(12345678),
129+
fee_amount=uint64(1234567),
130+
confirmed=False,
131+
sent=uint32(0),
132+
spend_bundle=WalletSpendBundle([], G2Element()),
133+
additions=[Coin(bytes32([1] * 32), bytes32([2] * 32), uint64(12345678))],
134+
removals=[Coin(bytes32([2] * 32), bytes32([4] * 32), uint64(12345678))],
135+
wallet_id=uint32(1),
136+
sent_to=[("aaaaa", uint8(1), None)],
137+
trade_id=None,
138+
type=uint32(TransactionType.OUTGOING_TX.value),
139+
name=bytes32([2] * 32),
140+
memos={bytes32([3] * 32): [bytes([4] * 32)]},
141+
valid_times=ConditionValidTimes(),
142+
),
143+
bytes32([2] * 32),
139144
)
140145

141146
async def get_cat_name(self, wallet_id: int) -> str:

chia/_tests/cmds/wallet/test_wallet.py

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from chia.wallet.trading.trade_status import TradeStatus
3636
from chia.wallet.transaction_record import TransactionRecord
3737
from chia.wallet.transaction_sorting import SortKey
38-
from chia.wallet.util.query_filter import HashFilter, TransactionTypeFilter
38+
from chia.wallet.util.query_filter import HashFilter
3939
from chia.wallet.util.transaction_type import TransactionType
4040
from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG, TXConfig
4141
from chia.wallet.util.wallet_types import WalletType
@@ -47,6 +47,9 @@
4747
CreateOfferForIDsResponse,
4848
FungibleAsset,
4949
GetHeightInfoResponse,
50+
GetTransaction,
51+
GetTransactions,
52+
GetTransactionsResponse,
5053
GetWalletBalance,
5154
GetWalletBalanceResponse,
5255
GetWallets,
@@ -57,6 +60,7 @@
5760
RoyaltyAsset,
5861
SendTransactionResponse,
5962
TakeOfferResponse,
63+
TransactionRecordWithMetadata,
6064
WalletInfoResponse,
6165
)
6266
from chia.wallet.wallet_spend_bundle import WalletSpendBundle
@@ -100,9 +104,9 @@ def test_get_transaction(capsys: object, get_test_cli_clients: tuple[TestRpcClie
100104
"get_wallets": [(GetWallets(type=None, include_data=True),)] * 3,
101105
"get_cat_name": [(1,)],
102106
"get_transaction": [
103-
(bytes32.from_hexstr(bytes32_hexstr),),
104-
(bytes32.from_hexstr(bytes32_hexstr),),
105-
(bytes32.from_hexstr(bytes32_hexstr),),
107+
(GetTransaction(bytes32.from_hexstr(bytes32_hexstr)),),
108+
(GetTransaction(bytes32.from_hexstr(bytes32_hexstr)),),
109+
(GetTransaction(bytes32.from_hexstr(bytes32_hexstr)),),
106110
],
107111
}
108112
test_rpc_clients.wallet_rpc_client.check_log(expected_calls)
@@ -113,24 +117,13 @@ def test_get_transactions(capsys: object, get_test_cli_clients: tuple[TestRpcCli
113117

114118
# set RPC Client
115119
class GetTransactionsWalletRpcClient(TestWalletRpcClient):
116-
async def get_transactions(
117-
self,
118-
wallet_id: int,
119-
start: int,
120-
end: int,
121-
sort_key: Optional[SortKey] = None,
122-
reverse: bool = False,
123-
to_address: Optional[str] = None,
124-
type_filter: Optional[TransactionTypeFilter] = None,
125-
confirmed: Optional[bool] = None,
126-
) -> list[TransactionRecord]:
127-
self.add_to_log(
128-
"get_transactions", (wallet_id, start, end, sort_key, reverse, to_address, type_filter, confirmed)
129-
)
120+
async def get_transactions(self, request: GetTransactions) -> GetTransactionsResponse:
121+
self.add_to_log("get_transactions", (request,))
130122
l_tx_rec = []
131-
for i in range(start, end):
132-
t_type = TransactionType.INCOMING_CLAWBACK_SEND if i == end - 1 else TransactionType.INCOMING_TX
133-
tx_rec = TransactionRecord(
123+
assert request.start is not None and request.end is not None
124+
for i in range(request.start, request.end):
125+
t_type = TransactionType.INCOMING_CLAWBACK_SEND if i == request.end - 1 else TransactionType.INCOMING_TX
126+
tx_rec = TransactionRecordWithMetadata(
134127
confirmed_at_height=uint32(1 + i),
135128
created_at_time=uint64(1234 + i),
136129
to_puzzle_hash=bytes32([1 + i] * 32),
@@ -152,7 +145,7 @@ async def get_transactions(
152145
)
153146
l_tx_rec.append(tx_rec)
154147

155-
return l_tx_rec
148+
return GetTransactionsResponse(l_tx_rec, request.wallet_id)
156149

157150
async def get_coin_records(self, request: GetCoinRecords) -> dict[str, Any]:
158151
self.add_to_log("get_coin_records", (request,))
@@ -201,8 +194,8 @@ async def get_coin_records(self, request: GetCoinRecords) -> dict[str, Any]:
201194
expected_calls: logType = {
202195
"get_wallets": [(GetWallets(type=None, include_data=True),)] * 2,
203196
"get_transactions": [
204-
(1, 2, 4, SortKey.RELEVANCE, True, None, None, None),
205-
(1, 2, 4, SortKey.RELEVANCE, True, None, None, None),
197+
(GetTransactions(uint32(1), uint16(2), uint16(4), SortKey.RELEVANCE.name, True, None, None, None),),
198+
(GetTransactions(uint32(1), uint16(2), uint16(4), SortKey.RELEVANCE.name, True, None, None, None),),
206199
],
207200
"get_coin_records": [
208201
(GetCoinRecords(coin_id_filter=HashFilter.include([expected_coin_id])),),
@@ -490,7 +483,7 @@ async def cat_spend(
490483
test_condition_valid_times,
491484
)
492485
],
493-
"get_transaction": [(get_bytes32(2),), (get_bytes32(2),)],
486+
"get_transaction": [(GetTransaction(get_bytes32(2)),), (GetTransaction(get_bytes32(2)),)],
494487
}
495488
test_rpc_clients.wallet_rpc_client.check_log(expected_calls)
496489

chia/_tests/pools/test_pool_rpc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from chia.wallet.util.wallet_types import WalletType
4242
from chia.wallet.wallet_node import WalletNode
4343
from chia.wallet.wallet_request_types import (
44+
GetTransactions,
4445
GetWalletBalance,
4546
GetWallets,
4647
PWAbsorbRewards,
@@ -605,7 +606,7 @@ async def test_absorb_self(
605606
PWAbsorbRewards(wallet_id=uint32(2), fee=uint64(fee), push=True), DEFAULT_TX_CONFIG
606607
)
607608

608-
tx1 = await client.get_transactions(1)
609+
tx1 = (await client.get_transactions(GetTransactions(uint32(1)))).transactions
609610
assert (250_000_000_000 + fee) in [tx.amount for tx in tx1]
610611

611612
@pytest.mark.anyio

chia/_tests/wallet/rpc/test_wallet_rpc.py

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@
122122
GetPrivateKey,
123123
GetSyncStatusResponse,
124124
GetTimestampForHeight,
125+
GetTransaction,
126+
GetTransactions,
125127
GetWalletBalance,
126128
GetWalletBalances,
127129
GetWallets,
@@ -345,7 +347,7 @@ async def assert_get_balance(rpc_client: WalletRpcClient, wallet_node: WalletNod
345347

346348

347349
async def tx_in_mempool(client: WalletRpcClient, transaction_id: bytes32) -> bool:
348-
tx = await client.get_transaction(transaction_id)
350+
tx = (await client.get_transaction(GetTransaction(transaction_id))).transaction
349351
return tx.is_in_mempool()
350352

351353

@@ -433,7 +435,7 @@ async def test_send_transaction(wallet_rpc_environment: WalletRpcTestEnvironment
433435
await farm_transaction(full_node_api, wallet_node, spend_bundle)
434436

435437
# Checks that the memo can be retrieved
436-
tx_confirmed = await client.get_transaction(transaction_id)
438+
tx_confirmed = (await client.get_transaction(GetTransaction(transaction_id))).transaction
437439
assert tx_confirmed.confirmed
438440
assert len(tx_confirmed.memos) == 1
439441
assert [b"this is a basic tx"] in tx_confirmed.memos.values()
@@ -479,7 +481,7 @@ async def test_push_transactions(wallet_rpc_environment: WalletRpcTestEnvironmen
479481
await farm_transaction(full_node_api, wallet_node, spend_bundle)
480482

481483
for tx in resp_client.transactions:
482-
assert (await client.get_transaction(transaction_id=tx.name)).confirmed
484+
assert (await client.get_transaction(GetTransaction(transaction_id=tx.name))).transaction.confirmed
483485

484486
# Just testing NOT failure here really (parsing)
485487
await client.push_tx(PushTX(spend_bundle))
@@ -973,7 +975,7 @@ async def test_send_transaction_multi(wallet_rpc_environment: WalletRpcTestEnvir
973975
await time_out_assert(20, get_confirmed_balance, generated_funds - amount_outputs - amount_fee, client, 1)
974976

975977
# Checks that the memo can be retrieved
976-
tx_confirmed = await client.get_transaction(send_tx_res.name)
978+
tx_confirmed = (await client.get_transaction(GetTransaction(send_tx_res.name))).transaction
977979
assert tx_confirmed.confirmed
978980
memos = tx_confirmed.memos
979981
assert len(memos) == len(outputs)
@@ -996,18 +998,20 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
996998

997999
await generate_funds(full_node_api, env.wallet_1, 5)
9981000

999-
all_transactions = await client.get_transactions(1)
1001+
all_transactions = (await client.get_transactions(GetTransactions(uint32(1)))).transactions
10001002
assert len(all_transactions) >= 10
10011003
# Test transaction pagination
1002-
some_transactions = await client.get_transactions(1, 0, 5)
1003-
some_transactions_2 = await client.get_transactions(1, 5, 10)
1004+
some_transactions = (await client.get_transactions(GetTransactions(uint32(1), uint16(0), uint16(5)))).transactions
1005+
some_transactions_2 = (
1006+
await client.get_transactions(GetTransactions(uint32(1), uint16(5), uint16(10)))
1007+
).transactions
10041008
assert some_transactions == all_transactions[0:5]
10051009
assert some_transactions_2 == all_transactions[5:10]
10061010

10071011
# Testing sorts
10081012
# Test the default sort (CONFIRMED_AT_HEIGHT)
10091013
assert all_transactions == sorted(all_transactions, key=attrgetter("confirmed_at_height"))
1010-
all_transactions = await client.get_transactions(1, reverse=True)
1014+
all_transactions = (await client.get_transactions(GetTransactions(uint32(1), reverse=True))).transactions
10111015
assert all_transactions == sorted(all_transactions, key=attrgetter("confirmed_at_height"), reverse=True)
10121016

10131017
# Test RELEVANCE
@@ -1018,13 +1022,20 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
10181022
1, uint64(1), encode_puzzle_hash(puzhash, "txch"), DEFAULT_TX_CONFIG
10191023
) # Create a pending tx
10201024

1021-
all_transactions = await client.get_transactions(1, sort_key=SortKey.RELEVANCE)
1025+
with pytest.raises(ValueError, match="There is no known sort foo"):
1026+
await client.get_transactions(GetTransactions(uint32(1), sort_key="foo"))
1027+
1028+
all_transactions = (
1029+
await client.get_transactions(GetTransactions(uint32(1), sort_key=SortKey.RELEVANCE.name))
1030+
).transactions
10221031
sorted_transactions = sorted(all_transactions, key=attrgetter("created_at_time"), reverse=True)
10231032
sorted_transactions = sorted(sorted_transactions, key=attrgetter("confirmed_at_height"), reverse=True)
10241033
sorted_transactions = sorted(sorted_transactions, key=attrgetter("confirmed"))
10251034
assert all_transactions == sorted_transactions
10261035

1027-
all_transactions = await client.get_transactions(1, sort_key=SortKey.RELEVANCE, reverse=True)
1036+
all_transactions = (
1037+
await client.get_transactions(GetTransactions(uint32(1), sort_key=SortKey.RELEVANCE.name, reverse=True))
1038+
).transactions
10281039
sorted_transactions = sorted(all_transactions, key=attrgetter("created_at_time"))
10291040
sorted_transactions = sorted(sorted_transactions, key=attrgetter("confirmed_at_height"))
10301041
sorted_transactions = sorted(sorted_transactions, key=attrgetter("confirmed"), reverse=True)
@@ -1036,31 +1047,41 @@ async def test_get_transactions(wallet_rpc_environment: WalletRpcTestEnvironment
10361047
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
10371048
await client.send_transaction(1, uint64(1), encode_puzzle_hash(ph_by_addr, "txch"), DEFAULT_TX_CONFIG)
10381049
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)
1039-
tx_for_address = await client.get_transactions(1, to_address=encode_puzzle_hash(ph_by_addr, "txch"))
1050+
tx_for_address = (
1051+
await client.get_transactions(GetTransactions(uint32(1), to_address=encode_puzzle_hash(ph_by_addr, "txch")))
1052+
).transactions
10401053
assert len(tx_for_address) == 1
10411054
assert tx_for_address[0].to_puzzle_hash == ph_by_addr
10421055

10431056
# Test type filter
1044-
all_transactions = await client.get_transactions(
1045-
1, type_filter=TransactionTypeFilter.include([TransactionType.COINBASE_REWARD])
1046-
)
1057+
all_transactions = (
1058+
await client.get_transactions(
1059+
GetTransactions(uint32(1), type_filter=TransactionTypeFilter.include([TransactionType.COINBASE_REWARD]))
1060+
)
1061+
).transactions
10471062
assert len(all_transactions) == 5
10481063
assert all(transaction.type == TransactionType.COINBASE_REWARD.value for transaction in all_transactions)
10491064
# Test confirmed filter
1050-
all_transactions = await client.get_transactions(1, confirmed=True)
1065+
all_transactions = (await client.get_transactions(GetTransactions(uint32(1), confirmed=True))).transactions
10511066
assert len(all_transactions) == 10
10521067
assert all(transaction.confirmed for transaction in all_transactions)
1053-
all_transactions = await client.get_transactions(1, confirmed=False)
1068+
all_transactions = (await client.get_transactions(GetTransactions(uint32(1), confirmed=False))).transactions
10541069
assert len(all_transactions) == 2
10551070
assert all(not transaction.confirmed for transaction in all_transactions)
10561071

10571072
# Test bypass broken txs
10581073
await wallet.wallet_state_manager.tx_store.add_transaction_record(
10591074
dataclasses.replace(all_transactions[0], type=uint32(TransactionType.INCOMING_CLAWBACK_SEND))
10601075
)
1061-
all_transactions = await client.get_transactions(
1062-
1, type_filter=TransactionTypeFilter.include([TransactionType.INCOMING_CLAWBACK_SEND]), confirmed=False
1063-
)
1076+
all_transactions = (
1077+
await client.get_transactions(
1078+
GetTransactions(
1079+
uint32(1),
1080+
type_filter=TransactionTypeFilter.include([TransactionType.INCOMING_CLAWBACK_SEND]),
1081+
confirmed=False,
1082+
)
1083+
)
1084+
).transactions
10641085
assert len(all_transactions) == 1
10651086

10661087

@@ -1073,7 +1094,7 @@ async def test_get_transaction_count(wallet_rpc_environment: WalletRpcTestEnviro
10731094

10741095
await generate_funds(full_node_api, env.wallet_1)
10751096

1076-
all_transactions = await client.get_transactions(1)
1097+
all_transactions = (await client.get_transactions(GetTransactions(uint32(1)))).transactions
10771098
assert len(all_transactions) > 0
10781099
transaction_count = await client.get_transaction_count(1)
10791100
assert transaction_count == len(all_transactions)

chia/_tests/wallet/test_wallet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ async def test_wallet_clawback_clawback(self, wallet_environments: WalletTestFra
395395
assert len(txs["transactions"]) == 1
396396
assert not txs["transactions"][0]["confirmed"]
397397
assert txs["transactions"][0]["metadata"]["recipient_puzzle_hash"][2:] == normal_puzhash.hex()
398-
assert txs["transactions"][0]["metadata"]["coin_id"] == merkle_coin.name().hex()
398+
assert txs["transactions"][0]["metadata"]["coin_id"] == "0x" + merkle_coin.name().hex()
399399
with pytest.raises(ValueError):
400400
await api_0.spend_clawback_coins({})
401401

chia/_tests/wallet/vc_wallet/test_vc_wallet.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pytest
88
from chia_rs import G2Element
99
from chia_rs.sized_bytes import bytes32
10-
from chia_rs.sized_ints import uint8, uint16, uint64
10+
from chia_rs.sized_ints import uint8, uint16, uint32, uint64
1111
from typing_extensions import Literal
1212

1313
from chia._tests.environments.wallet import WalletEnvironment, WalletStateTransition, WalletTestFramework
@@ -31,6 +31,7 @@
3131
from chia.wallet.wallet import Wallet
3232
from chia.wallet.wallet_node import WalletNode
3333
from chia.wallet.wallet_request_types import (
34+
GetTransactions,
3435
GetWallets,
3536
VCAddProofs,
3637
VCGet,
@@ -454,13 +455,17 @@ async def test_vc_lifecycle(wallet_environments: WalletTestFramework) -> None:
454455
assert await wallet_node_1.wallet_state_manager.wallets[env_1.dealias_wallet_id("crcat")].match_hinted_coin(
455456
next(c for tx in txs for c in tx.additions if c.amount == 90), wallet_1_ph
456457
)
457-
pending_tx = await client_1.get_transactions(
458-
env_1.dealias_wallet_id("crcat"),
459-
0,
460-
1,
461-
reverse=True,
462-
type_filter=TransactionTypeFilter.include([TransactionType.INCOMING_CRCAT_PENDING]),
463-
)
458+
pending_tx = (
459+
await client_1.get_transactions(
460+
GetTransactions(
461+
uint32(env_1.dealias_wallet_id("crcat")),
462+
uint16(0),
463+
uint16(1),
464+
reverse=True,
465+
type_filter=TransactionTypeFilter.include([TransactionType.INCOMING_CRCAT_PENDING]),
466+
)
467+
)
468+
).transactions
464469
assert len(pending_tx) == 1
465470

466471
# Send the VC to wallet_1 to use for the CR-CATs

0 commit comments

Comments
 (0)