Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions cardano_node_tests/tests/plutus_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,33 @@ class PlutusScriptData:
)


# Slots between the tip and the end of the validity interval of a transaction that runs
# a "time range" script. Long enough for the transaction to get submitted and land in a
# block, and capped by `get_timerange_slots_offset`.
TIMERANGE_SLOTS_OFFSET = 300


def get_timerange_slots_offset(*, cluster_obj: clusterlib.ClusterLib) -> int:
"""Return the slot offset to use for the validity interval of a "time range" script.

A script that looks at the transaction validity interval makes the ledger translate
the end of the interval to a time, which it can do only up to its forecast horizon:
the end of the first epoch that starts at or after the stability window from the tip.
An interval reaching past that fails the script with `TimeTranslationPastHorizon`, so
`TIMERANGE_SLOTS_OFFSET` is capped with the stability window, which is by definition
always inside the horizon.

Args:
cluster_obj: An instance of `clusterlib.ClusterLib`.

Returns:
int: The number of slots to set the validity interval to, counted from the tip.
"""
return min(
TIMERANGE_SLOTS_OFFSET, clusterlib_utils.get_stability_window(cluster_obj=cluster_obj)
)


def rotate_shift_bitwise_fails(protocol_version: int) -> bool:
"""Check if the rotate/shift bitwise builtin scripts fail on the given protocol version.

Expand Down
9 changes: 3 additions & 6 deletions cardano_node_tests/tests/tests_plutus/test_mint_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ def test_time_range_minting(
# Step 2: mint the "qacoin"

slot_step2 = cluster.g_query.get_slot_no()
slots_offset = 300
slots_offset = plutus_common.get_timerange_slots_offset(cluster_obj=cluster)
timestamp_offset_ms = int(slots_offset * cluster.slot_length + 5) * 1_000

# POSIX timestamp + offset
Expand Down Expand Up @@ -653,7 +653,7 @@ def test_two_scripts_minting(
]

# "time range" qacoin
slots_offset = 300
slots_offset = plutus_common.get_timerange_slots_offset(cluster_obj=cluster)
timestamp_offset_ms = int(slots_offset * cluster.slot_length + 5) * 1_000

# POSIX timestamp + offset
Expand Down Expand Up @@ -997,10 +997,7 @@ def test_ttl_horizon(
*mint_txouts,
]

# Calculate 3k/f
offset_3kf = round(
3 * cluster.genesis["securityParam"] / cluster.genesis["activeSlotsCoeff"]
)
offset_3kf = clusterlib_utils.get_stability_window(cluster_obj=cluster)

# Use 3k/f + `epoch_length` slots for ttl - this will not meet the `expect_pass` condition
if ttl_offset == -1:
Expand Down
10 changes: 4 additions & 6 deletions cardano_node_tests/tests/tests_plutus/test_mint_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from cardano_node_tests.tests import common
from cardano_node_tests.tests import plutus_common
from cardano_node_tests.tests.tests_plutus import mint_raw
from cardano_node_tests.utils import clusterlib_utils
from cardano_node_tests.utils import dbsync_utils
from cardano_node_tests.utils import helpers
from cardano_node_tests.utils import tx_view
Expand Down Expand Up @@ -422,7 +423,7 @@ def test_time_range_minting(
# Step 2: mint the "qacoin"

slot_step2 = cluster.g_query.get_slot_no()
slots_offset = 300
slots_offset = plutus_common.get_timerange_slots_offset(cluster_obj=cluster)
timestamp_offset_ms = int(slots_offset * cluster.slot_length + 5) * 1_000

# POSIX timestamp + offset
Expand Down Expand Up @@ -625,7 +626,7 @@ def test_two_scripts_minting(
]

# "timerange" qacoin
slots_offset = 300
slots_offset = plutus_common.get_timerange_slots_offset(cluster_obj=cluster)
timestamp_offset_ms = int(slots_offset * cluster.slot_length + 5) * 1_000

# POSIX timestamp + offset
Expand Down Expand Up @@ -1117,10 +1118,7 @@ def test_ttl_horizon(
*mint_txouts,
]

# Calculate 3k/f
offset_3kf = round(
3 * cluster.genesis["securityParam"] / cluster.genesis["activeSlotsCoeff"]
)
offset_3kf = clusterlib_utils.get_stability_window(cluster_obj=cluster)

# Use 3k/f + `epoch_length` slots for ttl - this will not meet the `expect_pass` condition
if ttl_offset == -1:
Expand Down
19 changes: 19 additions & 0 deletions cardano_node_tests/utils/clusterlib_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,25 @@ def save_ledger_state(
return json_file


def get_stability_window(*, cluster_obj: clusterlib.ClusterLib) -> int:
"""Return the stability window (`3k/f`) in slots.

Rounded down, so that the result is never above the window the ledger itself uses. A
caller that uses it as a limit therefore stays inside the window. The division is
exact on every testnet variant, so the rounding only guards against a variant that
picks a `securityParam` and `activeSlotsCoeff` that don't divide.

Args:
cluster_obj: An instance of `clusterlib.ClusterLib`.

Returns:
int: The number of slots in the stability window.
"""
security_param = int(cluster_obj.genesis["securityParam"])
active_slots_coeff = float(cluster_obj.genesis["activeSlotsCoeff"])
return math.floor(3 * security_param / active_slots_coeff)


def wait_for_epoch_interval(
*,
cluster_obj: clusterlib.ClusterLib,
Expand Down
Loading