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
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ YAML Scene -> Steps -> Transactions/Queries -> MultiversX Network
### Key Directories
| Directory | Purpose |
|-----------|---------|
| `mxops/execution/steps/` | All step implementations (28 types) |
| `mxops/execution/steps/` | All step implementations (32 types) |
| `mxops/smart_values/` | Dynamic value resolution (`%`, `$`, `&`, `=` syntax) |
| `mxops/data/` | ScenarioData persistence per network+scenario |
| `mxops/cli/` | CLI commands (execute, data, config, chain-simulator) |
| `tests/` | Unit tests (pytest) |
| `integration_tests/` | Chain-simulator/devnet integration tests |

### All Step Types (29)
### All Step Types (32)
**Contracts**: `ContractDeploy`, `ContractUpgrade`, `ContractCall`, `ContractQuery`, `FileFuzzer`
**Transfers**: `Transfer`
**Tokens**: `FungibleIssue`, `NonFungibleIssue`, `SemiFungibleIssue`, `MetaIssue`, `FungibleMint`, `NonFungibleMint`, `ManageFungibleTokenRoles`, `ManageNonFungibleTokenRoles`, `ManageSemiFungibleTokenRoles`, `ManageMetaTokenRoles`
**Setup**: `GenerateWallets`, `ChainSimulatorFaucet`, `R3D4Faucet`, `AccountClone`, `AccountBatchClone`
**Control**: `Loop`, `Scene`, `SetVars`, `SetSeed`, `Assert`, `Wait`, `Log`, `Python`
**Setup**: `GenerateWallets`, `ChainSimulatorFaucet`, `R3D4Faucet`, `AccountClone`, `AccountBatchClone`, `ChainSimulatorSetState`, `ChainSimulatorSetTokenBalance`
**Control**: `Loop`, `Scene`, `SetVars`, `SetSeed`, `SetConfig`, `Assert`, `Wait`, `Log`, `Python`

### Smart Values Syntax
| Symbol | Source | Example |
Expand Down
1 change: 1 addition & 0 deletions docs/dictionary/custom_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ AppFolder
arg
backend
backoff
behaviour
bitwise
blake
blockchain
Expand Down
1 change: 1 addition & 0 deletions docs/source/dev_documentation/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- `_set_state_with_retry` helper for transient failure resilience on `set_state` calls
- `PROXY_TIMEOUT` configuration parameter (default 10s, mainnet 30s, chain simulator 60s) to prevent read timeouts when fetching large contract storage
- `AUTO_GENERATE_BLOCKS` chain simulator configuration parameter (default `true`) to control whether MxOps drives block production itself; set it to `false` when the simulator auto-generates blocks so MxOps behaves like on other networks
- `SetConfigStep` to change a configuration option at runtime for the current network (process-only, never persisted), for example to toggle `AUTO_GENERATE_BLOCKS` mid-scene

### Changed

Expand Down
5 changes: 5 additions & 0 deletions docs/source/user_documentation/chain_simulator.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,8 @@ AUTO_GENERATE_BLOCKS=true

This option only applies to the chain-simulator network and has no effect on
other networks.

You can also toggle this option mid-scene with the
[Set Config step](set_config_step_target), for example to run fast
MxOps-driven setup steps and then switch to `AUTO_GENERATE_BLOCKS=false` so the
rest of the scene relies on the simulator's own block production.
26 changes: 26 additions & 0 deletions docs/source/user_documentation/steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,32 @@ variables:
```


(set_config_step_target)=
### Set Config Step

This step allows you to change a [configuration](config) option at runtime for the network the scene is running against. This is useful when you want to alter MxOps behaviour mid-scene, for example to toggle `AUTO_GENERATE_BLOCKS` on the chain-simulator (see the [chain-simulator chapter](chain_simulator)):

```yaml
- type: SetConfig
option: AUTO_GENERATE_BLOCKS
value: "false"
# ... steps that rely on the simulator auto-producing blocks ...
- type: SetConfig
option: AUTO_GENERATE_BLOCKS
value: "true"
```

```{note}
- The option is set on the **current network's** config section only. An unknown option name (e.g. a typo) raises an error rather than silently creating an unused key.
- The change lasts for the current process only: it is never written to disk and each `mxops execute` run reloads the configuration from file.
- Configuration values are strings. A non-string YAML scalar such as `value: false` is coerced to the string `"False"`, so quoting the value (`value: "false"`) is recommended for clarity.
```

```{warning}
Only options that are read fresh on each use (such as `AUTO_GENERATE_BLOCKS`) take effect mid-scene. Connection-level options such as `PROXY` and `PROXY_TIMEOUT` are read once when the network provider is first created, so changing them with this step has no effect on the already-running process.
```


(wait_target)=
### Wait Step

Expand Down
10 changes: 10 additions & 0 deletions mxops/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,16 @@ class InvalidConfigValue(Exception):
"""


class UnknownConfigOption(Exception):
"""
to be raised when a specified configuration option does not exist
"""

def __init__(self, option: str, network_name: str) -> None:
message = f"Unknown config option '{option}' for network '{network_name}'"
super().__init__(message)


class WrongFuzzTestFile(Exception):
"""
to be raised when the file given for fuzz testing in not correctly formatted
Expand Down
2 changes: 2 additions & 0 deletions mxops/execution/steps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
LoopStep,
PythonStep,
SceneStep,
SetConfigStep,
SetSeedStep,
SetVarsStep,
WaitStep,
Expand Down Expand Up @@ -72,6 +73,7 @@
"R3D4FaucetStep",
"SceneStep",
"SemiFungibleIssueStep",
"SetConfigStep",
"SetSeedStep",
"SetVarsStep",
"TransferStep",
Expand Down
25 changes: 25 additions & 0 deletions mxops/execution/steps/msc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from mxops import errors
from mxops.common.providers import MyProxyNetworkProvider, should_generate_blocks
from mxops.config.config import Config
from mxops.data.execution_data import ScenarioData
from mxops.data.utils import json_dumps
from mxops.enums import LogGroupEnum
Expand Down Expand Up @@ -137,6 +138,30 @@ def _execute(self):
scenario_data.set_value(key, value)


@dataclass
class SetConfigStep(Step):
"""
Represents a step to set a configuration option at runtime for the
current network.
"""

option: SmartStr
value: SmartStr

def _execute(self):
"""
Set the configuration option to the given value for the current network
"""
logger = ScenarioData.get_scenario_logger(LogGroupEnum.EXEC)
option = self.option.get_evaluated_value()
value = self.value.get_evaluated_value()
config = Config.get_config()
if option.upper() not in config.get_options():
raise errors.UnknownConfigOption(option, config.get_network().name)
logger.info(f"Setting config option `{option}` to `{value}`")
config.set_option(option, value)


@dataclass
class WaitStep(Step):
"""
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "mxops"
version = "3.2.0-dev3"
version = "3.2.0-dev4"
authors = [
{name="Etienne Wallet"},
]
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 3.2.0-dev3
current_version = 3.2.0-dev4
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-(?P<release>[^-0-9]+)(?P<build>\d+))?
serialize =
{major}.{minor}.{patch}-{release}{build}
Expand Down
4 changes: 4 additions & 0 deletions tests/data/all_steps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ steps:
my_var_2: ["alice", "bob"]
"prefix_%{dynamic_name}_suffix": "%dynamic_value"

- type: SetConfig
option: AUTO_GENERATE_BLOCKS
value: "true"

- type: Wait
for_seconds: 1.2 # optional, defaults to null
for_blocks: 123 # optional, defaults to null
Expand Down
49 changes: 48 additions & 1 deletion tests/test_msc_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@
from mxops.data.execution_data import ScenarioData
from mxops.execution.scene import execute_step
from mxops.execution.steps.base import Step
from mxops.execution.steps import LoopStep, PythonStep, SetVarsStep, WaitStep
from mxops.common.providers import should_generate_blocks
from mxops.execution.steps import (
LoopStep,
PythonStep,
SetConfigStep,
SetVarsStep,
WaitStep,
)
from mxops.smart_values import (
SmartAddress,
SmartBech32,
Expand Down Expand Up @@ -256,6 +263,46 @@ def test_set_vars_step():
}


def test_set_config_step(chain_simulator_network):
# Given
config = Config.get_config()
original_value = config.get("TX_TIMEOUT")
step = SetConfigStep(option="TX_TIMEOUT", value="42")

# When
try:
step.execute()

# Then
assert config.get("TX_TIMEOUT") == "42"
finally:
config.set_option("TX_TIMEOUT", original_value)


def test_set_config_step_toggles_block_generation(chain_simulator_network):
# Given
assert should_generate_blocks() is True
step = SetConfigStep(option="AUTO_GENERATE_BLOCKS", value="false")

# When
try:
step.execute()

# Then
assert should_generate_blocks() is False
finally:
Config.get_config().set_option("AUTO_GENERATE_BLOCKS", "true")


def test_set_config_step_unknown_option_raises():
# Given
step = SetConfigStep(option="NOT_A_REAL_OPTION", value="42")

# When / Then
with pytest.raises(errors.UnknownConfigOption):
step.execute()


def test_time_wait_step():
# Given
step = WaitStep(for_seconds=0.1)
Expand Down