Skip to content

Commit 1467c4b

Browse files
Compatible group... Include group.
1 parent 1b12fdc commit 1467c4b

File tree

1 file changed

+121
-67
lines changed

1 file changed

+121
-67
lines changed

cardano_clusterlib/compat_common.py

Lines changed: 121 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,113 @@ def registration_certificate(
297297
self._clusterlib_obj.cli(cmd, add_default_args=False)
298298

299299

300+
class GovernanceActionGroup:
301+
"""Governance action subcommands for compatible eras."""
302+
303+
def __init__(self, clusterlib_obj: "ClusterLib", era: str) -> None:
304+
self._clusterlib_obj = clusterlib_obj
305+
self._base = ("cardano-cli", "compatible", era, "governance", "action")
306+
307+
def _resolve_pparam_args(
308+
self,
309+
*,
310+
epoch: int | None = None,
311+
genesis_vkey_file: itp.FileType | None = None,
312+
pparams: dict[str, object] | None = None,
313+
) -> list[str]:
314+
"""Resolve protocol parameter update CLI arguments."""
315+
if epoch is None:
316+
message = "The `epoch` parameter is required for protocol parameters update."
317+
raise ValueError(message)
318+
319+
if not genesis_vkey_file:
320+
message = "`genesis_vkey_file` is required for protocol parameters update."
321+
raise ValueError(message)
322+
323+
if not pparams:
324+
message = "At least one protocol parameter must be provided."
325+
raise ValueError(message)
326+
327+
args: list[str] = ["--epoch", str(epoch)]
328+
329+
for flag, value in pparams.items():
330+
if value is None:
331+
continue
332+
args.extend([flag, str(value)])
333+
334+
args.extend(["--genesis-verification-key-file", str(genesis_vkey_file)])
335+
336+
return args
337+
338+
def create_protocol_parameters_update(
339+
self,
340+
*,
341+
epoch: int,
342+
genesis_vkey_file: itp.FileType,
343+
out_file: itp.FileType,
344+
**pparams: object,
345+
) -> None:
346+
"""Wrap the protocol parameters update command."""
347+
flag_map = {
348+
"min_fee_linear": "--min-fee-linear",
349+
"min_fee_constant": "--min-fee-constant",
350+
"max_block_body_size": "--max-block-body-size",
351+
"max_tx_size": "--max-tx-size",
352+
"max_block_header_size": "--max-block-header-size",
353+
"key_reg_deposit_amt": "--key-reg-deposit-amt",
354+
"pool_reg_deposit": "--pool-reg-deposit",
355+
"pool_retirement_epoch_interval": "--pool-retirement-epoch-interval",
356+
"number_of_pools": "--number-of-pools",
357+
"pool_influence": "--pool-influence",
358+
"treasury_expansion": "--treasury-expansion",
359+
"monetary_expansion": "--monetary-expansion",
360+
"min_pool_cost": "--min-pool-cost",
361+
"price_execution_steps": "--price-execution-steps",
362+
"price_execution_memory": "--price-execution-memory",
363+
"max_tx_execution_units": "--max-tx-execution-units",
364+
"max_block_execution_units": "--max-block-execution-units",
365+
"max_value_size": "--max-value-size",
366+
"collateral_percent": "--collateral-percent",
367+
"max_collateral_inputs": "--max-collateral-inputs",
368+
"protocol_major_version": "--protocol-major-version",
369+
"protocol_minor_version": "--protocol-minor-version",
370+
"utxo_cost_per_byte": "--utxo-cost-per-byte",
371+
"cost_model_file": "--cost-model-file",
372+
}
373+
374+
pparam_args: dict[str, object] = {}
375+
376+
for py_key, value in pparams.items():
377+
if py_key not in flag_map:
378+
msg = f"Unknown protocol parameter: {py_key}"
379+
raise ValueError(msg)
380+
if value is not None:
381+
pparam_args[flag_map[py_key]] = value
382+
383+
resolved_args = self._resolve_pparam_args(
384+
epoch=epoch,
385+
genesis_vkey_file=genesis_vkey_file,
386+
pparams=pparam_args,
387+
)
388+
389+
cmd = [
390+
*self._base,
391+
"create-protocol-parameters-update",
392+
*resolved_args,
393+
"--out-file",
394+
str(out_file),
395+
]
396+
397+
self._clusterlib_obj.cli(cmd, add_default_args=False)
398+
399+
300400
class GovernanceGroup:
301401
"""Generic governance group for all compatible eras."""
302402

303403
def __init__(self, clusterlib_obj: "ClusterLib", era: str) -> None:
304404
self._clusterlib_obj = clusterlib_obj
305405
self._base = ("cardano-cli", "compatible", era, "governance")
406+
self.action = GovernanceActionGroup(clusterlib_obj, era)
306407

307408
def _resolve_mir_direct_args(
308409
self,
@@ -313,19 +414,9 @@ def _resolve_mir_direct_args(
313414
reward: int | None,
314415
out_file: itp.FileType,
315416
) -> list[str] | None:
316-
"""Resolve direct MIR mode args (no subcommand).
317-
318-
Direct mode syntax:
319-
(--reserves | --treasury)
320-
--stake-address ADDRESS
321-
--reward LOVELACE
322-
--out-file FILEPATH
323-
"""
324-
# No direct mode selected
325417
if not reserves and not treasury:
326418
return None
327419

328-
# Invalid: both pots selected
329420
if reserves and treasury:
330421
msg = "Cannot specify both `reserves` and `treasury` in direct MIR mode."
331422
raise ValueError(msg)
@@ -338,10 +429,10 @@ def _resolve_mir_direct_args(
338429
msg = "`reward` is required in direct MIR mode."
339430
raise ValueError(msg)
340431

341-
pot_flag = "--reserves" if reserves else "--treasury"
432+
flag = "--reserves" if reserves else "--treasury"
342433

343-
args: list[str] = [
344-
pot_flag,
434+
args = [
435+
flag,
345436
"--stake-address",
346437
stake_address,
347438
"--reward",
@@ -359,7 +450,6 @@ def _mir_stake_addresses_args(
359450
funds: str | None,
360451
out_file: itp.FileType,
361452
) -> list[str]:
362-
"""Arguments for `create-mir-certificate stake-addresses`."""
363453
if not stake_address:
364454
msg = "`stake_address` is required for 'stake-addresses' MIR subcommand."
365455
raise ValueError(msg)
@@ -372,7 +462,7 @@ def _mir_stake_addresses_args(
372462
msg = "`funds` must be either 'reserves' or 'treasury' for 'stake-addresses'."
373463
raise ValueError(msg)
374464

375-
args: list[str] = [
465+
args = [
376466
"stake-addresses",
377467
f"--{funds}",
378468
"--stake-address",
@@ -390,39 +480,35 @@ def _mir_transfer_to_treasury_args(
390480
transfer_amt: int | None,
391481
out_file: itp.FileType,
392482
) -> list[str]:
393-
"""Arguments for `create-mir-certificate transfer-to-treasury`."""
394483
if transfer_amt is None:
395484
msg = "`transfer_amt` is required for 'transfer-to-treasury' MIR subcommand."
396485
raise ValueError(msg)
397486

398-
args: list[str] = [
487+
return [
399488
"transfer-to-treasury",
400489
"--transfer",
401490
str(transfer_amt),
402491
"--out-file",
403492
str(out_file),
404493
]
405-
return args
406494

407495
def _mir_transfer_to_rewards_args(
408496
self,
409497
*,
410498
transfer_amt: int | None,
411499
out_file: itp.FileType,
412500
) -> list[str]:
413-
"""Arguments for `create-mir-certificate transfer-to-rewards`."""
414501
if transfer_amt is None:
415502
msg = "`transfer_amt` is required for 'transfer-to-rewards' MIR subcommand."
416503
raise ValueError(msg)
417504

418-
args: list[str] = [
505+
return [
419506
"transfer-to-rewards",
420507
"--transfer",
421508
str(transfer_amt),
422509
"--out-file",
423510
str(out_file),
424511
]
425-
return args
426512

427513
def _resolve_mir_subcommand_args(
428514
self,
@@ -434,13 +520,6 @@ def _resolve_mir_subcommand_args(
434520
funds: str | None,
435521
out_file: itp.FileType,
436522
) -> list[str] | None:
437-
"""Resolve MIR subcommand arguments, if any.
438-
439-
Supported subcommands:
440-
* stake-addresses
441-
* transfer-to-treasury
442-
* transfer-to-rewards
443-
"""
444523
if not subcommand:
445524
return None
446525

@@ -470,34 +549,15 @@ def _resolve_mir_subcommand_args(
470549
def create_mir_certificate(
471550
self,
472551
*,
473-
# Direct MIR mode
474552
reserves: bool = False,
475553
treasury: bool = False,
476554
reward: int | None = None,
477555
stake_address: str | None = None,
478-
# Subcommand mode
479556
subcommand: str | None = None,
480557
transfer_amt: int | None = None,
481558
funds: str | None = None,
482-
# Output
483559
out_file: itp.FileType,
484560
) -> None:
485-
"""Wrap the `governance create-mir-certificate` command (compatible eras).
486-
487-
Two usage modes:
488-
489-
1. Direct MIR:
490-
* `reserves` or `treasury` (exactly one)
491-
* `stake_address`
492-
* `reward`
493-
* `out_file`
494-
495-
2. Subcommands:
496-
* `subcommand="stake-addresses"`, `funds=("reserves"|"treasury")`,
497-
`stake_address`, `reward`, `out_file`
498-
* `subcommand="transfer-to-treasury"`, `transfer_amt`, `out_file`
499-
* `subcommand="transfer-to-rewards"`, `transfer_amt`, `out_file`
500-
"""
501561
direct_args = self._resolve_mir_direct_args(
502562
reserves=reserves,
503563
treasury=treasury,
@@ -515,21 +575,24 @@ def create_mir_certificate(
515575
out_file=out_file,
516576
)
517577

518-
# Cannot mix modes
519578
if direct_args and subcmd_args:
520579
msg = "Cannot mix direct MIR mode with MIR subcommand mode."
521580
raise ValueError(msg)
522581

523582
if not direct_args and not subcmd_args:
524583
msg = (
525584
"No MIR mode selected. Provide either direct MIR parameters "
526-
"(reserves/treasury + stake_address + reward) "
527585
"or a valid MIR subcommand."
528586
)
529587
raise ValueError(msg)
530588

531-
final_args = direct_args or subcmd_args
532-
assert final_args is not None
589+
if direct_args is not None:
590+
final_args: list[str] = direct_args
591+
else:
592+
msg = "Internal error: MIR subcommand arguments missing."
593+
if subcmd_args is None:
594+
raise ValueError(msg)
595+
final_args = subcmd_args
533596

534597
cmd = [
535598
*self._base,
@@ -539,14 +602,17 @@ def create_mir_certificate(
539602

540603
self._clusterlib_obj.cli(cmd, add_default_args=False)
541604

605+
self._clusterlib_obj.cli(cmd, add_default_args=False)
606+
607+
self._clusterlib_obj.cli(cmd, add_default_args=False)
608+
542609
def _resolve_genesis_key_args(
543610
self,
544611
*,
545612
genesis_vkey: str = "",
546613
genesis_vkey_file: itp.FileType | None = None,
547614
genesis_vkey_hash: str = "",
548615
) -> list[str]:
549-
"""Resolve genesis verification key specification."""
550616
if genesis_vkey:
551617
return ["--genesis-verification-key", genesis_vkey]
552618

@@ -556,10 +622,7 @@ def _resolve_genesis_key_args(
556622
if genesis_vkey_hash:
557623
return ["--genesis-verification-key-hash", genesis_vkey_hash]
558624

559-
msg = (
560-
"One of genesis_vkey, genesis_vkey_file or genesis_vkey_hash "
561-
"must be provided for genesis key delegation."
562-
)
625+
msg = "One of genesis_vkey, genesis_vkey_file or genesis_vkey_hash must be provided."
563626
raise ValueError(msg)
564627

565628
def _resolve_delegate_key_args(
@@ -569,7 +632,6 @@ def _resolve_delegate_key_args(
569632
delegate_vkey_file: itp.FileType | None = None,
570633
delegate_vkey_hash: str = "",
571634
) -> list[str]:
572-
"""Resolve delegate verification key specification."""
573635
if delegate_vkey:
574636
return ["--genesis-delegate-verification-key", delegate_vkey]
575637

@@ -579,10 +641,7 @@ def _resolve_delegate_key_args(
579641
if delegate_vkey_hash:
580642
return ["--genesis-delegate-verification-key-hash", delegate_vkey_hash]
581643

582-
msg = (
583-
"One of delegate_vkey, delegate_vkey_file or delegate_vkey_hash "
584-
"must be provided for genesis key delegation."
585-
)
644+
msg = "One of delegate_vkey, delegate_vkey_file or delegate_vkey_hash must be provided."
586645
raise ValueError(msg)
587646

588647
def _resolve_vrf_key_args(
@@ -592,7 +651,6 @@ def _resolve_vrf_key_args(
592651
vrf_vkey_file: itp.FileType | None = None,
593652
vrf_vkey_hash: str = "",
594653
) -> list[str]:
595-
"""Resolve VRF key specification."""
596654
if vrf_vkey:
597655
return ["--vrf-verification-key", vrf_vkey]
598656

@@ -602,10 +660,7 @@ def _resolve_vrf_key_args(
602660
if vrf_vkey_hash:
603661
return ["--vrf-verification-key-hash", vrf_vkey_hash]
604662

605-
msg = (
606-
"One of vrf_vkey, vrf_vkey_file or vrf_vkey_hash "
607-
"must be provided for genesis key delegation."
608-
)
663+
msg = "One VRF key argument must be provided."
609664
raise ValueError(msg)
610665

611666
def create_genesis_key_delegation_certificate(
@@ -622,7 +677,6 @@ def create_genesis_key_delegation_certificate(
622677
vrf_vkey_hash: str = "",
623678
out_file: itp.FileType,
624679
) -> None:
625-
"""Wrap the `governance create-genesis-key-delegation-certificate` command."""
626680
genesis_args = self._resolve_genesis_key_args(
627681
genesis_vkey=genesis_vkey,
628682
genesis_vkey_file=genesis_vkey_file,

0 commit comments

Comments
 (0)