20
20
from chia ._tests .environments .wallet import WalletStateTransition , WalletTestFramework
21
21
from chia ._tests .util .setup_nodes import SimulatorsAndWalletsServices
22
22
from chia ._tests .util .time_out_assert import time_out_assert , time_out_assert_not_none
23
+ from chia ._tests .wallet .cat_wallet .test_cat_wallet import mint_cat
23
24
from chia ._tests .wallet .test_wallet_coin_store import (
24
25
get_coin_records_amount_filter_tests ,
25
26
get_coin_records_amount_range_tests ,
69
70
from chia .wallet .cat_wallet .cat_constants import DEFAULT_CATS
70
71
from chia .wallet .cat_wallet .cat_utils import CAT_MOD , construct_cat_puzzle
71
72
from chia .wallet .cat_wallet .cat_wallet import CATWallet
73
+ from chia .wallet .cat_wallet .r_cat_wallet import RCATWallet
72
74
from chia .wallet .conditions import (
73
75
ConditionValidTimes ,
74
76
CreateCoinAnnouncement ,
@@ -1077,23 +1079,34 @@ async def test_get_transaction_count(wallet_rpc_environment: WalletRpcTestEnviro
1077
1079
assert transaction_count == 0
1078
1080
1079
1081
1082
+ @pytest .mark .parametrize (
1083
+ "wallet_environments" ,
1084
+ [
1085
+ {
1086
+ "num_environments" : 2 ,
1087
+ "blocks_needed" : [1 , 1 ],
1088
+ }
1089
+ ],
1090
+ indirect = True ,
1091
+ )
1092
+ @pytest .mark .limit_consensus_modes (reason = "irrelevant" )
1093
+ @pytest .mark .parametrize ("wallet_type" , [CATWallet , RCATWallet ])
1080
1094
@pytest .mark .anyio
1081
- async def test_cat_endpoints (wallet_rpc_environment : WalletRpcTestEnvironment ) -> None :
1082
- env : WalletRpcTestEnvironment = wallet_rpc_environment
1083
-
1084
- wallet_node : WalletNode = env .wallet_1 .node
1085
-
1086
- client : WalletRpcClient = env .wallet_1 .rpc_client
1087
- client_2 : WalletRpcClient = env .wallet_2 .rpc_client
1088
-
1089
- full_node_api : FullNodeSimulator = env .full_node .api
1090
-
1091
- await generate_funds (full_node_api , env .wallet_1 , 1 )
1092
- await generate_funds (full_node_api , env .wallet_2 , 1 )
1093
-
1095
+ async def test_cat_endpoints (wallet_environments : WalletTestFramework , wallet_type : type [CATWallet ]) -> None :
1096
+ env_0 = wallet_environments .environments [0 ]
1097
+ env_1 = wallet_environments .environments [1 ]
1098
+ env_0 .wallet_aliases = {
1099
+ "xch" : 1 ,
1100
+ "cat0" : 2 ,
1101
+ "cat1" : 3 ,
1102
+ }
1103
+ env_1 .wallet_aliases = {
1104
+ "xch" : 1 ,
1105
+ "cat0" : 2 ,
1106
+ }
1094
1107
# Test a deprecated path
1095
1108
with pytest .raises (ValueError , match = "dropped" ):
1096
- await client .fetch (
1109
+ await env_0 . rpc_client .fetch (
1097
1110
"create_new_wallet" ,
1098
1111
{
1099
1112
"wallet_type" : "cat_wallet" ,
@@ -1102,136 +1115,232 @@ async def test_cat_endpoints(wallet_rpc_environment: WalletRpcTestEnvironment) -
1102
1115
)
1103
1116
1104
1117
# Creates a CAT wallet with 100 mojos and a CAT with 20 mojos and fee=10
1105
- await client .create_new_cat_and_wallet (uint64 (100 ), fee = uint64 (10 ), test = True )
1106
- await time_out_assert (20 , check_client_synced , True , client )
1107
-
1108
- res = await client .create_new_cat_and_wallet (uint64 (20 ), test = True )
1109
- assert res ["success" ]
1110
- cat_0_id = res ["wallet_id" ]
1111
- asset_id = bytes32 .fromhex (res ["asset_id" ])
1112
- assert len (asset_id ) > 0
1113
-
1114
- await assert_wallet_types (client , {WalletType .STANDARD_WALLET : 1 , WalletType .CAT : 2 })
1115
- await assert_wallet_types (client_2 , {WalletType .STANDARD_WALLET : 1 })
1116
-
1117
- bal_0 = await client .get_wallet_balance (cat_0_id )
1118
- assert bal_0 ["confirmed_wallet_balance" ] == 0
1119
- assert bal_0 ["pending_coin_removal_count" ] == 1
1120
- col = await client .get_cat_asset_id (cat_0_id )
1121
- assert col == asset_id
1122
- assert (await client .get_cat_name (cat_0_id )) == CATWallet .default_wallet_name_for_unknown_cat (asset_id .hex ())
1123
- await client .set_cat_name (cat_0_id , "My cat" )
1124
- assert (await client .get_cat_name (cat_0_id )) == "My cat"
1125
- result = await client .cat_asset_id_to_name (col )
1118
+ await mint_cat (
1119
+ wallet_environments ,
1120
+ env_0 ,
1121
+ "xch" ,
1122
+ "cat0" ,
1123
+ uint64 (100 ),
1124
+ wallet_type ,
1125
+ "cat0" ,
1126
+ )
1127
+ await mint_cat (
1128
+ wallet_environments ,
1129
+ env_0 ,
1130
+ "xch" ,
1131
+ "cat1" ,
1132
+ uint64 (20 ),
1133
+ wallet_type ,
1134
+ "cat1" ,
1135
+ )
1136
+
1137
+ cat_0_id = env_0 .wallet_aliases ["cat0" ]
1138
+ # The RPC response contains more than just the balance info but all the
1139
+ # balance info should match. We're leveraging the `<=` operator to check
1140
+ # for subset on `dict` `.items()`.
1141
+ assert (
1142
+ env_0 .wallet_states [uint32 (env_0 .wallet_aliases ["cat0" ])].balance .to_json_dict ().items ()
1143
+ <= (await env_0 .rpc_client .get_wallet_balance (cat_0_id )).items ()
1144
+ )
1145
+ asset_id = await env_0 .rpc_client .get_cat_asset_id (cat_0_id )
1146
+ assert (await env_0 .rpc_client .get_cat_name (cat_0_id )) == wallet_type .default_wallet_name_for_unknown_cat (
1147
+ asset_id .hex ()
1148
+ )
1149
+ await env_0 .rpc_client .set_cat_name (cat_0_id , "My cat" )
1150
+ assert (await env_0 .rpc_client .get_cat_name (cat_0_id )) == "My cat"
1151
+ result = await env_0 .rpc_client .cat_asset_id_to_name (asset_id )
1126
1152
assert result is not None
1127
1153
wid , name = result
1128
1154
assert wid == cat_0_id
1129
1155
assert name == "My cat"
1130
- result = await client .cat_asset_id_to_name (bytes32 .zeros )
1156
+ result = await env_0 . rpc_client .cat_asset_id_to_name (bytes32 .zeros )
1131
1157
assert result is None
1132
1158
verified_asset_id = next (iter (DEFAULT_CATS .items ()))[1 ]["asset_id" ]
1133
- result = await client .cat_asset_id_to_name (bytes32 .from_hexstr (verified_asset_id ))
1159
+ result = await env_0 . rpc_client .cat_asset_id_to_name (bytes32 .from_hexstr (verified_asset_id ))
1134
1160
assert result is not None
1135
1161
should_be_none , name = result
1136
1162
assert should_be_none is None
1137
1163
assert name == next (iter (DEFAULT_CATS .items ()))[1 ]["name" ]
1138
1164
1139
- # make sure spend is in mempool before farming tx block
1140
- await time_out_assert (5 , check_mempool_spend_count , True , full_node_api , 2 )
1141
- for i in range (5 ):
1142
- if check_mempool_spend_count (full_node_api , 0 ):
1143
- break
1144
- await farm_transaction_block (full_node_api , wallet_node )
1145
-
1146
- # check that we farmed the transaction
1147
- assert check_mempool_spend_count (full_node_api , 0 )
1148
- await full_node_api .wait_for_wallet_synced (wallet_node = wallet_node , timeout = 5 )
1149
-
1150
- await time_out_assert (5 , get_confirmed_balance , 20 , client , cat_0_id )
1151
- bal_0 = await client .get_wallet_balance (cat_0_id )
1152
- assert bal_0 ["pending_coin_removal_count" ] == 0
1153
- assert bal_0 ["unspent_coin_count" ] == 1
1154
-
1155
1165
# Creates a second wallet with the same CAT
1156
- res = await client_2 .create_wallet_for_existing_cat (asset_id )
1166
+ res = await env_1 . rpc_client .create_wallet_for_existing_cat (asset_id )
1157
1167
assert res ["success" ]
1158
1168
cat_1_id = res ["wallet_id" ]
1159
1169
cat_1_asset_id = bytes .fromhex (res ["asset_id" ])
1160
1170
assert cat_1_asset_id == asset_id
1161
1171
1162
- await assert_wallet_types (client , {WalletType .STANDARD_WALLET : 1 , WalletType .CAT : 2 })
1163
- await assert_wallet_types (client_2 , {WalletType .STANDARD_WALLET : 1 , WalletType .CAT : 1 })
1164
-
1165
- await farm_transaction_block (full_node_api , wallet_node )
1166
-
1167
- bal_1 = await client_2 .get_wallet_balance (cat_1_id )
1168
- assert bal_1 ["confirmed_wallet_balance" ] == 0
1172
+ await wallet_environments .process_pending_states (
1173
+ [
1174
+ WalletStateTransition (),
1175
+ WalletStateTransition (
1176
+ pre_block_balance_updates = {
1177
+ "cat0" : {
1178
+ "init" : True ,
1179
+ }
1180
+ },
1181
+ post_block_balance_updates = {},
1182
+ ),
1183
+ ]
1184
+ )
1169
1185
1170
- addr_0 = await client .get_next_address (cat_0_id , False )
1171
- addr_1 = await client_2 .get_next_address (cat_1_id , False )
1186
+ addr_0 = await env_0 . rpc_client .get_next_address (cat_0_id , False )
1187
+ addr_1 = await env_1 . rpc_client .get_next_address (cat_1_id , False )
1172
1188
1173
1189
assert addr_0 != addr_1
1174
1190
1175
1191
# Test CAT spend without a fee
1176
1192
with pytest .raises (ValueError ):
1177
- await client .cat_spend (
1193
+ await env_0 . rpc_client .cat_spend (
1178
1194
cat_0_id ,
1179
1195
DEFAULT_TX_CONFIG .override (
1180
- excluded_coin_amounts = [uint64 (20 )],
1196
+ excluded_coin_amounts = [uint64 (100 )],
1181
1197
excluded_coin_ids = [bytes32 .zeros ],
1182
1198
),
1183
1199
uint64 (4 ),
1184
1200
addr_1 ,
1185
1201
uint64 (0 ),
1186
1202
["the cat memo" ],
1187
1203
)
1188
- tx_res = await client .cat_spend (cat_0_id , DEFAULT_TX_CONFIG , uint64 (4 ), addr_1 , uint64 (0 ), ["the cat memo" ])
1204
+ tx_res = await env_0 .rpc_client .cat_spend (
1205
+ cat_0_id , wallet_environments .tx_config , uint64 (4 ), addr_1 , uint64 (0 ), ["the cat memo" ]
1206
+ )
1189
1207
1190
1208
spend_bundle = tx_res .transaction .spend_bundle
1191
1209
assert spend_bundle is not None
1192
1210
assert uncurry_puzzle (spend_bundle .coin_spends [0 ].puzzle_reveal ).mod == CAT_MOD
1193
- await farm_transaction (full_node_api , wallet_node , spend_bundle )
1194
1211
1195
- await farm_transaction_block (full_node_api , wallet_node )
1212
+ await wallet_environments .process_pending_states (
1213
+ [
1214
+ WalletStateTransition (
1215
+ pre_block_balance_updates = {
1216
+ "cat0" : {
1217
+ "unconfirmed_wallet_balance" : - 4 ,
1218
+ "spendable_balance" : - 100 ,
1219
+ "max_send_amount" : - 100 ,
1220
+ "pending_change" : 96 ,
1221
+ "pending_coin_removal_count" : 1 ,
1222
+ }
1223
+ },
1224
+ post_block_balance_updates = {
1225
+ "cat0" : {
1226
+ "confirmed_wallet_balance" : - 4 ,
1227
+ "spendable_balance" : 96 ,
1228
+ "max_send_amount" : 96 ,
1229
+ "pending_change" : - 96 ,
1230
+ "pending_coin_removal_count" : - 1 ,
1231
+ }
1232
+ },
1233
+ ),
1234
+ WalletStateTransition (
1235
+ pre_block_balance_updates = {},
1236
+ post_block_balance_updates = {
1237
+ "cat0" : {
1238
+ "confirmed_wallet_balance" : 4 ,
1239
+ "unconfirmed_wallet_balance" : 4 ,
1240
+ "spendable_balance" : 4 ,
1241
+ "max_send_amount" : 4 ,
1242
+ "unspent_coin_count" : 1 ,
1243
+ }
1244
+ },
1245
+ ),
1246
+ ]
1247
+ )
1196
1248
1197
1249
# Test CAT spend with a fee
1198
- tx_res = await client .cat_spend (cat_0_id , DEFAULT_TX_CONFIG , uint64 (1 ), addr_1 , uint64 (5_000_000 ), ["the cat memo" ])
1250
+ tx_res = await env_0 .rpc_client .cat_spend (
1251
+ cat_0_id , wallet_environments .tx_config , uint64 (1 ), addr_1 , uint64 (5_000_000 ), ["the cat memo" ]
1252
+ )
1199
1253
1200
1254
spend_bundle = tx_res .transaction .spend_bundle
1201
1255
assert spend_bundle is not None
1202
- await farm_transaction (full_node_api , wallet_node , spend_bundle )
1256
+
1257
+ cat_spend_changes = [
1258
+ WalletStateTransition (
1259
+ pre_block_balance_updates = {
1260
+ "xch" : {
1261
+ "unconfirmed_wallet_balance" : - 5_000_000 ,
1262
+ "<=#spendable_balance" : - 5_000_000 ,
1263
+ "<=#max_send_amount" : - 5_000_000 ,
1264
+ ">=#pending_change" : 1 , # any amount increase
1265
+ "unspent_coin_count" : 0 ,
1266
+ "pending_coin_removal_count" : 1 ,
1267
+ },
1268
+ "cat0" : {
1269
+ "unconfirmed_wallet_balance" : - 1 ,
1270
+ "<=#spendable_balance" : - 1 ,
1271
+ "<=#max_send_amount" : - 1 ,
1272
+ ">=#pending_change" : 1 ,
1273
+ "pending_coin_removal_count" : 1 ,
1274
+ },
1275
+ },
1276
+ post_block_balance_updates = {
1277
+ "xch" : {
1278
+ "confirmed_wallet_balance" : - 5_000_000 ,
1279
+ ">=#spendable_balance" : 1 , # any amount increase
1280
+ ">=#max_send_amount" : 1 , # any amount increase
1281
+ "<=#pending_change" : - 1 , # any amount decrease
1282
+ "unspent_coin_count" : 0 ,
1283
+ "pending_coin_removal_count" : - 1 ,
1284
+ },
1285
+ "cat0" : {
1286
+ "confirmed_wallet_balance" : - 1 ,
1287
+ ">=#spendable_balance" : 1 , # any amount increase
1288
+ ">=#max_send_amount" : 1 , # any amount increase
1289
+ "<=#pending_change" : - 1 , # any amount decrease
1290
+ "pending_coin_removal_count" : - 1 ,
1291
+ },
1292
+ },
1293
+ ),
1294
+ WalletStateTransition (
1295
+ pre_block_balance_updates = {},
1296
+ post_block_balance_updates = {
1297
+ "cat0" : {
1298
+ "confirmed_wallet_balance" : 1 ,
1299
+ "unconfirmed_wallet_balance" : 1 ,
1300
+ "spendable_balance" : 1 ,
1301
+ "max_send_amount" : 1 ,
1302
+ "unspent_coin_count" : 1 ,
1303
+ },
1304
+ },
1305
+ ),
1306
+ ]
1307
+ await wallet_environments .process_pending_states (cat_spend_changes )
1203
1308
1204
1309
# Test CAT spend with a fee and pre-specified removals / coins
1205
- removals = await client .select_coins (
1206
- amount = uint64 (2 ), wallet_id = cat_0_id , coin_selection_config = DEFAULT_COIN_SELECTION_CONFIG
1310
+ removals = await env_0 . rpc_client .select_coins (
1311
+ amount = uint64 (2 ), wallet_id = cat_0_id , coin_selection_config = wallet_environments . tx_config . coin_selection_config
1207
1312
)
1208
- tx_res = await client .cat_spend (
1209
- cat_0_id , DEFAULT_TX_CONFIG , uint64 (1 ), addr_1 , uint64 (5_000_000 ), ["the cat memo" ], removals = removals
1313
+ tx_res = await env_0 .rpc_client .cat_spend (
1314
+ cat_0_id ,
1315
+ wallet_environments .tx_config ,
1316
+ uint64 (1 ),
1317
+ addr_1 ,
1318
+ uint64 (5_000_000 ),
1319
+ ["the cat memo" ],
1320
+ removals = removals ,
1210
1321
)
1211
1322
1212
1323
spend_bundle = tx_res .transaction .spend_bundle
1213
1324
assert spend_bundle is not None
1214
1325
assert removals [0 ] in {removal for tx in tx_res .transactions for removal in tx .removals }
1215
- await farm_transaction (full_node_api , wallet_node , spend_bundle )
1326
+
1327
+ await wallet_environments .process_pending_states (cat_spend_changes )
1216
1328
1217
1329
# Test unacknowledged CAT
1218
- await wallet_node .wallet_state_manager .interested_store .add_unacknowledged_token (
1330
+ await env_0 .wallet_state_manager .interested_store .add_unacknowledged_token (
1219
1331
asset_id , "Unknown" , uint32 (10000 ), bytes32 (b"\00 " * 32 )
1220
1332
)
1221
- cats = await client .get_stray_cats ()
1333
+ cats = await env_0 . rpc_client .get_stray_cats ()
1222
1334
assert len (cats ) == 1
1223
1335
1224
- await time_out_assert (20 , get_confirmed_balance , 14 , client , cat_0_id )
1225
- await time_out_assert (20 , get_confirmed_balance , 6 , client_2 , cat_1_id )
1226
-
1227
1336
# Test CAT coin selection
1228
- selected_coins = await client .select_coins (
1229
- amount = 1 , wallet_id = cat_0_id , coin_selection_config = DEFAULT_COIN_SELECTION_CONFIG
1337
+ selected_coins = await env_0 . rpc_client .select_coins (
1338
+ amount = 1 , wallet_id = cat_0_id , coin_selection_config = wallet_environments . tx_config . coin_selection_config
1230
1339
)
1231
1340
assert len (selected_coins ) > 0
1232
1341
1233
1342
# Test get_cat_list
1234
- cat_list = (await client .get_cat_list ()).cat_list
1343
+ cat_list = (await env_0 . rpc_client .get_cat_list ()).cat_list
1235
1344
assert len (DEFAULT_CATS ) == len (cat_list )
1236
1345
default_cats_set = {
1237
1346
DefaultCAT (asset_id = bytes32 .from_hexstr (cat ["asset_id" ]), name = cat ["name" ], symbol = cat ["symbol" ])
0 commit comments