Skip to content

Commit fd4db74

Browse files
committed
feat(utils): add stake address re-registration
- Implemented `reregister_stake_addr` function to handle stake address re-registration and vote delegation. - Updated `deregister_stake_addr` to use the new re-registration function. - Adjusted transaction names and certificate names to include `rf_` prefix. - Improved batch processing logic in `return_funds_to_faucet` and `cleanup_addresses`.
1 parent 7921141 commit fd4db74

File tree

1 file changed

+78
-30
lines changed

1 file changed

+78
-30
lines changed

cardano_node_tests/utils/testnet_cleanup.py

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,63 @@
2424
LOGGER = logging.getLogger(__name__)
2525

2626

27+
def reregister_stake_addr(
28+
cluster_obj: clusterlib.ClusterLib,
29+
pool_user: clusterlib.PoolUser,
30+
stake_addr_info: clusterlib.StakeAddrInfo,
31+
name_template: str,
32+
deposit_amt: int,
33+
) -> clusterlib.StakeAddrInfo:
34+
"""Re-register stake address.
35+
36+
The address needs to be registered and delegated to a DRep to be able to withdraw rewards.
37+
"""
38+
rereg_certs = []
39+
rereg_deposit = 0
40+
41+
is_not_registered = not stake_addr_info
42+
has_no_vote_deleg = not stake_addr_info.vote_delegation
43+
has_rewards = stake_addr_info and stake_addr_info.reward_account_balance
44+
45+
if is_not_registered:
46+
reg_cert = cluster_obj.g_stake_address.gen_stake_addr_registration_cert(
47+
addr_name=f"rf_{name_template}",
48+
deposit_amt=deposit_amt,
49+
stake_vkey_file=pool_user.stake.vkey_file,
50+
)
51+
rereg_certs.append(reg_cert)
52+
rereg_deposit += deposit_amt
53+
54+
# We need to delegate votes only when there are rewards to withdraw
55+
if is_not_registered or (has_rewards and has_no_vote_deleg):
56+
deleg_cert = cluster_obj.g_stake_address.gen_vote_delegation_cert(
57+
addr_name=f"rf_{name_template}",
58+
stake_vkey_file=pool_user.stake.vkey_file,
59+
always_abstain=True,
60+
)
61+
rereg_certs.append(deleg_cert)
62+
63+
if rereg_certs:
64+
tx_files_register = clusterlib.TxFiles(
65+
certificate_files=rereg_certs,
66+
signing_key_files=[pool_user.payment.skey_file, pool_user.stake.skey_file],
67+
)
68+
try:
69+
cluster_obj.g_transaction.send_tx(
70+
src_address=pool_user.payment.address,
71+
tx_name=f"rf_{name_template}_rereg_stake",
72+
tx_files=tx_files_register,
73+
deposit=rereg_deposit,
74+
)
75+
except clusterlib.CLIError:
76+
LOGGER.error(f"Failed to re-register stake address '{pool_user.stake.address}'") # noqa: TRY400
77+
else:
78+
LOGGER.debug(f"Re-registered stake address '{pool_user.stake.address}'")
79+
stake_addr_info = cluster_obj.g_query.get_stake_addr_info(pool_user.stake.address)
80+
81+
return stake_addr_info
82+
83+
2784
def deregister_stake_addr(
2885
cluster_obj: clusterlib.ClusterLib,
2986
pool_user: clusterlib.PoolUser,
@@ -34,11 +91,15 @@ def deregister_stake_addr(
3491
"""Deregister stake address."""
3592
withdrawals = []
3693
if stake_addr_info.reward_account_balance:
37-
withdrawals = [clusterlib.TxOut(address=pool_user.stake.address, amount=-1)]
94+
withdrawals = [
95+
clusterlib.TxOut(
96+
address=pool_user.stake.address, amount=stake_addr_info.reward_account_balance
97+
)
98+
]
3899

39100
# Files for deregistering stake address
40101
stake_addr_dereg_cert = cluster_obj.g_stake_address.gen_stake_addr_deregistration_cert(
41-
addr_name=f"rf_{name_template}_addr0_dereg",
102+
addr_name=f"rf_{name_template}",
42103
deposit_amt=deposit_amt,
43104
stake_vkey_file=pool_user.stake.vkey_file,
44105
)
@@ -47,38 +108,19 @@ def deregister_stake_addr(
47108
signing_key_files=[pool_user.payment.skey_file, pool_user.stake.skey_file],
48109
)
49110

50-
dereg_failed = False
51111
try:
52112
cluster_obj.g_transaction.send_tx(
53113
src_address=pool_user.payment.address,
54-
tx_name=f"{name_template}_dereg_withdraw_stake_addr",
114+
tx_name=f"rf_{name_template}_dereg_withdraw_stake",
55115
tx_files=tx_files_deregister,
56116
withdrawals=withdrawals,
57117
deposit=-deposit_amt,
58118
)
59119
except clusterlib.CLIError:
60-
dereg_failed = True
61120
LOGGER.error(f"Failed to deregister stake address '{pool_user.stake.address}'") # noqa: TRY400
62121
else:
63122
LOGGER.debug(f"Deregistered stake address '{pool_user.stake.address}'")
64123

65-
# Try to at least withdraw rewards if deregistration was not successful
66-
if dereg_failed and withdrawals:
67-
tx_files_withdrawal = clusterlib.TxFiles(
68-
signing_key_files=[pool_user.payment.skey_file, pool_user.stake.skey_file],
69-
)
70-
try:
71-
cluster_obj.g_transaction.send_tx(
72-
src_address=pool_user.payment.address,
73-
tx_name=f"rf_{name_template}_reward_withdrawal",
74-
tx_files=tx_files_withdrawal,
75-
withdrawals=withdrawals,
76-
)
77-
except clusterlib.CLIError:
78-
LOGGER.error(f"Failed to withdraw rewards for '{pool_user.stake.address}'") # noqa: TRY400
79-
else:
80-
LOGGER.debug(f"Withdrawn rewards for '{pool_user.stake.address}'")
81-
82124

83125
def retire_drep(
84126
cluster_obj: clusterlib.ClusterLib,
@@ -89,7 +131,7 @@ def retire_drep(
89131
) -> None:
90132
"""Retire a DRep."""
91133
ret_cert = cluster_obj.g_conway_governance.drep.gen_retirement_cert(
92-
cert_name=f"{name_template}_cleanup",
134+
cert_name=f"rf_{name_template}",
93135
deposit_amt=deposit_amt,
94136
drep_vkey_file=drep_keys.vkey_file,
95137
)
@@ -101,7 +143,7 @@ def retire_drep(
101143
try:
102144
cluster_obj.g_transaction.send_tx(
103145
src_address=payment_addr.address,
104-
tx_name=f"{name_template}_retire_drep",
146+
tx_name=f"rf_{name_template}_retire_drep",
105147
tx_files=tx_files,
106148
deposit=-deposit_amt,
107149
)
@@ -149,7 +191,7 @@ def return_funds_to_faucet(
149191
fund_tx_files = clusterlib.TxFiles(signing_key_files=skeys)
150192

151193
txins_len = len(txins)
152-
batch_size = min(100, txins_len)
194+
batch_size = min(100, txins_len or 1)
153195
batch_num = 1
154196
for b in range(0, txins_len, batch_size):
155197
tx_name = f"{tx_name}_batch{batch_num}"
@@ -236,7 +278,7 @@ def cleanup_addresses(
236278
) -> None:
237279
"""Cleanup addresses."""
238280
files_found = group_addr_files(find_addr_files(location))
239-
num_threads = min(10, len(files_found) // 200)
281+
num_threads = min(10, (len(files_found) // 200) + 1)
240282

241283
stake_deposit_amt = cluster_obj.g_query.get_address_deposit()
242284

@@ -263,9 +305,15 @@ def _run(files: list[pl.Path]) -> None:
263305

264306
pool_user = clusterlib.PoolUser(payment=payment, stake=stake)
265307

266-
stake_addr_info = cluster_obj.g_query.get_stake_addr_info(pool_user.stake.address)
267-
if not stake_addr_info:
268-
continue
308+
stake_addr_info = reregister_stake_addr(
309+
cluster_obj=cluster_obj,
310+
pool_user=pool_user,
311+
stake_addr_info=cluster_obj.g_query.get_stake_addr_info(
312+
pool_user.stake.address
313+
),
314+
name_template=f_name,
315+
deposit_amt=stake_deposit_amt,
316+
)
269317

270318
deregister_stake_addr(
271319
cluster_obj=cluster_obj,
@@ -304,7 +352,7 @@ def cleanup_certs(
304352
) -> None:
305353
"""Cleanup DRep certs."""
306354
files_found = list(find_cert_files(location))
307-
num_threads = min(10, len(files_found) // 10)
355+
num_threads = min(10, (len(files_found) // 10) + 1)
308356

309357
drep_deposit_amt = cluster_obj.g_query.get_drep_deposit()
310358

0 commit comments

Comments
 (0)