cardano_node_tests.tests.tests_dijkstra packageο
Submodulesο
cardano_node_tests.tests.tests_dijkstra.bls moduleο
The node BLS (Leios voting) keys, shared by the BLS tests.
Holds what the key files look like, what the ledger reports for a registered key, and the two facts that follow from the key being registered on chain - how long it stays honoured, and when the Leios committee starts holding it.
The scheme is BLS12-381 in its minimal signature size variant, so the verification key is 96 bytes in G2 and a signature is 48 bytes in G1. CIP-0164 fixes the on-chain encodings in Appendix B:
leios_bls_verification_key = bytes .size 96
leios_bls_signature = bytes .size 48
leios_bls_pop = bytes .size 48
The signing key is a 32 byte scalar. It never goes on chain, so the CIP says nothing about it.
- class cardano_node_tests.tests.tests_dijkstra.bls.KeySpec(envelope_type: str, envelope_desc: str, bech32_prefix: str, key_len: int)[source]ο
Bases:
objectExpected properties of a generated BLS key.
- cardano_node_tests.tests.tests_dijkstra.bls.check_bech32_key(*, key_file: Path, spec: KeySpec) bytes[source]ο
Check that the file is a bech32 encoded BLS key of the expected kind.
- Parameters:
key_file β A path to the key file.
spec β The expected properties of the key.
- Returns:
The raw key material.
- Return type:
bytes
- cardano_node_tests.tests.tests_dijkstra.bls.check_envelope_key(*, key_file: Path, spec: KeySpec) bytes[source]ο
Check that the file is a BLS key text envelope of the expected kind.
Accepts both
Minimaland legacyMininimaltype spellings, as experimental CLI builds cannot be distinguished by version alone.- Parameters:
key_file β A path to the key file.
spec β The expected properties of the key.
- Returns:
The raw key material.
- Return type:
bytes
- cardano_node_tests.tests.tests_dijkstra.bls.get_bls_pub_key(*, bls_key_state: dict | None) str | None[source]ο
Return the hex encoded BLS verification key of a key state record.
Both the
spsBlsKeyof a pool and thekeyof a Leios committee seat are a key with its registration epoch, and either can be missing - a pool doesnβt have to have a BLS key.- Parameters:
bls_key_state β A BLS key state record, or None when there is none.
- Returns:
The hex encoded verification key, or None when there is no key.
- Return type:
str | None
- cardano_node_tests.tests.tests_dijkstra.bls.get_max_key_age(*, cluster_obj: ClusterLib) int[source]ο
Return the BLS key lifetime in epochs, as the ledger derives it from genesis.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
- Returns:
The number of epochs a registered BLS key is honoured for.
- Return type:
int
- cardano_node_tests.tests.tests_dijkstra.bls.get_registered_bls_key(*, cluster_obj: ClusterLib, pool_id: str) dict[source]ο
Return the BLS key state the ledger holds for a pool.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_id β An ID of the stake pool (Bech32-encoded or hex-encoded).
- Returns:
- The
spsBlsKeyrecord, i.e. the key with the epoch it was registered in, or an empty dict when the pool has no registered BLS key.
- The
- Return type:
dict
- cardano_node_tests.tests.tests_dijkstra.bls.get_vkey_hex(*, vkey_file: Path) str[source]ο
Return the raw BLS verification key of a key file, hex encoded.
The ledger reports a registered key as hex, while the key file stores it CBOR-wrapped inside a text envelope. The envelope is checked on the way, so that a signing key passed here by mistake is reported as such instead of as a key mismatch.
- Parameters:
vkey_file β A path to the BLS verification key file.
- Returns:
The hex encoded verification key.
- Return type:
str
- cardano_node_tests.tests.tests_dijkstra.bls.reregister_cluster_pool(*, cluster_obj: ClusterLib, pool_rec: dict, pool_name: str, pool_id: str, bls_skey_file: Path, tx_name: str, allow_xfail: bool = True) None[source]ο
Re-register a cluster pool with a new BLS key, keeping everything else as it is.
Xfails, unless disabled by allow_xfail, on a cluster instance whose pools came from the genesis: the ledger records no occurrence of their VRF key hash, so the Dijkstra POOL rule rejects the update with VRFKeyHashAlreadyRegistered even though the VRF key does not change. Once the ledger populates the map on genesis injection, the rejection stops and the tests run.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_rec β The addresses and keys of the pool, from the cluster manager cache.
pool_name β A name of the pool, e.g.
node-pool1.pool_id β An ID of the stake pool (Bech32-encoded or hex-encoded).
bls_skey_file β A path to the BLS signing key file to register.
tx_name β A name of the transaction.
allow_xfail β Whether to xfail on the known VRFKeyHashAlreadyRegistered ledger issue instead of failing (optional, default True).
cardano_node_tests.tests.tests_dijkstra.conftest moduleο
Shared fixtures for Dijkstra-era tests.
cardano_node_tests.tests.tests_dijkstra.leios moduleο
Leios committee queries, trace messages and log search helpers.
The Leios activity of a node is visible only in its trace messages, and the messages are emitted only in the Dijkstra era and only when there is enough Tx load for a block producer to have something to put into an endorser block (EB). Tests therefore search the node log files for the messages they expect, over the log content that got appended since they started looking.
Committee queries vary between feature branches. Keep their temporary compatibility handling here, without adding the experimental query to clusterlib.
- cardano_node_tests.tests.tests_dijkstra.leios.collect_vote_outcome_msgs(*, pool_logs: list[Path], deadline: float) tuple[dict[Path, set[str]], list[str]][source]ο
Search the pool logs for votes, EB announcements and declined votes.
The three outcomes together say whether a pool voted, whether there was anything for it to vote on, and whether it reported why it didnβt vote. The whole window is searched, with no early exit: a pool that is expected not to vote can report the reason first and vote afterwards, and a search that stopped at the first message would not see that.
- Parameters:
pool_logs β Log files of the block producing nodes.
deadline β A time.monotonic() value the search must not go past, so that the searched part of the logs stays inside the epoch the search started in.
- Returns:
The searched messages found in each pool log, and the problems that got in the way of the search - a log file that could not be searched. They explain a missing message, so they are reported only together with one.
- cardano_node_tests.tests.tests_dijkstra.leios.get_certificate_problems(*, found_per_pool: dict[str, set[str]], epoch: int) tuple[list[str], list[str]][source]ο
Judge whether the votes of one epoch added up to a certificate.
Meant for a committee that is expected to certify, e.g. one that lost seats while the quorum was lowered to match. Without an EB to vote on there is nothing to certify, and then the absence of certificates says nothing.
- Parameters:
found_per_pool β The searched messages found in the log of each pool.
epoch β The epoch the logs were searched in, for the reported messages.
- Returns:
The failures, and the reasons the outcome is inconclusive. Both empty when a certificate was assembled.
- cardano_node_tests.tests.tests_dijkstra.leios.get_committee(*, cluster_obj: ClusterLib, snapshot: dict | None = None, required_fields: tuple[str, ...] = ()) list[dict][source]ο
Read the current Leios committee, resolving debug voting keys temporarily.
Prefer the old stake-snapshot schema when present. Otherwise inspect query help before using the experimental leios-committee command. Match its voting keys to the set snapshot to recover pool identities and key state, decoding debug keys when necessary. Keyless seats cannot establish pool identities this way.
Missing capabilities skip the affected check. The raw queryβs missing details are covered separately by the ledger issue 6245 test, without using this workaround. An advertised command failing, or malformed JSON, is always a failure.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
snapshot β An already queried stake snapshot, to keep legacy committee and stake data in one query. Query all pools when omitted.
required_fields β Seat fields needed by the caller, e.g. poolId, key, voting. An empty legacy committee retains its known schema. An empty experimental committee cannot establish support for these fields.
- Returns:
The current committee seats, retaining the original fields and adding resolved poolId, key and voting fields when the temporary workaround is needed.
- cardano_node_tests.tests.tests_dijkstra.leios.get_committee_seat(*, cluster_obj: ClusterLib, pool_id: str) dict[source]ο
Return the Leios committee seat of a pool in the current epoch.
Use either committee query schema, requiring pool identities and structured key state. Skip when neither schema nor the voting-key workaround supports the check.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_id β An ID of the stake pool (Bech32-encoded or hex-encoded).
- Returns:
The seat of the pool, or an empty dict when the pool holds no seat.
- Return type:
dict
- cardano_node_tests.tests.tests_dijkstra.leios.get_eb_tx_ref(*, tx_file: Path) tuple[str, int][source]ο
Return the EB reference to a valid Dijkstra payment transaction.
An EB doesnβt list its txs by tx id (the hash of the tx body), but by the Blake2b-256 hash and size of the block-format tx (serializeTxForLeios in ouroboros-consensus LeiosDemoTypes.hs). The signed file holds the three-element mempool format [body, witnesses, auxiliary_data]. Block inclusion adds a trailing is_valid flag, which is true for the payment txs this helper supports. Only the outer array header is replaced and the flag appended, preserving the original bytes of every component.
- Parameters:
tx_file β A path to a signed valid Dijkstra payment tx (a text envelope).
- Returns:
The block-format tx hash as a hex string, and its size in bytes.
- Raises:
AssertionError β If the file doesnβt hold a three-element mempool transaction.
- cardano_node_tests.tests.tests_dijkstra.leios.get_voting_problems(*, found_per_pool: dict[str, set[str]], out_pool_names: frozenset[str], epoch: int) tuple[list[str], list[str]][source]ο
Judge what each pool was seen doing about the EBs of one epoch.
A pool that holds no committee seat must have answered every EB announcement with NotOnCommittee and cast no vote, the seated pools must have voted and must not have declined for any of the searched reasons, and their votes must have added up to a certificate - meant for a committee that lost seats while the quorum was lowered to match, so a certificate is what says the seats that are left still reach it. A pool that didnβt vote and said nothing about it is a failure only when there was an EB to vote on; without one the absence of votes says nothing, so it is reported as a reason to skip instead of as an error.
- Parameters:
found_per_pool β The searched messages found in the log of each pool.
out_pool_names β Names of the pools that the committee left out.
epoch β The epoch the logs were searched in, for the reported messages.
- Returns:
The failures, and the reasons the outcome is inconclusive. Both empty when every pool did what it was supposed to.
- cardano_node_tests.tests.tests_dijkstra.leios.is_committee_seated_in_genesis(*, cluster_obj: ClusterLib) bool[source]ο
Check whether the Leios voting committee is seated from epoch 0.
A pool can vote once its BLS key is in a stake distribution snapshot the committee is drawn from. A pool registered by a transaction on a freshly started cluster instance gets there only in VOTING_START_EPOCH, while a pool whose parameters, BLS key included, are already in the genesis is in the initial ledger state and so on the committee from the first slot.
The genesis always lists the pools created by genesis create-staked βgen-pools, but their entries carry a BLS key only when the cluster start script wrote the real pool parameters into them instead of submitting a registration transaction. The key is therefore what tells the two setups apart, not the presence of the pools. The entries live under extraConfig since cardano-cli 11.2 and under staking before that.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
- Returns:
True when a pool is on the voting committee from epoch 0.
- cardano_node_tests.tests.tests_dijkstra.leios.skip_if_no_ebs(*, cluster_obj: ClusterLib) None[source]ο
Skip the test when the cluster settings donβt allow an EB to be forged.
The settings are known only once a cluster instance is assigned to the test, so this cannot be a skipif marker.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
- cardano_node_tests.tests.tests_dijkstra.leios.skip_if_no_ebs_in_genesis(*, genesis: dict) None[source]ο
Skip the test when the genesis settings donβt allow an EB to be forged.
Takes the genesis instead of a cluster instance, so that a test which starts a cluster of its own can be ruled out before paying for the startup.
- Parameters:
genesis β The Shelley genesis of the cluster instance, or the genesis spec the instance is started from.
- cardano_node_tests.tests.tests_dijkstra.leios.skip_unsupported_committee(reason: str) NoReturn[source]ο
Skip a committee check that the available query schemas cannot support.
Feature branches report different committee schemas under the same version. The raw queryβs missing details are covered separately by the ledger issue 6245 test.
- Parameters:
reason β The committee capability that the current CLI cannot report.
cardano_node_tests.tests.tests_dijkstra.sub_tx_utils moduleο
Small assembly helpers for independently authorized payment children.
- class cardano_node_tests.tests.tests_dijkstra.sub_tx_utils.SignedChild(output: SubTxRawOutput, signed_file: Path, txid: str)[source]ο
Bases:
objectKeep independently signed child artifacts and predicted output references.
- cardano_node_tests.tests.tests_dijkstra.sub_tx_utils.append_body_field(*, tx_file: Path, out_file: Path, key: int, value: Any) Path[source]ο
Append an absent field before signing without re-encoding embedded children.
- cardano_node_tests.tests.tests_dijkstra.sub_tx_utils.build_child(*, cluster: ClusterLib, name: str, txins: list[UTXOData], txouts: list[TxOut], signing_keys: list[Path], reference_inputs: list[UTXOData] | None = None, tx_files: TxFiles | None = None, treasury_donation: int | None = None, invalid_before: int | None = None, invalid_hereafter: int | None = None, direct_deposits: list[TxOut] | None = None, withdrawals: list[TxOut] | None = None) SignedChild[source]ο
Build and independently sign an explicitly balanced or unbalanced child.
- cardano_node_tests.tests.tests_dijkstra.sub_tx_utils.build_parent(*, cluster: ClusterLib, name: str, sponsor: AddressRecord, txins: list[UTXOData], txouts: list[TxOut], children: list[SignedChild], fee_lovelace: int = 500000, reference_inputs: list[UTXOData] | None = None, signing_keys: list[Path] | None = None, collateral_inputs: list[UTXOData] | None = None, invalid_before: int | None = None, invalid_hereafter: int | None = None, tx_files: TxFiles | None = None) tuple[TxRawOutput, Path][source]ο
Assemble file-only children without automatically repairing batch balance.
- cardano_node_tests.tests.tests_dijkstra.sub_tx_utils.check_child_outputs(*, cluster: ClusterLib, child: SignedChild) None[source]ο
Check exact originating child output references, values, and addresses.
- cardano_node_tests.tests.tests_dijkstra.sub_tx_utils.remove_output_datum_hash(*, tx_file: Path, out_file: Path) Path[source]ο
Remove the first outputβs hash before signing, preserving all other CBOR bytes.
Retain the CLI-generated datum witness and integrity hash to exercise its supplemental scope. Never rewrite an embedded signed child or accept an already key-witnessed transaction as input to this mutation.
- cardano_node_tests.tests.tests_dijkstra.sub_tx_utils.replace_body_field(*, tx_file: Path, out_file: Path, key: int, value_cbor: bytes) Path[source]ο
Replace one unsigned body field with explicit bytes, preserving all other fields.
The caller supplies complete CBOR for the replacement field, including any already signed children. Reject parent key witnesses so intentional parent mutations cannot accidentally leave stale authorization in the artifact.
cardano_node_tests.tests.tests_dijkstra.test_bls_keys moduleο
Tests for generating and registering the node BLS (Leios voting) keys.
- class cardano_node_tests.tests.tests_dijkstra.test_bls_keys.TestBlsKeys[source]ο
Bases:
objectTests for generating node BLS key pairs.
- test_gen_bls_key_pair(cluster: ClusterLib)[source]ο
Generate a node BLS key pair.
Generate the key pair using gen_bls_key_pair
Check that the key files were created with the expected names
Check that both keys are text envelopes of the expected type and description
Check that the raw key material has the expected size
- test_gen_bls_key_pair_matching_keys(cluster: ClusterLib)[source]ο
Check that the generated BLS verification key matches the signing key.
The pool registration certificate stores the BLS verification key and a proof of possession, both derived from the BLS signing key. So the certificate can be used to check that the generated key pair is consistent.
Generate a BLS key pair
Generate a pool registration certificate using the BLS signing key
Check that the certificate contains the generated BLS verification key
Check that the certificate contains a proof of possession of the expected size
- test_gen_bls_key_pair_out_format(cluster: ClusterLib, out_format: str)[source]ο
Generate a BLS key pair in the parametrized output format.
Generate the key pair with βkey-output-text-envelope or βkey-output-bech32
Check that the keys are in the requested format
Check that the raw key material has the expected size
- class cardano_node_tests.tests.tests_dijkstra.test_bls_keys.TestBlsProofOfPossession[source]ο
Bases:
objectTests for the proof of possession that accompanies a registered BLS key.
- pool_user(cluster_manager: ClusterManager, cluster: ClusterLib) PoolUser[source]ο
Create a pool user with a registered stake address.
- test_mismatched_pop_is_rejected(cluster: ClusterLib, pool_user: PoolUser)[source]ο
Reject a pool registration whose BLS proof of possession belongs to another key.
CIP-0164 requires the proof of possession to be verified at registration, so a mismatched proof must be rejected before the key can reach a committee seat.
Generate a pool registration certificate with another BLS keyβs proof
Check that submission fails with BlsKeyInvalidProofOfPossession
Check that the pool was not registered
- class cardano_node_tests.tests.tests_dijkstra.test_bls_keys.TestNegativeBlsKeys[source]ο
Bases:
objectNegative tests for generating node BLS key pairs.
- test_bls_skey_not_accepted_as_ed25519(cluster: ClusterLib)[source]ο
Try to derive a verification key from a BLS signing key using key verification-key.
The BLS signing key is not an ed25519 key, so it is not accepted by the generic cardano-cli key verification-key command.
Expect failure.
- test_bls_vkey_not_accepted_as_signing_key(cluster: ClusterLib)[source]ο
Try to build a pool registration certificate with a BLS verification key.
The certificate carries a proof of possession, which the CLI can derive only from the signing key, so there is no command that takes the verification key instead.
Expect failure.
Try to generate a BLS key pair using the conway command era.
BLS keys donβt exist in Conway, so the cardano-cli conway node command group has no key-gen-BLS subcommand.
Expect failure.
- cardano_node_tests.tests.tests_dijkstra.test_bls_keys.gen_pool_registration_with_mismatched_pop(*, cluster_obj: ClusterLib, pool_user: PoolUser, temp_template: str) tuple[TxFiles, str][source]ο
Prepare a pool registration whose BLS proof of possession belongs to another key.
The proof cannot be produced on its own - the CLI derives it from the signing key and emits it only inside a registration certificate - so the mismatch is built by taking the proof out of a second poolβs certificate and splicing it into the first one.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_user β A pool user that owns the pool and pays for the registration.
temp_template β A test identifier used for naming the created files.
- Returns:
The registration transaction files and pool ID.
- Return type:
tuple[clusterlib.TxFiles, str]
cardano_node_tests.tests.tests_dijkstra.test_bls_rotation moduleο
Tests for rotation and expiration of the stake pool BLS (Leios voting) keys.
A pool registers its BLS key through the stake pool registration certificate, and the
ledger stores the key together with the epoch the registration took effect in
(bksRegisteredIn). That pair is what the Leios voting committee is drawn from, and
the key is offered to the committee only while:
currentEpoch < bksRegisteredIn + maxKeyAge
maxKeyAge is not a protocol parameter. The ledger derives it from the KES setup in
the Shelley genesis, so that voting key rotation rides along with the KES rotation pools
already run:
maxKeyAge = ceil(maxKESEvolutions * slotsPerKESPeriod / epochLength) + 2
Rotating is the same operation as registering - submit a fresh pool registration
certificate carrying the new key. The ledger treats a registration of an already
registered pool as an update, so it lands in futurePoolParams and takes effect at the
next epoch boundary, which is where bksRegisteredIn is re-stamped for a changed key.
Re-registering the same key preserves its original registration epoch and does not
extend its lifetime. The committee itself is seated once per epoch from the stake snapshot
that rotates into the set position, so a rotated key needs one more boundary before the
committee holds it - two epoch boundaries in total from the rotation transaction.
An aged-out key does not free the seat: the pool keeps its committee weight, cannot vote
with it, and the seat is not reallocated. That is what query stake-snapshot reports as
a seat with a key and "voting": false. A pool that never registered a key holds
the same kind of seat, reported with a key of null - CIP-0164 keeps the
bls_key field of the registration certificate optional for backwards compatibility.
The two epoch boundaries are a design choice rather than a necessity. CIP-0164 notes that a voting key carries no nonce grinding concern and could therefore activate a full epoch earlier than a VRF key, and settles on the VRF schedule anyway so that an operator who rotates both keys does a single hot key swap. The tests check the boundary the ledger implements, so the committee still holding the old key in the epoch after the rotation is asserted rather than merely tolerated - moving to the earlier activation has to fail here, not pass quietly.
CIP-0164 still lists the rotation mechanism as an open acceptance criterion (Appendix A requirement 2), so what these tests pin down is the mechanism the ledger implements today: re-registration through the pool certificate, with the key time-to-live derived from the KES setup. The CIP requires rotation and a corresponding time-to-live, but neither the certificate route nor the formula is settled there.
The two tests that rotate the key of a cluster pool need that pool to be re-registrable, which a pool whose parameters come from the genesis is not - see bls.reregister_cluster_pool. They xfail on such an instance, so today they run for real only on a testnet variant that starts before Dijkstra and hard-forks into it.
See CIP-0164 and the Leios testnet guide for the operator side of this.
- class cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.TestBlsKeyExpiration[source]ο
Bases:
objectTests for the expiration of a registered BLS key.
- test_expired_bls_key(cluster_short_bls_keyage: ClusterLib, cluster_manager: ClusterManager)[source]ο
Test that a BLS key expires, and that rotating it in time prevents that.
Start a local cluster instance whose KES setup gives the BLS keys a lifetime of only SHORT_MAX_KEY_AGE epochs, so the keys the cluster pools registered on startup expire during the test
Refresh the operational certificates of all the pools, so that the short KES lifetime doesnβt stop them from forging before the BLS keys expire
Rotate the BLS key of one pool, early enough for the rotated key to be seated before the original keys expire
Check that in the last epoch before the expiration every pool is voting, and that the rotated pool is voting with its new key
Check that in the expiration epoch the pools that didnβt rotate are still seated, with their key reported and not voting, while the rotated pool keeps voting
- class cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.TestBlsKeyRotation[source]ο
Bases:
objectTests for rotating the BLS key of a registered stake pool.
- test_drop_and_restore_bls_key(cluster: ClusterLib, cluster_conway_cmd: ClusterLib, cluster_manager: ClusterManager, request: FixtureRequest)[source]ο
Drop the BLS key of a pool with a Conway-era certificate, then rotate one back in.
A Conway-era pool registration certificate carries no BLS key, and the Dijkstra ledger accepts it as a pool update - it just leaves the pool without a voting key. The pool keeps its committee seat, so this is the βseated but keylessβ case an operator ends up in, reached on purpose. Rotating a key back in is the way out of it.
test_pools.TestCompatibility.test_pool_registration_conway_cert covers the same certificate as a first registration, where the pool simply never had a key. What is checked here is the update path that takes a key away, and what the committee makes of the pool afterwards.
Register a new stake pool with a BLS key and delegate owner stake to it
Re-register the pool in the same epoch with a Conway-era certificate, which carries no BLS key
Check that after the epoch boundary the pool has no registered BLS key
Check that the pool still holds a Leios committee seat, with no key and not voting
Re-register the pool with a freshly generated BLS key
Check that after the epoch boundary the pool holds the new key again
- test_reregister_same_bls_key(cluster: ClusterLib, cluster_manager: ClusterManager, request: FixtureRequest)[source]ο
Check that re-registering the same BLS key preserves its registration epoch.
Re-registering a key the pool already holds does not restart its lifetime clock. Only a changed key is stamped with the epoch the update takes effect in.
Register a new stake pool with a BLS key and delegate owner stake to it
Re-register the pool in the next epoch with the same BLS key
Check that after the epoch boundary both the registered key and its original registration epoch are unchanged
- test_rotate_bls_key(cluster: ClusterLib, cluster_manager: ClusterManager, request: FixtureRequest)[source]ο
Rotate the BLS key of a stake pool by re-registering the pool.
Register a new stake pool with a BLS key, delegate owner stake to it, and check that the ledger stamped the key with the epoch the registration landed in
Re-register the pool in the next epoch with a freshly generated BLS key
Check that the new key is pending in futurePoolParams and that the active key didnβt change yet
Check that after the epoch boundary the new key is the registered one, and that its registration epoch was re-stamped with the epoch the update took effect in
Check that the Leios committee still holds the old key in that epoch - the committee was seated from a snapshot that predates the update
Check that after one more epoch boundary the committee seat holds the new key and is voting
Check that the rotation didnβt change any other pool parameter
- class cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.TestBlsKeyRotationVoting[source]ο
Bases:
objectEnd to end test of the BLS key rotation procedure on a block producing pool.
- test_rotation_pair_keeps_voting(cluster_leios_singleton: ClusterLib, cluster_manager: ClusterManager, subtests: SubTests)[source]ο
Rotate the BLS key of a block producing pool and check that it keeps voting.
The ledger swaps the seated key on an epoch boundary, while the node votes with whatever βshelley-bls-key it was started with. Handing the node both keys as a JSON array - the rotation pair - is what bridges that boundary: the node casts a vote for every seat any of its keys holds, so it votes with the old key in the epoch that still has the old key seated, and with the new one from the next epoch on.
Wait for the epoch in which the voting committee becomes active
Rotate the BLS key of the pool by re-registering it, and restart the node with both the old and the new key in one file
Check that in the epoch after the rotation the committee still holds the old key, and that the pool votes
Check that in the epoch after that the committee holds the new key, and that the pool still votes
Restart the node with the old key alone and check that it declines to vote, because the key it holds no longer matches its committee seat
Restart the node with the new key alone - the cut over an operator does once the rotation is seated - and check that the pool votes again
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.check_seat_keyless(*, cluster_obj: ClusterLib, pool_name: str, pool_id: str, epoch: int, errors: list[str]) None[source]ο
Record whether a pool kept its seat with an aged-out key, in place.
An expired key doesnβt free the seat, and the key is still reported - what is gone is the ability to vote with the weight the seat carries.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_name β A name of the stake pool, for the reported message.
pool_id β An ID of the stake pool (Bech32-encoded or hex-encoded).
epoch β The epoch the seat is checked in, for the reported message.
errors β Collects the failures, appended to in place.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.check_seat_voting(*, cluster_obj: ClusterLib, pool_name: str, pool_id: str, epoch: int, errors: list[str], expected_vkey: str | None = None, context: str = '') None[source]ο
Record whether a pool holds a committee seat it can vote with, in place.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_name β A name of the stake pool, for the reported message.
pool_id β An ID of the stake pool (Bech32-encoded or hex-encoded).
epoch β The epoch the seat is checked in, for the reported message.
errors β Collects the failures, appended to in place.
expected_vkey β The hex encoded BLS key the seat is expected to hold (optional).
context β Added to the reported message, to say why the pool should be voting.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.check_voted(*, found: set[str], problems: list[str], errors: list[str], skip_reasons: list[str], description: str) None[source]ο
Record whether a pool was seen voting, in place.
A pool that didnβt vote is a failure only when there was an EB to vote on. Without one, the absence of votes says nothing, so it is reported as a reason to skip instead of as an error.
- Parameters:
found β The messages a search_voting_activity call found.
problems β The problems the same call reported.
errors β Collects the failures, appended to in place.
skip_reasons β Collects the inconclusive outcomes, appended to in place.
description β Names the checked situation, for the reported message.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.cluster_leios_singleton(cluster_manager: ClusterManager) ClusterLib[source]ο
Lock the whole cluster instance and skip unless Leios EBs can be observed on it.
The whole instance is locked because the test re-registers one of the cluster pools and restarts its node several times. It is respun afterwards rather than handed back, as the pool ends up with a different BLS key than the one it was set up with - so everything that can rule the test out is checked before the instance is marked.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.cluster_short_bls_keyage(cluster_manager: ClusterManager, short_bls_keyage_start_cluster: Path) ClusterLib[source]ο
Return a short-key-lifetime cluster with observable committee key state.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.create_test_pool(*, cluster_obj: ClusterLib, cluster_manager: ClusterManager, temp_template: str, request: FixtureRequest) PoolCreationOutput[source]ο
Register a new stake pool with a BLS key and schedule its deregistration.
The pool is not backed by a running node, so it never forges or votes. It is a member of the Leios committee all the same, because the committee is seated from the registered pools and the local testnet committee size is far above the number of pools.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
cluster_manager β An instance of cluster_management.ClusterManager.
temp_template β A test identifier used for naming the created files.
request β A pytest fixture request, used to register the deregistration.
- Returns:
The pool creation output.
- Return type:
clusterlib.PoolCreationOutput
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.get_future_bls_key(*, cluster_obj: ClusterLib, pool_id: str) dict[source]ο
Return the BLS key of a pool update that is waiting for the next epoch boundary.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_id β An ID of the stake pool (Bech32-encoded or hex-encoded).
- Returns:
- The pending BLS key record, or an empty dict when there is no pending
update, or it carries no BLS key.
- Return type:
dict
Note
futureStakePoolParams.blsKeycontains the key directly, unlike the active key state, which wraps it inbksKeyalongside its registration epoch. Also accept the wrappedfuturePoolParams.spsBlsKey.bksKeyquery format.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.get_pool_bls_key_pair(*, pool_creation_out: PoolCreationOutput) KeyPair[source]ο
Return the BLS key pair a created pool was registered with.
- Parameters:
pool_creation_out β The output of a pool registration.
- Returns:
The BLS key pair of the pool.
- Return type:
clusterlib.KeyPair
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.install_node_bls_key(*, cluster_obj: ClusterLib, key_file: Path, key_pair: KeyPair, vkey_file: Path | None = None) None[source]ο
Put a BLS signing key file in place of a poolβs own and restart the nodes.
The node reads its BLS key only on startup, so a key swap needs a restart. All the nodes are restarted, so that the connections between them are established again, and the chain is given time to advance afterwards - a node that is still coming up logs no Leios activity, and a log search started too early would search that gap.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
key_file β A path to the signing key file, or a key bundle, to put in place.
key_pair β The BLS key pair of the pool, pointing into the cluster state dir.
vkey_file β A path to the matching verification key file, when the swap is meant to be the poolβs new key for good (optional).
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.register_pool_with_bls_key(*, cluster_obj: ClusterLib, cluster_manager: ClusterManager, temp_template: str, request: FixtureRequest) tuple[PoolCreationOutput, int, str][source]ο
Register a new stake pool with a BLS key and delegate stake in a single epoch.
The registration and the checks that read back the epoch it was stamped with must not be split by an epoch boundary, so the registration is started early enough in the epoch for the whole transaction to fit into it.
Register and delegate the funded ownerβs stake address so that the pool has active stake when its registration epochβs snapshot reaches the Leios committee.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
cluster_manager β An instance of cluster_management.ClusterManager.
temp_template β A test identifier used for naming the created files.
request β A pytest fixture request, used to register the deregistration.
- Returns:
The pool creation output, the epoch the registration landed in, and the hex encoded BLS verification key the pool registered.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.report_subtest(*, subtests: SubTests, name: str, errors: list[str], skip_reasons: list[str]) None[source]ο
Report one phase of a test as a subtest, so that the others still report.
- Parameters:
subtests β The pytest-subtests fixture.
name β Names the phase in the subtest report.
errors β The failures the phase collected, empty when it passed.
skip_reasons β Why the phase was inconclusive, empty when it was not.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.require_committee_details(cluster: ClusterLib) None[source]ο
Require pool membership and structured BLS state before registration or waits.
Try both committee query schemas and the voting-key workaround. Missing capabilities skip the test rather than being interpreted as an empty committee.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.rotate_bls_key(*, cluster_obj: ClusterLib, pool_creation_out: PoolCreationOutput, bls_skey_file: Path | None, tx_name: str, cert_suffix: str) None[source]ο
Re-register a pool with the supplied BLS signing key, leaving everything else as is.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
pool_creation_out β The output of the original pool registration.
bls_skey_file β A path to the BLS signing key file to register, or None to submit a certificate that carries no BLS key at all.
tx_name β A name of the transaction.
cert_suffix β A short name of this rotation, added to the pool name. The certificate file is named after the pool, so a rotation needs a name of its own to avoid overwriting the certificate of the original registration. It is kept short because a pool name is limited to 50 characters.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.search_voting_activity(*, cluster_obj: ClusterLib, logfile: Path, within_epoch: bool = True, full_window: bool = False) tuple[set[str], list[str]][source]ο
Search a pool log for a cast vote, an EB announcement and a declined vote.
The three outcomes together say whether the pool voted, whether there was anything to vote on in the first place, and whether the pool declined because none of the keys its node holds is seated.
- Parameters:
cluster_obj β An instance of clusterlib.ClusterLib.
logfile β A path to the log file of the block producing node.
within_epoch β End the window before the current epoch does, so that a vote cast in the next epoch cannot land in the searched part of the log. Needed only while the committee still changes at the next boundary.
full_window β Keep searching for the whole window even after a vote was found. Needed when the absence of votes is what is being checked, as the evidence that there was something to vote on can show up after the first message.
- Returns:
The messages that were found, and the problems that got in the way of the search.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.short_bls_keyage_start_cluster() Path[source]ο
Return startup scripts with a KES setup that gives BLS keys a short lifetime.
The ledger derives the BLS key lifetime from
maxKESEvolutionsandslotsPerKESPeriod, so slotsPerKESPeriod is picked to make the KES lifetime exactly KES_LIFETIME_EPOCHS epochs. That makesmaxKeyAgeSHORT_MAX_KEY_AGE epochs on any testnet variant, regardless of its epoch length.Skip when the node cannot load BLS signing keys.
- cardano_node_tests.tests.tests_dijkstra.test_bls_rotation.write_bls_key_bundle(*, key_files: list[Path], out_file: Path) Path[source]ο
Write several BLS signing keys into one file, as a JSON array of key envelopes.
cardano-node run βshelley-bls-key takes either a single text envelope or an array of them, and casts a vote for every committee seat any of the keys holds. A pair of the old and the new key is what keeps a pool voting across the epoch boundary where its registered key changes, as only the currently registered key matches a seat.
The multi-key file is a convenience the node offers, not something CIP-0164 asks for - the CIP only says the operator has to have the newly active key on the block producing machine for the epoch it becomes effective in.
- Parameters:
key_files β Paths to the BLS signing key files to bundle, in order.
out_file β A path to write the bundle to.
- Returns:
The path of the written bundle.
- Return type:
pl.Path
cardano_node_tests.tests.tests_dijkstra.test_leios_blocks moduleο
Tests for Leios endorser blocks (EBs).
The tests check that the node reports the expected Leios activity in its logs. The Leios trace messages are emitted only in the Dijkstra era, and only when there is enough Tx load to fill the mempool, so that the block producer has something to put into an endorser block.
Who may vote on an EB is decided once per epoch by the Leios voting committee, which
the ledger seats from the stake snapshot: the leiosCommitteeSize pools with the
most stake, largest first, ties broken by ascending pool id. A local testnet has far
fewer pools than the committee has room for, so every pool is normally seated and the
ranking never shows. TestLeiosCommitteeRank starts a cluster instance whose committee
has fewer seats than the cluster has pools, which is what makes the ranking, and the
pools it leaves out, observable.
TestLeiosEbTxs follows particular txs from the mempool through an EB and its certificate into the ledger.
- class cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.TestLeios[source]ο
Bases:
objectTests for Leios endorser blocks.
- test_eb_logs(cluster_leios: ClusterLib)[source]ο
Check that the nodes report the expected endorser block activity.
Wait for the epoch in which the voting committee becomes active
Record the current end of each pool log file
Wait for new blocks to be created
Check that each pool reports EB announcements, votes and certificates
Check that at least one pool reports forging, announcing, storing and certifying an EB
- test_no_voting_before_committee_epoch(cluster_leios: ClusterLib)[source]ο
Check that no EB is voted on before the voting committee becomes active.
Skip when the genesis seats the voting committee from epoch 0, as there is then no epoch in which a vote would be premature
Skip when no epoch before leios.VOTING_START_EPOCH has room left for the whole search window
Wait for a point in an epoch where the window fits before the next epoch boundary
Record the current end of each pool log file
Search the log content that gets appended, until every pool reports that it declined to vote because it is not a member of the voting committee
Check that no pool reported a vote, a vote from a peer or a certificate
- class cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.TestLeiosCommitteeRank[source]ο
Bases:
objectTests for the pools the Leios voting committee has no room for.
- test_ranked_out_pool_doesnt_vote(cluster_small_committee: ClusterLib, cluster_manager: ClusterManager)[source]ο
Check that the pools the Leios committee left out are not voting.
Start a local cluster instance whose Leios committee is one seat short of the number of pools, with a quorum the smaller committee can still reach
Wait for the epoch in which the voting committee becomes active
Find the cluster pools the committee left out - at least one, as it has fewer seats than the cluster has pools
Check that they were left out on rank alone - they have a registered BLS key, and no seated pool ranks behind them by stake, ties broken by ascending pool id
Search the pool logs for the rest of the epoch the committee was read in
Check that the pools without a seat cast no vote and answered the EB announcements they did see with NotOnCommittee
Check that the seated pools did vote, so that the silence of the others is the committee and not a quiet cluster
Check that a certificate was assembled, so that the seats the committee has left still add up to the lowered quorum
- class cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.TestLeiosEbTxs[source]ο
Bases:
objectTests for the txs that get into the ledger through a certified EB.
- test_txs_in_certified_eb(cluster_manager: ClusterManager, cluster_leios_perf: ClusterLib)[source]ο
Check that txs that donβt fit into an RB reach the ledger through a certified EB.
The oracle for βthe tx came through an EBβ are the node logs. An EB lists its txs by the Blake2b-256 hash of the block-format tx, which the test computes from the signed tx file by adding the trailing validity flag (leios.get_eb_tx_ref). The block producerβs EB forged message lists the hashes. The EB announced message of the same slot gives the EB its hash. The EB certified message of a later block producer names the certified EB. A certifying RB carries no txs of its own; the ledger applies the txs of the certified EB in its place. The RB is checked to be adopted by its block producer and to become the tip of another poolβs chain, so that it is not an RB that lost a slot battle.
Rejected oracles: the node-to-client chain sync that would serve the block contents has no client in the framework and no cardano-cli query; db-sync is not part of the Leios regression setup; and the statistical argument that more txs reached the ledger than the RBs can hold is weaker than following particular txs.
The txs of an EB that is not certified stay in the mempool and get into a later RB or EB, so the test submits another batch when none of the txs of a batch was certified in an EB.
Wait for the epoch in which the voting committee becomes active, unless it is seated from the genesis
Create NUM_TXS UTxOs and build a tx with ~13 kB of metadata spending each one, so that the txs together are several times the max block body size
Submit all the txs at once
Wait until all the txs are in the ledger
Search the pool logs for an EB holding a test tx, that a pool certified in an RB that it adopted and that another pool took onto its chain
Repeat with a new batch of txs when no such EB was found
Check that the outputs of the txs in the certified EB are in the UTxO set, also after securityParam more blocks (at most MAX_SETTLE_BLOCKS)
Check that no node switched to a fork since the certifying RB was adopted, so that the RB is still on every chain - skip as inconclusive when one did, as the log doesnβt say where the chains split
- class cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.TestLeiosQuorum[source]ο
Bases:
objectTests for a Leios committee that loses and regains its quorum.
- test_quorum_loss_and_recovery(cluster_leios_lock: ClusterLib, cluster_manager: ClusterManager)[source]ο
Check that the chain stays live without a quorum, and certifies again after.
Wait for the epoch in which the voting committee becomes active
Check that stopping one pool takes the committee below the quorum - the seats of the remaining pools weigh less than leiosQuorumStakeThreshold
Search the pool logs until a certificate is assembled, so that the cluster is known to certify EBs before the stop
Stop the pool node, and wait for the votes and certificates of the EBs that were announced before the stop to settle
Record the current end of the logs of the running pools
Submit payment Txs and check that their outputs are in the UTxO
Search the logs of the running pools for the rest of the window
Check that the running pools assembled no certificate and no block certified an EB, while they did see EBs to vote on - skip as inconclusive when they saw none, or when a log could not be searched
Check that the running pools kept forging blocks
Start the pool node again
Check that a certificate is assembled again within a bounded time
- cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.cluster_leios(cluster_manager: ClusterManager) ClusterLib[source]ο
Return a cluster instance that is able to produce Leios endorser blocks.
- cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.cluster_leios_lock(cluster_manager: ClusterManager) ClusterLib[source]ο
Lock the whole cluster instance and skip unless Leios EBs can be observed on it.
The whole instance is locked because the test stops one of the pool nodes, which takes a part of the stake out of block production and out of the Leios voting. Require observable pool membership before any waits or node stops.
- cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.cluster_leios_perf(cluster_manager: ClusterManager) ClusterLib[source]ο
Return a cluster instance that is able to produce Leios endorser blocks.
Mark also the performance as βin useβ, so tests generating heavy load donβt run at the same time and donβt take the block space.
- cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.cluster_small_committee(cluster_manager: ClusterManager, small_committee_start_cluster: Path) ClusterLib[source]ο
Return a cluster instance whose Leios committee has no room for every pool.
Check genesis constraints off the startup scripts before starting the dedicated cluster. Check committee query capabilities as soon as that cluster is available, before waiting for epochs or searching its logs.
- cardano_node_tests.tests.tests_dijkstra.test_leios_blocks.small_committee_start_cluster() Path[source]ο
Return startup scripts whose Leios committee has no room for every pool.
The committee size and the quorum are Dijkstra protocol parameters, so they are set in the Dijkstra genesis spec and not in the Shelley one the other custom cluster fixtures edit.
cardano_node_tests.tests.tests_dijkstra.test_leios_pparams moduleο
Tests for governance of the Leios protocol parameters.
All the Leios protocol parameters are in the network group and in the security group (PPGroups NetworkGroup SecurityGroup in the Dijkstra PParams.hs), so a change needs the votes of the DReps, the SPOs and the CC.
The changes donβt all take effect at the same epoch boundary:
At an epoch boundary, the Dijkstra EPOCH rule first enacts the new pparams and only then runs SNAP. The mark snapshot that SNAP takes therefore records the leiosCommitteeSize of the just enacted pparams. The committee is seated from that snapshot only when it rotates into the βsetβ position at the next boundary. A committee size enacted at the boundary of epoch E therefore applies to the committee of epoch E+1.
Consensus reads leiosQuorumStakeThreshold from the current pparams, so a quorum enacted at the boundary of epoch E applies already in epoch E.
- class cardano_node_tests.tests.tests_dijkstra.test_leios_pparams.TestLeiosPParamsGov[source]ο
Bases:
objectTests for changing the Leios protocol parameters through governance.
- test_committee_size_and_quorum(cluster_lock_leios_gov: tuple[ClusterLib, GovernanceRecords], pool_user_llg: PoolUser, cluster_manager: ClusterManager, subtests: SubTests)[source]ο
Test that a change of the Leios committee size and quorum takes effect.
The committee is shrunk to a single seat, and the quorum is lowered below the stake share of a single pool. With the default quorum of 0.75 a single pool out of the cluster pools of equal stake could never certify an EB alone, so a certificate assembled by the single seat committee is what proves that the lowered quorum is in effect.
Compute a quorum that the smallest cluster pool reaches alone
Submit an action changing the committee size to 1, approve it by CC and DReps, and leave it without SPO votes
Submit an action changing the committee size to 1 and the quorum to the computed value, approve it by CC, DReps and SPOs
Check that only the action with the SPO votes is ratified in the next epoch
Check that the pparams are changed in the enactment epoch, and that the committee of that epoch still holds more than one seat
In the next epoch, check that the committee holds a single seat, taken by the cluster pool with the most stake (ties broken by ascending pool id), and that the poolβs stake share reaches the lowered quorum
Search the pool logs for the rest of the epoch
Check that the pools without a seat cast no vote and answered the EB announcements with NotOnCommittee
Check that the seated pool voted, and that a certificate was assembled
On older branches without pool identities, skip only the membership-query subtest. Retain size checks and compare actual voting logs with the expected top-ranked pool, without treating stake-derived identities as queried data.
- test_edge_values_well_formed(cluster_use_governance: tuple[ClusterLib, GovernanceRecords], pool_user_ug: PoolUser)[source]ο
Test that the ledger accepts edge values of the Leios committee size and quorum.
The Dijkstra ppuWellFormed has no bounds checks for the Leios pparams, so an action with the edge values is accepted. The actions are never voted on, so they are never enacted. A committee size of 0 would seat an empty committee, so no EB could be voted on or certified - that consequence is not checked here.
Submit an action changing the committee size to 0 and the quorum to 0
Submit an action changing the committee size to the max Word16 value and the quorum to 1
Check that both actions are in the governance state with the proposed values
- cardano_node_tests.tests.tests_dijkstra.test_leios_pparams.cluster_lock_leios_gov(cluster_manager: ClusterManager) tuple[ClusterLib, GovernanceRecords][source]ο
Lock the whole cluster instance for changing the Leios pparams.
The changed pparams shrink the voting committee for every test on the instance and they are not restored, so the instance is respun afterwards - everything that can rule the test out is checked before the instance is marked.
- cardano_node_tests.tests.tests_dijkstra.test_leios_pparams.pool_user_llg(cluster_manager: ClusterManager, cluster_lock_leios_gov: tuple[ClusterLib, GovernanceRecords]) PoolUser[source]ο
Create a registered pool user for βlock Leios governanceβ.
- cardano_node_tests.tests.tests_dijkstra.test_leios_pparams.pool_user_ug(cluster_manager: ClusterManager, cluster_use_governance: tuple[ClusterLib, GovernanceRecords]) PoolUser[source]ο
Create a registered pool user for βuse governanceβ.
cardano_node_tests.tests.tests_dijkstra.test_leios_queries moduleο
Tests for the user-facing Leios committee query, without compatibility workarounds.
- class cardano_node_tests.tests.tests_dijkstra.test_leios_queries.TestLeiosQueries[source]ο
Bases:
objectTests for identifying Leios committee members directly from CLI output.
- test_leios_committee_member_details(cluster_manager: ClusterManager, committee_name: str)[source]ο
Check that every queried seat identifies its pool and exposes key/voting state.
Query the current or future committee without enriching its seats from ledger state. Report ledger issue 6245 when member details are missing. Skip an empty or unavailable committee, since it cannot establish support for seat fields. No transaction load generator or voting activity is needed.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx moduleο
Smoke tests for building and sponsoring Dijkstra sub-transactions.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx.TestSubTransactions[source]ο
Bases:
objectBuild and submit straightforward signed payment batches.
- payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache two funded source addresses and a destination address.
- test_build_raw_tx(cluster: ClusterLib, payment_addrs: list[AddressRecord])[source]ο
Build and submit a transaction containing a signed sub-transaction.
Collect inputs and balanced outputs, including change, for the sub-transaction, then build and sign it.
Build the top-level transaction with automatically selected inputs from a separate source address and the signed sub-transaction.
Check the embedded child and the batch balance with the top-level fee.
Sign and submit the top-level transaction, checking that signing preserves both transaction IDs.
Verify the childβs inputs are spent and its payment and change outputs exist.
Verify the top-level sourceβs change and transaction presence on all nodes.
- test_sponsored_payment(cluster: ClusterLib, payment_addrs: list[AddressRecord])[source]ο
Settle Aliceβs independently signed payment with a sponsorβs fee.
Alice signs a balanced child payment without fee or collateral fields.
The sponsor builds and signs a parent containing only its own change.
Check the serialized child is unchanged and only the sponsor witnesses the parent. Alice never signs the parent.
Submit and check every parent and child input is spent, the recipient and Alice receive the signed outputs under the child ID, and the sponsor receives its input value minus exactly the parent fee as change.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting moduleο
Batch value conservation, minimum-ADA outputs, and atomic state transitions.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.TestSubTransactionAccounts[source]ο
Bases:
objectAccount operations must respect original reward balances across the batch.
- test_original_balance_withdrawals(cluster_treasury: ClusterLib, atomicity_addrs: list[AddressRecord], registered_account: AddressRecord, subtests: SubTests)[source]ο
Bound aggregate withdrawals by the original balance, not earlier deposits.
Fund a registered, nondelegated account through a confirmed direct deposit. Reject individual and aggregate over-withdrawals, including a withdrawal covered only by an earlier same-batch deposit. Split an exact original-balance withdrawal across two children while depositing again; verify exact outputs, the residual account balance, and no failed effects.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.TestSubTransactionAtomicity[source]ο
Bases:
objectReject a complete batch without committing earlier component effects.
- test_phase_one_atomic_rejection(cluster_treasury: ClusterLib, atomicity_addrs: list[AddressRecord], stake_address: AddressRecord, subtests: SubTests)[source]ο
Discard a child payment, registration and donation on phase-one failure.
Omit a required key witness in either child position or the parent. Check owned inputs (including separate collateral), absent outputs and an unregistered stake credential after each rejection. Then confirm the fully authorized batch and deregister to refund its actual deposit.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.TestSubTransactionCertificates[source]ο
Bases:
objectThread registration state and deposit refunds through ordered components.
- test_ordered_registration_refund(cluster_treasury: ClusterLib, atomicity_addrs: list[AddressRecord], stake_address: AddressRecord, refund_level: str, subtests: SubTests)[source]ο
Register before deregistering across children or child-to-parent processing.
Reject reversed siblings and a duplicate deregistration without effects. Then register in one child and refund the exact same declared deposit in a later sibling or parent. Check exact outputs, no lasting stake registration, and preservation of unused inputs and collateral.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.TestSubTransactionConservation[source]ο
Bases:
objectEnforce ADA and native-asset conservation over the complete batch.
- test_global_value_conservation(cluster: ClusterLib, payment_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Balance complementary children collectively, rejecting one-unit mismatches.
Move ADA and a fresh native asset between individually unbalanced, independently signed children. Re-sign each one-lovelace or one-token mismatch to isolate conservation from authorization. Check unchanged owned state on rejection, then confirm the balanced batch and outputs.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.TestSubTransactionMinUtxo[source]ο
Bases:
objectSponsor minimum-ADA outputs without relaxing per-output requirements.
- min_utxo_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache user, sponsor, recipient and issuer; fund the latter three as needed.
- test_min_utxo_sponsorship(cluster: ClusterLib, min_utxo_addrs: list[AddressRecord], output_kind: str)[source]ο
Sponsor child outputs at their minimum ADA without changing signed terms.
Prepare one token-bearing input and two asset-bearing child outputs, optionally carrying a large inline datum or native reference script.
Calculate each outputβs minimum ADA using current protocol parameters. The child cannot fund both outputs; the sponsor covers the deficit and fee.
Build a valid baseline, then reduce one child output by one lovelace and add that lovelace to parent change, preserving complete-batch balance.
Check node rejection leaves all inputs unspent and creates no outputs, despite sufficient ADA elsewhere in the batch.
Submit the original signed child and verify exact-minimum outputs, attached data/scripts, and the sponsorβs exact contribution.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.TestSubTransactionTreasury[source]ο
Bases:
objectCheck treasury declarations against original state despite batch donations.
- test_treasury_declarations(cluster_treasury: ClusterLib, atomicity_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Validate original treasury declarations in children and parent.
Give the early child and parent small donations. Reject incorrect declarations in either child or parent, including later declarations increased by an earlier childβs donation. Preserve test-owned inputs and outputs on rejection. Confirm correct original-value declarations with exact UTxO donation/fee deductions. No donation accumulator or phase-2-invalid effects are inferred from these checks.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.atomicity_addrs(cluster_manager: ClusterManager, cluster_treasury: ClusterLib) list[AddressRecord][source]ο
Cache participants with enough funding for registration and subsequent batches.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.cluster_treasury(cluster_manager: ClusterManager) ClusterLib[source]ο
Serialize treasury donations while exercising child state changes.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache two participants and a sponsor/issuer; fund only the sponsor.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.registered_account(cluster_treasury: ClusterLib, atomicity_addrs: list[AddressRecord], stake_address: AddressRecord) Generator[AddressRecord, None, None][source]ο
Register a test-owned account, then drain it and refund its recorded deposit.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_accounting.stake_address(cluster_manager: ClusterManager, cluster_treasury: ClusterLib) AddressRecord[source]ο
Cache an independent stake credential used by the early child.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_guards moduleο
Non-Plutus required top-level guards and transaction-local guard scope.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_guards.TestNativeRequireGuard[source]ο
Bases:
objectEvaluate native guard predicates in the executing childβs own scope.
- guard_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Keep action funding separate from the top-level requirement tests.
- test_native_require_guard(cluster: ClusterLib, guard_addrs: list[AddressRecord], require_guard_script: Path, purpose: str, nested_timelock: bool, subtests: SubTests)[source]ο
Enforce child-local native guard entries, authorization and timelocks.
Exercise spending and minting with a standalone key-guard predicate or its conjunction with a lower-bound timelock. Reject omitted/wrong guards, missing guard signatures, and guards supplied only by parent or sibling. For the conjunction, also violate only the interval. Re-sign every intentional body change. All failures preserve owned inputs and create no outputs/assets; the fully authorized control confirms exact outputs.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_guards.TestRequiredTopLevelGuards[source]ο
Bases:
objectRequire explicit enclosing guard entries and their enclosing authorization.
- test_parent_required_guard_field(cluster: ClusterLib, guard_addrs: list[AddressRecord], native_guard: Path, guard_kind: str, subtests: SubTests)[source]ο
Require and authorize a guard declared in the parentβs own requirement field.
Put a key/native requirement with no argument on the parent, not its child. Reject a signed parent lacking the guard entry and a parent whose guard lacks its signature. Confirm the fully authorized parent with unchanged child bytes. This establishes current non-legacy field compatibility, not V4 datum support or normative CIP conformance.
Satisfy two childrenβs shared key/native requirements only at parent level.
Independently require a key and native guard without arguments in both children. Reject each missing parent entry or signature, and reject satisfaction solely through a child-local guard. Explicit parent guards and their own authorization settle the unchanged payment terms.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_guards.guard_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache two users, sponsor, key guard, and native signature guard owner.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_guards.native_guard(cluster_manager: ClusterManager, cluster: ClusterLib, guard_addrs: list[AddressRecord]) Path[source]ο
Cache an independent native script guard, without a Plutus fixture.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_guards.require_guard_script(cluster_manager: ClusterManager, cluster: ClusterLib, guard_addrs: list[AddressRecord], nested_timelock: bool) Path[source]ο
Cache a native key-guard predicate, optionally conjoined with a lower bound.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_inputs moduleο
Spending conflicts, original UTxO references, and supplemental datum scope.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_inputs.TestSubTransactionInputs[source]ο
Bases:
objectCheck that spending is exclusive and reference lookups use original state.
- test_spending_conflict(cluster: ClusterLib, payment_addrs: list[AddressRecord], conflict: str)[source]ο
Reject duplicate spending within the batch, then settle disjoint children.
Independently sign two children sharing a live input, or share an input between parent and child. Reverse sibling order and check no owned input is consumed or output created. A disjoint baseline settles afterward. These payment-only batches have no certificate or governance effects.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_inputs.TestSubTransactionReferences[source]ο
Bases:
objectDistinguish original UTxO references from unavailable new child outputs.
- test_no_output_chaining(cluster: ClusterLib, payment_addrs: list[AddressRecord], use: str, placement: str)[source]ο
Reject spending or referencing a new child output within the same batch.
Predict an output before assembly and use it in a sibling in either order, or in the parent. Check original-input rejection without effects. Confirm the producer separately, then use that exact output reference in a later ordinary transaction as a spend or read-only reference.
- test_original_utxo_references(cluster: ClusterLib, payment_addrs: list[AddressRecord], placement: str)[source]ο
Reference an existing input even when another component spends it.
Exercise both sibling orders and each parent/child direction. In the sibling cases the parent also references the same consumed input. Confirm exact child and parent outputs, exclusive spending, and any unused owner inputs. No intra-batch output is used as a reference.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_inputs.TestSubTransactionSupplementalDatums[source]ο
Bases:
objectCheck non-legacy supplemental datum scope without executing Plutus.
- test_supplemental_datum_scope(cluster: ClusterLib, payment_addrs: list[AddressRecord], scope: str)[source]ο
Allow the parentβs child-related datums but reject sibling-only or unrelated data.
Generate a datum witness/integrity hash through the CLI, then remove its supplying outputβs hash before signing. Only another child output or reference input relates to the datum, or no output does. Confirm allowed parent supply; reject other scopes without effects and settle a control without the extraneous witness. No legacy script executes in these cases.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_inputs.payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache three funded independent owners and an unfunded recipient.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_lifecycle moduleο
Validity windows, competing wrappers, and replay of nested payments.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_lifecycle.TestSubTransactionOfferLifecycle[source]ο
Bases:
objectInvalidate published offers without changing an aggregatorβs stored copy.
- test_stale_offer(cluster: ClusterLib, payment_addrs: list[AddressRecord], invalidation: str)[source]ο
Reject a stored offer after expiry or a confirmed independent input spend.
Publish one live signed payment and store identical copies for two assemblers. Build a funded wrapper before invalidation. Either wait until the signed upper bound or confirm an ordinary cancellation spend. Submit the stale wrapper and a freshly assembled wrapper from the other stored copy. Both must fail without charging the sponsor or creating child outputs. Expiry leaves the original input spendable; cancellation leaves only the ordinary cancellation outputs.
- test_unmatched_offer(cluster: ClusterLib, payment_addrs: list[AddressRecord])[source]ο
Keep an unmatched child off-chain until a sponsor supplies its deficit.
Store an independently signed, ADA-deficient offer without reserving its input. Ordinary transaction submission must refuse its child envelope. This is tooling evidence, not proof of node-side decoding rejection. Confirm the unchanged offer later through a fully funded parent, checking originating output references and the sponsorβs exact contribution. No production matching service is required.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_lifecycle.TestSubTransactionReplay[source]ο
Bases:
objectSettle competing wrappers once and reject spent-child replays.
- replay_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache a user, three independently funded assemblers, and a recipient.
- test_replay_competing_wrappers(cluster: ClusterLib, replay_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Settle a raced child payment once and reject replay through any wrapper.
Publish one independently signed child payment and build two parents with distinct assembler keys and disjoint parent spending inputs.
Race their submissions to the same node and confirm exactly one parent.
Check the child payment and winning parent change, consumed inputs, and untouched funding inputs of the losing and third assemblers.
Build a fresh third parent around the unchanged, now-spent child.
Retry both raced parents and submit the third. Check spent-input errors, unchanged test-owned UTxOs, and no losing or third-parent outputs.
This payment-only batch has no certificate or governance effects.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_lifecycle.TestSubTransactionValidity[source]ο
Bases:
objectRequire every parent/child validity interval to hold at submission.
- test_validity_intersection(cluster: ClusterLib, payment_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Reject an expired/future component or disjoint intervals, then settle their overlap.
Independently sign expired and not-yet-valid children and parents around otherwise valid payments. Every rejection preserves owned inputs and creates no outputs. Confirm overlapping, unequal and open-ended bounds. This does not claim exact-slot boundary scheduling or guard range checks.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_lifecycle.payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache two users, fee sponsor and recipient with minimal reusable funding.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_limits moduleο
Measured transaction-size and fee boundaries for complete nested batches.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_limits.TestSubTransactionLimits[source]ο
Bases:
objectMeasure actual serialized batches rather than sum guessed child sizes.
- test_complete_batch_size_limit(cluster: ClusterLib, payment_addrs: list[AddressRecord])[source]ο
Enforce measured whole-batch size and fee boundaries for individually fitting children.
Search using actual signed parent/child CBOR sizes and current protocol parameters. Child metadata uses valid at-most-64-byte chunks. Reject the smallest oversized candidate without effects, then settle the adjacent valid candidate at its exact linear minimum fee. Reject one lovelace below that fee, checking every consumed input and originating output.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_limits.payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache two independent metadata-bearing child owners and a fee sponsor.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_plutus moduleο
Plutus execution and sponsorship in independently signed children.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_plutus.TestSubTransactionDatums[source]ο
Bases:
objectKeep required spending datums local despite batch-wide script supply.
- test_required_datum_scope(cluster_plutus: ClusterLib, payment_addrs: list[AddressRecord], subtests: SubTests, spender_level: str)[source]ο
Reject remote-only spending datums, then settle with the local datum.
Lock an output with a datum hash. Supply its datum only in another component, attached to that componentβs output so it is not unrelated supplemental data. Exercise child spending with parent/sibling supply and parent spending with child supply. Missing required local data must leave all owned inputs and collateral unchanged. The local control confirms the same hash-locked input and exact child/parent payments.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_plutus.TestSubTransactionPhaseOne[source]ο
Bases:
objectCheck observable phase-one rejection around child Plutus execution.
- test_phase_one_with_child_script(cluster_plutus: ClusterLib, payment_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Reject missing authorization around a child that would fail evaluation.
Place an unauthorized payment before/after the script child, then omit parent authorization instead. Check the intended phase-one error and unchanged script, payment, fee and collateral inputs. With authorization repaired the control reaches a real V4 evaluation failure. This does not prove evaluator invocation order without supported node telemetry.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_plutus.TestSubTransactionSponsorship[source]ο
Bases:
objectCheck fee and collateral sponsorship for child-only Plutus execution.
- test_script_sponsorship(cluster_plutus: ClusterLib, payment_addrs: list[AddressRecord], subtests: SubTests, script_fails: bool)[source]ο
Sponsor a child contract action without parent redeemers or user collateral.
Lock a user-funded output at a V4 script, then independently sign its child spend. Reject missing and insufficient sponsor collateral without changing owned state. Settle a passing action with collateral untouched, or reject a failing action without ordinary or collateral effects. Dijkstra tooling currently cannot submit a phase-2-invalid declaration.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_plutus.cluster_plutus(cluster_manager: ClusterManager) ClusterLib[source]ο
Protect script execution parameters and require child construction support.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_plutus.payment_addrs(cluster_manager: ClusterManager, cluster_plutus: ClusterLib) list[AddressRecord][source]ο
Cache user, sponsor, collateral owner, and recipient with modest funding.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts moduleο
Batch-wide native/V4 script supply with transaction-local authorization.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts.TestSubTransactionConfirmedOutputs[source]ο
Bases:
objectUse confirmed parent/child outputs and stored older scripts normally.
- test_confirmed_output_usability(cluster: ClusterLib, payment_addrs: list[AddressRecord])[source]ο
Spend parent/child outputs and execute a V3 script stored by a child.
Confirm a normal-mode batch whose child creates a key output carrying an inline datum and V3 reference script. A parent-to-child imbalance proves storing old script bytes does not activate legacy balance rules. In a later ordinary transaction, use the parentβs output for fees and the childβs predicted output as the reference source for a V3 spend. Finally spend the child key output itself. Check exact original output references, stored datum/script, consumed inputs, and untouched collateral.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts.TestSubTransactionLegacyMode[source]ο
Bases:
objectKeep legacy parent balance and context restrictions separate from child features.
- test_legacy_parent_balance(cluster: ClusterLib, payment_addrs: list[AddressRecord], plutus_version: str)[source]ο
Enforce legacy parent balance even when the complete batch balances.
Execute a passing older script in the parent. Reject a balanced batch that transfers parent ADA into a childβs imbalance. Then confirm two complementary children whose net imbalance is zero and whose inline datum output remains isolated from the parentβs legacy script context. For V1, reject that same newer output feature directly in the parent.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts.TestSubTransactionNewOutputScripts[source]ο
Bases:
objectDistinguish newly attached scripts from confirmed reference-script sources.
- test_new_output_script_source(cluster: ClusterLib, payment_addrs: list[AddressRecord], native_script: Path, source_level: str, script_kind: str)[source]ο
Reject new-output-only script supply, then use the confirmed source.
Remove script witness bytes from a signed childβs spending action. Attach its native/V4 program only to a new parent or sibling output, without an existing reference input. Current Dijkstra script collection rejects this batch without effects. Confirm the source separately, then settle the exact unchanged signed spender using that now-existing reference output. This records current behavior, not CIP-172 acceptance.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts.TestSubTransactionScriptSupply[source]ο
Bases:
objectShare script bytes without sharing native key authorization.
- test_script_supply(cluster: ClusterLib, payment_addrs: list[AddressRecord], native_script: Path, supply: str, script_kind: str)[source]ο
Resolve child native/V4 script bytes batch-wide while keeping keys local.
Supply bytes in the parent, sibling, or a parent reference input. Reject missing script bytes, an extraneous script, or native authorization supplied only by the parent. Check rejection has no effects and settle a correctly witnessed control. Confirm exact child and parent outputs.
Execute one shared V4 program separately for each childβs local budget.
Spend two distinct script inputs with distinct local redeemers, supplying the script bytes once in the parent. Give either child a zero budget; the other childβs successful execution cannot substitute for it. Reject each case without effects, then settle with both local budgets funded. The context-independent program does not verify business predicates.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts.cluster(cluster_manager: ClusterManager) ClusterLib[source]ο
Protect V4 execution parameters for the shared script-supply matrix.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts.native_script(cluster_manager: ClusterManager, cluster: ClusterLib, payment_addrs: list[AddressRecord]) Path[source]ο
Cache a native signature script controlled by the first participant.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_scripts.payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache script owner, sponsor, sibling owner, recipient and collateral owner.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_serialization moduleο
Child identity, ordering, and supported canonical transaction workflows.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_serialization.TestSubTransactionCanonicalWorkflows[source]ο
Bases:
objectBuild canonical children before signing and preserve them through parent tooling.
- test_canonical_child_workflow(cluster: ClusterLib, payment_addrs: list[AddressRecord], signing_path: str)[source]ο
Confirm canonical metadata-bearing children through three signing paths.
Canonicalize a child at construction, then sign its fixed body. Embed it in a canonical parent and use direct body signing, adding signatures through a transaction file, or separate witness/assembly. Check exact child bytes, metadata/hash association and predicted outputs at each outer operation before confirming through the node. Script-purpose matrices and noncanonical rewrite refusal are separate coverage gaps.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_serialization.TestSubTransactionIdentity[source]ο
Bases:
objectPreserve independently signed child identities across wrapper and order changes.
- test_child_identity_across_wrappers(cluster: ClusterLib, payment_addrs: list[AddressRecord], confirmed_order: int)[source]ο
Confirm either order of unchanged children through independently signed wrappers.
Record child IDs and predicted references before either wrapper exists. Build both sibling orders with different parent fees and change addresses, preserving the exact independently signed children. Confirm either variant on fresh test-owned inputs and check every predicted originating output. This key-payment test does not establish index-sensitive script behavior.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_serialization.TestSubTransactionWireStructure[source]ο
Bases:
objectRetain structural boundary cases through real encoders and node submission.
- test_duplicate_child_decode_refusal(cluster: ClusterLib, payment_addrs: list[AddressRecord])[source]ο
Reject duplicate child decoding locally without silently deduplicating.
Bypass the builderβs duplicate-ID check with exact signed child bytes. Verify the duplicate collection is present, then check the CLI decoder refuses signing without writing an output or changing owned state. Confirm a single copy of the same signed child through the node. This tooling regression does not prove node-side rejection, because the supported CLI path cannot submit the malformed collection.
- cardano_node_tests.tests.tests_dijkstra.test_sub_tx_serialization.payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache two child owners, sponsor, and recipient with modest funding.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_signatures moduleο
Signature isolation for child bodies, witnesses, and required guard arguments.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_signatures.TestSubTransactionGuardSignatures[source]ο
Bases:
objectPreserve signed child authorization of required Plutus guard arguments.
- cluster_plutus(cluster_manager: ClusterManager) ClusterLib[source]ο
Protect Plutus execution parameters while running guarded transactions.
- plutus_guard_addrs(cluster_manager: ClusterManager, cluster_plutus: ClusterLib) list[AddressRecord][source]ο
Cache sponsor, user, recipient, and separate sponsor collateral addresses.
- test_required_guard_signature_isolation(cluster_plutus: ClusterLib, plutus_guard_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Reject a changed required-guard argument with the original child signature.
Sign a balanced payment child requiring an always-succeeding V4 guard.
Change only its required guard datum, preserving original witness bytes.
Supply the parent guard and collateral and check node signature rejection, unchanged owned UTxOs, and absence of parent and child outputs.
Settle the unchanged original child through a sponsor-only signed parent, checking the payment, sponsor fee, and untouched collateral.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_signatures.TestSubTransactionSignatures[source]ο
Bases:
objectKeep child authorization independent of parent assembly.
- payment_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache two funded source addresses and a destination address.
- test_signature_isolation(cluster: ClusterLib, payment_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Reject unauthorized child changes while allowing independently signed wrappers.
Build a valid payment child with metadata and record its body and witness bytes.
Change its output, validity interval, or metadata hash independently, retaining the original witness. Keep metadata and batch balances otherwise valid.
Remove or corrupt the child signature; separately sign the parent with the childβs key but leave the child without a witness.
Check node signature failures leave inputs unspent and create no outputs.
Change only the parent fee and change address, sign with the sponsor alone, and confirm the original child with its exact payment and metadata.
Required-guard argument mutations are covered by TestSubTransactionGuardSignatures.
cardano_node_tests.tests.tests_dijkstra.test_sub_tx_workflows moduleο
Open swaps, Babel payments, and multi-party clearing with signed children.
- class cardano_node_tests.tests.tests_dijkstra.test_sub_tx_workflows.TestSubTransactionWorkflows[source]ο
Bases:
objectSettle independently published offers through third-party assembly.
- babel_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache user, providers, recipient, and issuer; fund only the issuer.
- clearing_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache three traders, aggregator fee/liquidity addresses, and a funded issuer.
- swap_addrs(cluster_manager: ClusterManager, cluster: ClusterLib) list[AddressRecord][source]ο
Cache traders and issuer; fund only counterparties and issuer as needed.
- test_babel_payment(cluster: ClusterLib, babel_addrs: list[AddressRecord], subtests: SubTests)[source]ο
Pay a recipient using a token offer and provider-funded ADA and fees.
Give the user a token-bearing input but no separate ADA-only input.
Publish a signed child fixing the recipient payment, token change, and provider compensation. The child needs additional ADA, not collateral.
Model a provider declining the offer without any on-chain reservation.
Build a valid wrapper, then submit variants lacking fee funding, using insufficient provider ADA, or claiming excess token compensation. Check node rejection leaves all inputs and outputs unchanged.
Settle the original child without another user signature and verify exact recipient and provider outputs and an ADA-denominated parent fee.
- test_multi_party_clearing(cluster: ClusterLib, clearing_addrs: list[AddressRecord], needs_liquidity: bool, subtests: SubTests)[source]ο
Clear three independent offers atomically, optionally using aggregator liquidity.
Prepare offers exchanging A for B, B for C, and C for A. Each participant signs only its own child and publishes it for independent assembly.
In the liquidity variant, Alice offers one extra A and demands one extra B; the aggregator supplies that B and receives the extra A in parent change.
Build the complete valid batch, then omit each offer in turn and remove required liquidity. Check node rejection leaves every input unspent and creates no parent or child outputs.
Settle the complete batch and check all signed participant outputs, aggregator change and compensation, spent inputs, and unused liquidity.
- test_open_swap(cluster: ClusterLib, swap_addrs: list[AddressRecord], winner: str, counterparty_child: bool)[source]ο
Settle a published offer with either of two independent counterparties.
Prepare Aliceβs 12 ADA input and five tokens each for Bob and Carol.
Alice signs and publishes an unguarded offer returning 2 ADA and demanding five tokens. Neither counterparty needs another signature from Alice.
Bob and Carol independently assemble wrappers using the published file, supplying tokens in the parent or in a complementary signed child.
Confirm one wrapper and check exact signed outputs and batch conservation.
Submit the competing wrapper and check rejection due to Aliceβs spent input, unchanged counterparty inputs, and no additional outputs.