diff --git a/.claude/agents/reviewer-implementation.md b/.claude/agents/reviewer-implementation.md new file mode 100644 index 000000000..e9756f396 --- /dev/null +++ b/.claude/agents/reviewer-implementation.md @@ -0,0 +1,76 @@ +--- +name: reviewer-implementation +description: Reviews the implementation of a GenVM branch — code-vs-spec drift, code quality, AI slop, duplicated logic, useless comments, and doc completeness. Use as the "implementation" pass of a branch review. +tools: Bash, Read, Grep, Glob +model: opus +--- + +You are the **implementation** pass of a GenVM branch review. You read the code +and judge how it is built. Read-only: never edit code. + +## Baseline + +Diff against the active dev branch, not `main`: + +- Default to `v0.3-dev` (or the current `v0.x-dev`) — confirm with + `git branch -a | grep dev`; fall back to `main` only if none exists. +- State the base in one line; ignore commits already on it. +- `git log --oneline ..HEAD` / `git diff --stat ..HEAD`, then read the + diffs of the changed code. + +## What to report (with file:line evidence) + +1. **Code-vs-spec drift.** Verify the implementation matches the ADR/spec + claim-for-claim: every form/grammar/permission/limit the spec names exists in + code with the same semantics, and the code does not add user-visible behavior + the spec omits. Call out each divergence. + +2. **Doc / SDK completeness.** New `gl_call`s, permissions, runner-id forms, etc. + must be reflected in `doc/website/src/spec/**`, `doc/schemas/*.json`, and any + SDK wrappers/docstrings. Flag anything implemented but undocumented. + +3. **AI slop & duplicated logic.** Deliberate engineering or generated filler? + Flag over-abstraction, padded boilerplate, dead/duplicated parsers, copy-paste, + and clever-for-no-reason indirection. Say plainly when it is NOT slop. + Specifically: a new `gl_call` handler (e.g. `register_runner` in + `wasi/genlayer_sdk.rs` and `Supervisor` helpers) must **share the underlying + loading/resolution logic with the runner loader in + `executor/src/rt/supervisor/actions.rs`** rather than reimplementing archive + parsing, id canonicalization, or cache insertion. A second parallel code path + doing what the loader already does is a finding — name the function it should + route through. + + **Responsibilities must be encapsulated in the layer that owns them.** Each + layer does its own job and exposes ONE entry point; callers in other layers + delegate, they don't reach across and re-orchestrate. Concretely: the + wasi/vfs layer (`wasi/genlayer_sdk.rs`, `wasi/preview1.rs`) is a thin syscall + shim — it must NOT contain runner-resolution logic (computing a contract's + runner id, picking storage slots/state, stitching together + `get_runner_of_contract` + `load_runner` + archive mapping). That belongs in + the runners/supervisor layer; the gl_call handler should call a single + encapsulated function there. A handler that assembles a cross-layer flow + inline (even if each piece is "shared") is a finding — name the boundary it + violates and the single function it should call instead. Likewise, storage + layout, permission derivation, and limiter accounting each have one home; + flag logic that leaks into a layer that shouldn't know about it. + +4. **Correctness & quality.** Panics on malformed input (`slice`, `unwrap`), + error handling, idempotency. + +5. **Edge cases are tested.** Enumerate the edge cases of each new surface and + verify each has a test: the happy path is not enough. Expect negative tests for + missing permission, non-deterministic mode, malformed / non-existing ids, and + stress/loop cases (e.g. registering the same thing ~1000× to prove + consume-once). Name each untested edge case as a gap. + +6. **Useless comments.** Flag narrate-the-obvious comments. Good comments explain + *why* (invariants, cache dedup, lifecycle) — credit those. + +Do NOT flag the dev-mode / `hashes=test` build state — intentional, not a finding. +Resource-accounting / consume-once limiter bugs are owned by the security +reviewer; mention only if it also reads as duplicated logic. + +## Style + +Concise and direct. Lead with: is the implementation correct and clean enough to +merge? Separate blocking issues from nits. Note if you did not build or run tests. diff --git a/.claude/agents/reviewer-security.md b/.claude/agents/reviewer-security.md new file mode 100644 index 000000000..11798cf71 --- /dev/null +++ b/.claude/agents/reviewer-security.md @@ -0,0 +1,57 @@ +--- +name: reviewer-security +description: Security review of a GenVM branch — attacker mindset over permissions, resource limits, sandbox propagation, parsing, and state-exfiltration. Use as the "security" pass of a branch review. +tools: Bash, Read, Grep, Glob +model: opus +--- + +You are the **security** pass of a GenVM branch review. Think like an attacker +writing a malicious contract. Read-only: never edit code. + +First read the repo root `SECURITY.md` — it is the source of truth for the threat +model, scope, and severity ladder. Rank every finding by the priority it defines +and cite that priority. Do not restate its contents in your report; reference it. + +## Baseline + +Diff against the active dev branch, not `main`: + +- Default to `v0.3-dev` (or the current `v0.x-dev`) — confirm with + `git branch -a | grep dev`; fall back to `main` only if none exists. +- State the base in one line; ignore commits already on it. +- `git log --oneline ..HEAD` / `git diff --stat ..HEAD`, then read the + diffs of the executor, wasi, supervisor, storage, and runner code. + +## What to check (with file:line evidence) + +- **Permission gates.** Every new capability is gated on its permission char AND + on `is_deterministic` where required. Check the gate is at entry, before any + side effect. +- **Permission propagation.** New capabilities are correctly disabled / inherited + in sub-VMs, the sandbox (`& allow_write_ops`), and nondet spawns — not silently + leaked into a more-privileged child. +- **Allocation bounded before allocating.** Reads/parses must charge the limiter + *before* allocating: decompression bombs (reject non-`Stored` zip entries), + length-prefixed reads, archive sizes. Charging after the alloc is a finding. +- **Resource accounting is consume-once.** A charge that scales with repeated + calls is a REAL BUG, not a conservative nit. Content-addressed resources (e.g. a + `custom:` runner) must be charged **once** — registering/loading the same + thing N times must not consume the limit N times. The test: "do it ~1000× in a + loop — does the limit overflow?" If yes, flag it and prescribe dedup-by-hash / + consume-once. Never excuse N-times charging as "errs safe." +- **Strict input parsing.** IDs/addresses/slots parsed with exact lengths and a + closed grammar; reserved prefixes truly reserved; malformed input rejected, not + coerced. +- **Read-oracle / exfiltration.** Does a new primitive let a contract read another + contract's state, or observe data it shouldn't? A blob that is loaded+executed + (not returned) is usually safe; a path that returns bytes to the caller is not. +- **Determinism.** New reads/branches in deterministic mode must be consensus-safe + (same result across validators). + +Do NOT flag the dev-mode / `hashes=test` build state — intentional, not a finding. + +## Style + +Concise. Lead with: any exploitable issue, yes/no, and what blocks merge. +Distinguish a real vuln from a hardening nice-to-have. Note if you did not build +or run anything. diff --git a/.claude/agents/reviewer-spec.md b/.claude/agents/reviewer-spec.md new file mode 100644 index 000000000..4fc4f4683 --- /dev/null +++ b/.claude/agents/reviewer-spec.md @@ -0,0 +1,63 @@ +--- +name: reviewer-spec +description: Reviews the ADR/proposal and spec/schema of a GenVM branch as documents — soundness, clarity, and completeness (what was forgotten). Use as the "spec" pass of a branch review. +tools: Bash, Read, Grep, Glob +model: opus +--- + +You review the **specification** of a GenVM branch — the ADR, the spec/docs, the +schemas — as documents: is the proposal sound, clear, and self-consistent? You do +NOT cross-check the implementation (whether the code matches the spec is the +implementation reviewer's job). Read-only: never edit code. + +## Baseline + +Diff against the active dev branch, not `main`: + +- Default to `v0.3-dev` (or the current `v0.x-dev`) — confirm with + `git branch -a | grep dev`; fall back to `main` only if none exists. +- State the base in one line at the top; ignore commits already on it. +- `git log --oneline ..HEAD` and `git diff --stat ..HEAD`, then read + the diffs of `doc/**` and `*.json` schemas. + +## What to report + +With file:line evidence: + +1. **ADR / proposal quality.** If the branch adds or changes a `doc/adr/*.md` + (or design doc), rate it. Good = concrete context with real linked issues, a + precise decision (grammar/types/IDs spelled out unambiguously), honest + consequences including breaking changes and footguns, and genuine + alternatives-considered. If there's no ADR for a change that warrants one, + say so. + +2. **Spec / schema soundness.** Read the spec and schema changes as a contract a + third party would implement against: is every form/grammar/permission/limit + defined precisely and unambiguously? Are there gaps, contradictions, or + under-specified edges? Is the JSON schema itself valid and matching the prose? + This is about the spec being *correct and complete on its own terms* — not + about the code. + +3. **Completeness — what did we forget to add?** A change usually touches a whole + family of surfaces; flag any the proposal/spec missed. E.g. a new `gl_call` + typically needs: a spec page, a JSON-schema entry, a permission (with its char + documented in the permissions spec), an SDK wrapper, error/edge-case + documentation, and a migration/breaking-change note if it changes existing + behavior. A new id/grammar form needs its schema pattern plus mention anywhere + the old forms are enumerated. List the surfaces that *should* have changed + together but didn't. + +4. **Edge cases are documented or inferrable.** Enumerate the edge cases of each + new surface (malformed input, missing permission, non-deterministic mode, + not-found / collision, limits hit) and check the spec either states the + behavior or makes it unambiguously inferrable from the stated rules. A behavior + a reader would have to guess is a spec gap — list each one. (Whether those + edge cases are *tested* is the implementation reviewer's job.) + +Do NOT flag the dev-mode / `hashes=test` build state — it is intentional (known +flag to ignore test hashes), not a finding. + +## Style + +Concise and direct. Lead with: is the proposal sound and the spec implementable +as written? Separate blocking gaps from nits. Don't pad. diff --git a/.claude/skills/branch-review/SKILL.md b/.claude/skills/branch-review/SKILL.md new file mode 100644 index 000000000..78fa08f8f --- /dev/null +++ b/.claude/skills/branch-review/SKILL.md @@ -0,0 +1,42 @@ +--- +name: branch-review +description: Reviews the current GenVM branch by fanning out three specialized review agents (spec, security, implementation). Use when asked to "review this branch", "review the PR", or do a full code review of a diff. +--- + +# Reviewing a GenVM branch + +Run a three-pass review using the dedicated subagents. The spec pass runs +**first** as a gate; the security and implementation passes run **concurrently** +after it (both in a single message). All three are read-only. + +| Pass | Agent (`subagent_type`) | Owns | +| --- | --- | --- | +| Spec | `reviewer-spec` | ADR/proposal quality; spec & schema soundness; completeness; edge cases documented/inferrable | +| Security | `reviewer-security` | permissions, sandbox propagation, limiter/consume-once, parsing, exfiltration (ranked by `SECURITY.md`) | +| Implementation | `reviewer-implementation` | code-vs-spec drift, AI slop, duplicated logic, edge cases tested, doc completeness, useless comments | + +## Baseline + +All three diff against the active **dev** branch, not `main` (default +`v0.3-dev`; confirm with `git branch -a | grep dev`). Pass the base in the prompt +if the user named one. Do NOT treat the dev-mode / `hashes=test` build state as a +finding — it is intentional. + +## Procedure + +1. Confirm the base branch (default `v0.3-dev`). +2. Spawn `reviewer-spec`, told the base branch and any extra scope the user gave. + After it finishes, if it found issues discuss with the user before proceeding. +3. In one message, spawn `reviewer-security` and `reviewer-implementation`, each + told the base branch and any extra scope the user gave. +4. Synthesize their three reports into one review: lead with the merge verdict, + then a **Blocking** section and a **Nits** section, attributing findings to + their pass. De-duplicate overlaps (e.g. a duplicated-logic issue both security + and implementation raise) into a single entry. + +## Scope notes + +- If the user asks for only one dimension ("just the security review"), run that + one agent instead of all three. +- Each agent is read-only; none will edit code. If the user wants fixes after the + review, that is a separate, explicit follow-up. diff --git a/.claude/skills/rust-test-style/SKILL.md b/.claude/skills/rust-test-style/SKILL.md index 379c2b0d5..364d02484 100644 --- a/.claude/skills/rust-test-style/SKILL.md +++ b/.claude/skills/rust-test-style/SKILL.md @@ -15,16 +15,29 @@ To run these tests, see the `/test` skill (`--filter-tag rust`). ## Where tests go +**Decision rule — default to a separate file.** If the item under test is +reachable from the crate's public API (a `pub fn`/`pub` type, even via a +re-export), its test goes in its own `tests/.rs` file. Use an inline +`#[cfg(test)] mod tests` **only** when the test must reach a *private* item that +cannot be exercised through the public API. A public function tested inline is a +review finding — move it to `tests/`. + Two locations, both in use: 1. **Integration tests** — one file per concern under the crate's `tests/` dir. - Preferred for exercising a crate's public API. Each `tests/*.rs` file is its - own compilation unit and gets its own runner case. + **This is the default** for anything testable through the public API. Each + `tests/*.rs` file is its own compilation unit (a separate crate) and gets its + own runner case. - e.g. `executor/crates/calldata/tests/derive_decode.rs`, + `executor/crates/calldata/tests/address_checksum.rs`, `executor/crates/common/tests/expr.rs`, `modules/implementation/tests/test_rat.rs` + - Because each is a separate crate, it sees only the library crate plus + `[dev-dependencies]` — **not** the library's regular `[dependencies]`. If a + test needs a util the crate already depends on (e.g. `hex`), add it to + `[dev-dependencies]` too. 2. **Inline unit tests** — `#[cfg(test)] mod tests { ... }` at the bottom of a - `src/*.rs` file, for testing private items. e.g. + `src/*.rs` file, reserved for testing **private** items. e.g. `executor/crates/calldata/src/lib.rs`, `executor/crates/common/src/logger/mod.rs`. ```rust diff --git a/.claude/skills/test/SKILL.md b/.claude/skills/test/SKILL.md index fcf9fff60..93fef3163 100644 --- a/.claude/skills/test/SKILL.md +++ b/.claude/skills/test/SKILL.md @@ -40,6 +40,13 @@ ya-test-runner run [OPTIONS] | `--fail-fast` | Stop execution after first failure | | `--coverage` | Enable coverage collection for Rust tests | | `--log-level LEVEL` | Set log level (trace/debug/info/warning/error) | +| `--ignore-hash` | Skip `.hash` (execution-hash) comparison entirely | + +**`--ignore-hash`:** integration cases compare both the printed semantics +(`.N.stdout`) and a deterministic execution hash (`.N.hash`). When adding a new +case, you usually don't have a correct `.hash` yet — run with `--ignore-hash` so +only the `.stdout` semantics are checked, or set `stable_hash: false` on the +entry (then validators compare to the leader's hash instead of a committed file). ### Show Information ```bash diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 535d78c6d..bca7c536d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -87,4 +87,4 @@ repos: entry: ./support/ci/check-versions.py language: system pass_filenames: false - files: ^(executor/Cargo\.toml|modules/implementation/Cargo\.toml|\.genvm-monorepo-root)$ + files: ^(executor/Cargo\.toml|executor/crates/common/Cargo\.toml|modules/implementation/Cargo\.toml|\.genvm-monorepo-root)$ diff --git a/configure.rb b/configure.rb index 5c2c7f558..d1ad1afe5 100755 --- a/configure.rb +++ b/configure.rb @@ -483,14 +483,18 @@ def generator.register_cargo(rel_path, extra_args: [], build_to: nil) var :pool, :console end +runners_nix_inputs = $source_dir.join('runners').glob('**/*.nix') + generator.build(:nix_eval, 'out/executor/vTEST/data/latest.json') do - var 'expr', 'let drv = import ./runners { host-system = builtins.currentSystem; } ; conv-hash = hash: if hash == "test" then "test" else builtins.convertHash { inherit hash; toHashFormat = "nix32"; } ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = conv-hash x.hash; }) drv)' + var 'expr', 'let drv = import ./runners { host-system = builtins.currentSystem; } ; hash-of = x: builtins.head (builtins.tail (builtins.match "([^:]+):(.*)" x.uid)) ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = hash-of x; }) drv)' var 'wd', $source_dir + add_implicit_dependency runners_nix_inputs end generator.build(:nix_eval, 'out/executor/vTEST/data/all.json') do - var 'expr', 'let drv = import ./runners { host-system = builtins.currentSystem; } ; conv-hash = hash: if hash == "test" then "test" else builtins.convertHash { inherit hash; toHashFormat = "nix32"; } ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = [ (conv-hash x.hash) ]; }) drv)' + var 'expr', 'let drv = import ./runners { host-system = builtins.currentSystem; } ; hash-of = x: builtins.head (builtins.tail (builtins.match "([^:]+):(.*)" x.uid)) ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = [ (hash-of x) ]; }) drv)' var 'wd', $source_dir + add_implicit_dependency runners_nix_inputs end generator.build(:phony, 'all/data') do diff --git a/doc/adr/011. runner ids and runtime registration.md b/doc/adr/011. runner ids and runtime registration.md new file mode 100644 index 000000000..1d7bb3b23 --- /dev/null +++ b/doc/adr/011. runner ids and runtime registration.md @@ -0,0 +1,111 @@ +# ADR-011: Runner IDs and Runtime Runner Registration + +## Status + +- **Status**: Accepted +- **Date**: 2026-06-19 + +## Context + +[ADR-002](<002. code loading.md>) introduced runners and identified them by a +`:` string, with a special `` literal for the +contract currently being executed and an internal `on_chain:0x
` id used +when loading a contract's own runner from its code. + +This scheme is limiting: + +- The `` literal and the `on_chain:` id were implementation details + that were never specified, so contracts could not reference runner code stored + on chain in a documented, stable way. +- There is no way to load runner code from an arbitrary contract's storage, which + blocks reuse of code parts between contracts (see research + [GVM-231](https://linear.app/genlayer-labs/issue/GVM-231)). +- There is no way for a contract to provide runner code at runtime (e.g. to build + a more capable / user-provided execution environment) — the runner set was + fixed at load time. + +## Decision + +Rework runner ids into four explicit, specified forms (parsed in +`executor/src/runners`): + +1. `name:hash` — a packaged runner by human readable name (`[a-zA-Z0-9_-]+`) and + archive hash. In debug mode the hash may be `test`/`latest`. Unchanged. +2. `contract` — the runner of the contract currently being executed. Replaces the + old, undocumented `` literal. +3. `chain:
[:[:]]` — load a runner code blob directly from a + storage slot of an arbitrary contract: `
` is a `0x` 20 byte hex + address, `a`/`f` selects accepted (latest non final) / finalized state, and + `` is a 32 byte slot id encoded with GVM32 (Crockford Base32, not `0x` + hex). Both `` and `` are optional: `` defaults to `a` and + `` defaults to the target contract's resolved root code slot, so + `chain:
` and `chain:
:a` are valid shorthands. The current + contract's runner is the canonical `chain:` id pointing at itself and the code + slot, so `contract` and an explicit self reference deduplicate in the cache. +4. `custom:` — a runner registered at runtime, looked up in an in-memory map + keyed by `` (the GVM32-encoded SHA3-256 of the registered code). + +`contract`, `chain` and `custom` are reserved prefixes and cannot be used as +human readable runner names. + +Add a `gl_call` `RegisterRunner { code: Bytes }` that parses `code` as a runner +archive, charges its size against the memory limit and stores it under +`custom:`, where `` is the GVM32-encoded SHA3-256 of `code`. It +returns the resulting runner id. It is allowed only in deterministic mode and only when the contract +holds the new `register_runners` permission (permission char `u`). A friendly +`genlayer.vm.register_runner(code) -> str` wrapper is exposed in the Python SDK. + +Add a companion `gl_call` `MapFile { runner, path_in_runner, path_in_vfs }` that maps +a file (or, when `path_in_runner` ends with `/`, a directory subtree) from any +runner into the VM filesystem at runtime, sharing the exact logic of the `MapFile` +runner action. Because resolving a `chain:` runner reads another contract's +storage, it requires the `read_storage` permission. Exposed as +`genlayer.vm.map_file(...)` in the Python SDK. + +## Consequences + +### Positive + +- Runner ids are fully specified and uniform; `contract`/`chain`/`custom` are + first-class instead of hidden literals. +- Contracts can load code parts from other contracts' storage on chain. +- Contracts can extend their execution environment with runtime-provided code. + +### Negative + +- `` is no longer accepted; runners embedding it must be rebuilt to use + `contract` (done for the bundled `py-genlayer` wrappers). +- `chain` and `custom` become reserved prefixes, slightly shrinking the space of + valid human readable runner names. + +### Neutral + +- The `custom:` map is per-execution and starts empty; registered runners do not + persist across executions. + +## Alternatives Considered + +- **Keep ``/`on_chain:` internal-only**: rejected because contracts + need a documented way to reference on-chain and current-contract runners. +- **A dedicated `exec` gl_call that replaces the current VM with a new one + carrying user code** (GVM-231 idea A): rejected for now because propagating the + extended runner into sub-sub-VMs is not obvious; registering under `custom:` and + referencing it from ordinary `Depends`/`With` composes with the existing loader. + +## Implementation Notes + +- Parsing/canonicalization lives in `executor/src/runners/mod.rs` + (`parse_runner_id`, `chain_canonical`, `custom_runner_hash`); resolution and + loading in `executor/src/rt/supervisor/actions.rs`. +- `chain:` reads code via a fresh `Storage` pointed at the target address/state + and `read_code_at(slot)`. +- A dependency whose runner declares a public-ABI major different from the host's + `CURRENT_MAJOR` is rejected before its code is loaded, so an incompatible + on-chain runner cannot be pulled in via `Depends`/`With`. +- Runner ids are interned via a `StrSymbol` newtype so the runner maps stay + interned while lookups accept `&str` without interning untrusted input (an + attacker-supplied id cannot grow the global symbol table). +- The `custom:` map lives on `Supervisor` (`register_custom_runner` / + `get_custom_runner`). +- Spec: `doc/schemas/runners.json` (`runner-id` type), + `doc/website/src/spec/.../02-gl_call.rst` and `.../03-vm/05-permissions.rst`. diff --git a/doc/internal/comparisons/py-api.md b/doc/internal/comparisons/py-api.md index 4e9b57692..6bb008cbe 100644 --- a/doc/internal/comparisons/py-api.md +++ b/doc/internal/comparisons/py-api.md @@ -80,7 +80,7 @@ So, unless leader gets some score for agreeing or disagreeing with validators it Basis function: ```rust -fn eq_principle(leader_fn: () -> bytes|rollback, validator_fn: (leaders_result: bytes|rollback) -> bool) -> bytes|rollback +fn eq_principle(leader_fn: () -> bytes|user_error, validator_fn: (leaders_result: bytes|user_error) -> bool) -> bytes|user_error ``` On top of it all sorts of API can be built, including `eq_principle(prompt_template, result_producer)` diff --git a/doc/internal/node.md b/doc/internal/node.md deleted file mode 100644 index a749332ad..000000000 --- a/doc/internal/node.md +++ /dev/null @@ -1,186 +0,0 @@ -## Running the GenVM - -To run a genvm, one must start a genvm process with following arguments: -- `--host` tcp-it address or `unix://` prefixed unix domain socket -- `--message` message data as json, follows [schema](../schemas/message.json) - See [example](../../executor/testdata/templates/message.json) that is used in tests - -## How to ask GenVM to quit? -Send it `SIGTERM`. If it doesn't quit in some sensible amount of time just `SIGKILL` it - -## How node receives code, message, ... from user -It is for node to decide. GenVM knows only about the calldata (and potentially message) and nothing else - -## Communication protocol -All further communication is done via socket. If the GenVM process exited before sending the result, it means that GenVM crashed. Potential bugs should be reported - -Method ids list is available as [json](../../executor/codegen/data/host-fns.json). It is advised to use it in the build system to codegen constants - -Below is pseudo code, but [real code](../../executor/testdata/runner/base_host.py) is always up to date and is as readable as this code is (see `async def host_loop(handler: IHost):`) - -``` -const ACCOUNT_ADDR_SIZE = 20 -const SLOT_ID_SIZE = 32 - -fn write_byte_slice(arr): - write_u32_le len(arr) - write_bytes arr -fn read_slice(): - len := read_u32_le - data := read_bytes(len) - return data - -loop: - method_id := read_byte - match method_id - json/methods/get_calldata: - calldata, err := host_get_calldata() - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - write_byte_slice calldata - json/methods/storage_read: - read_type := read_byte as json/storage_type - address := read_bytes(ACCOUNT_ADDR_SIZE) - slot := read_bytes(SLOT_ID_SIZE) - index := read_u32_le - len := read_u32_le - data, err := host_storage_read(read_type, address, slot, index, len) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - write_bytes data # must be exactly len in size - json/methods/storage_write: - slot := read_bytes(SLOT_ID_SIZE) - index := read_u32_le - len := read_u32_le - data := read_bytes(len) - err := host_storage_write(slot, index, data) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - json/methods/consume_result: - host_result := read_slice() - # this is needed to ensure that genvm doesn't close socket before all data is read - write_byte 0x00 - break - json/methods/get_leader_nondet_result: - call_no := read_u32_le - data, err := host_get_leader_nondet_result(call_no) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - write_byte_slice result_data - json/methods/post_nondet_result: - call_no := read_u32_le - result := read_slice() - err := host_post_nondet_result(call_no, result) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - json/methods/post_message: - address := read_bytes(ACCOUNT_ADDR_SIZE) - calldata := read_slice() - message_data := read_slice() # JSON string - err := host_post_message(address, calldata, message_data) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - json/methods/consume_fuel: - gas := read_u64_le - host_consume_fuel(gas) - # note: this method doesn't send any response - json/methods/deploy_contract: - calldata := read_slice() - code := read_slice() - message_data := read_slice() # JSON string - err := host_deploy_contract(calldata, code, message_data) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - json/methods/eth_call: - address := read_bytes(ACCOUNT_ADDR_SIZE) - calldata := read_slice() - result, err := host_eth_call(address, calldata) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - write_byte_slice result - json/methods/eth_send: - address := read_bytes(ACCOUNT_ADDR_SIZE) - calldata := read_slice() - message_data := read_slice() # JSON string - err := host_eth_send(address, calldata, message_data) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - json/methods/get_balance: - address := read_bytes(ACCOUNT_ADDR_SIZE) - balance, err := host_get_balance(address) - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - write_bytes balance.to_le_bytes(32) # 256-bit integer - json/methods/remaining_fuel_as_gen: - fuel, err := host_remaining_fuel_as_gen() - if err != json/errors/ok: - write_byte err - else: - write_byte json/errors/ok - write_bytes fuel.to_le_bytes(8) # 64-bit integer, must be safe integer (fits in double) -``` - -See [mock implementation](../../executor/testdata/runner/mock_host.py) - -## Types - -### VM results -There are following codes: -- `Return` -- `VMError` indicating vm-produced error that usually can't be handled -- `UserError` user-produced error - -#### Nondet blocks and sandbox encoding -- 1 byte of result code -- result as-is (calldata for `Return`, string for `VMError|UserError`) - -#### Parent VM result -- 1 byte of result code -- calldata for `Return`, `{ "message": "string", "fingerprint": ... }` for `VMError|UserError` - -### Calldata -`get_calldata` method must return [calldata encoded](../calldata.md) bytes that conform to ABI: -```typescript -{ - method?: string, // only for non-consturctors - args: Array, - kwargs?: { [key: string]: any } -} -``` - -### Read result -It has code followed by bytes, codes are: -- return, it is followed by calldata -- rollback and contract error, followed by a string; from host point of view there is no distinction between them -- just error, which is internal error, like llm's modules being absent - -### Storage format -Storage can be seen as a mapping from account address to slot address to linear memory. It supports two operations: `read` and `write`. Reading undefined memory **must** return zeroes - -Storage can be seen as a file system tree containing directories named as contracts which contain files named as slots, then following implementation is valid: -```bash -# read contract_a slot_b 10...100 -cat db/contract_a/slot_b.bytes /dev/null | tail -c +10 | head -c +100 -``` - -**NOTE**: calculating storage updates, hashes and so on is host's (node's) responsibility. It is [the same in geth](https://github.com/ethereum/go-ethereum/blob/67a3b087951a3f3a8e341ae32b6ec18f3553e5cc/core/state/state_object.go#L232): they have dirty override for the store diff --git a/doc/schemas/default-config.json b/doc/schemas/default-config.json index 7c136a6be..3f56aa017 100644 --- a/doc/schemas/default-config.json +++ b/doc/schemas/default-config.json @@ -324,9 +324,22 @@ "type": "object", "properties": { "bucket_no": { - "type": "integer", - "minimum": 0, - "maximum": 255 + "oneOf": [ + { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + { + "type": "array", + "items": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 1 + } + ] }, "subtract_on_start_expr": { "type": "string", diff --git a/doc/schemas/runners.json b/doc/schemas/runners.json index 86751c0e5..779fe9eda 100644 --- a/doc/schemas/runners.json +++ b/doc/schemas/runners.json @@ -11,6 +11,29 @@ "WasmMode": { "enum": ["det", "nondet"] }, + "runner-id": { + "type": "string", + "description": "Identifier of a runner to load", + "anyOf": [ + { + "pattern": "^[a-zA-Z0-9_-]+:[a-zA-Z0-9_=-]+$", + "not": { "pattern": "^(contract|chain|custom):" }, + "description": "`name:hash` — packaged runner by human readable name and archive hash (in debug mode hash may be `test`/`latest`). `contract`/`chain`/`custom` are reserved and cannot be used as a name" + }, + { + "const": "contract", + "description": "the runner of the contract that is currently being executed" + }, + { + "pattern": "^chain:0x[0-9a-fA-F]{40}(:[af](:[0-9abcdefghjkmnpqrstvwxyz]{52})?)?$", + "description": "`chain:
[:[:]]` — code blob read from a `0x` 20 byte address at a GVM32-encoded 32 byte slot, `a`=accepted / `f`=finalized. `` and `` are optional: `` defaults to `a` and `` to the target contract's root code slot" + }, + { + "pattern": "^custom:[a-zA-Z0-9_=-]+$", + "description": "`custom:` — runner registered at runtime" + } + ] + }, "InitAction": { "description": "A single rule for loading.", "type": "object", @@ -116,8 +139,8 @@ "type": "string" }, "Depends": { - "description": "Depend on other runner by id:hash", - "type": "string" + "description": "Depend on another runner", + "$ref": "#/definitions/runner-id" }, "Seq": { "description": "Execute sequence", @@ -138,7 +161,10 @@ "description": "Makes given runner current without executing it's action. It means that MapFile will fork with files from this archive. Useful for creating lock files", "type": "object", "properties": { - "runner": { "type": "string" }, + "runner": { + "description": "runner id to make current", + "$ref": "#/definitions/runner-id" + }, "action": { "$ref": "#/definitions/InitAction" } } } diff --git a/doc/website/src/impl-spec/01-core-architecture/02-host-interface.rst b/doc/website/src/impl-spec/01-core-architecture/02-host-interface.rst index 97d1fcb81..a898e71ce 100644 --- a/doc/website/src/impl-spec/01-core-architecture/02-host-interface.rst +++ b/doc/website/src/impl-spec/01-core-architecture/02-host-interface.rst @@ -22,9 +22,8 @@ GenVM Execution **Process Control**: -- **Graceful Shutdown**: Send ``SIGTERM`` signal -- **Force Termination**: Send ``SIGKILL`` if not responding -- **Crash Detection**: Process exit before sending result indicates crash (should be reported as bug) +- **Termination**: The executor has no internal timeout or graceful-shutdown path and may be killed at any moment with ``SIGKILL`` (see :doc:`04-executor`). Timeouts are enforced by the :term:`Manager`. +- **Crash Detection**: Process exit before sending result indicates a kill/timeout or a crash (a crash should be reported as a bug) **Node Responsibilities**: Node decides how to receive code and messages from users. GenVM only knows about calldata and message data. @@ -56,7 +55,7 @@ Result Encoding **Non-deterministic Blocks and Sandbox Encoding**: - 1 byte of result code -- Result data: calldata for ``Return``, string for ``VMError`` or ``UserError`` +- Result data: calldata for ``Return``, calldata for ``UserError``, string for ``VMError`` **Parent VM Result Encoding**: diff --git a/doc/website/src/impl-spec/01-core-architecture/04-executor.rst b/doc/website/src/impl-spec/01-core-architecture/04-executor.rst new file mode 100644 index 000000000..a5fb25194 --- /dev/null +++ b/doc/website/src/impl-spec/01-core-architecture/04-executor.rst @@ -0,0 +1,93 @@ +Executor +======== + +The executor (the ``genvm`` binary) runs a single contract execution to +completion and writes its result back to the :term:`Host`. It is a short-lived, +stateless process that the :term:`Manager` spawns once per execution. + +No Internal Timeout +------------------- + +The executor does **not** implement any execution timeout, deadline, or signal +handling of its own. It runs until the contract finishes — producing a +``Return``, ``UserError``, or ``VMError`` result — or until it is terminated +externally. + +Timeouts are enforced entirely by the :term:`Manager`, which owns the executor +process lifecycle. When an execution exceeds its budget (or must otherwise be +stopped), the manager kills the executor process directly with ``SIGKILL``. The +executor installs no signal handlers and has no graceful-shutdown path, so it +**can be killed at any moment**, between any two operations, without notice. + +Implications +----------- + +- The executor keeps no durable state of its own. All persistent state lives in + the host and is written only as part of delivering a result. A killed executor + simply produces no result, which the manager treats as a failed / timed-out + execution. +- Executor code must not rely on running cleanup, flushing buffers, or + cancellation logic during shutdown — there is no shutdown to hook into. + +Debug modes +----------- + +The debug level is a top-level field of the manager ``run`` request +(``debug_mode``), forwarded to the executor as ``--debug-mode ``. The +default is ``disabled``. + +Output **capture** is a derived property with three states: + +- ``disabled`` — nothing is captured into the result: the executor's + stdout/stderr go to ``/dev/null`` and its logs are *forwarded to the manager's + own log* (so they are not lost, just not returned in the response). +- ``bounded`` — captured into the result, but bounded: at most the 128 most + recent log entries are kept (oldest dropped), and stdout/stderr are truncated + to a 4 MiB tail each. +- ``unbounded`` — captured into the result in full. + +When capture is ``disabled`` the result's log/stdout/stderr fields are empty +(empty list / empty strings), not omitted; ``bounded`` and ``unbounded`` use the +same field shapes, differing only in how much they contain. + +The levels are ordered; each *adds* to the previous one: + +.. list-table:: + :header-rows: 1 + :widths: 20 22 58 + + * - Level + - Capture + - Adds + * - ``disabled`` + - ``disabled`` + - Production default. Logs are forwarded to the manager log; no result capture; no debug aids. + * - ``safe`` + - ``bounded`` + - Logs and stdout/stderr are captured into the result (bounded). Deterministic. + * - ``safe-unbounded`` + - ``unbounded`` + - Capture becomes unbounded and ``Trace`` gl_call output is emitted. Deterministic. + * - ``unsafe`` + - ``unbounded`` + - The ``:latest`` / ``:test`` runner ids may be resolved. **Unsafe across machines**: different nodes may resolve different code and diverge consensus, though a single node stays deterministic. + * - ``unsafe-tracing`` + - ``unbounded`` + - Real wall-clock time is exposed to the contract in deterministic mode (``RuntimeMicroSec`` returns actual elapsed time instead of ``0``; non-deterministic mode already returns real time regardless of debug level). **Can break determinism on a single machine.** Local debugging only. + +Only ``unsafe`` and ``unsafe-tracing`` can affect determinism (across machines +and on a single machine respectively); ``safe`` and ``safe-unbounded`` are fully +consensus-safe (``safe-unbounded`` deliberately couples unbounded capture with +``Trace`` emission — both are deterministic, verbose debug aids). In code these +distinctions are methods on ``genvm_common::DebugMode``: ``capture()`` (returns +the ``Capture`` state), ``allows_tracing()``, ``allows_latest_resolution()``, +and ``allows_nondeterminism()``. + +**Enforcement.** ``debug_mode`` is a per-request field, so on a consensus +network the manager MUST reject (or clamp to a configured maximum) ``unsafe`` +and ``unsafe-tracing`` from untrusted callers — otherwise a single request could +force ``:latest``/``:test`` resolution (cross-node divergence) or expose real +time (single-machine non-determinism). Unbounded capture (``safe-unbounded`` and +above) also trades the memory bound for completeness, so operators should treat +the higher levels as privileged. An unrecognized ``debug_mode`` value is +rejected rather than silently downgraded. diff --git a/doc/website/src/impl-spec/01-core-architecture/index.rst b/doc/website/src/impl-spec/01-core-architecture/index.rst index 96fe82009..af000fbfe 100644 --- a/doc/website/src/impl-spec/01-core-architecture/index.rst +++ b/doc/website/src/impl-spec/01-core-architecture/index.rst @@ -9,3 +9,4 @@ Overview of GenVM's core architectural components and design patterns. 01-components 02-host-interface 03-modules/index + 04-executor diff --git a/doc/website/src/impl-spec/04-fees.rst b/doc/website/src/impl-spec/04-fees.rst index 5547da08e..36a240116 100644 --- a/doc/website/src/impl-spec/04-fees.rst +++ b/doc/website/src/impl-spec/04-fees.rst @@ -37,11 +37,14 @@ The ``fees`` block of the GenVM config (see ``doc/schemas/default-config.json``, per-bucket expressions can reference. ``bucket_no`` - Index into the ``Vec`` of bucket totals the host passes to - ``DataLimit::new``. Two bucket configs MAY share the same ``bucket_no``; in that - case both charge against the same reservoir. The ``message_fee`` / - ``message_receipt`` pair has special atomic-debit behaviour when they share a - bucket (``consume_message_fee`` in ``fees.rs:332``). + Either a single index, or an array of indices, into the ``Vec`` of bucket + totals the host passes to ``DataLimit::new``. With an array, a scalar ``delta_expr`` + result is charged against every listed bucket, while an array result is charged + element-wise (lengths must match); all debits in one charge are atomic + (all-or-nothing). Two bucket configs MAY share the same index; in that case both + charge against the same reservoir. The ``message_fee`` / ``message_receipt`` pair + has special atomic-debit behaviour when they share a bucket (``consume_message_fee`` + in ``fees.rs:332``). ``subtract_on_start_expr`` A bare numeric expression. Evaluated once at startup with ``node`` bound to the diff --git a/doc/website/src/impl-spec/appendix/manager-api.yaml b/doc/website/src/impl-spec/appendix/manager-api.yaml index f21fcc5e0..fdae60607 100644 --- a/doc/website/src/impl-spec/appendix/manager-api.yaml +++ b/doc/website/src/impl-spec/appendix/manager-api.yaml @@ -617,7 +617,6 @@ components: - major - message - is_sync - - capture_output - storage_pages - host_data - timestamp @@ -633,9 +632,19 @@ components: is_sync: type: boolean description: Whether execution is synchronous - capture_output: - type: boolean - description: Whether to capture execution output + debug_mode: + type: string + default: disabled + enum: [disabled, safe, safe-unbounded, unsafe, unsafe-tracing] + description: | + Executor debug level (see the Executor "Debug modes" section). Each level + adds to the previous one. Replaces the former `capture_output` boolean, + from which the output `Capture` (disabled/bounded/unbounded) is now derived. + + On a consensus network the manager MUST reject (or clamp) `unsafe` and + `unsafe-tracing` from untrusted callers: `unsafe` enables `:latest`/`:test` + resolution (different nodes may diverge) and `unsafe-tracing` exposes real + time (breaks single-machine determinism). An unrecognized value is rejected. max_execution_minutes: type: integer format: uint64 diff --git a/doc/website/src/python-sdk/changelog-notes/v0.3.rst b/doc/website/src/python-sdk/changelog-notes/v0.3.rst index b54bd1dfc..9798de297 100644 --- a/doc/website/src/python-sdk/changelog-notes/v0.3.rst +++ b/doc/website/src/python-sdk/changelog-notes/v0.3.rst @@ -7,7 +7,7 @@ Migration Guide v0.3.0 introduces a major restructuring of the standard library. The ``genlayer.gl`` and ``genlayer.py`` intermediate packages are removed. All public API is now accessible directly under the ``genlayer`` namespace. Import Pattern -~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~ The recommended import pattern has changed: @@ -23,7 +23,7 @@ The recommended import pattern has changed: The ``from genlayer import *`` star-import previously brought ``gl`` (a lazy proxy to ``genlayer.gl``), all types, and storage names into scope. Now ``import genlayer as gl`` gives you direct access to submodules (``gl.contract``, ``gl.vm``, ``gl.message``, ``gl.chain``, etc.), decorators (``gl.public``, ``gl.private``), and storage types (``gl.TreeMap``, ``gl.DynArray``, ``gl.Array``). The ``from genlayer.types import *`` import brings the type aliases (``u8``..``u256``, ``i8``..``i256``, ``Address``, ``bigint``, etc.) into local scope. Module Path Changes -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~ All ``genlayer.py.*`` and ``genlayer.gl.*`` paths are removed. Here is the mapping: @@ -35,6 +35,8 @@ All ``genlayer.py.*`` and ``genlayer.gl.*`` paths are removed. Here is the mappi - v0.3.0 * - ``genlayer.py.types`` - ``genlayer.types`` + * - ``genlayer.py.keccak`` + - ``genlayer.types.keccak`` * - ``genlayer.py.calldata`` - ``genlayer.calldata`` * - ``genlayer.py.storage`` @@ -54,8 +56,19 @@ All ``genlayer.py.*`` and ``genlayer.gl.*`` paths are removed. Here is the mappi * - ``genlayer.gl.advanced`` - removed (see below) +.. note:: + Type aliases (``u8``..``u256``, ``i8``..``i256``) are no longer ``typing.NewType`` instances; they are now ``typing.Annotated[int, ...]``. They still work as type annotations, but they are no longer callable, so the ``u256(0)`` wrapping is gone — pass a plain ``int`` instead: + + .. code-block:: python + + # v0.2.x + gl.contract.deploy(code=source, value=u256(1000), salt_nonce=u256(42)) + + # v0.3.0 + gl.contract.deploy(code=source, value=1000, salt_nonce=42) + Contract Declaration -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~ ``gl.Contract`` is now ``gl.contract.Contract``: @@ -70,7 +83,7 @@ Contract Declaration ... Contract Interaction -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~ Functions for interacting with other contracts have been renamed and moved into ``gl.contract``: @@ -99,7 +112,7 @@ The ``ContractProxy`` type is renamed to ``gl.contract.Proxy``. Contract proxies, ``Contract`` itself, and the new ``gl.chain.Account`` all implement the ``gl.chain.IAccount`` protocol, exposing ``address``, ``balance``, and ``emit_transfer(value, *, on=...)``. Value Transfers and ``on=`` Parameter -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Write-call and deploy APIs now take an ``on`` keyword controlling when the message is applied, with values ``'accepted'`` or ``'finalized'`` (default ``'finalized'``): @@ -160,7 +173,7 @@ The ``Event`` class has moved from ``genlayer.gl`` to ``genlayer.chain``: ``gl.advanced.emit_raw_event(topics, blob)`` is now ``gl.chain.Event.emit_raw(topics, blob)``. Advanced / Error Handling -~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ``genlayer.gl.advanced`` module is removed. Its functionality has been relocated: @@ -202,6 +215,45 @@ Trace functions have moved from ``genlayer.gl`` to ``genlayer.vm``: gl.vm.trace("debug message") gl.vm.trace_time_micro() +Non-deterministic Execution (``gl.vm``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. warning:: + ``gl.vm.run_nondet`` **changed meaning**. The two ``run_nondet`` functions were renamed: + + * the old ``run_nondet_unsafe`` (no validator sandbox) is now ``run_nondet``; + * the old ``run_nondet`` (safe, validator runs in a sandbox) is now ``run_nondet_default``. + + Code that called ``gl.vm.run_nondet`` still compiles but now silently uses the + *unsafe* variant. To keep the previous behavior, switch to ``gl.vm.run_nondet_default``: + + .. code-block:: python + + # v0.2.x (safe) # v0.3.0 (same behavior) + gl.vm.run_nondet(...) gl.vm.run_nondet_default(...) + + # v0.2.x (unsafe) # v0.3.0 (same behavior) + gl.vm.run_nondet_unsafe(...) gl.vm.run_nondet(...) + +The high-level equivalence principles (``gl.eq_principle.*``) are unaffected — they were updated internally. + +``gl.vm.spawn_sandbox`` replaced the single ``allow_write_ops`` flag with three granular permissions, each effective only if the current VM holds it: + +.. code-block:: python + + # v0.2.x + gl.vm.spawn_sandbox(fn, allow_write_ops=True) + + # v0.3.0 + gl.vm.spawn_sandbox( + fn, + allow_write_storage=True, + allow_send_messages=True, + allow_register_runners=True, + ) + +Two runtime helpers were added: ``gl.vm.register_runner(code)`` registers a runner archive and returns its ``custom:`` id, and ``gl.vm.map_file(runner, path_in_runner, path_in_vfs)`` maps a file from a runner into the VM filesystem. + Storage ~~~~~~~ @@ -236,17 +288,17 @@ Decorators def balance_of(self, owner: Address) -> u256: ... Non-deterministic Operations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``gl.nondet`` now raises a dedicated ``gl.nondet.NondetException`` (with ``causes`` and ``ctx``) on errors instead of a bare exception. Web request helpers (``gl.nondet.web.get``/``post``/``put``/...) accept a ``sign: bool`` keyword to sign outbound requests with the contract's identity. Environment Detection -~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~ -A new top-level ``gl.IS_IN_VM`` boolean indicates whether code is running inside the GenVM, which is useful for code that is shared between contracts and off-chain tooling. The raw WASI module is available as ``gl.wasi``. +A new top-level ``gl.IS_IN_VM`` boolean indicates whether code is running inside the GenVM, which is useful for code that is shared between contracts and off-chain tooling. The raw WASI module is available as ``gl.wasi``. A ``gl.gvm32`` module provides Crockford Base32 ``encode``/``decode`` helpers (mirroring the Rust ``genlayer_sdk::gvm32`` implementation). Summary of Renames -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 @@ -274,6 +326,10 @@ Summary of Renames - ``gl.vm.trace(...)`` * - ``gl.trace_time_micro()`` - ``gl.vm.trace_time_micro()`` + * - ``gl.vm.run_nondet_unsafe(...)`` + - ``gl.vm.run_nondet(...)`` + * - ``gl.vm.run_nondet(...)`` + - ``gl.vm.run_nondet_default(...)`` * - ``gl.message_raw`` - ``gl.message.raw`` * - ``gl.storage.allow_storage`` diff --git a/doc/website/src/spec/02-execution-environment/02-wasip1.rst b/doc/website/src/spec/02-execution-environment/02-wasip1.rst index 1fd508363..beeabe004 100644 --- a/doc/website/src/spec/02-execution-environment/02-wasip1.rst +++ b/doc/website/src/spec/02-execution-environment/02-wasip1.rst @@ -144,8 +144,10 @@ runs with identical stdin see the same ``random_get`` stream, while differing in produce diverging streams. Non-deterministic randomness MUST be obtained via :ref:`gvm-def-non-det-mode` calls. -Non-deterministic mode: cryptographically secure random number generator, -with optional fallback to pseudo-random numbers, if secure source is exhausted or unavailable. +Non-deterministic mode: a cryptographically secure random number generator. If the +secure source is unavailable or fails, ``random_get`` MUST fail with ``errno::io`` +instead of falling back to a predictable stream (pseudo-random or zeroed output). A +caller that wants a graceful fallback must handle that error explicitly. ``proc_exit`` Function ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/02-gl_call.rst b/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/02-gl_call.rst index 9b8621314..7e100c853 100644 --- a/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/02-gl_call.rst +++ b/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/02-gl_call.rst @@ -179,13 +179,69 @@ Payload { "Sandbox": { - "data": Bytes, // Code/data for sandbox execution - "allow_write_ops": Bool // Whether to allow write operations + "data": Bytes, // Code/data for sandbox execution + "allow_write_storage": Bool, // Whether to allow storage writes + "allow_send_messages": Bool, // Whether to allow sending messages + "allow_register_runners": Bool // Whether to allow registering runners } } Creates isolated VM instance. See :ref:`gvm-permissions` for permission inheritance details. +``RegisterRunner`` Message +-------------------------- + +Registers a runner archive at runtime, making it available under the +``custom:`` runner id. The ```` is the SHA3-256 of the supplied +``code`` encoded with :doc:`../../04-contract-interface/06-gvm32`, and the parsed +archive is charged against the memory limit. Returns the resulting runner id +(calldata-encoded string). + +Payload +~~~~~~~ + +.. code-block:: + + { + "RegisterRunner": { + "code": Bytes // runner archive (ustar/zip or commented text) + } + } + +Requirements +~~~~~~~~~~~~ + +#. :ref:`gvm-perm-deterministic` +#. :ref:`gvm-perm-register-runners` + +``MapFile`` Message +------------------- + +Maps a file from a runner into the VM filesystem at runtime, behaving the same as +the ``MapFile`` runner action (see :doc:`../../../python-sdk` runners). If +``path_in_runner`` ends with ``/`` the whole directory subtree is mapped. + +Payload +~~~~~~~ + +.. code-block:: + + { + "MapFile": { + "runner": String, // runner id (name:hash, contract, chain:..., custom:...) + "path_in_runner": String, // path within the runner archive + "path_in_vfs": String // absolute destination path in the VM filesystem + } + } + +Mapping into ``/vm/`` is forbidden. Resolving a ``chain:`` runner reads another +contract's storage, so this requires :ref:`gvm-perm-read-storage`. + +Requirements +~~~~~~~~~~~~ + +#. :ref:`gvm-perm-read-storage` + ``WebRender`` Message --------------------- @@ -349,11 +405,6 @@ Requirements Topics must be exactly 32 bytes each. -``Rollback`` Message --------------------- - -Deprecated. Use ``UserError`` instead. - ``UserError`` Message --------------------- @@ -422,7 +473,7 @@ Requirements ------------------------------------- In :ref:`gvm-def-non-det-mode` returns the elapsed execution time in microseconds since VM start. -In :ref:`gvm-def-det-mode`, it always returns ``0``. +In :ref:`gvm-def-det-mode`, it returns ``0`` — exposing real elapsed time there would break determinism. The sole exception is the ``unsafe-tracing`` debug level (see the executor "Debug modes" section), which returns real elapsed time even in deterministic mode; that level is for local debugging only and must never be used on a consensus network. Payload ~~~~~~~ @@ -442,3 +493,53 @@ Requirements #. GenVM version 0.1.10 or higher #. :term:`GenVM` implementation is allowed ignore this message + +``Yield`` Message +----------------- + +Cooperative yield. Currently a no-op and returns no value; it is reserved for future use in waiting loops. + +Payload +~~~~~~~ + +.. code-block:: + + { + "Yield": null + } + +.. note:: + + Implementations may choose to ignore this message. + +Requirements +~~~~~~~~~~~~ + +#. GenVM version 0.3.0 or higher +#. :term:`GenVM` implementation is allowed ignore this message + +.. _get-timestamp: + +``GetTimestamp`` Message +------------------------ + +Returns the current timestamp as the number of seconds since the Unix epoch. + +In :ref:`gvm-def-det-mode` it returns the transaction timestamp, keeping the value deterministic across validators. +In :ref:`gvm-def-non-det-mode` it returns the real wall-clock time. + +Payload +~~~~~~~ + +.. code-block:: + + { + "GetTimestamp": null + } + +Returns the timestamp encoded as a :ref:`Calldata Encoded ` number. + +Requirements +~~~~~~~~~~~~ + +#. GenVM version 0.3.0 or higher diff --git a/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/03-schemas.rst b/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/03-schemas.rst index 469f97039..f127af46c 100644 --- a/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/03-schemas.rst +++ b/doc/website/src/spec/02-execution-environment/03-wasi_genlayer_sdk/03-schemas.rst @@ -19,13 +19,13 @@ results through a file descriptor with the following binary format: Where ``result_code`` is a :ref:`gvm-def-enum-result-code`: - :ref:`gvm-def-enum-value-result-code-return` (``0``): Successful execution -- :ref:`gvm-def-enum-value-result-code-user-error` (``1``): Contract-initiated error via ``Rollback`` +- :ref:`gvm-def-enum-value-result-code-user-error` (``1``): Contract-initiated error - :ref:`gvm-def-enum-value-result-code-vm-error` (``2``): VM-level error The ``data`` portion depends on the result code: - **return**: :ref:`Calldata Encoded ` return value -- **user_error**: UTF-8 encoded error message string (from ``Rollback`` message) +- **user_error**: :ref:`Calldata Encoded ` error value - **vm_error**: UTF-8 encoded :ref:`gvm-def-str-trie-vm-error` string .. _gvm-def-module-result-encoding: diff --git a/doc/website/src/spec/02-execution-environment/04-runners.rst b/doc/website/src/spec/02-execution-environment/04-runners.rst index 2ccc54c11..d56882e36 100644 --- a/doc/website/src/spec/02-execution-environment/04-runners.rst +++ b/doc/website/src/spec/02-execution-environment/04-runners.rst @@ -11,34 +11,31 @@ Identification and Packaging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Each :term:`runner` is identified by ``:``. -``human-readable-id`` is provided for convenience. -``hash`` is a sha3-256 hash of its contents +A :term:`runner` is referenced by a runner id, which has one of the following +forms (see the ``runner-id`` definition in the runner.json schema): + +- ``:`` — a packaged runner. ``human-readable-id`` is + provided for convenience; ``hash`` is a hash of its contents (see `Hash Format`_). +- ``contract`` — the runner of the contract currently being executed. +- ``chain:
[:[:]]`` — a runner code blob read from a storage + slot of an arbitrary contract (``a`` = accepted, ``f`` = finalized). ``
`` + is a ``0x`` 20 byte hex address and ```` is a :term:`SlotID` encoded with + :doc:`../../04-contract-interface/06-gvm32`. Both ```` and ```` are + optional: ```` defaults to ``a`` and ```` to the target contract's + root code slot. +- ``custom:`` — a runner registered at runtime via the ``RegisterRunner`` + ``gl_call``, looked up by its hash. + +``contract``, ``chain`` and ``custom`` are reserved prefixes and cannot be used +as human-readable ids. Hash Format ~~~~~~~~~~~ -Hash is SHA3 256-bit hash, converted to a string with following algorithm: - -.. code-block:: python - - def digest_to_hash_id(got_hash: bytes) -> str: - chars = '0123456789abcdfghijklmnpqrsvwxyz' - - bytes_count = len(got_hash) - base32_len = (bytes_count * 8 - 1) // 5 + 1 - - my_hash_arr = [] - for n in range(base32_len - 1, -1, -1): - b = n * 5 - i = b // 8 - j = b % 8 - c = (got_hash[i] >> j) | (0 if i >= bytes_count - 1 else got_hash[i + 1] << (8 - j)) - my_hash_arr.append(chars[c & 0x1F]) - - return ''.join(my_hash_arr) - -This ensures that it contains no fs-illegal characters and is case insensitive. +``hash`` is the SHA3 256-bit hash of the runner's contents, encoded with +:doc:`../../04-contract-interface/06-gvm32` (GVM32, a lowercase Crockford +Base32). This keeps it free of filesystem-illegal characters and +case-insensitive. Runner Layout ------------- diff --git a/doc/website/src/spec/03-vm/05-permissions.rst b/doc/website/src/spec/03-vm/05-permissions.rst index ec7e18ada..1435ec1d1 100644 --- a/doc/website/src/spec/03-vm/05-permissions.rst +++ b/doc/website/src/spec/03-vm/05-permissions.rst @@ -28,6 +28,8 @@ Allows reading contract storage slots. When unset, any attempt to read storage w Allows writing to contract storage slots. Requires :ref:`gvm-perm-deterministic` as well. +This permission also gates ``EmitEvent``: a VM may emit events *iff* it can write storage, since events are state-mutating log emissions. Consequently a read-only (static) context, such as a ``CallContract`` child, cannot emit events. + .. _gvm-perm-send-messages: ``send_messages`` @@ -51,6 +53,14 @@ Requires :ref:`gvm-perm-deterministic` as well. Allows spawning :ref:`gvm-def-non-det-mode` :term:`sub-VM` instances via ``RunNondet``. +.. _gvm-perm-register-runners: + +``register_runners`` +-------------------- + +Allows registering runner archives at runtime via ``RegisterRunner``, making +them available under ``custom:`` runner ids. Requires :ref:`gvm-perm-deterministic` as well. + Permission Changes on Sub-VM Creation -------------------------------------- @@ -59,9 +69,12 @@ Different operations modify permissions when creating child :term:`sub-VM` insta ``CallContract`` ~~~~~~~~~~~~~~~~ -Inherits all parent permissions except: +A ``CallContract`` child runs as a read-only (static) call. It inherits all parent permissions except: - :ref:`gvm-perm-write-storage` is **disabled** +- :ref:`gvm-perm-send-messages` is **disabled** + +A static call must not produce externally visible effects, so storage writes, message sends, and event emissions all fail: emitting an event additionally requires :ref:`gvm-perm-write-storage` (disabled here). Allowing any such emission would charge fees for effects that are discarded together with the child VM. ``RunNondet`` ~~~~~~~~~~~~~ @@ -74,6 +87,7 @@ The non-deterministic :term:`sub-VM` has: - :ref:`gvm-perm-spawn-nondet` is **disabled** - :ref:`gvm-perm-call-others` is **disabled** - :ref:`gvm-perm-send-messages` is **disabled** +- :ref:`gvm-perm-register-runners` is **disabled** ``Sandbox`` ~~~~~~~~~~~ @@ -82,7 +96,8 @@ The sandboxed :term:`sub-VM` has: - :ref:`gvm-perm-deterministic` is **inherited** - :ref:`gvm-perm-read-storage` is **inherited** -- :ref:`gvm-perm-write-storage` is **inherited** if ``allow_write_ops`` is set, otherwise **disabled** +- :ref:`gvm-perm-write-storage` is **inherited** *iff* ``allow_write_storage`` is set, otherwise **disabled** - :ref:`gvm-perm-spawn-nondet` is **disabled** - :ref:`gvm-perm-call-others` is **disabled** -- :ref:`gvm-perm-send-messages` is **inherited** if ``allow_write_ops`` is set, otherwise **disabled** +- :ref:`gvm-perm-send-messages` is **inherited** *iff* ``allow_send_messages`` is set, otherwise **disabled** +- :ref:`gvm-perm-register-runners` is **inherited** *iff* ``allow_register_runners`` is set, otherwise **disabled** diff --git a/doc/website/src/spec/04-contract-interface/03-storage.rst b/doc/website/src/spec/04-contract-interface/03-storage.rst index 07ee1014c..58182d53b 100644 --- a/doc/website/src/spec/04-contract-interface/03-storage.rst +++ b/doc/website/src/spec/04-contract-interface/03-storage.rst @@ -44,19 +44,29 @@ Root Slot the following data: -- ``contract_instance``: (offset 0) Reference to the contract instance data. -- ``code``: (offset 1) The contract's code. Slot contains 4 bytes little-endian length followed by data -- ``locked_slots``: (offset 2) A list of storage :term:`SlotID`\s that cannot be modified by non-upgraders. - Slot contains 4 bytes little-endian length followed length arrays of 32 byte :term:`SlotID`\s -- ``upgraders``: (offset 3) A list of addresses that are authorized to modify the contract code and locked slots. - Slot contains 4 bytes little-endian length followed length arrays of 20 byte addresses -- ``major``: (offset 4) Single octet (``u8``) identifying the major version of the public ABI +- ``major``: (offset 0) Single octet (``u8``) identifying the major version of the public ABI that the contract was built against. It is written at deploy time (the value is detected from the contract package — see :doc:`04-upgradability` and the impl-spec for the detection flow) and read on every load so :term:`GenVM` can refuse to execute a contract whose public ABI major does not match the host's ``CURRENT_MAJOR``. - -Offsets at and above ``5`` are unused by :term:`GenVM` itself and are available to the contract -runtime for bootstrapping its own storage (see ``Root.get_vacant_slot`` in the Python SDK). +- ``contract_instance``: (offset 1) Reference to the contract instance data. +- ``code``: (offset 2) The contract's code. Slot contains 4 bytes little-endian length followed by data +- ``locked_slots``: (offset 3) A list of storage :term:`SlotID`\s that cannot be modified by non-upgraders. + Slot contains 4 bytes little-endian length followed length arrays of 32 byte :term:`SlotID`\s +- ``upgraders``: (offset 4) A list of addresses that are authorized to modify the contract code and locked slots. + Slot contains 4 bytes little-endian length followed length arrays of 20 byte addresses +- ``code_slot``: (offset 5) A raw 32-byte :term:`SlotID`. If it is all-zero (the default), + the contract code is read from the ``code`` slot (offset 2); otherwise the code is read from + the slot it points to (same 4-byte-length-prefixed layout). This lets a contract serve its + code from an arbitrary slot, including one shared via a ``chain:
::`` runner id. + +Offsets are byte offsets into the root slot, so ``code_slot`` (32 bytes) occupies offsets ``5`` +through ``36``; the next field would start at offset ``37``. + +Offsets at and above ``37`` are reserved for future :term:`GenVM` use and should remain zero: +a contract must not store data in them, otherwise a future :term:`GenVM` version that starts +reading those offsets may break the contract. Contract runtimes that need scratch space for +bootstrapping should derive a separate sub-slot instead (see ``Root.get_vacant_slot`` in the +Python SDK). Upgrade permissions and slot locking are described in :doc:`04-upgradability`. diff --git a/doc/website/src/spec/04-contract-interface/04-upgradability.rst b/doc/website/src/spec/04-contract-interface/04-upgradability.rst index e27226018..f75607c6e 100644 --- a/doc/website/src/spec/04-contract-interface/04-upgradability.rst +++ b/doc/website/src/spec/04-contract-interface/04-upgradability.rst @@ -47,7 +47,7 @@ Sub-VMs created by ``Sandbox`` and ``RunNondet`` cannot reach storage at all Contract Major Version ---------------------- -The ``major`` field of :ref:`genvm-def-root-slot` (offset 4) stores the public-ABI major version +The ``major`` field of :ref:`genvm-def-root-slot` (offset 0) stores the public-ABI major version that the contract was built against. On every load :term:`GenVM` compares this byte to its own ``CURRENT_MAJOR`` constant and refuses to execute a contract whose major differs. diff --git a/doc/website/src/spec/04-contract-interface/05-execution-flow.rst b/doc/website/src/spec/04-contract-interface/05-execution-flow.rst index 72208c602..5ba584229 100644 --- a/doc/website/src/spec/04-contract-interface/05-execution-flow.rst +++ b/doc/website/src/spec/04-contract-interface/05-execution-flow.rst @@ -79,3 +79,19 @@ Extended-Message Format pub entry_stage_data: calldata::Value, } + +``CallContract`` semantics +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``CallContract`` performs a read-only (view) call into another contract. It **preserves** ``sender_address`` and ``origin_address``: the callee observes the *same* ``sender_address`` as the caller did, **not** the address of the immediate caller. + +The immediate caller — the contract that issued the ``CallContract`` — is pushed onto ``stack`` instead, so the callee always sees it as ``stack[-1]`` (the last element). For the top-level entrypoint ``stack`` is empty (refer to ``contract_address``); each nested ``CallContract`` appends one entry. + +Therefore a callee that needs to authorize its *immediate* caller MUST inspect ``stack[-1]`` rather than ``sender_address`` — the latter identifies the original transaction sender shared across the whole view-call chain. + +State visibility +"""""""""""""""" + +A ``CallContract`` child reads **committed** on-chain storage (the latest accepted / non-final state); it does **not** see the calling transaction's uncommitted writes. Consequently a contract does not observe its own in-transaction storage delta through a ``CallContract`` — including a self-call ``get_at(self.address)`` — even though a *direct* read does. + +This is intentional: it preserves causality and avoids exposing stale-then-fresh reads within one call. It is also a footgun: relying on a self-``CallContract`` to read state written earlier in the same transaction returns the old value. Use direct reads for in-transaction data, and treat ``get_at(self.address)`` as a read of the committed snapshot only. diff --git a/doc/website/src/spec/04-contract-interface/06-gvm32.rst b/doc/website/src/spec/04-contract-interface/06-gvm32.rst new file mode 100644 index 000000000..dd658944a --- /dev/null +++ b/doc/website/src/spec/04-contract-interface/06-gvm32.rst @@ -0,0 +1,68 @@ +GVM32 (Base32) +============== + +:term:`GenVM` encodes hash-like binary values — runner content hashes, +``custom:`` ids and :term:`SlotID`\s — as text using **GVM32**, a variant +of `Crockford's Base32 `_. + +Alphabet +-------- + +The 32-symbol alphabet is:: + + 0123456789abcdefghjkmnpqrstvwxyz + +That is, the digits ``0`` -- ``9`` followed by the lowercase letters ``a`` -- ``z`` with +``i``, ``l``, ``o`` and ``u`` removed. The symbol at index ``v`` (``0 <= v < 32``) +encodes the 5-bit value ``v``. + +Encoding +-------- + +The input is treated as a big-endian bit stream (the most significant bit of the +first octet first). It is split into groups of 5 bits, each group emitted as the +alphabet symbol for its value. If the final group has fewer than 5 bits it is +padded on the **low** side with zero bits. There is **no** ``=`` padding. + +An input of ``N`` octets therefore produces ``ceil(N * 8 / 5)`` symbols. The +canonical (and default) encoding is **lowercase**. + +.. code-block:: python + + ALPHABET = '0123456789abcdefghjkmnpqrstvwxyz' + + def encode(data: bytes) -> str: + out = [] + value = bits = 0 + for byte in data: + value = (value << 8) | byte + bits += 8 + while bits >= 5: + bits -= 5 + out.append(ALPHABET[(value >> bits) & 0x1F]) + if bits > 0: + out.append(ALPHABET[(value << (5 - bits)) & 0x1F]) + return ''.join(out) + +Decoding +-------- + +Decoding is **case-insensitive**. Following Crockford's rules, the letters ``i`` +and ``l`` (and ``I``, ``L``) are read as ``1`` and ``o`` (and ``O``) as ``0``. +Hyphens (``-``) may appear for readability and are ignored. Any other character +makes the string invalid. + +The 5-bit values are concatenated big-endian; every full group of 8 bits is one +output octet. A well-formed string has its trailing (sub-octet) bits all zero — +a decoder must reject a string whose leftover bits are non-zero. + +Usage +----- + +- **Runner content hashes** — the ``hash`` component of a ``name:hash`` runner id + (see :doc:`../02-execution-environment/04-runners`) is the GVM32 encoding of the + runner archive's hash. +- **Custom runner ids** — ``custom:`` where ```` is the GVM32 encoding + of the SHA3-256 of the registered code. +- **Slot ids** — a :term:`SlotID` is rendered in GVM32, including the ```` + component of a ``chain:
::`` runner id. diff --git a/doc/website/src/spec/04-contract-interface/index.rst b/doc/website/src/spec/04-contract-interface/index.rst index 5d468c7fe..8ef110031 100644 --- a/doc/website/src/spec/04-contract-interface/index.rst +++ b/doc/website/src/spec/04-contract-interface/index.rst @@ -11,3 +11,4 @@ Interfaces and protocols for contract interaction and data management. 03-storage 04-upgradability 05-execution-flow + 06-gvm32 diff --git a/doc/website/src/spec/appendix/constants.rst b/doc/website/src/spec/appendix/constants.rst new file mode 100644 index 000000000..0a4140517 --- /dev/null +++ b/doc/website/src/spec/appendix/constants.rst @@ -0,0 +1,384 @@ +Constants +========= + +.. _gvm-def-enum-result-code: + +result_code +----------- + +Type: u8 + +.. _gvm-def-enum-value-result-code-return: + +return +~~~~~~ + +Value: ``0`` + +.. _gvm-def-enum-value-result-code-user-error: + +user_error +~~~~~~~~~~ + +Value: ``1`` + +.. _gvm-def-enum-value-result-code-vm-error: + +vm_error +~~~~~~~~ + +Value: ``2`` + +.. _gvm-def-enum-value-result-code-internal-error: + +internal_error +~~~~~~~~~~~~~~ + +Value: ``3`` + +.. _gvm-def-enum-storage-type: + +storage_type +------------ + +Type: u8 + +.. _gvm-def-enum-value-storage-type-default: + +default +~~~~~~~ + +Value: ``0`` + +.. _gvm-def-enum-value-storage-type-latest-final: + +latest_final +~~~~~~~~~~~~ + +Value: ``1`` + +.. _gvm-def-enum-value-storage-type-latest-non-final: + +latest_non_final +~~~~~~~~~~~~~~~~ + +Value: ``2`` + +.. _gvm-def-enum-entry-kind: + +entry_kind +---------- + +Type: u8 + +.. _gvm-def-enum-value-entry-kind-main: + +main +~~~~ + +Value: ``0`` + +.. _gvm-def-enum-value-entry-kind-sandbox: + +sandbox +~~~~~~~ + +Value: ``1`` + +.. _gvm-def-enum-value-entry-kind-consensus-stage: + +consensus_stage +~~~~~~~~~~~~~~~ + +Value: ``2`` + +.. _gvm-def-consts-memory-limiter-consts: + +memory_limiter_consts +--------------------- + +Type: u32 + +.. _gvm-def-consts-value-memory-limiter-consts-table-entry: + +table_entry +~~~~~~~~~~~ + +Value: ``64`` + +.. _gvm-def-consts-value-memory-limiter-consts-file-mapping: + +file_mapping +~~~~~~~~~~~~ + +Value: ``256`` + +.. _gvm-def-consts-value-memory-limiter-consts-fd-allocation: + +fd_allocation +~~~~~~~~~~~~~ + +Value: ``96`` + +.. _gvm-def-consts-root-offsets: + +root_offsets +------------ + +Type: u32 + +.. _gvm-def-consts-value-root-offsets-major: + +major +~~~~~ + +Value: ``0`` + +.. _gvm-def-consts-value-root-offsets-contract: + +contract +~~~~~~~~ + +Value: ``1`` + +.. _gvm-def-consts-value-root-offsets-code: + +code +~~~~ + +Value: ``2`` + +.. _gvm-def-consts-value-root-offsets-locked-slots: + +locked_slots +~~~~~~~~~~~~ + +Value: ``3`` + +.. _gvm-def-consts-value-root-offsets-upgraders: + +upgraders +~~~~~~~~~ + +Value: ``4`` + +.. _gvm-def-consts-value-root-offsets-code-slot: + +code_slot +~~~~~~~~~ + +Value: ``5`` + +.. _gvm-def-consts-top-limits: + +top_limits +---------- + +Type: u32 + +.. _gvm-def-consts-value-top-limits-nondet-blocks: + +nondet_blocks +~~~~~~~~~~~~~ + +Value: ``4096`` + +.. _gvm-def-consts-value-top-limits-locked-slots: + +locked_slots +~~~~~~~~~~~~ + +Value: ``256`` + +.. _gvm-def-consts-value-top-limits-upgraders: + +upgraders +~~~~~~~~~ + +Value: ``32`` + +.. _gvm-def-consts-value-top-limits-vm-recursion: + +vm_recursion +~~~~~~~~~~~~ + +Value: ``512`` + +.. _gvm-def-consts-value-top-limits-web-request-min-space: + +web_request_min_space +~~~~~~~~~~~~~~~~~~~~~ + +Value: ``65536`` + +.. _gvm-def-consts-value-top-limits-web-render-min-space: + +web_render_min_space +~~~~~~~~~~~~~~~~~~~~ + +Value: ``134217728`` + +.. _gvm-def-consts-value-top-limits-max-fds: + +max_fds +~~~~~~~ + +Value: ``1024`` + +.. _gvm-def-enum-special-method: + +special_method +-------------- + +Type: str + +.. _gvm-def-enum-value-special-method-get-schema: + +get_schema +~~~~~~~~~~ + +Value: ``#get-schema`` + +.. _gvm-def-enum-value-special-method-errored-message: + +errored_message +~~~~~~~~~~~~~~~ + +Value: ``#error`` + +.. _gvm-def-str-trie-vm-error: + +vm_error +-------- + +Type: str_trie + +.. _gvm-def-str-trie-value-vm-error-timeout: + +``timeout`` +~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-absent-leader-nondet-output: + +``absent_leader_nondet_output`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-exit-code: + +``exit_code`` +~~~~~~~~~~~~~ + +Param: i32 + +.. _gvm-def-str-trie-value-vm-error-wasm-trap: + +``wasm_trap`` +~~~~~~~~~~~~~ + +Param: str + +.. _gvm-def-str-trie-value-vm-error-OOM-RAM: + +``OOM RAM`` +~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-RAM-table: + +``OOM RAM table`` +~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-RAM-memory: + +``OOM RAM memory`` +~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-RAM-limit: + +``OOM RAM limit`` +~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-storage: + +``OOM storage`` +~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-receipt-nondet-output: + +``OOM receipt nondet_output`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-receipt-message-internal: + +``OOM receipt message internal`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-receipt-message-external: + +``OOM receipt message external`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-fees-internal: + +``OOM fees internal`` +~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-OOM-fees-external: + +``OOM fees external`` +~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract: + +``invalid_contract`` +~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract-absent-runner-comment: + +``invalid_contract absent_runner_comment`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract-not-utf8-text: + +``invalid_contract not_utf8_text`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract-malformed-runner: + +``invalid_contract malformed_runner`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract-major-mismatch: + +``invalid_contract major_mismatch`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract-wasm-validating: + +``invalid_contract wasm validating`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract-wasm-linking: + +``invalid_contract wasm linking`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-invalid-contract-wasm-entrypoint: + +``invalid_contract wasm entrypoint`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _gvm-def-str-trie-value-vm-error-host: + +``host`` +~~~~~~~~ + +Param: str + +.. _gvm-def-const-event-max-topics: + +event_max_topics +---------------- + +Type: u32 + +Value: ``4`` diff --git a/executor/Cargo.lock b/executor/Cargo.lock index aa0cca546..a347bf38a 100644 --- a/executor/Cargo.lock +++ b/executor/Cargo.lock @@ -958,6 +958,7 @@ dependencies = [ "num-bigint", "primitive-types", "serde", + "sha3", ] [[package]] @@ -1026,7 +1027,6 @@ dependencies = [ "serde_with", "serde_yaml", "sha3", - "signal-hook", "symbol_table", "tokio", "tokio-mpmc", @@ -1044,7 +1044,7 @@ dependencies = [ [[package]] name = "genvm-common" -version = "0.1.0" +version = "0.3.0" dependencies = [ "anyhow", "arbitrary", @@ -1066,6 +1066,7 @@ dependencies = [ "rpds", "rustix 0.38.44", "serde", + "serde_bytes", "serde_json", "serde_yaml", "symbol_table", @@ -2141,16 +2142,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" version = "1.4.2" diff --git a/executor/Cargo.toml b/executor/Cargo.toml index c7a49b2ae..6814eeb25 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -49,7 +49,6 @@ clap = { version = "4.5.35", features = ["derive"] } serde_with = { version = "3.12.0", features = ["base64"] } itertools = "0.14.0" zip = "4.0.0" -signal-hook = "0.3.17" once_cell = "1.21.3" chrono = { version = "0.4.41", default-features = false, features = ["clock", "std", "serde"] } base64 = "0.22.1" diff --git a/executor/codegen/data/public-abi.json b/executor/codegen/data/public-abi.json index 9d49a4582..ad7993c6c 100644 --- a/executor/codegen/data/public-abi.json +++ b/executor/codegen/data/public-abi.json @@ -45,11 +45,12 @@ "name": "root_offsets", "repr": "u32", "values": { - "contract": 0, - "code": 1, - "locked_slots": 2, - "upgraders": 3, - "major": 4 + "major": 0, + "contract": 1, + "code": 2, + "locked_slots": 3, + "upgraders": 4, + "code_slot": 5 } }, { @@ -122,6 +123,7 @@ "absent_runner_comment", "not_utf8_text", "malformed_runner", + "major_mismatch", { "head": "wasm", "tail": ["validating", "linking", "entrypoint"] diff --git a/executor/codegen/templates/rs.rb b/executor/codegen/templates/rs.rb index dbdb78234..a058f763e 100755 --- a/executor/codegen/templates/rs.rb +++ b/executor/codegen/templates/rs.rb @@ -130,9 +130,9 @@ def gen_rust_trie_builder(entries, root_name, buf) buf << "#[derive(Debug, Clone, PartialEq, Eq, Serialize)]\n" buf << "pub struct #{root_name}(pub Cow<'static, str>);\n\n" - buf << "impl Into for #{root_name} {\n" - buf << " fn into(self) -> String {\n" - buf << " self.0.into()\n" + buf << "impl From<#{root_name}> for String {\n" + buf << " fn from(val: #{root_name}) -> String {\n" + buf << " val.0.into()\n" buf << " }\n" buf << "}\n" buf << "#[rustfmt::skip]\n" diff --git a/executor/crates/calldata/Cargo.lock b/executor/crates/calldata/Cargo.lock index 434876756..5d204f1f7 100644 --- a/executor/crates/calldata/Cargo.lock +++ b/executor/crates/calldata/Cargo.lock @@ -53,6 +53,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.20.2" @@ -136,12 +145,41 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crunchy" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -172,6 +210,16 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "genlayer_calldata" version = "0.0.2" @@ -185,6 +233,7 @@ dependencies = [ "num-bigint", "primitive-types", "serde", + "sha3", ] [[package]] @@ -301,6 +350,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + [[package]] name = "libc" version = "0.2.183" @@ -523,6 +581,16 @@ dependencies = [ "syn", ] +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "shlex" version = "1.3.0" @@ -582,6 +650,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + [[package]] name = "uint" version = "0.10.0" @@ -606,6 +680,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" diff --git a/executor/crates/calldata/Cargo.toml b/executor/crates/calldata/Cargo.toml index 6d439c06a..78b591c35 100644 --- a/executor/crates/calldata/Cargo.toml +++ b/executor/crates/calldata/Cargo.toml @@ -30,6 +30,7 @@ arbitrary = ["dep:arbitrary"] genlayer_calldata_derive = { path = "../calldata-derive" } hex = "0.4.3" num-bigint = {version = "0.4.6", features = ["serde"] } +sha3 = { version = "0.10" } serde = { version = "1.0", features = ["derive"] } arbitrary = { version = "1.0", optional = true } primitive-types = { version = "0.13", features = ["impl-serde"] } @@ -38,3 +39,4 @@ chrono = { version = "0.4", features = ["serde"] } [dev-dependencies] afl = { version = "0.15.18", features = ["no_cfg_fuzzing"] } +hex = "0.4.3" diff --git a/executor/crates/calldata/src/types.rs b/executor/crates/calldata/src/types.rs index 3329f449b..f94215d50 100644 --- a/executor/crates/calldata/src/types.rs +++ b/executor/crates/calldata/src/types.rs @@ -7,13 +7,13 @@ pub struct Address(pub(super) [u8; ADDRESS_SIZE]); impl std::fmt::Debug for Address { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!("addr#{}", hex::encode(self.0))) + f.write_fmt(format_args!("addr#{}", self.checksum_hex_string())) } } impl std::fmt::Display for Address { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "addr#{}", hex::encode(self.0)) + f.write_fmt(format_args!("addr#{}", self.checksum_hex_string())) } } @@ -37,6 +37,37 @@ impl Address { self.0 } + /// Returns the address as an [EIP-55](https://eips.ethereum.org/EIPS/eip-55) + /// mixed-case checksummed hex, as 40 ASCII bytes (no `0x` prefix). + pub fn checksum_hex(self) -> [u8; 40] { + use sha3::Digest as _; + + const HEX: &[u8; 16] = b"0123456789abcdef"; + let mut out = [0u8; 40]; + for (i, &b) in self.0.iter().enumerate() { + out[i * 2] = HEX[(b >> 4) as usize]; + out[i * 2 + 1] = HEX[(b & 0x0f) as usize]; + } + + // hash of the lowercase hex; a hex letter is upper-cased when the + // matching hash nibble is >= 8 + let hash = sha3::Keccak256::digest(out); + for i in 0..out.len() { + if out[i].is_ascii_alphabetic() { + let nibble = hash[i / 2] >> (if i % 2 == 0 { 4 } else { 0 }) & 0x0f; + if nibble >= 8 { + out[i] = out[i].to_ascii_uppercase(); + } + } + } + out + } + + /// Like [`Address::checksum_hex`], but as an owned `String`. + pub fn checksum_hex_string(self) -> String { + self.checksum_hex().iter().map(|&b| b as char).collect() + } + pub fn ref_mut(&mut self) -> &mut [u8; ADDRESS_SIZE] { &mut self.0 } diff --git a/executor/crates/calldata/tests/address_checksum.rs b/executor/crates/calldata/tests/address_checksum.rs new file mode 100644 index 000000000..287932b87 --- /dev/null +++ b/executor/crates/calldata/tests/address_checksum.rs @@ -0,0 +1,22 @@ +use genlayer_calldata::Address; + +fn addr(lower_hex: &str) -> Address { + let mut b = [0u8; 20]; + hex::decode_to_slice(lower_hex, &mut b).unwrap(); + Address::from(b) +} + +#[test] +fn eip55_checksum() { + // vectors from EIP-55 (https://eips.ethereum.org/EIPS/eip-55) + for expected in [ + "5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", + "fB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", + "dbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", + "D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", + ] { + let a = addr(&expected.to_lowercase()); + assert_eq!(a.checksum_hex().as_slice(), expected.as_bytes()); + assert_eq!(a.checksum_hex_string(), expected); + } +} diff --git a/executor/crates/common/Cargo.lock b/executor/crates/common/Cargo.lock index e27cb8e67..68c55320b 100644 --- a/executor/crates/common/Cargo.lock +++ b/executor/crates/common/Cargo.lock @@ -485,6 +485,7 @@ dependencies = [ "num-bigint", "primitive-types", "serde", + "sha3", ] [[package]] @@ -514,7 +515,7 @@ dependencies = [ [[package]] name = "genvm-common" -version = "0.1.0" +version = "0.3.0" dependencies = [ "anyhow", "arbitrary", diff --git a/executor/crates/common/Cargo.toml b/executor/crates/common/Cargo.toml index d1ff41dfb..76418ca91 100644 --- a/executor/crates/common/Cargo.toml +++ b/executor/crates/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "genvm-common" -version = "0.1.0" +version = "0.3.0" edition = "2021" [profile.release] @@ -16,6 +16,7 @@ regex = "1.11.1" serde = { version = "1.0.219", features = ["derive", "rc"] } serde_json = "1.0.140" serde_yaml = "0.9.34" +serde_bytes = "0.11.17" tokio = { version = "1.44.1", features = ["rt", "rt-multi-thread", "net", "time", "macros", "sync"], default-features = false} num-bigint = { version = "0.4.6", features = ["serde"] } num-rational = { version = "0.4", default-features = false, features = ["num-bigint"] } diff --git a/executor/crates/common/build.rs b/executor/crates/common/build.rs index b55b44a33..609fd1368 100644 --- a/executor/crates/common/build.rs +++ b/executor/crates/common/build.rs @@ -16,7 +16,7 @@ fn main() -> std::io::Result<()> { let profile = std::env::var("PROFILE").unwrap(); println!("cargo::rustc-env=PROFILE={profile}"); - let tag = tag.replace("-", "_"); + // tag can have `-`, parse from the right let arch = arch.replace("-", "_"); let os = os.replace("-", "_"); let profile = profile.replace("-", "_"); diff --git a/executor/crates/common/src/bytes32.rs b/executor/crates/common/src/bytes32.rs new file mode 100644 index 000000000..a3d9223ff --- /dev/null +++ b/executor/crates/common/src/bytes32.rs @@ -0,0 +1,109 @@ +//! A 32-byte hash (runner content hash, `custom:` hash, …) with GVM32 formatting. + +/// A 32-byte hash value. Formats (and parses) as GVM32 / Crockford Base32 (see +/// [`genlayer_sdk::gvm32`]). +#[derive( + Clone, + Copy, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + serde::Serialize, + serde::Deserialize, + genlayer_calldata::Encode, + genlayer_calldata::Decode, + arbitrary::Arbitrary, +)] +#[repr(transparent)] +pub struct Bytes32Hash( + #[serde(with = "serde_bytes")] + #[calldata( + serialize_with = genlayer_calldata::codec::as_bytes::serialize, + deserialize_with = genlayer_calldata::codec::as_bytes::deserialize, + )] + pub [u8; 32], +); + +impl Bytes32Hash { + pub const ZERO: Self = Self([0; 32]); + + pub const fn from_bytes(bytes: [u8; 32]) -> Self { + Self(bytes) + } + + pub fn as_bytes(&self) -> &[u8; 32] { + &self.0 + } + + pub fn raw(&self) -> [u8; 32] { + self.0 + } + + /// The GVM32 (Crockford Base32) textual form. + pub fn to_gvm32(&self) -> String { + genlayer_sdk::gvm32::encode(&self.0) + } + + /// Parses a hash from its GVM32 form. + /// + /// Fails with [`FromGvm32Error::InvalidEncoding`] for a malformed encoding or + /// [`FromGvm32Error::WrongLength`] for one that does not decode to exactly 32 + /// bytes. + pub fn from_gvm32(s: &str) -> Result { + let bytes = genlayer_sdk::gvm32::decode(s).map_err(FromGvm32Error::InvalidEncoding)?; + let got = bytes.len(); + let bytes: [u8; 32] = bytes + .try_into() + .map_err(|_| FromGvm32Error::WrongLength { got })?; + Ok(Self(bytes)) + } +} + +/// Error returned by [`Bytes32Hash::from_gvm32`]. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum FromGvm32Error { + /// The string is not valid GVM32. + InvalidEncoding(genlayer_sdk::gvm32::DecodeError), + /// Decoded successfully, but not to exactly 32 bytes. + WrongLength { got: usize }, +} + +impl std::fmt::Display for FromGvm32Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FromGvm32Error::InvalidEncoding(e) => write!(f, "invalid gvm32 encoding: {e}"), + FromGvm32Error::WrongLength { got } => { + write!(f, "expected 32 bytes, got {got}") + } + } + } +} + +impl std::error::Error for FromGvm32Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + FromGvm32Error::InvalidEncoding(e) => Some(e), + FromGvm32Error::WrongLength { .. } => None, + } + } +} + +impl From<[u8; 32]> for Bytes32Hash { + fn from(bytes: [u8; 32]) -> Self { + Self(bytes) + } +} + +impl std::fmt::Display for Bytes32Hash { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.to_gvm32()) + } +} + +impl std::fmt::Debug for Bytes32Hash { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("hash#{}", self.to_gvm32())) + } +} diff --git a/executor/crates/common/src/debug_mode.rs b/executor/crates/common/src/debug_mode.rs new file mode 100644 index 000000000..0aee8c128 --- /dev/null +++ b/executor/crates/common/src/debug_mode.rs @@ -0,0 +1,100 @@ +use serde::{Deserialize, Serialize}; + +/// How the manager captures a per-execution's logs and stdout/stderr. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum Capture { + /// Nothing is captured: stdout/stderr go to `/dev/null` and logs are routed + /// to the manager's own log. + #[default] + Disabled, + /// Captured, but bounded: the oldest log entries are dropped past a cap and + /// stdout/stderr are truncated to a tail. + Bounded, + /// Captured in full. + Unbounded, +} + +/// Executor debug level. Levels are ordered and each *adds* to the previous one. +/// +/// - `Disabled`: production. No capture, no debug aids. +/// - `Safe`: captures logs and stdout/stderr (bounded). Deterministic. +/// - `SafeUnbounded`: capture is unbounded and `Trace` gl_call output is emitted. +/// Deterministic. +/// - `Unsafe`: also resolves the `:latest` / `:test` runner ids. This is +/// *unsafe across machines* — different nodes may resolve different code — so +/// it can diverge consensus, but a single node stays deterministic. +/// - `UnsafeTracing`: also exposes real wall-clock time to the contract +/// (`RuntimeMicroSec`). This can break determinism even on a single machine. +/// Local debugging only. +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + clap::ValueEnum, + Serialize, + Deserialize, + ::genlayer_calldata::Encode, + ::genlayer_calldata::Decode, +)] +#[clap(rename_all = "kebab-case")] +#[serde(rename_all = "kebab-case")] +pub enum DebugMode { + #[default] + #[calldata(rename = "disabled")] + Disabled, + #[calldata(rename = "safe")] + Safe, + #[calldata(rename = "safe-unbounded")] + SafeUnbounded, + #[calldata(rename = "unsafe")] + Unsafe, + #[calldata(rename = "unsafe-tracing")] + UnsafeTracing, +} + +impl DebugMode { + /// How the manager should capture logs and stdout/stderr. + pub fn capture(self) -> Capture { + match self { + DebugMode::Disabled => Capture::Disabled, + DebugMode::Safe => Capture::Bounded, + DebugMode::SafeUnbounded | DebugMode::Unsafe | DebugMode::UnsafeTracing => { + Capture::Unbounded + } + } + } + + /// `SafeUnbounded`+: emit `Trace` gl_call output instead of skipping it. + pub fn allows_tracing(self) -> bool { + self >= DebugMode::SafeUnbounded + } + + /// `Unsafe`+: the `:latest` / `:test` runner ids may be resolved. Unsafe + /// across machines (consensus may diverge). + pub fn allows_latest_resolution(self) -> bool { + self >= DebugMode::Unsafe + } + + /// `UnsafeTracing`: exposes non-deterministic data to the contract, such as + /// real wall-clock time metering. Can break determinism on a single machine. + pub fn allows_nondeterminism(self) -> bool { + self >= DebugMode::UnsafeTracing + } + + /// CLI value passed to the executor's `--debug-mode` flag. + pub fn as_arg(self) -> &'static str { + match self { + DebugMode::Disabled => "disabled", + DebugMode::Safe => "safe", + DebugMode::SafeUnbounded => "safe-unbounded", + DebugMode::Unsafe => "unsafe", + DebugMode::UnsafeTracing => "unsafe-tracing", + } + } +} diff --git a/executor/crates/common/src/lib.rs b/executor/crates/common/src/lib.rs index c4e6132cc..ed150c507 100644 --- a/executor/crates/common/src/lib.rs +++ b/executor/crates/common/src/lib.rs @@ -5,7 +5,12 @@ use serde::{Deserialize, Serialize}; pub use genlayer_sdk::calldata; +pub mod bytes32; +pub use bytes32::Bytes32Hash; + pub mod cancellation; +pub mod debug_mode; +pub use debug_mode::DebugMode; pub mod io; pub mod logger; pub mod stats; diff --git a/executor/crates/common/src/sync.rs b/executor/crates/common/src/sync.rs index 4f5593eca..2159e512f 100644 --- a/executor/crates/common/src/sync.rs +++ b/executor/crates/common/src/sync.rs @@ -444,6 +444,11 @@ impl CacheMap { Self(dashmap::DashMap::new()) } + pub fn insert(&self, key: symbol_table::GlobalSymbol, value: T) { + self.0 + .insert(key, DArc::new(tokio::sync::OnceCell::new_with(Some(value)))); + } + pub async fn get_or_create( &self, key: symbol_table::GlobalSymbol, diff --git a/executor/crates/common/src/version.rs b/executor/crates/common/src/version.rs index 647d77ec4..c344f56b7 100644 --- a/executor/crates/common/src/version.rs +++ b/executor/crates/common/src/version.rs @@ -71,24 +71,81 @@ impl Version { } } -pub static CURRENT: std::sync::LazyLock = std::sync::LazyLock::new(|| { - if crate::VERSION.starts_with("vTEST") { +/// Parses a `u16` starting at `i`, returning the value and the index past the +/// last digit consumed. +const fn parse_u16(s: &[u8], mut i: usize) -> (u16, usize, bool) { + let mut n: u16 = 0; + let mut consumed = false; + while i < s.len() && s[i] >= b'0' && s[i] <= b'9' { + n = n * 10 + (s[i] - b'0') as u16; + i += 1; + consumed = true; + } + (n, i, consumed) +} + +const fn const_starts_with(s: &[u8], prefix: &[u8]) -> bool { + if s.len() < prefix.len() { + return false; + } + let mut i = 0; + while i < prefix.len() { + if s[i] != prefix[i] { + return false; + } + i += 1; + } + true +} + +const fn current_version() -> Version { + if const_starts_with(crate::VERSION.as_bytes(), b"vTEST") { + // vTEST has no numeric build id, so report this crate's compile-time + // version (kept at the active dev major/minor via `.genvm-monorepo-root`) + // with a max patch so it sorts newer than any real release of that line. + let pkg = env!("CARGO_PKG_VERSION").as_bytes(); + let (major, i, ok_major) = parse_u16(pkg, 0); + if !ok_major || i >= pkg.len() || pkg[i] != b'.' { + panic!("invalid CARGO_PKG_VERSION: missing major"); + } + let (minor, _, ok_minor) = parse_u16(pkg, i + 1); // skip the '.' + if !ok_minor { + panic!("invalid CARGO_PKG_VERSION: missing minor"); + } return Version { - major: 99, - minor: 0, - patch: 0, + major, + minor, + patch: u16::MAX, }; } - regex::Regex::new(r"^v(\d+)\.(\d+)\.(\d+)") - .unwrap() - .captures(crate::VERSION) - .and_then(|caps| { - Some(Version { - major: caps[1].parse().ok()?, - minor: caps[2].parse().ok()?, - patch: caps[3].parse().ok()?, - }) - }) - .unwrap() -}); + // release build id is `v..-...` + let id = crate::VERSION.as_bytes(); + let start = if !id.is_empty() && id[0] == b'v' { + 1 + } else { + 0 + }; + let (major, i, ok_major) = parse_u16(id, start); + if !ok_major || i >= id.len() || id[i] != b'.' { + panic!("invalid VERSION: missing major"); + } + let (minor, i, ok_minor) = parse_u16(id, i + 1); // skip '.' + if !ok_minor || i >= id.len() || id[i] != b'.' { + panic!("invalid VERSION: missing minor"); + } + let (patch, i, ok_patch) = parse_u16(id, i + 1); // skip '.' + if !ok_patch { + panic!("invalid VERSION: missing patch"); + } + if i < id.len() && id[i] != b'-' && id[i] != b'\n' { + panic!("invalid VERSION: unexpected character after patch"); + } + Version { + major, + minor, + patch, + } +} + +pub const CURRENT: Version = current_version(); diff --git a/executor/crates/common/tests/bytes32.rs b/executor/crates/common/tests/bytes32.rs new file mode 100644 index 000000000..22db664a2 --- /dev/null +++ b/executor/crates/common/tests/bytes32.rs @@ -0,0 +1,45 @@ +use genlayer_sdk::gvm32::DecodeError; +use genvm_common::bytes32::FromGvm32Error; +use genvm_common::Bytes32Hash; + +#[test] +fn gvm32_round_trip() { + let bytes = [0xabu8; 32]; + let h = Bytes32Hash::from_bytes(bytes); + + let s = h.to_gvm32(); + assert_eq!(s.len(), 52); // ceil(256 / 5) + assert_eq!(Bytes32Hash::from_gvm32(&s), Ok(h)); + assert_eq!(h.to_string(), s); // Display == gvm32 + assert_eq!(h.as_bytes(), &bytes); +} + +#[test] +fn from_gvm32_rejects_invalid() { + // valid gvm32, but decodes to fewer than 32 bytes + assert_eq!( + Bytes32Hash::from_gvm32("00"), // decodes to 1 byte + Err(FromGvm32Error::WrongLength { got: 1 }) + ); + assert_eq!( + Bytes32Hash::from_gvm32(""), // decodes to 0 bytes + Err(FromGvm32Error::WrongLength { got: 0 }) + ); + // '!' is not in the alphabet + assert_eq!( + Bytes32Hash::from_gvm32("!"), + Err(FromGvm32Error::InvalidEncoding(DecodeError::InvalidChar( + '!' + ))) + ); + // valid alphabet, but non-zero trailing padding bits + assert_eq!( + Bytes32Hash::from_gvm32("abc"), + Err(FromGvm32Error::InvalidEncoding( + DecodeError::NonZeroPadding { + bits: 7, + value: 108 + } + )) + ); +} diff --git a/executor/crates/sdk-rs/Cargo.lock b/executor/crates/sdk-rs/Cargo.lock index 4fac2d5cf..0fb63fa8d 100644 --- a/executor/crates/sdk-rs/Cargo.lock +++ b/executor/crates/sdk-rs/Cargo.lock @@ -246,6 +246,7 @@ dependencies = [ "num-bigint", "primitive-types", "serde", + "sha3", ] [[package]] diff --git a/executor/crates/sdk-rs/examples/fetch_webpage.rs b/executor/crates/sdk-rs/examples/fetch_webpage.rs index 59bf9a4ac..8ef1e27c0 100644 --- a/executor/crates/sdk-rs/examples/fetch_webpage.rs +++ b/executor/crates/sdk-rs/examples/fetch_webpage.rs @@ -167,7 +167,11 @@ fn run_nondet(entry_data: &[u8]) -> Result { match result { LeaderResult::Return(value) => Ok(value), - LeaderResult::UserError(msg) => { + LeaderResult::UserError(value) => { + let msg = match value { + Value::Str(s) => s, + other => format!("{other:?}"), + }; genlayer_sdk::abi::entry::user_error_immediately(msg); } LeaderResult::VmError(msg) => { diff --git a/executor/crates/sdk-rs/src/abi/consts.rs b/executor/crates/sdk-rs/src/abi/consts.rs index ec17ae01a..7d84c7869 100644 --- a/executor/crates/sdk-rs/src/abi/consts.rs +++ b/executor/crates/sdk-rs/src/abi/consts.rs @@ -158,11 +158,12 @@ pub mod memory_limiter_consts { } pub mod root_offsets { - pub const CONTRACT: u32 = 0; - pub const CODE: u32 = 1; - pub const LOCKED_SLOTS: u32 = 2; - pub const UPGRADERS: u32 = 3; - pub const MAJOR: u32 = 4; + pub const MAJOR: u32 = 0; + pub const CONTRACT: u32 = 1; + pub const CODE: u32 = 2; + pub const LOCKED_SLOTS: u32 = 3; + pub const UPGRADERS: u32 = 4; + pub const CODE_SLOT: u32 = 5; } pub mod top_limits { @@ -276,6 +277,7 @@ pub mod __VmError { pub const fn absent_runner_comment(&self) -> VmError { VmError(Cow::Borrowed("invalid_contract absent_runner_comment")) } pub const fn not_utf8_text(&self) -> VmError { VmError(Cow::Borrowed("invalid_contract not_utf8_text")) } pub const fn malformed_runner(&self) -> VmError { VmError(Cow::Borrowed("invalid_contract malformed_runner")) } + pub const fn major_mismatch(&self) -> VmError { VmError(Cow::Borrowed("invalid_contract major_mismatch")) } pub const fn wasm(&self) -> InvalidContractWasm { InvalidContractWasm } } @@ -309,7 +311,7 @@ pub mod __VmError { pub struct VmError(pub Cow<'static, str>); impl From for String { - fn from(val: VmError) -> Self { + fn from(val: VmError) -> String { val.0.into() } } diff --git a/executor/crates/sdk-rs/src/abi/entry.rs b/executor/crates/sdk-rs/src/abi/entry.rs index fd22e65f0..d21c6025d 100644 --- a/executor/crates/sdk-rs/src/abi/entry.rs +++ b/executor/crates/sdk-rs/src/abi/entry.rs @@ -406,7 +406,7 @@ pub mod contract_def { #[derive(Debug, Clone)] pub enum LeaderResult { Return(Value), - UserError(String), + UserError(Value), VmError(String), } @@ -428,11 +428,9 @@ pub mod contract_def { Ok(LeaderResult::Return(value)) } ResultCode::UserError => { - // FIXME: deprecate in next release (raw-string user error encoding; - // switch to the tagged calldata form) - let msg = String::from_utf8(rest.to_vec()) - .map_err(|e| ConsensusStageParseError::InvalidUtf8(e.to_string()))?; - Ok(LeaderResult::UserError(msg)) + let value = calldata::decode(rest) + .map_err(|e| ConsensusStageParseError::DecodeError(e.to_string()))?; + Ok(LeaderResult::UserError(value)) } ResultCode::VmError | ResultCode::InternalError => { let msg = String::from_utf8(rest.to_vec()) diff --git a/executor/crates/sdk-rs/src/abi/gl_call.rs b/executor/crates/sdk-rs/src/abi/gl_call.rs index 0a2ce6992..78d571ca2 100644 --- a/executor/crates/sdk-rs/src/abi/gl_call.rs +++ b/executor/crates/sdk-rs/src/abi/gl_call.rs @@ -231,13 +231,9 @@ pub mod llm_iface { #[serde(rename = "text")] #[calldata(rename = "text")] Text, - // FIXME: deprecate in next release (json will adopt json2 behavior) #[serde(rename = "json")] #[calldata(rename = "json")] JSON, - #[serde(rename = "json2")] - #[calldata(rename = "json2")] - JSON2, } fn default_text() -> OutputFormat { @@ -573,7 +569,22 @@ pub enum Message { #[cfg_attr(feature = "arbitrary", arbitrary(with = crate::abi::arb::arb_bytes))] data: Bytes, - allow_write_ops: bool, + runner: String, + + allow_write_storage: bool, + allow_send_messages: bool, + allow_register_runners: bool, + }, + + RegisterRunner { + #[cfg_attr(feature = "arbitrary", arbitrary(with = crate::abi::arb::arb_bytes))] + code: Bytes, + }, + + MapFile { + runner: String, + path_in_runner: String, + path_in_vfs: String, }, WebRender(web_iface::RenderPayload), @@ -581,11 +592,18 @@ pub enum Message { ExecPrompt(llm_iface::PromptPayload), ExecPromptTemplate(llm_iface::PromptTemplatePayload), - // FIXME: deprecate in next release - #[deprecated(note = "Use UserError. Will be removed before 1.0 release")] - Rollback(calldata::unparsed::Maybe), UserError(calldata::unparsed::Maybe), Return(calldata::unparsed::Maybe), Trace(TracePayload), + + /// Cooperative yield. Currently a no-op; reserved for future use in + /// waiting loops. + Yield, + + /// Get the current timestamp as seconds since the Unix epoch. + /// + /// In [deterministic mode](super) returns the transaction timestamp; in + /// non-deterministic mode returns the real wall-clock time. + GetTimestamp, } diff --git a/executor/crates/sdk-rs/src/gvm32.rs b/executor/crates/sdk-rs/src/gvm32.rs new file mode 100644 index 000000000..142db82c1 --- /dev/null +++ b/executor/crates/sdk-rs/src/gvm32.rs @@ -0,0 +1,92 @@ +//! # GenVM base32 encoder/decoder +//! +//! Uses [Crockford's Base32](https://www.crockford.com/base32.html): the +//! alphabet `0123456789abcdefghjkmnpqrstvwxyz` (excludes `i`, `l`, `o`, `u`), +//! no padding, big-endian bit packing. Encoding is lowercase by default; +//! decoding is case-insensitive, treats `i`/`l` as `1` and `o` as `0`, and +//! ignores `-`. Used for encoding hashes. + +const ALPHABET: &[u8] = b"0123456789abcdefghjkmnpqrstvwxyz"; + +/// Encodes a byte slice as a Crockford Base32 string (lowercase, no padding). +pub fn encode(bytes: &[u8]) -> String { + let mut out = String::with_capacity(bytes.len() * 8 / 5 + 1); + let mut value: u32 = 0; + let mut bits: u32 = 0; + for &b in bytes { + value = (value << 8) | b as u32; + bits += 8; + while bits >= 5 { + bits -= 5; + out.push(ALPHABET[((value >> bits) & 0x1f) as usize] as char); + } + value &= (1 << bits) - 1; + } + if bits > 0 { + out.push(ALPHABET[((value << (5 - bits)) & 0x1f) as usize] as char); + } + out +} + +fn decode_char(c: u8) -> Option { + let c = match c.to_ascii_lowercase() { + b'o' => b'0', + b'i' | b'l' => b'1', + other => other, + }; + ALPHABET.iter().position(|&b| b == c).map(|p| p as u8) +} + +/// Reason a [`decode`] call failed. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DecodeError { + /// A character outside the Crockford Base32 alphabet (after the `i`/`l`/`o` + /// aliases and `-` handling). + InvalidChar(char), + /// The final group carried non-zero padding bits, so the input is not a + /// canonical encoding of any byte sequence. Carries the number of leftover + /// `bits` and their non-zero `value` to aid debugging. + NonZeroPadding { bits: u32, value: u32 }, +} + +impl core::fmt::Display for DecodeError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + DecodeError::InvalidChar(c) => write!(f, "invalid gvm32 character `{c}`"), + DecodeError::NonZeroPadding { bits, value } => write!( + f, + "non-zero gvm32 trailing padding: {bits} bit(s) = {value:#x}" + ), + } + } +} + +impl std::error::Error for DecodeError {} + +/// Decodes a Crockford Base32 string. Case-insensitive; `i`/`l` are read as `1`, +/// `o` as `0` and `-` is ignored. +/// +/// Fails with [`DecodeError::InvalidChar`] on a character outside the alphabet +/// or [`DecodeError::NonZeroPadding`] on non-zero trailing padding bits. +pub fn decode(s: &str) -> Result, DecodeError> { + let mut out = Vec::with_capacity(s.len() * 5 / 8); + let mut value: u32 = 0; + let mut bits: u32 = 0; + for &c in s.as_bytes() { + if c == b'-' { + continue; + } + let digit = decode_char(c).ok_or(DecodeError::InvalidChar(c as char))?; + value = (value << 5) | digit as u32; + bits += 5; + if bits >= 8 { + bits -= 8; + out.push((value >> bits) as u8); + value &= (1 << bits) - 1; + } + } + if value != 0 { + return Err(DecodeError::NonZeroPadding { bits, value }); + } + Ok(out) +} diff --git a/executor/crates/sdk-rs/src/lib.rs b/executor/crates/sdk-rs/src/lib.rs index ac89b1cc2..eb6236d62 100644 --- a/executor/crates/sdk-rs/src/lib.rs +++ b/executor/crates/sdk-rs/src/lib.rs @@ -1,4 +1,5 @@ pub mod abi; +pub mod gvm32; pub use genlayer_calldata as calldata; #[cfg(feature = "storage")] diff --git a/executor/crates/sdk-rs/src/storage/array.rs b/executor/crates/sdk-rs/src/storage/array.rs index 19712ae76..f5896d88e 100644 --- a/executor/crates/sdk-rs/src/storage/array.rs +++ b/executor/crates/sdk-rs/src/storage/array.rs @@ -23,6 +23,10 @@ impl StorageArray { N } + pub const fn is_empty(&self) -> bool { + N == 0 + } + pub fn index(&self, idx: usize) -> T::Handle { assert!(idx < N, "index {idx} out of bounds for array of length {N}"); T::handle_at(self.slot, self.offset + idx as u32 * T::SIZE) diff --git a/executor/crates/sdk-rs/src/storage/mod.rs b/executor/crates/sdk-rs/src/storage/mod.rs index 33ebfaba9..e534b6e86 100644 --- a/executor/crates/sdk-rs/src/storage/mod.rs +++ b/executor/crates/sdk-rs/src/storage/mod.rs @@ -11,12 +11,16 @@ pub use self::tree_map::*; use crate::calldata::Address; +// Field order defines slot offsets; must match `root_offsets` in the public ABI +// and `Root` in runners/genlayer-py-std/.../storage/root.py: +// MAJOR=0, CONTRACT=1, CODE=2, LOCKED_SLOTS=3, UPGRADERS=4, CODE_SLOT=5. crate::record!(Root[T] { + major: u8, contract_instance: Indirection, code: Indirection>, locked_slots: Indirection>, upgraders: Indirection>, - major: u8, + code_slot: primitive_types::U256, }); impl Root { @@ -27,4 +31,19 @@ impl Root { pub fn get() -> Self { ::handle_at(Self::SLOT, 0) } + + /// Resolve the handle to the contract code. + /// + /// If `code_slot` is zero (the default), the code is read from the default + /// `code` indirection; otherwise it is read from the slot pointed to by + /// `code_slot` (see `chain:` runner ids). Mirrors `Root.get_resolved_code` + /// in the Python runner. + pub fn get_resolved_code(&self) -> StorageVLA { + let code_slot = self.code_slot().get(); + if code_slot.is_zero() { + self.code().get() + } else { + VLA::::handle_at(Slot(code_slot.to_little_endian()), 0) + } + } } diff --git a/executor/crates/sdk-rs/tests/gvm32.rs b/executor/crates/sdk-rs/tests/gvm32.rs new file mode 100644 index 000000000..befd1d7fb --- /dev/null +++ b/executor/crates/sdk-rs/tests/gvm32.rs @@ -0,0 +1,71 @@ +use genlayer_sdk::gvm32; + +#[test] +fn round_trip() { + let cases = [ + // hex, gvm32 (Crockford Base32, lowercase) + ( + "ab335240fd942ab8191c5e628cd4ff3903c577bda961fb75df08e0303a00527b", + "ncsn4g7xjgnbg68wbsh8sn7z741waxxxn5gzpxez13g30eg0a9xg", + ), + ( + "47b2d8f260c2d48116044bc43fe3de0f", + "8ysdhwk0rba825g49f23zryy1w", + ), + ( + "1f74d74729abdc08f4f84e8f7f8c808c8ed92ee5", + "3xtdehs9nfe0hx7r9t7qz340hj7djbq5", + ), + ( + "a315ab26a0c4829321730c44a26f4497f7da0631402669caa4e24bdcd9db7c87", + "mcatp9n0rj1968bk1h2a4vt4jzvxm1hh80k6kjn4w95xspevfj3g", + ), + ( + "296a445bfa5e1990af299ec74582468ab7a77e495861691ff79ab21234e514b64fc72b294d7305ecdd0febaa13b1bc1a3f359a711bb93dfb2b82804c64354dab", + "55n48pztbrcs1bs9kv3mb0j6havtezj9b1gpj7zqkas14d752jv4zhsb556q61fcvm7yqagkp6y1mfsnk9rhqe9xzcnr502ccgtmvar", + ), + ( + "99a2da84cec54d17325bcee0a079669c1b15eb7ead32246514b75b97862f1e00", + "k6hdn16ern6hecjvsvga0yb6kgdhbtvynms28s8mpxdsf1hf3r00", + ), + ]; + + for (hex, b32) in cases { + let bytes = hex::decode(hex).unwrap(); + assert_eq!(gvm32::encode(&bytes), b32, "encode {hex}"); + assert_eq!(gvm32::decode(b32).unwrap(), bytes, "decode {b32}"); + } +} + +#[test] +fn empty() { + assert_eq!(gvm32::encode(&[]), ""); + assert_eq!(gvm32::decode("").unwrap(), Vec::::new()); +} + +#[test] +fn case_insensitive_and_aliases() { + let bytes = hex::decode("47b2d8f260c2d48116044bc43fe3de0f").unwrap(); + let canonical = "8ysdhwk0rba825g49f23zryy1w"; + // uppercase decodes the same + assert_eq!(gvm32::decode(&canonical.to_uppercase()).unwrap(), bytes); + // hyphens are ignored + assert_eq!( + gvm32::decode("8ysd-hwk0-rba8-25g4-9f23-zryy-1w").unwrap(), + bytes + ); + // crockford aliases: i/l -> 1, o -> 0 + assert_eq!(gvm32::decode("OoIiLl"), gvm32::decode("001111")); +} + +#[test] +fn rejects_invalid() { + use gvm32::DecodeError; + // `u` is not in the alphabet and is not an alias + assert_eq!(gvm32::decode("u"), Err(DecodeError::InvalidChar('u'))); + // non-zero trailing padding bits + assert_eq!( + gvm32::decode("01"), + Err(DecodeError::NonZeroPadding { bits: 2, value: 1 }) + ); +} diff --git a/executor/fuzz/genvm-storage.rs b/executor/fuzz/genvm-storage.rs index e26de76aa..cde883e4f 100644 --- a/executor/fuzz/genvm-storage.rs +++ b/executor/fuzz/genvm-storage.rs @@ -155,27 +155,27 @@ async fn run_storage_fuzz(input: FuzzInput) -> anyhow::Result<()> { genvm::config::FeesConfig { expr_prelude: String::new(), storage: genvm::config::FeesBucketConfig { - bucket_no: 0, + bucket_no: vec![0], subtract_on_start_expr: "0".into(), delta_expr: r"\attrs = 0".into(), }, message_receipt: genvm::config::FeesBucketConfig { - bucket_no: 0, + bucket_no: vec![0], subtract_on_start_expr: "0".into(), delta_expr: r"\attrs = 0".into(), }, nondet_output: genvm::config::FeesBucketConfig { - bucket_no: 0, + bucket_no: vec![0], subtract_on_start_expr: "0".into(), delta_expr: r"\attrs = 0".into(), }, message_fee: genvm::config::FeesBucketConfig { - bucket_no: 0, + bucket_no: vec![0], subtract_on_start_expr: "0".into(), delta_expr: r"\attrs = 0".into(), }, event: genvm::config::FeesBucketConfig { - bucket_no: 0, + bucket_no: vec![0], subtract_on_start_expr: "0".into(), delta_expr: r"\attrs = 0".into(), }, diff --git a/executor/src/config.rs b/executor/src/config.rs index da0466b26..6483f3d59 100644 --- a/executor/src/config.rs +++ b/executor/src/config.rs @@ -15,9 +15,43 @@ fn default_fee_expr_zero() -> String { "0".to_owned() } +fn deserialize_bucket_nos<'de, D>(d: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + use serde::de; + + struct Visitor; + impl<'de> de::Visitor<'de> for Visitor { + type Value = Vec; + fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.write_str("an integer or array of integers") + } + fn visit_u64(self, v: u64) -> Result, E> { + u8::try_from(v) + .map(|b| vec![b]) + .map_err(|_| E::custom(format!("bucket_no {v} exceeds u8 range"))) + } + fn visit_i64(self, v: i64) -> Result, E> { + u8::try_from(v) + .map(|b| vec![b]) + .map_err(|_| E::custom(format!("bucket_no {v} out of u8 range"))) + } + fn visit_seq>(self, mut seq: A) -> Result, A::Error> { + let mut v = Vec::new(); + while let Some(n) = seq.next_element::()? { + v.push(n); + } + Ok(v) + } + } + d.deserialize_any(Visitor) +} + #[derive(Clone, Deserialize, Debug)] pub struct FeesBucketConfig { - pub bucket_no: u8, + #[serde(deserialize_with = "deserialize_bucket_nos")] + pub bucket_no: Vec, /// Cost charged once, up-front, when the bucket is created /// (the fixed part of `start + sum of per-change`). #[serde(default = "default_fee_expr_zero")] diff --git a/executor/src/exe/run.rs b/executor/src/exe/run.rs index 17ab463ab..44a81157f 100644 --- a/executor/src/exe/run.rs +++ b/executor/src/exe/run.rs @@ -17,9 +17,11 @@ const EXECUTION_DATA_HELP: &str = "path to file containing encoded execution dat pub struct Args { #[arg( long, - help = "whenever to allow `:latest` and `:test` as runners version, tracing, etc." + value_enum, + default_value = "disabled", + help = "debug level: disabled|safe|safe-unbounded|unsafe|unsafe-tracing. safe captures (bounded); safe-unbounded adds unbounded capture and tracing; unsafe adds `:latest`/`:test` resolution (diverges across machines); unsafe-tracing adds real time metering (non-deterministic)" )] - debug_mode: bool, + debug_mode: genvm_common::DebugMode, #[arg(long, default_value = "-", help = EXECUTION_DATA_HELP)] execution_data: String, @@ -35,7 +37,7 @@ pub struct Args { #[clap( long, default_value = "rwscn", - help = "r?w?s?c?n?, read/write/send messages/call contracts/spawn nondet" + help = "r?w?s?c?n?u?, read/write/send messages/call contracts/spawn nondet/register runners" )] permissions: String, #[clap(long, help = "override LLM module address from config")] @@ -85,17 +87,6 @@ pub fn handle(args: Args, mut config: config::Config) -> Result<()> { .create_rt() .with_context(|| "creating tokio runtime")?; - let (token, canceller) = genvm_common::cancellation::make(); - - let handle_sigterm = move || { - log_warn!("sigterm received"); - canceller(); - }; - unsafe { - signal_hook::low_level::register(signal_hook::consts::SIGTERM, handle_sigterm.clone())?; - signal_hook::low_level::register(signal_hook::consts::SIGINT, handle_sigterm)?; - } - let genvm_id = match &args.genvm_id { None => { let mut random_bytes = [0; 8]; @@ -135,13 +126,14 @@ pub fn handle(args: Args, mut config: config::Config) -> Result<()> { .collect::>>()?; let max_bucket_no = [ - config.fees.storage.bucket_no, - config.fees.message_receipt.bucket_no, - config.fees.nondet_output.bucket_no, - config.fees.message_fee.bucket_no, - config.fees.event.bucket_no, + &config.fees.storage.bucket_no, + &config.fees.message_receipt.bucket_no, + &config.fees.nondet_output.bucket_no, + &config.fees.message_fee.bucket_no, + &config.fees.event.bucket_no, ] .into_iter() + .flat_map(|v| v.iter().copied()) .max() .unwrap_or(0); @@ -152,7 +144,6 @@ pub fn handle(args: Args, mut config: config::Config) -> Result<()> { ); let shared_data = sync::DArc::new(genvm::rt::SharedData { - cancellation: token, is_sync: args.sync, genvm_id: genvm_modules_interfaces::GenVMId(genvm_id), debug_mode: args.debug_mode, @@ -178,6 +169,16 @@ pub fn handle(args: Args, mut config: config::Config) -> Result<()> { let method_hosts = execution_data.method_hosts.clone(); + // Validate every method->host mapping up front, once, so all later host + // selection (here and inside the VM) can index `hosts` safely instead of + // panicking on a misconfigured index. + if let Some(&bad) = method_hosts.iter().find(|&&h| h as usize >= hosts.len()) { + anyhow::bail!( + "method_hosts references host index {bad} but only {} host(s) are configured", + hosts.len() + ); + } + // Charge the per-bucket up-front fees now that the hosts are connected. If a // bucket cannot cover its `subtract_on_start`, report the resulting VM error // to the host as a normal receipt instead of crashing during setup. @@ -222,7 +223,7 @@ pub fn handle(args: Args, mut config: config::Config) -> Result<()> { } let mut perm_size = 0; - for perm in ["r", "w", "s", "c", "n"] { + for perm in ["r", "w", "s", "c", "n", "u"] { if args.permissions.contains(perm) { perm_size += 1; } diff --git a/executor/src/host/message.rs b/executor/src/host/message.rs index 4f2dd51f0..c718f8213 100644 --- a/executor/src/host/message.rs +++ b/executor/src/host/message.rs @@ -40,10 +40,15 @@ impl AccountAddress { #[repr(C)] pub struct SlotID(#[serde_as(as = "Base64")] pub [u8; 32]); -pub mod root_offsets { - pub const CODE: u32 = 1; - pub const LOCKED_SLOTS: u32 = 2; - pub const UPGRADERS: u32 = 3; +impl genvm_common::calldata::codec::Encode for SlotID { + type Error = W::Error; + + fn encode( + &self, + enc: &mut genvm_common::calldata::Encoder, + ) -> std::result::Result<(), Self::Error> { + enc.push_bytes(&self.0) + } } impl SlotID { @@ -89,3 +94,9 @@ impl From<&[u8; 32]> for SlotID { SlotID(*value) } } + +impl std::fmt::Display for SlotID { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&genlayer_sdk::gvm32::encode(&self.0)) + } +} diff --git a/executor/src/host/mod.rs b/executor/src/host/mod.rs index 38147c374..b1e547486 100644 --- a/executor/src/host/mod.rs +++ b/executor/src/host/mod.rs @@ -5,10 +5,10 @@ use genlayer_sdk::abi; use genvm_common::*; use crate::public_abi; +use crate::public_abi::root_offsets; use crate::public_abi::{ResultCode, StorageType}; use genvm_common::calldata::Address; use genvm_common::calldata::ADDRESS_SIZE; -use message::root_offsets; use core::str; use std::os::fd::FromRawFd; diff --git a/executor/src/lib.rs b/executor/src/lib.rs index e142e41ee..8cc54f8ae 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -93,7 +93,6 @@ pub fn create_supervisor( gas_data: named.gas_data.clone(), initial_time_units_allocation: named.initial_time_units_allocation, }, - shared_data.cancellation.clone(), shared_data.genvm_id, role, host_data.clone(), @@ -106,7 +105,6 @@ pub fn create_supervisor( gas_data: named.gas_data, initial_time_units_allocation: named.initial_time_units_allocation, }, - shared_data.cancellation.clone(), shared_data.genvm_id, role, host_data, @@ -167,18 +165,63 @@ pub async fn run_with_impl( ), ); - if let Some(code) = &entry_data.code { - log_debug!("using provided code for execution"); + let topmost_runner_id = match async { + anyhow::Ok(if let Some(code) = &entry_data.code { + log_debug!("using provided code for execution"); + + topmost_storage.write_code(code).await?; + // Record the major this contract is deployed for, so later runs can + // verify major compatibility (see `read_major` / major_mismatch check). + topmost_storage + .write_major(genvm_common::version::CURRENT.major as u8) + .await?; + + let code_slot = rt::vm::storage::default_code_slot(); + let archive = runners::parse(code.clone()).map_err(|e| { + rt::errors::VMError::wrap(public_abi::VmError::invalid_contract().val(), e) + })?; + supervisor.prepopulate_deploy_runner( + entry_data.message.contract_address, + code_slot, + archive, + ); + + runners::Id::Chain { + address: entry_data.message.contract_address, + on: runners::ChainState::Deploy, + slot: code_slot, + } + } else { + log_debug!("code is null"); - topmost_storage.write_code(code).await?; - } else { - log_debug!("code is null"); + let code_slot = topmost_storage.check_major_and_resolve_code_slot().await?; + + runners::Id::Chain { + address: entry_data.message.contract_address, + on: runners::ChainState::Accepted, + slot: code_slot, + } + }) } + .await + { + Ok(id) => id, + // A VMError raised while preparing the contract (bad code, major + // mismatch, missing code slot) is a contract error, not an internal + // failure: surface it as a VMError result. Genuine internal errors still + // propagate via `?`. + Err(e) => { + return Ok(rt::vm::FullResult::empty_from( + rt::errors::unwrap_vm_errors(e.into())?, + )); + } + }; let data_fees_limit = supervisor.shared_data.gep(|x| &x.data_fees_limit); let essential_data = Box::new(wasi::genlayer_sdk::SingleVMData { depth: 0, + // Permission model: doc/website/src/spec/03-vm/05-permissions.rst conf: wasi::base::Config { needs_error_fingerprint: true, is_deterministic: true, @@ -187,7 +230,9 @@ pub async fn run_with_impl( can_send_messages: permissions.contains("s"), can_call_others: permissions.contains("c"), can_spawn_nondet: permissions.contains("n"), + can_register_runners: permissions.contains("u"), state_mode: crate::public_abi::StorageType::Default, + topmost_runner_id, }, message_data: ExtendedMessage { message: entry_data.message, @@ -203,6 +248,7 @@ pub async fn run_with_impl( messages_value_decremented: primitive_types::U256::zero(), emissions: Vec::new(), message_fee_allocation: entry_data.message_fee_allocation, + custom_runners: Default::default(), }, det_subvm_hashes: Default::default(), }); @@ -254,21 +300,7 @@ pub async fn run_with( (Ok(res), Ok(c)) => Ok((res, c)), }; - let res = if supervisor.shared_data.cancellation.is_cancelled() { - match merged_result { - Ok(mut r) => { - if r.0.kind == public_abi::ResultCode::VmError { - r.0.data = calldata::Value::Str(public_abi::VmError::timeout().0.into()).into(); - } - Ok(r) - } - Err(_e) => Ok((rt::vm::FullResult::timeout(), None)), - } - } else { - merged_result - }; - - let res = res.inspect_err(|e| { + let res = merged_result.inspect_err(|e| { log_error!(error:ah = &e; "internal error"); }); @@ -281,66 +313,11 @@ pub async fn run_with( .context("notify non-deterministic disagreement")?; } - log_debug!("all executions done, collecting stats"); - - let is_timeout = supervisor.shared_data.cancellation.is_cancelled(); - - let web_metrics = if is_timeout { - None - } else { - supervisor - .modules - .web - .get_stats(genvm_modules_interfaces::web::Message::GetStats) - .await - .ok() - }; - let llm_metrics = if is_timeout { - None - } else { - supervisor - .modules - .llm - .get_stats(genvm_modules_interfaces::llm::Message::GetStats) - .await - .ok() - }; - - #[derive(serde::Serialize)] - struct AllMetrics<'a> { - web: Option, - llm: Option, - gvm: &'a crate::Metrics, - } - - impl calldata::codec::Encode for AllMetrics<'_> { - type Error = W::Error; - - fn encode(&self, enc: &mut calldata::Encoder) -> Result<(), Self::Error> { - enc.start_map(3)?; - - enc.push_map_k("gvm")?; - calldata::codec::Encode::encode(self.gvm, enc)?; - - enc.push_map_k("llm")?; - calldata::codec::Encode::encode(&self.llm, enc)?; - - enc.push_map_k("web")?; - calldata::codec::Encode::encode(&self.web, enc)?; - - Ok(()) - } - } - - let all_metrics = AllMetrics { - web: web_metrics, - llm: llm_metrics, - gvm: &supervisor.shared_data.metrics, - }; - - let all_metrics = calldata::to_value(&all_metrics); + // Module (llm/web) metrics are collected by the manager from its own + // execution context; the executor only reports its own counters here. + let gvm_metrics = calldata::to_value(&supervisor.shared_data.metrics); - log_info!(metrics:serde = all_metrics; "metrics"); + log_info!(metrics:serde = gvm_metrics; "metrics"); log_debug!("sending final result"); diff --git a/executor/src/modules.rs b/executor/src/modules.rs index abd3f1545..aaff5db6d 100644 --- a/executor/src/modules.rs +++ b/executor/src/modules.rs @@ -17,7 +17,6 @@ struct ModuleImpl { pub struct Module { name: String, - cancellation: Arc, imp: tokio::sync::Mutex, genvm_id: genvm_modules_interfaces::GenVMId, role: genvm_modules_interfaces::Role, @@ -60,10 +59,21 @@ const FD_PREFIX: &str = "fd://"; /// Connect to a module endpoint /// Supports: -/// - TCP: "host:port" or "ws://host:port" or "wss://host:port" +/// - TCP: "host:port" or "ws://host:port" (the latter is a plaintext alias) /// - Unix socket: "unix:///path/to/socket" /// - File descriptor: "fd://fd" (for bidirectional fd like socketpair) async fn connect(url: &str) -> anyhow::Result { + // `wss://` implies TLS, but this connector only speaks the plaintext + // length-prefixed protocol. Reject it rather than silently downgrading to + // an unencrypted link an operator believes is secure. Terminate TLS in a + // proxy and point the executor at the proxy's plain `host:port` instead. + if url.starts_with("wss://") { + anyhow::bail!( + "module scheme 'wss://' is not supported (no TLS is performed); \ + use 'host:port', 'ws://host:port', 'unix://', or 'fd://', and \ + terminate TLS in a proxy" + ); + } if let Some(socket_path) = url.strip_prefix(UNIX_PREFIX) { let stream = tokio::net::UnixStream::connect(socket_path) .await @@ -77,11 +87,8 @@ async fn connect(url: &str) -> anyhow::Result { let stream = unsafe { genvm_common::io::AsyncCustomFD::from_raw_fd(fd)? }; Ok(Box::new(stream)) } else { - // Strip ws:// or wss:// prefix if present for TCP connection - let addr = url - .strip_prefix("ws://") - .or_else(|| url.strip_prefix("wss://")) - .unwrap_or(url); + // `ws://` is a plaintext alias for a raw TCP connection. + let addr = url.strip_prefix("ws://").unwrap_or(url); let stream = tokio::net::TcpStream::connect(addr) .await @@ -100,7 +107,6 @@ pub struct ModuleNamedArgs { impl Module { pub fn new( named: ModuleNamedArgs, - cancellation: Arc, genvm_id: genvm_modules_interfaces::GenVMId, role: genvm_modules_interfaces::Role, host_data: genvm_modules_interfaces::HostData, @@ -111,7 +117,6 @@ impl Module { url: named.url, stream: None, }), - cancellation, genvm_id, role, name: named.name, @@ -197,39 +202,14 @@ impl Module { } } - pub async fn get_stats(&self, val: V) -> anyhow::Result - where - V: calldata::codec::Encode, Error = std::convert::Infallible>, - { - let zelf = self.imp.lock().await; - let mut zelf = sync::Lock::new(zelf, self.metrics.gep(|x| &x.time)); - - match &mut zelf.stream { - None => Ok(calldata::Value::Null), - Some(stream) => { - write_message(stream, &calldata::encode_obj(&val)).await?; - let response = read_message(stream).await?; - - let response = calldata::decode(&response)?; - - Ok(response) - } - } - } - pub async fn send(&self, val: V) -> anyhow::Result> where V: calldata::codec::Encode, Error = std::convert::Infallible>, R: calldata::codec::Decode, { - tokio::select! { - _ = self.cancellation.chan.closed() => { - anyhow::bail!("timeout") // it will be replaced later - } - res = self.send_impl(val) => { - res.with_context(|| "sending request to module") - } - } + self.send_impl(val) + .await + .with_context(|| "sending request to module") } } diff --git a/executor/src/rt/errors.rs b/executor/src/rt/errors.rs index f3771741a..40194d6cd 100644 --- a/executor/src/rt/errors.rs +++ b/executor/src/rt/errors.rs @@ -11,14 +11,29 @@ impl std::error::Error for VMError {} impl std::fmt::Display for VMError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "VMError({})", self.0 .0) + if f.alternate() { + f.write_fmt(format_args!("VMError({},", self.0 .0))?; + if let Some(cause) = &self.1 { + f.write_fmt(format_args!("{})", cause))?; + } else { + f.write_str("None)")?; + return Ok(()); + }; + } else { + f.write_fmt(format_args!("VMError({})", self.0 .0))?; + } + + Ok(()) } } impl VMError { pub fn wrap>(message: abi::consts::VmError, cause: E) -> Self { match cause.into().downcast::() { - Err(cause) => Self(message, Some(cause)), + Err(cause) => { + log_debug!(vm_error = message.0, cause:ah = cause; "wrapping VMError"); + Self(message, Some(cause)) + } Ok(v) => v, } } diff --git a/executor/src/rt/fees.rs b/executor/src/rt/fees.rs index 6d35bd49a..150471822 100644 --- a/executor/src/rt/fees.rs +++ b/executor/src/rt/fees.rs @@ -85,10 +85,7 @@ pub fn fee_params_value_external( Value::Object(Arc::new(m)) } -fn value_to_u256(value: genvm_common::expr::Value) -> anyhow::Result { - let rational = value - .into_rational() - .map_err(|e| anyhow::anyhow!("fee expression must yield a number: {e}"))?; +fn rational_to_u256(rational: num_rational::BigRational) -> anyhow::Result { anyhow::ensure!( rational.is_integer(), "fee expression must yield an integer, got {rational}" @@ -105,6 +102,35 @@ fn value_to_u256(value: genvm_common::expr::Value) -> anyhow::Result anyhow::Result> { + match value { + genvm_common::expr::Value::Rational(r) => { + let cost = rational_to_u256(r)?; + Ok(vec![cost; bucket_count]) + } + genvm_common::expr::Value::Array(arr) => { + anyhow::ensure!( + arr.len() == bucket_count, + "fee expression returned array of length {} but bucket_no has {bucket_count} entries", + arr.len(), + ); + arr.iter() + .map(|v| { + let r = v + .clone() + .into_rational() + .map_err(|e| anyhow::anyhow!("fee array element must be a number: {e}"))?; + rational_to_u256(r) + }) + .collect() + } + other => anyhow::bail!("fee expression must yield a number or array, got {other:?}",), + } +} + /// Parses `\node = ` and applies it to `node`, so the result /// closes over `node` (and the prelude). The `delta` form additionally /// returns a `\attrs = ...` function ready to be applied per charge. @@ -127,20 +153,24 @@ fn eval_with_node( /// A fee bucket: total = `subtract_on_start` (charged once by /// [`DataLimit::consume_initial`]) + Σ `delta(attrs)`. `delta` is a function /// closing over `node`/the prelude. +/// +/// `bucket_nos` can target multiple on-chain buckets. When the delta expression +/// returns a scalar it is charged identically against every bucket; when it +/// returns an array the lengths must match and each element is charged to the +/// corresponding bucket. All subtractions are atomic (all-or-nothing). struct Bucket { - bucket_no: u8, - subtract_on_start: primitive_types::U256, + bucket_nos: Vec, + subtract_on_start: Vec, delta: genvm_common::expr::Value, - /// VM error reported when `subtract_on_start` underflows the bucket. oom_error: abi::consts::VmError, - total_consumed: tokio::sync::Mutex, + total_consumed: Vec>, } impl std::fmt::Debug for Bucket { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Bucket") - .field("bucket_no", &self.bucket_no) + .field("bucket_nos", &self.bucket_nos) .field("subtract_on_start", &self.subtract_on_start) .finish() } @@ -152,27 +182,46 @@ fn build_bucket( node: &genvm_common::expr::Value, oom_error: abi::consts::VmError, ) -> anyhow::Result { - let subtract_on_start = value_to_u256(eval_with_node( - prelude, - "subtract_on_start", - &cfg.subtract_on_start_expr, - node, - )?)?; + let n = cfg.bucket_no.len(); + anyhow::ensure!(n > 0, "bucket_no must have at least one entry"); + + let subtract_on_start = value_to_u256_vec( + eval_with_node( + prelude, + "subtract_on_start", + &cfg.subtract_on_start_expr, + node, + )?, + n, + )?; let delta = eval_with_node(prelude, "delta", &cfg.delta_expr, node)?; Ok(Bucket { - bucket_no: cfg.bucket_no, + bucket_nos: cfg.bucket_no.clone(), subtract_on_start, delta, oom_error, - total_consumed: Default::default(), + total_consumed: (0..n).map(|_| Default::default()).collect(), }) } -#[derive(Debug, Clone, Copy)] +/// Per-bucket cost vector returned by `calculate_*` methods. +#[derive(Debug, Clone)] +pub struct CostVec(pub Vec); + +impl CostVec { + pub fn sum(&self) -> primitive_types::U256 { + self.0 + .iter() + .copied() + .fold(primitive_types::U256::zero(), |a, b| a + b) + } +} + +#[derive(Debug, Clone)] pub struct MessageFeeConsumption { - pub message_fee: primitive_types::U256, - pub receipt_fee: primitive_types::U256, + pub message_fee: CostVec, + pub receipt_fee: CostVec, } #[derive(Debug, Clone, Copy, Default, genlayer_calldata::Encode)] @@ -269,14 +318,14 @@ impl DataLimit { &self, bucket: &Bucket, vars: &[(&str, genvm_common::expr::Value)], - ) -> anyhow::Result { + ) -> anyhow::Result { match bucket .delta .apply_with(attrs_object(vars), no_free_vars) .map_err(|e| anyhow::anyhow!("{e}")) - .and_then(value_to_u256) + .and_then(|v| value_to_u256_vec(v, bucket.bucket_nos.len())) { - Ok(cost) => Ok(cost), + Ok(costs) => Ok(CostVec(costs)), Err(e) => { log_error!(error:ah = e; "failed to evaluate fee expression"); Err(e).context("failed to evaluate fee expression") @@ -289,50 +338,78 @@ impl DataLimit { bucket: &Bucket, vars: &[(&str, genvm_common::expr::Value)], ) -> anyhow::Result { - let cost = self.calculate_bucket(bucket, vars)?; - Ok(self.consume_bucket_raw(bucket, cost).await) + let costs = self.calculate_bucket(bucket, vars)?; + Ok(self.consume_bucket_raw(bucket, &costs.0).await) } - async fn consume_bucket_raw(&self, bucket: &Bucket, cost: primitive_types::U256) -> bool { + async fn consume_bucket_raw(&self, bucket: &Bucket, costs: &[primitive_types::U256]) -> bool { let mut buckets = self.buckets.lock().await; - let Some(remaining) = buckets.get_mut(bucket.bucket_no as usize) else { - log_warn!(bucket = bucket.bucket_no; "consume_bucket: bucket index out of range"); - return false; - }; - if *remaining >= cost { - *remaining -= cost; + for (idx, (&bno, &cost)) in bucket.bucket_nos.iter().zip(costs.iter()).enumerate() { + let Some(remaining) = buckets.get(bno as usize) else { + log_warn!(bucket = bno; "consume_bucket: bucket index out of range"); + return false; + }; + if *remaining < cost { + log_warn!( + bucket = bno, + cost:display = cost, + remaining:display = *remaining; + "consume_bucket: insufficient funds" + ); + return false; + } + // when the same bucket_no appears more than once, verify + // cumulative cost fits + let mut cumulative = cost; + for (&prev_bno, &prev_cost) in bucket.bucket_nos[..idx].iter().zip(costs[..idx].iter()) + { + if prev_bno == bno { + cumulative += prev_cost; + } + } + if *remaining < cumulative { + log_warn!( + bucket = bno, + cumulative:display = cumulative, + remaining:display = *remaining; + "consume_bucket: insufficient funds (cumulative)" + ); + return false; + } + } + for (i, (&bno, &cost)) in bucket.bucket_nos.iter().zip(costs.iter()).enumerate() { + buckets[bno as usize] -= cost; log_debug!( - bucket = bucket.bucket_no, + bucket = bno, cost:display = cost, - remaining:display = *remaining; + remaining:display = buckets[bno as usize]; "consume_bucket: ok" ); - std::mem::drop(buckets); - *bucket.total_consumed.lock().await += cost; - - true - } else { - log_warn!( - bucket = bucket.bucket_no, - cost:display = cost, - remaining:display = *remaining; - "consume_bucket: insufficient funds" - ); - false + *bucket.total_consumed[i].lock().await += cost; } + std::mem::drop(buckets); + true } pub async fn remaining(&self) -> Vec { self.buckets.lock().await.clone() } + async fn sum_consumed(bucket: &Bucket) -> primitive_types::U256 { + let mut total = primitive_types::U256::zero(); + for tc in &bucket.total_consumed { + total += *tc.lock().await; + } + total + } + pub async fn consumed(&self) -> BucketsConsumed { BucketsConsumed { - storage: *self.storage.total_consumed.lock().await, - message_receipt: *self.message_receipt.total_consumed.lock().await, - nondet_output: *self.nondet_output.total_consumed.lock().await, - message_fee: *self.message_fee.total_consumed.lock().await, - event: *self.event.total_consumed.lock().await, + storage: Self::sum_consumed(&self.storage).await, + message_receipt: Self::sum_consumed(&self.message_receipt).await, + nondet_output: Self::sum_consumed(&self.nondet_output).await, + message_fee: Self::sum_consumed(&self.message_fee).await, + event: Self::sum_consumed(&self.event).await, } } @@ -348,31 +425,17 @@ impl DataLimit { &self.message_fee, &self.event, ] { - let mut buckets = self.buckets.lock().await; - let Some(remaining) = buckets.get_mut(bucket.bucket_no as usize) else { + if !self + .consume_bucket_raw(bucket, &bucket.subtract_on_start.clone()) + .await + { return Some(rt::errors::VMError( bucket.oom_error.clone(), Some(anyhow::anyhow!( - "consume_initial: bucket {} index out of range", - bucket.bucket_no + "subtract_on_start exceeds bucket {:?} total", + bucket.bucket_nos )), )); - }; - match remaining.checked_sub(bucket.subtract_on_start) { - Some(v) => { - *remaining = v; - std::mem::drop(buckets); - *bucket.total_consumed.lock().await += bucket.subtract_on_start; - } - None => { - return Some(rt::errors::VMError( - bucket.oom_error.clone(), - Some(anyhow::anyhow!( - "subtract_on_start exceeds bucket {} total", - bucket.bucket_no - )), - )); - } } } None @@ -386,7 +449,7 @@ impl DataLimit { pub fn calculate_message_receipt( &self, params: MessageReceiptParams, - ) -> anyhow::Result { + ) -> anyhow::Result { self.calculate_bucket( &self.message_receipt, &[ @@ -414,15 +477,15 @@ impl DataLimit { blob_size: u64, topics_count: u64, ) -> anyhow::Result> { - let cost = self.calculate_bucket( + let costs = self.calculate_bucket( &self.event, &[ ("blobSize", num(blob_size)), ("topicsCount", num(topics_count)), ], )?; - if self.consume_bucket_raw(&self.event, cost).await { - Ok(Some(cost)) + if self.consume_bucket_raw(&self.event, &costs.0).await { + Ok(Some(costs.sum())) } else { Ok(None) } @@ -432,7 +495,7 @@ impl DataLimit { &self, on: abi::gl_call::On, matched_fee_params: &genvm_common::domain::fees::InternalMessageParams, - ) -> anyhow::Result { + ) -> anyhow::Result { self.calculate_bucket( &self.message_fee, &[ @@ -447,67 +510,64 @@ impl DataLimit { .context("calculating message fee internal") } - pub async fn consume_message_fee( - &self, - cost_fee: primitive_types::U256, - cost_receipt: primitive_types::U256, - ) -> bool { - if self.message_fee.bucket_no == self.message_receipt.bucket_no { - let Some(sum) = cost_fee.checked_add(cost_receipt) else { - log_warn!( - cost_fee:display = cost_fee, - cost_receipt:display = cost_receipt; - "consume_message_fee: overflow adding fee + receipt" - ); - return false; - }; - return self.consume_bucket_raw(&self.message_fee, sum).await; - } - + pub async fn consume_message_fee(&self, cost_fee: &CostVec, cost_receipt: &CostVec) -> bool { let mut buckets = self.buckets.lock().await; - if cost_fee > buckets[self.message_fee.bucket_no as usize] { - log_warn!( - bucket = self.message_fee.bucket_no, - cost_fee:display = cost_fee, - remaining:display = buckets[self.message_fee.bucket_no as usize]; - "consume_message_fee: insufficient funds for fee" - ); - return false; + // Build a cumulative deduction map: bucket_index → total to subtract. + let mut deductions: std::collections::BTreeMap = + std::collections::BTreeMap::new(); + + for (&bno, &cost) in self.message_fee.bucket_nos.iter().zip(cost_fee.0.iter()) { + *deductions.entry(bno).or_default() += cost; + } + for (&bno, &cost) in self + .message_receipt + .bucket_nos + .iter() + .zip(cost_receipt.0.iter()) + { + *deductions.entry(bno).or_default() += cost; } - if cost_receipt > buckets[self.message_receipt.bucket_no as usize] { - log_warn!( - bucket = self.message_receipt.bucket_no, - cost_receipt:display = cost_receipt, - remaining:display = buckets[self.message_receipt.bucket_no as usize]; - "consume_message_fee: insufficient funds for receipt" - ); - return false; + // Check all buckets first (atomic: all-or-nothing). + for (&bno, &total) in &deductions { + let Some(remaining) = buckets.get(bno as usize) else { + log_warn!(bucket = bno; "consume_message_fee: bucket index out of range"); + return false; + }; + if *remaining < total { + log_warn!( + bucket = bno, + cost:display = total, + remaining:display = *remaining; + "consume_message_fee: insufficient funds" + ); + return false; + } } - buckets[self.message_fee.bucket_no as usize] -= cost_fee; - buckets[self.message_receipt.bucket_no as usize] -= cost_receipt; + // Apply all deductions. + for (&bno, &total) in &deductions { + buckets[bno as usize] -= total; + } std::mem::drop(buckets); - *self.message_fee.total_consumed.lock().await += cost_fee; - *self.message_receipt.total_consumed.lock().await += cost_receipt; - - log_debug!( - fee_bucket = self.message_fee.bucket_no, - cost_fee:display = cost_fee, - receipt_bucket = self.message_receipt.bucket_no, - cost_receipt:display = cost_receipt; - "consume_message_fee: ok" - ); + // Update per-category consumed trackers. + for (i, &cost) in cost_fee.0.iter().enumerate() { + *self.message_fee.total_consumed[i].lock().await += cost; + } + for (i, &cost) in cost_receipt.0.iter().enumerate() { + *self.message_receipt.total_consumed[i].lock().await += cost; + } + log_debug!("consume_message_fee: ok"); true } pub fn calculate_message_fee_external( &self, matched_fee_params: &genvm_common::domain::fees::ExternalMessageParams, - ) -> anyhow::Result { + ) -> anyhow::Result { self.calculate_bucket( &self.message_fee, &[ diff --git a/executor/src/rt/mod.rs b/executor/src/rt/mod.rs index 7c4280bc8..f460c5116 100644 --- a/executor/src/rt/mod.rs +++ b/executor/src/rt/mod.rs @@ -48,10 +48,9 @@ impl DetNondet { /// basic data that is shared across all VMs pub struct SharedData { - pub cancellation: Arc, pub is_sync: bool, pub genvm_id: genvm_modules_interfaces::GenVMId, - pub debug_mode: bool, + pub debug_mode: genvm_common::DebugMode, pub metrics: crate::Metrics, pub data_fees_limit: fees::DataLimit, pub llm_consumption: tokio::sync::Mutex, @@ -78,6 +77,9 @@ pub async fn spawn_apply_run( ), SpawnErrorState::Unspawned(vm_data) => (Default::default(), vm_data), }; + + log_debug!(error:ah = error; "spawn_apply_run failed"); + match errors::unwrap_vm_errors_backtrace(errors::UnwrapDynError::from(error)) { Ok((run_ok, backtrace)) => Ok(vm::RunResult { run_ok, @@ -105,5 +107,6 @@ async fn spawn_apply_run_inner( } use anyhow::Context; +use genvm_common::log_debug; use crate::wasi; diff --git a/executor/src/rt/supervisor/actions.rs b/executor/src/rt/supervisor/actions.rs index 612fcad4d..89fac2d3c 100644 --- a/executor/src/rt/supervisor/actions.rs +++ b/executor/src/rt/supervisor/actions.rs @@ -5,13 +5,12 @@ use crate::{caching, public_abi, rt, runners}; use anyhow::Context as _; use genlayer_sdk::abi; use genvm_common::*; -use symbol_table::GlobalSymbol; use wiggle::error::Context as _; pub struct Ctx<'a, 'b> { pub env: BTreeMap, pub visited: HashSet, - pub contract_id: symbol_table::GlobalSymbol, + pub topmost_runner_id: runners::Id, pub supervisor: &'a rt::supervisor::Supervisor, pub vm: &'b mut rt::vm::VMBase, } @@ -28,97 +27,410 @@ fn maps_into_vm(to: &str) -> bool { to.split('/').find(|component| !component.is_empty()) == Some("vm") } -impl Ctx<'_, '_> { - async fn get_arch( - &mut self, - uid: symbol_table::GlobalSymbol, - ) -> anyhow::Result<( - symbol_table::GlobalSymbol, - sync::DArc, - )> { - let uid = self.full_check_runner_uid(uid)?; +/// Rejects mapping targets that are forbidden or could escape their intended +/// location. `maps_into_vm` only inspects the first component, so a `..` +/// component (e.g. from an archive entry name like `../vm/secrets`) would slip +/// past it and resolve into `/vm/` once the VFS normalizes the path. +fn check_mapping_target(to: &str) -> anyhow::Result<()> { + if maps_into_vm(to) { + return Err(make_malformed_runner_error(&format!( + "mapping into /vm/ is forbidden: {to}" + ))); + } + if to.split('/').any(|component| component == "..") { + return Err(make_malformed_runner_error(&format!( + "mapping path with a '..' component is forbidden: {to}" + ))); + } + Ok(()) +} + +/// How a resolved runner id should be loaded into the archive cache. +enum ResolvedKind { + /// A packaged `name:hash` runner read from the runners directory. + Disk { + name: symbol_table::GlobalSymbol, + hash: Bytes32Hash, + }, + /// `chain:
::` — code blob read from a storage slot. The + /// current contract (`contract`) also resolves here, pointing at its own + /// address/state/`code_slot`. + Chain { + address: calldata::Address, + on: runners::ChainState, + slot: crate::SlotID, + }, + /// `custom:` — a runner registered at runtime. + Custom { hash: Bytes32Hash }, +} - let Some((runner_id, runner_hash)) = runners::verify_runner(uid.as_str()) else { - return Err(make_malformed_runner_error( - "runner id doesn't match expected format", - )); +/// A runner id resolved to its canonical cache key together with the way it +/// should be loaded. +struct Resolved { + id: symbol_table::GlobalSymbol, + kind: ResolvedKind, +} + +impl From for Resolved { + fn from(id: runners::Id) -> Self { + let kind = match &id { + runners::Id::Builtin { name, hash } => ResolvedKind::Disk { + name: name.clone(), + hash: hash.clone(), + }, + runners::Id::Chain { address, on, slot } => ResolvedKind::Chain { + address: *address, + on: *on, + slot: *slot, + }, + runners::Id::Custom { hash } => ResolvedKind::Custom { hash: *hash }, }; + Self { + id: id.canonical(), + kind, + } + } +} - let limiter = &self.vm.store.data_mut().limits; +/// Resolves a runner id to its canonical cache key and load strategy. +/// +/// Free-standing so it can be shared between contract initialization +/// ([`Ctx`]) and runtime `gl_call`s ([`load_runner`]). +pub(crate) async fn resolve_runner_id( + supervisor: &rt::supervisor::Supervisor, + topmost_runner_id: &runners::Id, + id: &str, +) -> anyhow::Result { + let Some(parsed) = runners::parse_runner_id(id) else { + return Err(make_malformed_runner_error( + "runner id doesn't match expected format", + )); + }; + + let resolved: runners::Id = match parsed { + runners::IdUnresolved::Contract => topmost_runner_id.clone(), + runners::IdUnresolved::Builtin { name, hash } => { + let hash: Bytes32Hash = if hash == "test" || hash == "latest" { + if !supervisor.shared_data.debug_mode.allows_latest_resolution() { + log_warn!(":{hash} runner used in non-debug mode, this is not allowed"); + return Err(make_malformed_runner_error( + "runner id doesn't match expected format", + )); + } + let new_latest = supervisor.runner_cache.get_latest(&name); + log_info!(runner_id = name.as_str(), tag = hash.as_str(); "resolving :test/:latest runner"); + let Some(new_latest) = new_latest else { + return Err(make_malformed_runner_error( + "runner id doesn't match expected format", + )); + }; + Bytes32Hash::from_gvm32(new_latest).map_err(|e| { + make_malformed_runner_error(&format!( + "runner hash `{new_latest}` is not valid gvm32: {e}" + )) + })? + } else { + Bytes32Hash::from_gvm32(&hash).map_err(|e| { + make_malformed_runner_error(&format!( + "runner hash `{hash}` is not valid gvm32: {e}" + )) + })? + }; + + let hash_gvm32 = hash.to_gvm32(); + if !supervisor.runner_cache.has_in_all(&name, &hash_gvm32) { + anyhow::bail!("runner {}:{} not found", name, hash_gvm32); + } - let new_arch = self - .supervisor - .runner_cache - .get_or_create( - uid, - || async { - let mut path = self.supervisor.runner_cache.runners_path().to_owned(); - runners::append_runner_subpath(runner_id, runner_hash, &mut path); - path.set_extension("tar"); - if !path.exists() { - anyhow::bail!("runner {} not found", uid); - } + runners::Id::Builtin { + name: symbol_table::GlobalSymbol::new(&name), + hash, + } + } + runners::IdUnresolved::Chain { address, on, slot } => { + let on = on.unwrap_or(runners::ChainState::Accepted); + let slot = match slot { + Some(s) => s, + None => { + let mode = on.host_storage_type().ok_or_else(|| { + make_malformed_runner_error( + "deploy-state chain runner cannot resolve its code slot from chain", + ) + })?; + let mut storage = rt::vm::storage::Storage::new( + address, + supervisor.get_storage_limiter(), + crate::wasi::genlayer_sdk::StorageHostHolder( + supervisor.host.clone(), + crate::wasi::genlayer_sdk::ReadToken { + account: address, + mode, + }, + ), + ); + storage.resolve_code_slot().await.with_context(|| { + format!( + "resolving code slot for chain runner 0x{}", + address.checksum_hex_string() + ) + })? + } + }; + runners::Id::Chain { address, on, slot } + } + runners::IdUnresolved::Custom { hash } => { + let hash = Bytes32Hash::from_gvm32(&hash).map_err(|e| { + make_malformed_runner_error(&format!( + "custom runner hash `{hash}` is not valid gvm32: {e}" + )) + })?; + runners::Id::Custom { hash } + } + }; - let data = util::mmap_file(&path) - .with_context(|| format!("memory mapping runner archive for {uid}"))?; - let data = bytes::Bytes::copy_from_slice(data.as_ref()); - runners::Archive::from_ustar(data) - .with_context(|| format!("parsing ustar archive for {uid}")) - }, - limiter, - ) - .await?; + Ok(resolved) +} - Ok((uid, new_arch)) - } +async fn resolve_runner( + supervisor: &rt::supervisor::Supervisor, + topmost_runner_id: &runners::Id, + id: &str, +) -> anyhow::Result { + Ok(resolve_runner_id(supervisor, topmost_runner_id, id) + .await? + .into()) +} - fn full_check_runner_uid( - &mut self, - id: symbol_table::GlobalSymbol, - ) -> anyhow::Result { - if id.as_str() == "" { - return Ok(self.contract_id); +/// Loads (and caches) the archive for an already-resolved runner. +async fn get_arch( + supervisor: &rt::supervisor::Supervisor, + limiter: &rt::memlimiter::Limiter, + resolved: Resolved, +) -> anyhow::Result<( + symbol_table::GlobalSymbol, + sync::DArc, +)> { + let Resolved { id, kind } = resolved; + + let cache = &supervisor.runner_cache; + + let new_arch = match kind { + ResolvedKind::Disk { name, hash } => { + cache + .get_or_create( + id, + || async { + let mut path = cache.runners_path().to_owned(); + runners::append_runner_subpath(name.as_str(), &hash.to_gvm32(), &mut path); + path.set_extension("tar"); + if !path.exists() { + anyhow::bail!("runner {} not found", id); + } + + let data = util::mmap_file(&path) + .with_context(|| format!("memory mapping runner archive for {id}"))?; + let data = bytes::Bytes::copy_from_slice(data.as_ref()); + runners::Archive::from_ustar(data) + .with_context(|| format!("parsing ustar archive for {id}")) + }, + limiter, + ) + .await? } - let Some((runner_id, runner_hash)) = runners::verify_runner(id.as_str()) else { - return Err(make_malformed_runner_error( - "runner id doesn't match expected format", - )); - }; + ResolvedKind::Chain { address, on, slot } => { + cache + .get_or_create( + id, + || async { + let mode = on.host_storage_type().ok_or_else(|| { + make_malformed_runner_error( + "deploy-state chain runner is not available on chain", + ) + })?; + let mut storage = rt::vm::storage::Storage::new( + address, + supervisor.get_storage_limiter(), + crate::wasi::genlayer_sdk::StorageHostHolder( + supervisor.host.clone(), + crate::wasi::genlayer_sdk::ReadToken { + account: address, + mode, + }, + ), + ); - let runner_id = GlobalSymbol::new(runner_id); + let dep_major = storage + .read_major() + .await + .with_context(|| format!("reading major for chain runner {id}"))?; + let node_major = genvm_common::version::CURRENT.major; + if dep_major as u16 != node_major { + return Err(rt::errors::VMError( + public_abi::VmError::invalid_contract().major_mismatch(), + Some(anyhow::anyhow!( + "chain runner {id} major {dep_major} != node major {node_major}" + )), + ) + .into()); + } - let runner_hash = if runner_hash == "test" || runner_hash == "latest" { - if !self.supervisor.shared_data.debug_mode { - log_warn!(":test/ :latest runner used in non-debug mode, this is not allowed"); - None - } else { - let new_latest = self.supervisor.runner_cache.get_latest(runner_id); - log_info!(runner_id = runner_id.as_str(), new_latest:? = new_latest; "resolving :latest runner"); - new_latest - } + let code = storage + .read_code_at(slot, limiter) + .await + .with_context(|| format!("reading chain runner code for {id}"))?; + runners::parse(bytes::Bytes::from(code)) + .with_context(|| format!("parsing chain runner for {id}")) + }, + limiter, + ) + .await? + } + ResolvedKind::Custom { hash } => { + cache + .get_or_create( + id, + || async { + supervisor + .get_custom_runner(hash) + .ok_or_else(|| anyhow::anyhow!("custom runner {} not found", id)) + }, + limiter, + ) + .await? + } + }; + + Ok((id, new_arch)) +} + +/// Resolves and loads a runner archive by id. Shared entry point used by both +/// contract initialization and runtime `gl_call`s. +#[allow(clippy::too_many_arguments)] +pub(crate) async fn load_runner( + supervisor: &rt::supervisor::Supervisor, + limiter: &rt::memlimiter::Limiter, + id: runners::Id, + available_custom: &rpds::HashTrieSet, +) -> anyhow::Result<( + symbol_table::GlobalSymbol, + sync::DArc, +)> { + let resolved: Resolved = id.into(); + + // Custom runners are execution-scoped: a `custom:` is only resolvable + // by a scope that registered it (or inherited it from a det parent), so the + // shared registry cannot leak a runner across unrelated scopes (e.g. nondet). + if let ResolvedKind::Custom { hash } = &resolved.kind { + if !available_custom.contains(hash) { + return Err(make_malformed_runner_error(&format!( + "custom runner {} is not registered in this execution scope", + resolved.id + ))); + } + } + get_arch(supervisor, limiter, resolved).await +} + +/// Maps a file (or, when `file` ends with `/`, a directory subtree) from a +/// runner archive into the VM filesystem at `to`. Mirrors [`InitAction::MapFile`] +/// so the runtime `MapFile` `gl_call` behaves identically. +pub(crate) fn map_archive_file( + preview1: &mut crate::wasi::preview1::Context, + limiter: &rt::memlimiter::Limiter, + arch: &runners::ArchiveCache, + file: &str, + to: &str, +) -> anyhow::Result<()> { + if file.ends_with("/") { + let is_root = file == "/"; + + let range = if is_root { + arch.files.data.range::(..) } else { - Some(GlobalSymbol::new(runner_hash)) + arch.files.data.range(String::from(file)..) }; - let Some(runner_hash) = runner_hash else { - return Err(make_malformed_runner_error( - "runner id doesn't match expected format", - )); - }; + let must_start_with: &str = if is_root { "" } else { file }; - if !self - .supervisor - .runner_cache - .has_in_all(runner_id, runner_hash) - { - anyhow::bail!("runner {}:{} not found", runner_id, runner_hash); + for (name, file_contents) in range { + if name.ends_with("/") { + continue; + } + + if !name.starts_with(must_start_with) { + log_trace!( + from = file, + to = to, + name = name, + must_start_with = must_start_with; + "aborting file mapping" + ); + break; + } + + let mut name_in_fs = String::from(to); + if !name_in_fs.ends_with("/") { + name_in_fs.push('/'); + } + name_in_fs.push_str(&name[must_start_with.len()..]); + + check_mapping_target(&name_in_fs)?; + + if !limiter + .consume(public_abi::memory_limiter_consts::FILE_MAPPING + name_in_fs.len() as u32) + { + return Err( + rt::errors::VMError(abi::consts::VmError::oom().ram().val(), None).into(), + ); + } + + preview1.map_file(&name_in_fs, file_contents.clone())?; } + } else { + check_mapping_target(to)?; - let mut new_id = runner_id.as_str().to_owned(); - new_id.push(':'); - new_id.push_str(runner_hash.as_str()); + if !limiter.consume(public_abi::memory_limiter_consts::FILE_MAPPING + to.len() as u32) { + return Err(rt::errors::VMError(abi::consts::VmError::oom().ram().val(), None).into()); + } - Ok(symbol_table::GlobalSymbol::new(new_id)) + preview1.map_file(to, arch.get_file(file)?)?; + } + + Ok(()) +} + +/// Maps one of an already-resolved `runner`'s files into `preview1` at runtime. +/// This keeps all runner-loading knowledge in this module: callers (e.g. the +/// `MapFile` `gl_call`) resolve the id and delegate, instead of stitching the +/// archive loading together themselves. +#[allow(clippy::too_many_arguments)] +pub(crate) async fn map_runner_file( + supervisor: &rt::supervisor::Supervisor, + preview1: &mut crate::wasi::preview1::Context, + limiter: &rt::memlimiter::Limiter, + runner: runners::Id, + path_in_runner: &str, + path_in_vfs: &str, + available_custom: &rpds::HashTrieSet, +) -> anyhow::Result<()> { + let (_id, arch) = load_runner(supervisor, limiter, runner, available_custom).await?; + map_archive_file(preview1, limiter, &arch, path_in_runner, path_in_vfs) +} + +impl Ctx<'_, '_> { + async fn resolve_runner(&self, id: &str) -> anyhow::Result { + resolve_runner(self.supervisor, &self.topmost_runner_id, id).await + } + + async fn get_arch( + &mut self, + resolved: Resolved, + ) -> anyhow::Result<( + symbol_table::GlobalSymbol, + sync::DArc, + )> { + let limiter = self.vm.store.data_mut().limits.clone(); + get_arch(self.supervisor, &limiter, resolved).await } fn load_modules( @@ -200,7 +512,7 @@ impl Ctx<'_, '_> { self.supervisor .compile_wasm(contents.as_ref(), wasm_key.as_str()) .await - .with_context(|| format!("compiling wasm {path:?} of {}", self.contract_id)) + .with_context(|| format!("compiling wasm {path:?} of {}", current)) }) .await?; @@ -215,103 +527,11 @@ impl Ctx<'_, '_> { ) -> anyhow::Result> { use runners::InitAction; - if self.supervisor.shared_data.cancellation.is_cancelled() { - return Err(rt::errors::VMError(public_abi::VmError::timeout(), None).into()); - } - match action { InitAction::MapFile { to, file } => { - if file.ends_with("/") { - let is_root = file.as_ref() == "/"; - - let file_name_str = String::from(&file[..]); - - let range = if is_root { - current_runner_arch - .files - .data - .range::(..) - } else { - current_runner_arch.files.data.range(file_name_str..) - }; - - let must_start_with: &str = if is_root { "" } else { file.as_ref() }; - - for (name, file_contents) in range { - if self.supervisor.shared_data.cancellation.is_cancelled() { - return Err( - rt::errors::VMError(public_abi::VmError::timeout(), None).into() - ); - } - - if name.ends_with("/") { - continue; - } - - if !name.starts_with(must_start_with) { - log_trace!(from = file, to = to, name = name; "aborting file mapping"); - - break; - } - - let mut name_in_fs = String::from(&to[..]); - if !name_in_fs.ends_with("/") { - name_in_fs.push('/'); - } - name_in_fs.push_str(&name[must_start_with.len()..]); - - if maps_into_vm(&name_in_fs) { - return Err(make_malformed_runner_error(&format!( - "mapping into /vm/ is forbidden: {name_in_fs}" - ))); - } - - let limiter = &self.vm.store.data_mut().limits; - - if !limiter.consume( - public_abi::memory_limiter_consts::FILE_MAPPING - + name_in_fs.len() as u32, - ) { - return Err(rt::errors::VMError( - abi::consts::VmError::oom().ram().val(), - None, - ) - .into()); - } - - self.vm - .store - .data_mut() - .genlayer_ctx_mut() - .preview1 - .map_file(&name_in_fs, file_contents.clone())?; - } - } else { - if maps_into_vm(to) { - return Err(make_malformed_runner_error(&format!( - "mapping into /vm/ is forbidden: {to}" - ))); - } - - let limiter = &self.vm.store.data_mut().limits; - - if !limiter - .consume(public_abi::memory_limiter_consts::FILE_MAPPING + to.len() as u32) - { - return Err(rt::errors::VMError( - abi::consts::VmError::oom().ram().val(), - None, - ) - .into()); - } - - self.vm - .store - .data_mut() - .genlayer_ctx_mut() - .preview1 - .map_file(to, current_runner_arch.get_file(file)?)?; - } + let limiter = self.vm.store.data_mut().limits.clone(); + let preview1 = &mut self.vm.store.data_mut().genlayer_ctx_mut().preview1; + map_archive_file(preview1, &limiter, current_runner_arch, file, to)?; Ok(None) } InitAction::AddEnv { name, val } => { @@ -414,12 +634,6 @@ impl Ctx<'_, '_> { } InitAction::Seq(vec) => { for act in vec { - if self.supervisor.shared_data.cancellation.is_cancelled() { - return Err( - rt::errors::VMError(public_abi::VmError::timeout(), None).into() - ); - } - if let Some(x) = Box::pin(self.apply(act, current, current_runner_arch)).await? { return Ok(Some(x)); @@ -431,22 +645,27 @@ impl Ctx<'_, '_> { runner: uid, action, } => { - let (uid, new_arch) = self.get_arch(*uid).await?; + let resolved = self.resolve_runner(uid).await?; + let (uid, new_arch) = self.get_arch(resolved).await?; Box::pin(self.apply(action, uid, &new_arch)) .await .with_context(|| format!("With {uid}")) } InitAction::Depends(uid) => { - let uid = self.full_check_runner_uid(*uid)?; + let resolved = self.resolve_runner(uid).await?; - if !self.visited.insert(uid) { + if !self.visited.insert(resolved.id) { return Ok(None); } + let uid = resolved.id.clone(); log_trace!(uid = uid; "adding dependency"); - let (uid, new_arch) = self.get_arch(uid).await?; + let (uid, new_arch) = self + .get_arch(resolved) + .await + .with_context(|| format!("getting archive for {uid}"))?; let new_action = new_arch .get_actions() @@ -455,7 +674,7 @@ impl Ctx<'_, '_> { Box::pin(self.apply(&new_action, uid, &new_arch)) .await - .with_context(|| format!("Depends {uid}")) + .with_context(|| format!("applying Depends {uid}")) } } } diff --git a/executor/src/rt/supervisor/mod.rs b/executor/src/rt/supervisor/mod.rs index 529c2f499..1ee0ee120 100644 --- a/executor/src/rt/supervisor/mod.rs +++ b/executor/src/rt/supervisor/mod.rs @@ -13,7 +13,7 @@ use crate::{ runners, wasi, }; -mod actions; +pub(crate) mod actions; mod compilation; struct WasmModuleCache { @@ -76,6 +76,10 @@ pub struct Supervisor { runner_cache: runners::cache::Reader, wasm_mod_cache: WasmModuleCache, + /// Runners registered at runtime via `gl_call`, looked up by the + /// `custom:` runner id. Empty until a contract registers one. + custom_runners: dashmap::DashMap, + pub(crate) engines: rt::DetNondet, pub(crate) host: Arc, } @@ -145,6 +149,10 @@ pub async fn await_nondet_vms(zelf: &Arc) -> anyhow::Result Option { + self.custom_runners.get(&hash).map(|r| r.clone()) + } + + pub fn prepopulate_deploy_runner( + &self, + address: calldata::Address, + code_slot: crate::SlotID, + archive: runners::Archive, + ) { + let id = runners::Id::Chain { + address, + on: runners::ChainState::Deploy, + slot: code_slot, + } + .canonical(); + self.runner_cache.put(id, archive); + } + + /// Registers a runner from its `code`, returning the `custom:` id it can + /// be referenced by. + /// + /// The archive is parsed and charged against `limiter` only the first time a + /// given hash is seen — re-registering the same code is a cheap no-op, so a + /// contract cannot exhaust the memory limit by registering in a loop. + pub fn register_custom_runner( + &self, + code: bytes::Bytes, + limiter: &rt::memlimiter::Limiter, + ) -> anyhow::Result { + register_custom_runner_into(&self.custom_runners, code, limiter) + } + pub fn start(config: &config::Config, ctor: Ctor) -> anyhow::Result> { let my_cache_dir = runners::cache::get_cache_dir(&config.cache_dir).ok(); @@ -277,13 +318,14 @@ impl Supervisor { runner_cache: runners::cache::Reader::new( std::path::Path::new(&config.runners_dir), std::path::Path::new(&config.registry_dir), - debug_mode, + debug_mode.allows_latest_resolution(), ) .context("creating runner cache reader")?, wasm_mod_cache: WasmModuleCache { cache_dir: my_cache_dir, wasm_modules_cache: sync::CacheMap::new(), }, + custom_runners: dashmap::DashMap::new(), host: Arc::new(ctor.multi_host), engines, }); @@ -317,7 +359,7 @@ pub async fn spawn( }); } - let config_copy = vm.conf; + let config_copy = vm.conf.clone(); let engine = zelf.engines.get(vm.conf.is_deterministic); @@ -329,10 +371,12 @@ pub async fn spawn( error: anyhow::Error::from(a), state: Box::new(rt::SpawnErrorState::Unspawned(b)), })?, - supervisor: zelf.clone(), }, wasmtime::GenVMCtx { - should_quit: zelf.shared_data.cancellation.should_quit.clone(), + // The executor has no cooperative cancellation; the manager kills the + // process on timeout. wasmtime still requires this flag, so feed it a + // never-set atomic. + should_quit: std::sync::Arc::new(std::sync::atomic::AtomicU32::new(0)), }, ); @@ -364,22 +408,9 @@ pub async fn apply_contract_actions( zelf: &std::sync::Arc, mut vm: rt::vm::VM<()>, ) -> std::result::Result, rt::SpawnError> { - let contract_address = vm - .vm_base - .store - .data() - .genlayer_ctx - .genlayer_sdk - .data - .message_data - .message - .contract_address; - - let contract_id = runners::get_runner_of_contract(contract_address); - let limiter = vm.vm_base.store.data_mut().limits.clone(); - let res = apply_contract_actions_inner(zelf, &mut vm, contract_id, limiter).await; + let res = apply_contract_actions_inner(zelf, &mut vm, limiter).await; match res { Ok(inst) => Ok(rt::vm::VM { @@ -396,49 +427,57 @@ pub async fn apply_contract_actions( async fn apply_contract_actions_inner( zelf: &std::sync::Arc, vm: &mut rt::vm::VM<()>, - contract_id: GlobalSymbol, limiter: rt::memlimiter::Limiter, ) -> anyhow::Result { - let arch = zelf - .runner_cache - .get_or_create( - contract_id, - || async { - let code = vm - .vm_base - .store - .data_mut() - .genlayer_ctx - .genlayer_sdk - .data - .storage - .read_code(&limiter) - .await - .with_context(|| format!("reading contract code for {contract_id}"))?; - - runners::parse(bytes::Bytes::from(code)) - .with_context(|| format!("parsing contract runner for {contract_id}")) - }, - &limiter, - ) + let data = &mut vm.vm_base.store.data_mut().genlayer_ctx.genlayer_sdk.data; + + let topmost_runner_id = data.conf.topmost_runner_id.clone(); + let contract_major = data + .storage + .read_major() .await - .map_err(|e| rt::errors::VMError::wrap(public_abi::VmError::invalid_contract().val(), e))?; + .with_context(|| format!("reading contract major for {topmost_runner_id}"))?; + let node_major = genvm_common::version::CURRENT.major; + if contract_major as u16 != node_major { + return Err(rt::errors::VMError( + public_abi::VmError::invalid_contract().major_mismatch(), + Some(anyhow::anyhow!( + "contract major {contract_major} != node major {node_major}" + )), + ) + .into()); + } + + let topmost_runner_id = data.conf.topmost_runner_id.clone(); + + let arch = actions::load_runner( + zelf, + &limiter, + topmost_runner_id.clone(), + &data.accumulator.custom_runners, + ) + .await + .with_context(|| format!("getting runner for {topmost_runner_id}"))? + .1; let actions = arch .get_actions() .await - .with_context(|| format!("loading init actions for contract {contract_id}")) + .with_context(|| format!("loading init actions for contract {topmost_runner_id}")) .map_err(|e| rt::errors::VMError::wrap(public_abi::VmError::invalid_contract().val(), e))?; let mut ctx = actions::Ctx { env: BTreeMap::new(), visited: HashSet::new(), - contract_id, + topmost_runner_id: topmost_runner_id.clone(), supervisor: zelf, vm: &mut vm.vm_base, }; - let inst = match ctx.apply(&actions, contract_id, &arch).await { + let inst = match ctx + .apply(&actions, topmost_runner_id.canonical(), &arch) + .await + { Ok(Some(inst)) => inst, Ok(None) => { return Err(anyhow::anyhow!( @@ -488,11 +527,6 @@ async fn nondet_vm_processor( let mut count = 0; loop { tokio::select! { - _ = zelf.shared_data.cancellation.chan.closed() => { - log_debug!("cancellation requested, stopping nondet validator queue"); - break; - } - _ = zelf.queue.vm_countdown.wait() => { log_debug!("vm countdown reached zero, stopping nondet validator queue"); break; @@ -559,3 +593,53 @@ async fn nondet_vm_processor( std::mem::drop(read_permit); log_debug!(count = count; "nondet worker done"); } + +/// Core of [`Supervisor::register_custom_runner`]; charges the parsed archive +/// against `limiter` only on the first registration of a given hash. +fn register_custom_runner_into( + custom_runners: &dashmap::DashMap, + code: bytes::Bytes, + limiter: &rt::memlimiter::Limiter, +) -> anyhow::Result { + let hash = runners::custom_runner_hash(&code); + + if let dashmap::mapref::entry::Entry::Vacant(slot) = custom_runners.entry(hash) { + let archive = runners::parse(code).map_err(|e| { + rt::errors::VMError::wrap(public_abi::VmError::invalid_contract().val(), e) + })?; + if !limiter.consume(archive.total_size) { + return Err(rt::errors::VMError(public_abi::VmError::oom().ram().val(), None).into()); + } + slot.insert(archive); + } + + Ok(runners::Id::Custom { hash }.canonical()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn register_custom_runner_consumes_once() { + let map = dashmap::DashMap::new(); + let limiter = rt::memlimiter::Limiter::new("test-register"); + let code = bytes::Bytes::from_static(b"# { \"Depends\": \"py-genlayer:test\" }\n"); + + let id = register_custom_runner_into(&map, code.clone(), &limiter).unwrap(); + let remaining_after_first = limiter.get_remaining_memory(); + + // the first registration must have charged the archive + assert!(remaining_after_first < u32::MAX); + + // re-registering the same code must be a cheap no-op: same id, no extra + // memory charged and no duplicate map entries + for _ in 0..1000 { + let again = register_custom_runner_into(&map, code.clone(), &limiter).unwrap(); + assert_eq!(again, id); + } + + assert_eq!(limiter.get_remaining_memory(), remaining_after_first); + assert_eq!(map.len(), 1); + } +} diff --git a/executor/src/rt/vm/mod.rs b/executor/src/rt/vm/mod.rs index 5071c71b3..552d04fe6 100644 --- a/executor/src/rt/vm/mod.rs +++ b/executor/src/rt/vm/mod.rs @@ -92,17 +92,10 @@ impl RunOk { RunOk::UserError(val) => { let mut res = vec![ResultCode::UserError as u8]; match val { - // FIXME: deprecate in next release (always use the tagged calldata form below) - calldata::unparsed::Maybe::Materialized(calldata::Value::Str(s)) => { - res.extend_from_slice(s.as_bytes()); + calldata::unparsed::Maybe::Materialized(value) => { + res.extend_from_slice(&calldata::encode(value)); } - calldata::unparsed::Maybe::Materialized(other) => { - res.extend_from_slice(&0u32.to_le_bytes()); - res.extend_from_slice(&calldata::encode(other)); - } - // Already-encoded calldata bytes; emit them in the tagged form. calldata::unparsed::Maybe::Checked(raw) => { - res.extend_from_slice(&0u32.to_le_bytes()); res.extend_from_slice(&raw.0); } } @@ -149,7 +142,6 @@ impl std::fmt::Display for RunOk { pub struct WasmtimeStoreData { pub(super) genlayer_ctx: wasi::Context, pub(super) limits: rt::memlimiter::Limiter, - pub(super) supervisor: std::sync::Arc, } impl WasmtimeStoreData { @@ -226,32 +218,6 @@ impl VM { let wasm_store_hashes = self.vm_base.wasm_store_hashes(); - let res = if self - .vm_base - .store - .data() - .supervisor - .shared_data - .cancellation - .is_cancelled() - { - match res { - Ok((rt::vm::RunOk::VMError(msg, cause), backtrace)) => Ok(( - rt::vm::RunOk::VMError( - public_abi::VmError::timeout(), - cause.map(|v| v.context(msg.0)), - ), - backtrace, - )), - Ok(r) => Ok(r), - Err(e) => Ok(( - rt::vm::RunOk::VMError(public_abi::VmError::timeout(), Some(e)), - None, - )), - } - } else { - res - }; match &res { Ok((rt::vm::RunOk::Return(_), _)) => { log_debug!(result = "Return"; "execution result unwrapped") diff --git a/executor/src/rt/vm/storage.rs b/executor/src/rt/vm/storage.rs index eaa4bf31c..3ae2383d4 100644 --- a/executor/src/rt/vm/storage.rs +++ b/executor/src/rt/vm/storage.rs @@ -5,7 +5,7 @@ use const_lru::ConstLru; use genlayer_sdk::abi; use genvm_common::{calldata, sync}; -use crate::{host::message::root_offsets, rt, SlotID}; +use crate::{public_abi::root_offsets, rt, runners, SlotID}; #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] #[repr(C)] @@ -165,6 +165,10 @@ impl Storage { } } +pub fn default_code_slot() -> SlotID { + SlotID::ZERO.indirection(root_offsets::CODE) +} + impl Storage { pub async fn read( &mut self, @@ -257,8 +261,13 @@ impl Storage { let mut page_data = [0u8; 32]; page_data.copy_from_slice(&buf[src_offset..src_offset + 32]); - put_to_cache[put_to_cache_count].write((page_id, page_data)); - put_to_cache_count = (put_to_cache_count + 1) % put_to_cache.len(); + if put_to_cache_count < put_to_cache.len() { + put_to_cache[put_to_cache_count].write((page_id, page_data)); + put_to_cache_count += 1; + } else { + // staging buffer full: insert directly so no read page is dropped + self.cache.insert(page_id, page_data); + } } } @@ -392,7 +401,7 @@ impl Storage { } pub async fn write_code(&mut self, code: &[u8]) -> anyhow::Result<()> { - let code_slot = SlotID::ZERO.indirection(root_offsets::CODE); + let code_slot = default_code_slot(); if code.len() > (u32::MAX - 4) as usize { return Err(rt::errors::VMError(abi::consts::VmError::oom().storage(), None).into()); @@ -407,12 +416,60 @@ impl Storage { Ok(()) } - pub async fn read_code( + /// Reads the GenVM major version the contract was deployed for, from the + /// `major` root field (zero if never written). + pub async fn read_major(&mut self) -> anyhow::Result { + let mut buf = [0u8; 1]; + self.read(SlotID::ZERO, root_offsets::MAJOR, &mut buf) + .await?; + Ok(buf[0]) + } + + /// Writes the GenVM major version the contract is deployed for into the + /// `major` root field, so later runs can verify major compatibility (see + /// [`read_major`]). Written on deploy alongside the code. + pub async fn write_major(&mut self, major: u8) -> anyhow::Result<()> { + self.write(SlotID::ZERO, root_offsets::MAJOR, &[major]) + .await + } + + /// Resolves the slot the contract code is stored at: the raw `code_slot` root + /// field if set, otherwise the default `code` slot. + pub async fn resolve_code_slot(&mut self) -> anyhow::Result { + let mut raw = [0u8; 32]; + self.read(SlotID::ZERO, root_offsets::CODE_SLOT, &mut raw) + .await?; + if raw == [0u8; 32] { + Ok(default_code_slot()) + } else { + Ok(SlotID::from_bytes(raw)) + } + } + + /// Verifies the contract's major version matches this node's, then resolves + /// its code slot. The major is checked *first*, before trusting the + /// host-read code-slot pointer; on mismatch a `major_mismatch` [`VMError`] + /// is returned so the caller surfaces it as a contract error. + pub async fn check_major_and_resolve_code_slot(&mut self) -> anyhow::Result { + let contract_major = self.read_major().await?; + let node_major = genvm_common::version::CURRENT.major; + if contract_major as u16 != node_major { + return Err(rt::errors::VMError( + abi::consts::VmError::invalid_contract().major_mismatch(), + Some(anyhow::anyhow!( + "contract major {contract_major} != node major {node_major}" + )), + ) + .into()); + } + self.resolve_code_slot().await + } + + pub async fn read_code_at( &mut self, + code_slot: SlotID, limiter: &rt::memlimiter::Limiter, ) -> anyhow::Result> { - let code_slot = SlotID::ZERO.indirection(root_offsets::CODE); - let mut len_buf = [0; 4]; self.read(code_slot, 0, &mut len_buf).await?; let code_size = u32::from_le_bytes(len_buf); diff --git a/executor/src/runners/actions.rs b/executor/src/runners/actions.rs index ceef35ea1..83221e640 100644 --- a/executor/src/runners/actions.rs +++ b/executor/src/runners/actions.rs @@ -1,4 +1,3 @@ -use genvm_common::*; use std::sync::Arc; #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Debug)] @@ -19,9 +18,7 @@ pub enum InitAction { val: String, }, SetArgs(Vec), - Depends( - #[serde(deserialize_with = "util::global_symbol_deserialize")] symbol_table::GlobalSymbol, - ), + Depends(String), LinkWasm(Arc), StartWasm(Arc), @@ -32,8 +29,7 @@ pub enum InitAction { Seq(Vec), With { - #[serde(deserialize_with = "util::global_symbol_deserialize")] - runner: symbol_table::GlobalSymbol, + runner: String, action: Box, }, } diff --git a/executor/src/runners/cache.rs b/executor/src/runners/cache.rs index a7430a69c..e2b15d530 100644 --- a/executor/src/runners/cache.rs +++ b/executor/src/runners/cache.rs @@ -4,12 +4,53 @@ use super::*; use genlayer_sdk::abi; use genvm_common::*; +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[repr(transparent)] +pub struct StrSymbol(symbol_table::GlobalSymbol); + +impl StrSymbol { + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +impl std::borrow::Borrow for StrSymbol { + fn borrow(&self) -> &str { + self.0.as_str() + } +} + +impl Ord for StrSymbol { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.as_str().cmp(other.as_str()) + } +} + +impl PartialOrd for StrSymbol { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl serde::Serialize for StrSymbol { + fn serialize(&self, serializer: S) -> Result { + self.0.as_str().serialize(serializer) + } +} + +impl<'de> serde::Deserialize<'de> for StrSymbol { + fn deserialize>(deserializer: D) -> Result { + let s = String::deserialize(deserializer)?; + Ok(Self(symbol_table::GlobalSymbol::from(s))) + } +} + pub struct Reader { cache: sync::CacheMap, runners_data_path: std::path::PathBuf, - all: BTreeMap>, - latest: BTreeMap, + all: BTreeMap>, + latest: BTreeMap, } impl Reader { @@ -48,17 +89,13 @@ impl Reader { }) } - pub fn get_latest(&self, id: symbol_table::GlobalSymbol) -> Option { - self.latest.get(&id).cloned() + pub fn get_latest(&self, id: &str) -> Option<&str> { + self.latest.get(id).map(|s| s.as_str()) } - pub fn has_in_all( - &self, - id: symbol_table::GlobalSymbol, - hash: symbol_table::GlobalSymbol, - ) -> bool { - match self.all.get(&id) { - Some(hashes) => hashes.binary_search(&hash).is_ok(), + pub fn has_in_all(&self, id: &str, hash: &str) -> bool { + match self.all.get(id) { + Some(hashes) => hashes.binary_search_by(|h| h.as_str().cmp(hash)).is_ok(), None => false, } } @@ -67,6 +104,10 @@ impl Reader { &self.runners_data_path } + pub fn put(&self, id: symbol_table::GlobalSymbol, archive: Archive) { + self.cache.insert(id, ArchiveCache::new(id, archive)); + } + pub async fn get_or_create( &self, name: symbol_table::GlobalSymbol, diff --git a/executor/src/runners/mod.rs b/executor/src/runners/mod.rs index ebb0495b8..668c2c007 100644 --- a/executor/src/runners/mod.rs +++ b/executor/src/runners/mod.rs @@ -23,11 +23,231 @@ pub fn append_runner_subpath(id: &str, hash: &str, path: &mut std::path::PathBuf path.push(&hash[2..]); } -pub fn get_runner_of_contract(address: calldata::Address) -> symbol_table::GlobalSymbol { - let mut contract_id = String::from("on_chain:0x"); - contract_id.push_str(&hex::encode(address.raw())); +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, genlayer_calldata::Encode)] +pub enum ChainState { + Accepted, + Finalized, + Deploy, +} + +impl ChainState { + pub fn for_vm(is_init: bool, state: crate::public_abi::StorageType) -> Self { + if is_init { + ChainState::Deploy + } else { + match state { + crate::public_abi::StorageType::LatestFinal => ChainState::Finalized, + _ => ChainState::Accepted, + } + } + } + + pub fn host_storage_type(self) -> Option { + match self { + ChainState::Accepted => Some(crate::public_abi::StorageType::LatestNonFinal), + ChainState::Finalized => Some(crate::public_abi::StorageType::LatestFinal), + ChainState::Deploy => None, + } + } + + fn canonical_char(self) -> char { + match self { + ChainState::Accepted => 'a', + ChainState::Finalized => 'f', + ChainState::Deploy => 'd', + } + } +} + +/// A parsed runner id. Runner ids come in the following forms: +/// +/// - `name:hash` — a packaged runner identified by its human readable name and +/// content hash (in debug mode `hash` may also be `test`/`latest`). +/// - `contract` — the runner of the contract that is currently being executed. +/// - `chain:
::` — read the runner code blob from a storage +/// slot of an arbitrary contract. `address` is a `0x`-prefixed 20 byte hex +/// address, `a`/`f` selects accepted (latest non final) / finalized state and +/// `slot` is a 32 byte slot id encoded with GVM32 (Crockford Base32). +/// Both `` and `` are optional: `` defaults to `a` and +/// `` defaults to reading the target contract's root slot during +/// resolution (i.e. `chain:
` and `chain:
:a` are valid). +/// - `custom:` — a runner registered at runtime, looked up by its hash. +#[derive(Debug)] +pub enum IdUnresolved { + Builtin { + name: String, + hash: String, + }, + Contract, + Chain { + address: calldata::Address, + on: Option, + slot: Option, + }, + Custom { + hash: String, + }, +} + +#[derive(Debug, Clone)] +pub enum Id { + Builtin { + name: symbol_table::GlobalSymbol, + hash: Bytes32Hash, + }, + Chain { + address: calldata::Address, + on: ChainState, + slot: crate::SlotID, + }, + Custom { + hash: Bytes32Hash, + }, +} + +impl serde::Serialize for Id { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.canonical().as_str()) + } +} + +impl calldata::codec::Encode for Id { + type Error = ::Error; + + fn encode(&self, encoder: &mut genlayer_calldata::Encoder) -> Result<(), Self::Error> { + let canonical = self.canonical(); + encoder.push_str(canonical.as_str()) + } +} + +impl Id { + /// The canonical textual runner id, used as the archive cache key. Two ids + /// that resolve to the same `(name, hash)` / `(address, state, slot)` / hash + /// produce the same symbol (e.g. `contract` and an explicit self `chain:`). + pub fn canonical(&self) -> symbol_table::GlobalSymbol { + match self { + Id::Builtin { name, hash } => { + let mut id = name.as_str().to_owned(); + id.push(':'); + id.push_str(&hash.to_gvm32()); + symbol_table::GlobalSymbol::from(id) + } + Id::Chain { address, on, slot } => symbol_table::GlobalSymbol::from(format!( + "chain:0x{}:{}:{}", + address.checksum_hex_string(), + on.canonical_char(), + genlayer_sdk::gvm32::encode(&slot.raw()) + )), + Id::Custom { hash } => { + let mut id = String::from("custom:"); + id.push_str(&hash.to_gvm32()); + symbol_table::GlobalSymbol::from(id) + } + } + } +} + +impl std::fmt::Display for Id { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.canonical().as_str()) + } +} + +fn is_hash_char(c: char) -> bool { + c.is_ascii_alphanumeric() || c == '-' || c == '_' || c == '=' +} + +fn parse_hex_fixed(s: &str) -> Option<[u8; N]> { + let s = s.strip_prefix("0x")?; + if s.len() != N * 2 { + return None; + } + let mut out = [0u8; N]; + hex::decode_to_slice(s, &mut out).ok()?; + Some(out) +} + +pub fn parse_runner_id(id: &str) -> Option { + if id == "contract" { + return Some(IdUnresolved::Contract); + } + + if let Some(rest) = id.strip_prefix("chain:") { + let mut it = rest.split(':'); + let address = it.next()?; + let on_str = it.next(); + let slot_str = it.next(); + if it.next().is_some() { + return None; + } + + let address = calldata::Address::from(parse_hex_fixed::<20>(address)?); + let on = match on_str { + Some("a") | None => Some(ChainState::Accepted), + Some("f") => Some(ChainState::Finalized), + _ => return None, + }; + let slot = match slot_str { + Some(s) => { + let bytes: [u8; 32] = genlayer_sdk::gvm32::decode(s).ok()?.try_into().ok()?; + Some(crate::SlotID::from_bytes(bytes)) + } + None => None, + }; + + return Some(IdUnresolved::Chain { address, on, slot }); + } + + if let Some(rest) = id.strip_prefix("custom:") { + if rest.is_empty() || !rest.chars().all(is_hash_char) { + return None; + } + return Some(IdUnresolved::Custom { + hash: rest.to_owned(), + }); + } + + let (name, hash) = id.split_once(':')?; + if name.is_empty() || hash.is_empty() { + return None; + } + for c in name.chars() { + if !c.is_ascii_alphanumeric() && c != '-' && c != '_' { + log_warn!("character `{c}` is not allowed in runner id"); + return None; + } + } + if !hash.chars().all(is_hash_char) { + return None; + } + Some(IdUnresolved::Builtin { + name: name.to_owned(), + hash: hash.to_owned(), + }) +} + +/// The dev-mode magic builtin/custom runner hash. Its GVM32 form is the literal +/// string `test` padded with `0`s to 52 chars (`test0000…`), which is what shows +/// up on disk and in `all.json`/`latest.json`. The raw bytes below are exactly +/// `gvm32::decode("test0000…")`. Kept in sync with `hashToIDHash` in +/// `runners/support/default.nix`. +pub const TEST_RUNNER_HASH: Bytes32Hash = { + let mut bytes = [0u8; 32]; + bytes[0] = 0xd3; + bytes[1] = 0xb3; + bytes[2] = 0xa0; + Bytes32Hash::from_bytes(bytes) +}; - symbol_table::GlobalSymbol::from(contract_id) +pub fn custom_runner_hash(code: &[u8]) -> Bytes32Hash { + use sha3::Digest as _; + let mut digest = sha3::Sha3_256::new(); + digest.update(code); + let arr: [u8; 32] = digest.finalize().into(); + Bytes32Hash::from_bytes(arr) } pub struct ArchiveCache { diff --git a/executor/src/runners/ustar.rs b/executor/src/runners/ustar.rs index ebb93c9b9..217788b7a 100644 --- a/executor/src/runners/ustar.rs +++ b/executor/src/runners/ustar.rs @@ -1,5 +1,6 @@ use std::collections::BTreeMap; +#[derive(Clone)] pub struct Archive { pub data: BTreeMap, pub total_size: u32, @@ -94,7 +95,11 @@ impl Archive { begin += file_size; begin += (BLOCK_SIZE - (begin % BLOCK_SIZE)) % BLOCK_SIZE; - let file_contents = data.slice(BLOCK_SIZE..BLOCK_SIZE + file_size); + let file_end = BLOCK_SIZE + .checked_add(file_size) + .filter(|end| *end <= data.len()) + .ok_or_else(|| anyhow::anyhow!("tar file size exceeds archive bounds"))?; + let file_contents = data.slice(BLOCK_SIZE..file_end); map_try_insert(&mut res, name, file_contents)?; } @@ -119,13 +124,24 @@ impl Archive { } let start_index = file.data_start(); - let end_index = file.data_start() + file.compressed_size(); - if end_index > bytes.len() as u64 || start_index > bytes.len() as u64 { + let compressed_size = file.compressed_size(); + let end_index = start_index.checked_add(compressed_size).ok_or_else(|| { + anyhow::anyhow!( + "file {} data_start={} compressed_size={} overflow", + file.name(), + start_index, + compressed_size + ) + })?; + if end_index > bytes.len() as u64 + || start_index > bytes.len() as u64 + || end_index < start_index + { anyhow::bail!( "file {} data_start={} compressed_size={} end_index={} bytes_len={}", file.name(), - file.data_start(), - file.compressed_size(), + start_index, + compressed_size, end_index, bytes.len() ); diff --git a/executor/src/wasi/base.rs b/executor/src/wasi/base.rs index 88844f627..8bc391773 100644 --- a/executor/src/wasi/base.rs +++ b/executor/src/wasi/base.rs @@ -1,8 +1,8 @@ use serde::Serialize; -use crate::public_abi; +use crate::{public_abi, runners}; -#[derive(Clone, Copy, Serialize, genlayer_calldata::Encode)] +#[derive(Clone, Serialize, genlayer_calldata::Encode)] pub struct Config { pub needs_error_fingerprint: bool, pub is_deterministic: bool, @@ -11,7 +11,9 @@ pub struct Config { pub can_spawn_nondet: bool, pub can_send_messages: bool, pub can_call_others: bool, + pub can_register_runners: bool, pub state_mode: public_abi::StorageType, + pub topmost_runner_id: runners::Id, } impl Config { diff --git a/executor/src/wasi/genlayer_sdk.rs b/executor/src/wasi/genlayer_sdk.rs index e97fd00a4..482be4c86 100644 --- a/executor/src/wasi/genlayer_sdk.rs +++ b/executor/src/wasi/genlayer_sdk.rs @@ -1,7 +1,6 @@ use std::collections::BTreeMap; use std::sync::Arc; -use genlayer_sdk::abi::gl_call::llm_iface; use genvm_common::sync::DArc; use genvm_common::*; @@ -10,8 +9,7 @@ use sha3::digest::Update; use wiggle::GuestError; use crate::host::{self, SlotID}; -use crate::wasi::json_to_calldata::json_map_to_calldata; -use crate::{anyhow_to_wasmtime, calldata, public_abi, rt}; +use crate::{anyhow_to_wasmtime, calldata, public_abi, rt, runners, wasi}; use genlayer_calldata::codec::Encode; pub use genlayer_sdk::abi::entry::ExtendedMessage; @@ -49,10 +47,11 @@ async fn consume_message_fee_internal( .calculate_message_fee_internal(on, &fee_params) .map_err(|x| generated::types::Error::trap(anyhow_to_wasmtime(x)))?; - if fee_cost > node.budget { + let fee_total = fee_cost.sum(); + if fee_total > node.budget { log_warn!( node:cd = *node, - fee_cost:cd = fee_cost, + fee_cost:cd = fee_total, budget: cd = node.budget; "message fee cost exceeds node budget" ); @@ -76,20 +75,19 @@ async fn consume_message_fee_internal( if !shared_data .data_fees_limit - .consume_message_fee(fee_cost, receipt_cost) + .consume_message_fee(&fee_cost, &receipt_cost) .await { log_warn!( node:cd = *node, - fee_cost:cd = fee_cost, - receipt_cost: cd = receipt_cost, + fee_cost:cd = fee_total, buckets:? = shared_data.data_fees_limit; "not enough remaining fee limit to consume message fee" ); return Err(oom_trap(abi::consts::VmError::oom().fees().internal())); } - node.budget -= fee_cost; + node.budget -= fee_total; Ok(rt::fees::MessageFeeConsumption { message_fee: fee_cost, @@ -117,7 +115,8 @@ async fn consume_message_fee_external( .calculate_message_fee_external(¶ms) .map_err(|x| generated::types::Error::trap(anyhow_to_wasmtime(x)))?; - if fee_cost > node.budget { + let fee_total = fee_cost.sum(); + if fee_total > node.budget { return Err(oom_trap(abi::consts::VmError::oom().fees().external())); } @@ -134,13 +133,13 @@ async fn consume_message_fee_external( if !shared_data .data_fees_limit - .consume_message_fee(fee_cost, receipt_cost) + .consume_message_fee(&fee_cost, &receipt_cost) .await { return Err(oom_trap(abi::consts::VmError::oom().fees().external())); } - node.budget -= fee_cost; + node.budget -= fee_total; Ok(rt::fees::MessageFeeConsumption { message_fee: fee_cost, @@ -250,6 +249,26 @@ pub struct VMDataAccumulator { pub messages_value_decremented: primitive_types::U256, pub emissions: Vec, pub message_fee_allocation: Vec, + /// Custom runner hashes registered in (and inherited into) this execution + /// scope. Only these may be resolved via `custom:`. A nondet sub-VM + /// starts empty, so it cannot see runners the deterministic scope registered. + pub custom_runners: rpds::HashTrieSet, +} + +impl VMDataAccumulator { + /// Asserts the accumulator carries no surfaced effects (events, + /// message-fee allocations). Call it after running a sub-VM whose + /// accumulator is discarded (e.g. a `CallContract` child) to guarantee no + /// effect was charged but silently dropped. Returns a fatal error otherwise. + pub fn check_empty(&self) -> anyhow::Result<()> { + anyhow::ensure!( + self.emissions.is_empty() && self.message_fee_allocation.is_empty(), + "internal error: discarded sub-VM accumulator is not empty ({} emission(s), {} message-fee allocation(s))", + self.emissions.len(), + self.message_fee_allocation.len(), + ); + Ok(()) + } } pub struct SingleVMData { @@ -271,6 +290,7 @@ pub struct Context { pub struct ContextVFS<'a> { pub(super) vfs: &'a mut vfs::VFS, + pub(super) preview1: &'a mut super::preview1::Context, pub(super) context: &'a mut Context, } @@ -307,6 +327,18 @@ pub(crate) mod generated { }); } +impl From for generated::types::Fd { + fn from(fd: wasi::vfs::Fd) -> Self { + fd.as_u32().into() + } +} + +impl From for wasi::vfs::Fd { + fn from(fd: generated::types::Fd) -> Self { + wasi::vfs::Fd::new(fd.into()) + } +} + fn read_addr_from_mem( mem: &mut wiggle::GuestMemory<'_>, addr: wiggle::GuestPtr, @@ -448,6 +480,16 @@ impl From for generated::types::Error { } impl ContextVFS<'_> { + fn place_content( + &mut self, + content: vfs::FileContents, + ) -> Result { + self.vfs + .place_content(content) + .map(generated::types::Fd::from) + .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e))) + } + fn set_vm_run_result( &mut self, data: rt::vm::RunOk, @@ -462,18 +504,8 @@ impl ContextVFS<'_> { }; let data: Vec = data.as_bytes(); let len = data.len(); - Ok(( - generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(data), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - ), - len, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(data))) + .map(|fd| (fd, len)) } } @@ -635,8 +667,8 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { address, calldata, value, - message_fee: fees.message_fee, - receipt_fee: fees.receipt_fee, + message_fee: fees.message_fee.sum(), + receipt_fee: fees.receipt_fee.sum(), fee_params: matched_params, }); @@ -657,21 +689,13 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { } let supervisor = self.context.data.supervisor.clone(); - let res = supervisor + let data = supervisor .host .lock_for(host::host_fns::Methods::EthCall) .await .eth_call(address, &calldata) .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; - Ok(generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(res), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(data))) } gl_call::Message::CallContract { address, @@ -691,7 +715,7 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { let supervisor = self.context.data.supervisor.clone(); - let my_conf = self.context.data.conf; + let my_conf = self.context.data.conf.clone(); let calldata_encoded = calldata::encode_obj(&calldata); @@ -704,8 +728,26 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { let calldata_encoded = calldata::encode_obj(&calldata); + let mut child_storage = rt::vm::storage::Storage::new( + address, + supervisor.get_storage_limiter(), + StorageHostHolder( + supervisor.host.clone(), + ReadToken { + account: address, + mode: state, + }, + ), + ); + + let code_slot = child_storage + .check_major_and_resolve_code_slot() + .await + .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; + let vm_data = Box::new(SingleVMData { depth: self.context.data.depth + 1, + // Permission model: doc/website/src/spec/03-vm/05-permissions.rst conf: base::Config { needs_error_fingerprint: true, is_deterministic: true, @@ -713,8 +755,18 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { can_write_storage: false, can_spawn_nondet: my_conf.can_spawn_nondet, can_call_others: my_conf.can_call_others, - can_send_messages: my_conf.can_send_messages, + can_send_messages: false, + can_register_runners: my_conf.can_register_runners, state_mode: state, + topmost_runner_id: runners::Id::Chain { + address, + on: if state == public_abi::StorageType::LatestFinal { + runners::ChainState::Finalized + } else { + runners::ChainState::Accepted + }, + slot: code_slot, + }, }, message_data: ExtendedMessage { message: genlayer_sdk::abi::entry::MessageData { @@ -731,17 +783,7 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { entry_data: my_data.entry_data, entry_stage_data: default_entry_stage_data(), }, - storage: rt::vm::storage::Storage::new( - address, - supervisor.get_storage_limiter(), - StorageHostHolder( - supervisor.host.clone(), - ReadToken { - account: address, - mode: state, - }, - ), - ), + storage: child_storage, supervisor: supervisor.clone(), accumulator: VMDataAccumulator { data_fees_limit: self.context.data.accumulator.data_fees_limit.clone(), @@ -752,6 +794,9 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { .messages_value_decremented, emissions: Vec::new(), message_fee_allocation: Vec::new(), + // CallContract is a deterministic sub-call: inherit the + // runners registered so far. + custom_runners: self.context.data.accumulator.custom_runners.clone(), }, det_subvm_hashes: Default::default(), }); @@ -760,6 +805,13 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { .await .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; + // The child is read-only (static), so its accumulator must be + // empty — otherwise an effect was charged but discarded here. + res.vm_data + .accumulator + .check_empty() + .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; + let hash = res.small_hash(); self.context.data.det_subvm_hashes.update(&hash); @@ -771,6 +823,15 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { return Err(generated::types::Errno::Forbidden.into()); } + // Events are state-mutating log emissions, so they require the + // same write capability as storage. A read-only sub-VM (e.g. a + // `CallContract` child) must not emit events; otherwise the + // emission is charged but later discarded with the child. + if !self.context.data.conf.can_write_storage { + log_warn!("EmitEvent requires write_storage permission"); + + return Err(generated::types::Errno::Forbidden.into()); + } if topics.len() > public_abi::EVENT_MAX_TOPICS as usize { log_warn!(cnt = topics.len(), max = public_abi::EVENT_MAX_TOPICS; "too many topics"); @@ -933,8 +994,8 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { calldata, value, on, - message_fee: fees.message_fee, - receipt_fee: fees.receipt_fee, + message_fee: fees.message_fee.sum(), + receipt_fee: fees.receipt_fee.sum(), fee_params, subtree, }, @@ -1038,8 +1099,8 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { value, on, salt_nonce, - message_fee: fees.message_fee, - receipt_fee: fees.receipt_fee, + message_fee: fees.message_fee.sum(), + receipt_fee: fees.receipt_fee.sum(), fee_params, subtree, }, @@ -1090,15 +1151,7 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { .await .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; - Ok(generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(task), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(task))) } gl_call::Message::WebRequest(request_payload) => { let is_det = self.context.data.conf.is_deterministic; @@ -1136,15 +1189,7 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { .await .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; - Ok(generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(task), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(task))) } gl_call::Message::ExecPrompt(prompt_payload) => { if self.context.data.conf.is_deterministic { @@ -1168,7 +1213,6 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { let sup = self.context.data.supervisor.clone(); let task = taskify(async move { - let format = prompt_payload.response_format; let result = sup .modules .llm @@ -1194,7 +1238,7 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { if result.consumed_gen == primitive_types::U256::MAX { return Err( - rt::errors::VMError(abi::consts::VmError::timeout(), None).into(), + rt::errors::VMError(abi::consts::VmError::timeout(), None).into() ); } @@ -1203,44 +1247,14 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { *acc = acc.saturating_add(result.consumed_gen); } - let mut result = result.data; - - if format == llm_iface::OutputFormat::JSON { - let genvm_modules_interfaces::llm::PromptAnswerData::Text(t) = result - else { - return Err(anyhow::anyhow!("expected text response for json format")); - }; - - let val: serde_json::Map = - serde_json::from_str(&t).map_err(|e| { - generated::types::Error::trap(crate::anyhow_to_wasmtime(e.into())) - })?; - - log_debug!(text = t; "for backwards compatibility we convert text to object for JSON 1"); - - std::mem::drop(t); - - let val = json_map_to_calldata(val); - - log_debug!(converted:serde = val; "for backwards compatibility we convert text to object for JSON 1"); - - result = genvm_modules_interfaces::llm::PromptAnswerData::Object(val); - } + let result = result.data; Ok(Ok(result)) }) .await .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; - Ok(generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(task), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(task))) } gl_call::Message::ExecPromptTemplate(prompt_template_payload) => { if self.context.data.conf.is_deterministic { @@ -1316,20 +1330,8 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { .await .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; - Ok(generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(task), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(task))) } - #[allow(deprecated)] - gl_call::Message::Rollback(msg) => Err(generated::types::Error::trap( - crate::anyhow_to_wasmtime(rt::errors::UserError(msg).into()), - )), gl_call::Message::UserError(msg) => Err(generated::types::Error::trap( crate::anyhow_to_wasmtime(rt::errors::UserError(msg).into()), )), @@ -1342,9 +1344,29 @@ impl generated::genlayer_sdk::GenlayerSdk for ContextVFS<'_> { } => self.run_nondet(data_leader, data_validator).await, gl_call::Message::Sandbox { data, - allow_write_ops, - } => self.sandbox(data, allow_write_ops).await, + runner, + allow_write_storage, + allow_send_messages, + allow_register_runners, + } => { + self.sandbox( + data, + runner, + allow_write_storage, + allow_send_messages, + allow_register_runners, + ) + .await + } + gl_call::Message::RegisterRunner { code } => self.register_runner(code).await, + gl_call::Message::MapFile { + runner, + path_in_runner, + path_in_vfs, + } => self.map_file(runner, path_in_runner, path_in_vfs).await, gl_call::Message::Trace(message) => self.gl_call_trace(message).await, + gl_call::Message::Yield => Ok(file_fd_none()), + gl_call::Message::GetTimestamp => self.gl_call_get_timestamp().await, } } @@ -1540,6 +1562,19 @@ impl ContextVFS<'_> { ) -> Result { match msg { gl_call::TracePayload::Message(text) => { + // Tracing is a debug-only aid; skip the timing and logging work + // entirely when not in debug mode. + if !self + .context + .data + .supervisor + .shared_data + .debug_mode + .allows_tracing() + { + return Ok(file_fd_none()); + } + let now = std::time::Instant::now(); let since_prev = now.duration_since(self.context.prev_time); self.context.prev_time = now; @@ -1555,7 +1590,13 @@ impl ContextVFS<'_> { } gl_call::TracePayload::RuntimeMicroSec => { let elapsed_micros = if self.context.data.conf.is_deterministic - && !self.context.data.supervisor.shared_data.debug_mode + && !self + .context + .data + .supervisor + .shared_data + .debug_mode + .allows_nondeterminism() { 0u64 } else { @@ -1566,19 +1607,92 @@ impl ContextVFS<'_> { let data = calldata::encode(&calldata::Value::Number(num_bigint::BigInt::from( elapsed_micros, ))); - Ok(generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(data), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(data))) } } } + async fn gl_call_get_timestamp( + &mut self, + ) -> Result { + let timestamp = if self.context.data.conf.is_deterministic { + self.context.data.message_data.message.datetime.timestamp() + } else { + chrono::Utc::now().timestamp() + }; + + let data = calldata::encode(&calldata::Value::Number(num_bigint::BigInt::from( + timestamp, + ))); + self.place_content(vfs::FileContents::from(bytes::Bytes::from(data))) + } + + async fn register_runner( + &mut self, + code: bytes::Bytes, + ) -> Result { + if !self.context.data.conf.is_deterministic { + return Err(generated::types::Errno::Forbidden.into()); + } + if !self.context.data.conf.can_register_runners { + return Err(generated::types::Errno::Forbidden.into()); + } + + let is_det = self.context.data.conf.is_deterministic; + let supervisor = self.context.data.supervisor.clone(); + let hash = crate::runners::custom_runner_hash(&code); + let id = supervisor + .register_custom_runner(code, supervisor.limiter.get(is_det)) + .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; + + // Scope the runner to this execution (and its deterministic children) so + // it cannot be resolved from an unrelated scope (e.g. a nondet sub-VM). + self.context.data.accumulator.custom_runners = + self.context.data.accumulator.custom_runners.insert(hash); + + let data = calldata::encode(&calldata::Value::Str(id.as_str().to_owned())); + self.place_content(vfs::FileContents::from(bytes::Bytes::from(data))) + } + + async fn map_file( + &mut self, + runner: String, + path_in_runner: String, + path_in_vfs: String, + ) -> Result { + // Resolving a `chain:` runner reads another contract's storage, so this + // is gated on the same permission as `storage_read` to avoid becoming a + // read-storage bypass. + if !self.context.data.conf.can_read_storage { + return Err(generated::types::Errno::Forbidden.into()); + } + + let supervisor = self.context.data.supervisor.clone(); + let is_det = self.context.data.conf.is_deterministic; + let limiter = supervisor.limiter.get(is_det); + let topmost_runner_id = self.context.data.conf.topmost_runner_id.clone(); + let available_custom = self.context.data.accumulator.custom_runners.clone(); + + let runner = + rt::supervisor::actions::resolve_runner_id(&supervisor, &topmost_runner_id, &runner) + .await + .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; + + rt::supervisor::actions::map_runner_file( + &supervisor, + self.preview1, + limiter, + runner, + &path_in_runner, + &path_in_vfs, + &available_custom, + ) + .await + .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; + + Ok(file_fd_none()) + } + async fn run_nondet( &mut self, data_leader: bytes::Bytes, @@ -1652,22 +1766,11 @@ impl ContextVFS<'_> { )) } x if x == ResultCode::UserError as u8 => { - let val = if rest.len() >= 4 && rest[..4] == [0u8; 4] { - calldata::decode(&rest[4..]).map_err(|e| { - generated::types::Error::trap(crate::anyhow_to_wasmtime( - anyhow::anyhow!(e), - )) - })? - } else { - // FIXME: deprecate in next release (raw-string user error encoding) - calldata::Value::Str(String::from(std::str::from_utf8(rest).map_err( - |e| { - generated::types::Error::trap(crate::anyhow_to_wasmtime( - anyhow::anyhow!(e), - )) - }, - )?)) - }; + let val = calldata::decode(rest).map_err(|e| { + generated::types::Error::trap(crate::anyhow_to_wasmtime( + anyhow::anyhow!(e), + )) + })?; rt::vm::RunOk::UserError(calldata::unparsed::Maybe::Materialized(val)) } x if x == ResultCode::VmError as u8 => { @@ -1734,10 +1837,14 @@ impl ContextVFS<'_> { .messages_value_decremented, emissions: Vec::new(), message_fee_allocation: Vec::new(), + // Nondet is an isolated execution scope: it must NOT see custom + // runners registered by the deterministic scope. + custom_runners: Default::default(), }; let vm_data = Box::new(SingleVMData { depth: self.context.data.depth + 1, + // Permission model: doc/website/src/spec/03-vm/05-permissions.rst conf: base::Config { needs_error_fingerprint: false, is_deterministic: false, @@ -1746,7 +1853,9 @@ impl ContextVFS<'_> { can_spawn_nondet: false, can_call_others: false, can_send_messages: false, + can_register_runners: false, state_mode: public_abi::StorageType::Default, + topmost_runner_id: self.context.data.conf.topmost_runner_id.clone(), }, message_data, supervisor: supervisor.clone(), @@ -1798,10 +1907,19 @@ impl ContextVFS<'_> { async fn sandbox( &mut self, data: bytes::Bytes, - allow_write_ops: bool, + runner: String, + allow_write_storage: bool, + allow_send_messages: bool, + allow_register_runners: bool, ) -> Result { let supervisor = self.context.data.supervisor.clone(); + let parent_runner_id = self.context.data.conf.topmost_runner_id.clone(); + let topmost_runner_id = + rt::supervisor::actions::resolve_runner_id(&supervisor, &parent_runner_id, &runner) + .await + .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?; + let message_data = self .context .data @@ -1817,6 +1935,8 @@ impl ContextVFS<'_> { messages_value_decremented: primitive_types::U256::max_value(), emissions: Vec::new(), message_fee_allocation: Vec::new(), + // Sandbox is a deterministic sub-VM: inherit the registered runners. + custom_runners: self.context.data.accumulator.custom_runners.clone(), }; std::mem::swap(&mut self.context.data.accumulator, &mut fake_my_data); @@ -1825,15 +1945,18 @@ impl ContextVFS<'_> { let vm_data = Box::new(SingleVMData { depth: self.context.data.depth + 1, + // Permission model: doc/website/src/spec/03-vm/05-permissions.rst conf: base::Config { needs_error_fingerprint: false, is_deterministic: zelf_conf.is_deterministic, can_read_storage: zelf_conf.can_read_storage, - can_write_storage: zelf_conf.can_write_storage & allow_write_ops, + can_write_storage: zelf_conf.can_write_storage & allow_write_storage, can_spawn_nondet: false, can_call_others: false, - can_send_messages: zelf_conf.can_send_messages & allow_write_ops, + can_send_messages: zelf_conf.can_send_messages & allow_send_messages, + can_register_runners: zelf_conf.can_register_runners & allow_register_runners, state_mode: zelf_conf.state_mode, + topmost_runner_id, }, message_data, supervisor: supervisor.clone(), @@ -1855,14 +1978,6 @@ impl ContextVFS<'_> { self.context.data.storage = my_res.vm_data.storage; let data: Vec = my_res.run_ok.as_bytes(); - Ok(generated::types::Fd::from( - self.vfs - .place_content(vfs::FileContents { - contents: bytes::Bytes::from(data), - pos: 0, - release_memory: true, - }) - .map_err(|e| generated::types::Error::trap(crate::anyhow_to_wasmtime(e)))?, - )) + self.place_content(vfs::FileContents::from(bytes::Bytes::from(data))) } } diff --git a/executor/src/wasi/mod.rs b/executor/src/wasi/mod.rs index ef5a2141d..2bbee2ed2 100644 --- a/executor/src/wasi/mod.rs +++ b/executor/src/wasi/mod.rs @@ -39,7 +39,11 @@ impl Context { }; Ok(Self { vfs, - preview1: preview1::Context::new(data.message_data.message.datetime, data.conf, seed), + preview1: preview1::Context::new( + data.message_data.message.datetime, + data.conf.clone(), + seed, + ), genlayer_sdk: genlayer_sdk::Context::new(data), }) } @@ -153,6 +157,7 @@ pub(super) fn add_to_linker_sync( let r = self.0(arg); genlayer_sdk::ContextVFS { vfs: &mut r.vfs, + preview1: &mut r.preview1, context: &mut r.genlayer_sdk, } } diff --git a/executor/src/wasi/preview1.rs b/executor/src/wasi/preview1.rs index 94f1ac18b..3a146779f 100644 --- a/executor/src/wasi/preview1.rs +++ b/executor/src/wasi/preview1.rs @@ -9,7 +9,7 @@ use genvm_common::*; use super::vfs; use crate::{ rt, - wasi::{base, common::align_slice}, + wasi::{self, base, common::align_slice}, }; use std::collections::BTreeMap; @@ -93,6 +93,18 @@ pub(crate) mod generated { }); } +impl From for generated::types::Fd { + fn from(fd: wasi::vfs::Fd) -> Self { + fd.as_u32().into() + } +} + +impl From for wasi::vfs::Fd { + fn from(fd: generated::types::Fd) -> Self { + wasi::vfs::Fd::new(fd.into()) + } +} + impl wiggle::GuestErrorType for generated::types::Errno { fn success() -> Self { Self::Success @@ -434,7 +446,7 @@ impl generated::wasi_snapshot_preview1::WasiSnapshotPreview1 for ContextVFS<'_> _memory: &mut GuestMemory<'_>, fd: generated::types::Fd, ) -> impl std::future::Future> + Send { - let fdi: u32 = fd.into(); + let fdi = fd.into(); let res = if self.vfs.pop_fd(fdi).is_none() { Err(generated::types::Errno::Badf.into()) } else { @@ -1005,7 +1017,7 @@ impl generated::wasi_snapshot_preview1::WasiSnapshotPreview1 for ContextVFS<'_> flags: generated::types::Lookupflags, path: GuestPtr, ) -> Result { - let fdi: u32 = dirfd.into(); + let fdi = dirfd.into(); let path = super::common::read_string(memory, path)?; let Some(vfs::FileDescriptor::Dir { path: dir_path }) = self.vfs.fds.get(&fdi) else { return Err(generated::types::Errno::Badf.into()); @@ -1086,8 +1098,7 @@ impl generated::wasi_snapshot_preview1::WasiSnapshotPreview1 for ContextVFS<'_> fdflags: generated::types::Fdflags, ) -> Result { let file_path = super::common::read_string(memory, path)?; - let fdi: u32 = dirfd.into(); - let fdi: u32 = dirfd.into(); + let fdi = dirfd.into(); let new_fd = self .vfs .alloc_fd() @@ -1245,6 +1256,7 @@ impl generated::wasi_snapshot_preview1::WasiSnapshotPreview1 for ContextVFS<'_> // Non-deterministic mode: cryptographically secure random number generator if let Err(e) = getrandom::fill(&mut mem) { log_error!(error:err = e; "random failed"); + return Err(generated::types::Errno::Io.into()); } } @@ -1345,7 +1357,7 @@ impl ContextVFS<'_> { &self, fd: generated::types::Fd, ) -> Result<&vfs::FileDescriptor, generated::types::Error> { - let fdi: u32 = fd.into(); + let fdi = fd.into(); match self.vfs.fds.get(&fdi) { Some(x) => Ok(x), None => Err(generated::types::Errno::Badf.into()), @@ -1356,7 +1368,7 @@ impl ContextVFS<'_> { &mut self, fd: generated::types::Fd, ) -> Result<&mut vfs::FileDescriptor, generated::types::Error> { - let fdi: u32 = fd.into(); + let fdi = fd.into(); match self.vfs.fds.get_mut(&fdi) { Some(x) => Ok(x), None => Err(generated::types::Errno::Badf.into()), diff --git a/executor/src/wasi/vfs.rs b/executor/src/wasi/vfs.rs index 32f4b8e7b..ac151b042 100644 --- a/executor/src/wasi/vfs.rs +++ b/executor/src/wasi/vfs.rs @@ -12,6 +12,16 @@ pub struct FileContents { pub release_memory: bool, } +impl From for FileContents { + fn from(value: bytes::Bytes) -> Self { + Self { + contents: value, + pos: 0, + release_memory: true, + } + } +} + pub enum FileDescriptor { Stdin, Stdout, @@ -24,13 +34,32 @@ pub enum FileDescriptor { const _: FileDescriptor = FileDescriptor::Stdin; pub(crate) struct VFS { - pub fds: BTreeMap, - pub free_descriptors: Vec, - pub next_free_descriptor: u32, + pub fds: BTreeMap, + pub free_descriptors: Vec, + pub next_free_descriptor: Fd, pub limiter: rt::memlimiter::Limiter, } +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Fd(u32); + +impl From for u32 { + fn from(value: Fd) -> Self { + value.0 + } +} + +impl Fd { + pub fn new(fd: u32) -> Self { + Self(fd) + } + + pub fn as_u32(&self) -> u32 { + self.0 + } +} + impl VFS { pub fn new( stdin: Vec, @@ -49,18 +78,18 @@ impl VFS { let fds = BTreeMap::from([ ( - 0, + Fd::new(0), FileDescriptor::File(FileContents { contents: stdin_data, pos: 0, release_memory: true, }), ), - (1, FileDescriptor::Stdout), - (2, FileDescriptor::Stderr), - (3, FileDescriptor::Dir { path: Vec::new() }), + (Fd::new(1), FileDescriptor::Stdout), + (Fd::new(2), FileDescriptor::Stderr), + (Fd::new(3), FileDescriptor::Dir { path: Vec::new() }), ]); - let next_free_descriptor = fds.last_key_value().map(|x| *x.0).unwrap_or(0); + let next_free_descriptor = fds.last_key_value().map(|x| *x.0).unwrap_or(Fd::default()); Ok(Self { fds, next_free_descriptor, @@ -70,7 +99,7 @@ impl VFS { } /// gives vacant fd - pub fn alloc_fd(&mut self) -> anyhow::Result { + pub fn alloc_fd(&mut self) -> anyhow::Result { if self.fds.len() >= public_abi::top_limits::MAX_FDS as usize { return Err( rt::errors::VMError(abi::consts::VmError::oom().ram().limit(), None).into(), @@ -87,18 +116,18 @@ impl VFS { rt::errors::VMError(abi::consts::VmError::oom().ram().val(), None).into(), ); } - self.next_free_descriptor += 1; + self.next_free_descriptor.0 += 1; Ok(self.next_free_descriptor) } } } /// it must be removed from fds beforehand - pub fn free_fd(&mut self, fd: u32) { + pub fn free_fd(&mut self, fd: Fd) { self.free_descriptors.push(fd); } - pub fn pop_fd(&mut self, fd: u32) -> Option { + pub fn pop_fd(&mut self, fd: Fd) -> Option { match self.fds.remove(&fd) { Some(v) => { if let FileDescriptor::File(v) = &v { @@ -115,12 +144,20 @@ impl VFS { } } - pub fn place_content(&mut self, value: FileContents) -> anyhow::Result { + pub fn place_content(&mut self, value: FileContents) -> anyhow::Result { if value.release_memory && !self.limiter.consume(value.contents.len() as u32) { return Err(rt::errors::VMError(abi::consts::VmError::oom().ram().val(), None).into()); } - let fd = self.alloc_fd()?; + let fd = match self.alloc_fd() { + Ok(fd) => fd, + Err(e) => { + if value.release_memory { + self.limiter.release(value.contents.len() as u32); + } + return Err(e); + } + }; self.fds.insert(fd, FileDescriptor::File(value)); Ok(fd) } diff --git a/executor/tests/runner_id.rs b/executor/tests/runner_id.rs new file mode 100644 index 000000000..d3367f19e --- /dev/null +++ b/executor/tests/runner_id.rs @@ -0,0 +1,123 @@ +use genvm::calldata::Address; +use genvm::runners::{self, ChainState, Id, IdUnresolved}; +use genvm::SlotID; + +fn test_addr() -> String { + format!("0x{}1", "0".repeat(39)) +} + +fn test_slot() -> String { + genlayer_sdk::gvm32::encode(&[0x11u8; 32]) +} + +#[test] +fn chain_canonical_uses_checksum_address() { + let address = Address::from([ + 0x5a, 0xae, 0xb6, 0x05, 0x3f, 0x3e, 0x94, 0xc9, 0xb9, 0xa0, 0x9f, 0x33, 0x66, 0x94, 0x35, + 0xe7, 0xef, 0x1b, 0xea, 0xed, + ]); + + let id = Id::Chain { + address, + on: ChainState::Accepted, + slot: SlotID::ZERO, + }; + + let expected = format!( + "chain:0x{}:a:{}", + std::str::from_utf8(&address.checksum_hex()).unwrap(), + "0".repeat(52), + ); + assert_eq!(id.canonical().as_str(), expected.as_str()); + assert!(expected.contains("5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed")); +} + +#[test] +fn parse_runner_id_forms() { + assert!(matches!( + runners::parse_runner_id("contract"), + Some(IdUnresolved::Contract) + )); + assert!(matches!( + runners::parse_runner_id("py-genlayer:test"), + Some(IdUnresolved::Builtin { .. }) + )); + assert!(matches!( + runners::parse_runner_id("custom:deadbeef"), + Some(IdUnresolved::Custom { .. }) + )); + + match runners::parse_runner_id(&format!("chain:{}:f:{}", test_addr(), test_slot())) { + Some(IdUnresolved::Chain { on, slot, .. }) => { + assert_eq!(on, Some(ChainState::Finalized)); + assert!(slot.is_some()); + } + other => panic!("expected Chain, got {other:?}"), + } + match runners::parse_runner_id(&format!("chain:{}:a:{}", test_addr(), test_slot())) { + Some(IdUnresolved::Chain { on, slot, .. }) => { + assert_eq!(on, Some(ChainState::Accepted)); + assert!(slot.is_some()); + } + other => panic!("expected Chain, got {other:?}"), + } +} + +#[test] +fn parse_runner_id_rejects_malformed() { + assert!(runners::parse_runner_id("custom:").is_none()); + assert!(runners::parse_runner_id("custom:bad/char").is_none()); + assert!(runners::parse_runner_id(":hash").is_none()); + assert!(runners::parse_runner_id("name:").is_none()); + assert!(runners::parse_runner_id("with space:hash").is_none()); + + assert!(runners::parse_runner_id(&format!("chain:0x01:f:{}", test_slot())).is_none()); + assert!( + runners::parse_runner_id(&format!("chain:{}:f:{}", "0".repeat(40), test_slot())).is_none() + ); + assert!(runners::parse_runner_id(&format!("chain:{}:f:0x02", test_addr())).is_none()); + assert!( + runners::parse_runner_id(&format!("chain:{}:x:{}", test_addr(), test_slot())).is_none() + ); + assert!( + runners::parse_runner_id(&format!("chain:{}:f:{}:extra", test_addr(), test_slot())) + .is_none() + ); + assert!( + runners::parse_runner_id(&format!("chain:0x{}:f:{}", "z".repeat(40), test_slot())) + .is_none() + ); +} + +#[test] +fn chain_without_slot_id() { + match runners::parse_runner_id(&format!("chain:{}:a", test_addr())) { + Some(IdUnresolved::Chain { on, slot, .. }) => { + assert_eq!(on, Some(ChainState::Accepted)); + assert!(slot.is_none(), "slot must be None when omitted"); + } + other => panic!("expected Chain, got {other:?}"), + } +} + +#[test] +fn chain_without_on_or_slot() { + match runners::parse_runner_id(&format!("chain:{}", test_addr())) { + Some(IdUnresolved::Chain { on, slot, .. }) => { + assert_eq!(on, Some(ChainState::Accepted)); + assert!(slot.is_none(), "slot must be None when omitted"); + } + other => panic!("expected Chain, got {other:?}"), + } +} + +#[test] +fn chain_with_explicit_slot() { + match runners::parse_runner_id(&format!("chain:{}:f:{}", test_addr(), test_slot())) { + Some(IdUnresolved::Chain { on, slot, .. }) => { + assert_eq!(on, Some(ChainState::Finalized)); + assert!(slot.is_some(), "slot must be Some when given"); + } + other => panic!("expected Chain, got {other:?}"), + } +} diff --git a/modules/implementation/Cargo.lock b/modules/implementation/Cargo.lock index 34925db19..6838e6a7d 100644 --- a/modules/implementation/Cargo.lock +++ b/modules/implementation/Cargo.lock @@ -979,6 +979,7 @@ dependencies = [ "num-bigint", "primitive-types", "serde", + "sha3", ] [[package]] @@ -1008,7 +1009,7 @@ dependencies = [ [[package]] name = "genvm-common" -version = "0.1.0" +version = "0.3.0" dependencies = [ "anyhow", "arbitrary", @@ -1030,6 +1031,7 @@ dependencies = [ "rpds", "rustix 0.38.44", "serde", + "serde_bytes", "serde_json", "serde_yaml", "symbol_table", diff --git a/modules/implementation/src/common/mod.rs b/modules/implementation/src/common/mod.rs index 8cf6a80a9..0f976f538 100644 --- a/modules/implementation/src/common/mod.rs +++ b/modules/implementation/src/common/mod.rs @@ -1,7 +1,7 @@ use base64::Engine; use genvm_common::*; use genvm_modules_interfaces::GenericValue; -use serde::{Deserialize, Serialize, Serializer}; +use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, sync::Arc}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; @@ -803,6 +803,11 @@ const MAX_REDIRECTS: usize = 10; /// This policy closes that hole by rejecting redirect hops whose host is a /// non-globally-routable IP literal; hostname targets keep being filtered by the /// resolver when the next hop connects. +/// +/// It also rejects HTTPS->HTTP downgrade redirects: following one would carry +/// any request signature (which does not bind the scheme tightly enough at all +/// receivers) onto a plaintext hop observable and replayable by on-path +/// attackers. pub fn redirect_policy() -> reqwest::redirect::Policy { reqwest::redirect::Policy::custom(|attempt| { if attempt.previous().len() >= MAX_REDIRECTS { @@ -816,13 +821,33 @@ pub fn redirect_policy() -> reqwest::redirect::Policy { }; if bad { log_warn!(url = attempt.url().as_str(); "redirect to non-globally-routable IP-literal rejected"); - attempt.error(NoRoutableAddress) - } else { - attempt.follow() + return attempt.error(NoRoutableAddress); + } + let downgrade = attempt + .previous() + .last() + .is_some_and(|prev| prev.scheme() == "https" && attempt.url().scheme() == "http"); + if downgrade { + log_warn!(url = attempt.url().as_str(); "HTTPS->HTTP downgrade redirect rejected"); + return attempt.error(SchemeDowngrade); } + attempt.follow() }) } +/// Error returned by [`redirect_policy`] when a redirect would downgrade an +/// HTTPS hop to plaintext HTTP. +#[derive(Debug)] +struct SchemeDowngrade; + +impl std::fmt::Display for SchemeDowngrade { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("refusing to follow HTTPS->HTTP downgrade redirect") + } +} + +impl std::error::Error for SchemeDowngrade {} + /// A client whose resolver drops non-globally-routable addresses (see /// [`FilteringResolver`]) and whose redirect policy rejects non-routable /// IP-literal hops (see [`redirect_policy`]). For contract-controlled web URLs. @@ -918,7 +943,41 @@ impl LogSinkElement { } } -pub type LogSink = Arc>; +/// Maximum number of buffered log entries kept per execution when not in debug +/// mode; older entries are evicted to bound memory usage. +pub const LOG_SINK_LIMIT: usize = 128; + +#[derive(Default)] +pub struct LogSinkInner { + queue: crossbeam::queue::SegQueue, + debug: bool, +} + +impl LogSinkInner { + pub fn new(debug: bool) -> Self { + Self { + queue: crossbeam::queue::SegQueue::new(), + debug, + } + } + + /// Appends an entry. In debug mode the sink is unbounded; otherwise the + /// oldest entries are dropped to keep at most [`LOG_SINK_LIMIT`] buffered. + pub fn push(&self, elem: LogSinkElement) { + if !self.debug { + while self.queue.len() >= LOG_SINK_LIMIT { + self.queue.pop(); + } + } + self.queue.push(elem); + } + + pub fn pop(&self) -> Option { + self.queue.pop() + } +} + +pub type LogSink = Arc; pub static GENVM_BY_ID_LOGGER: std::sync::LazyLock< papaya::HashMap, diff --git a/modules/implementation/src/llm/handler.rs b/modules/implementation/src/llm/handler.rs index 8e5bdb44e..2cf78d303 100644 --- a/modules/implementation/src/llm/handler.rs +++ b/modules/implementation/src/llm/handler.rs @@ -1,4 +1,4 @@ -use super::{ctx, prompt, scripting, UserVM}; +use super::{ctx, prompt, scripting}; use crate::common::{MessageHandler, MessageHandlerProvider, ModuleError, ModuleResult}; use anyhow::Context as _; use genvm_common::*; @@ -9,13 +9,14 @@ use mlua::LuaSerdeExt; use std::{collections::BTreeMap, sync::Arc}; +type VmGuard = scripting::pool::PoolGuard, LlmSubContext>; + pub struct Inner { - user_vm: Arc, + user_vm: VmGuard, _ctx: sync::DArc, ctx_val: mlua::Value, - metrics: sync::DArc, genvm_id: genvm_modules_interfaces::GenVMId, } @@ -27,25 +28,9 @@ pub struct Provider { pub providers: Arc>>, } -#[derive(serde::Serialize)] -#[serde(untagged)] -pub enum FullResponse { - Answer(llm_iface::PromptAnswer), - GetStats(calldata::Value), -} - -impl calldata::codec::Encode for FullResponse { - type Error = W::Error; - - fn encode(&self, enc: &mut calldata::Encoder) -> std::result::Result<(), Self::Error> { - match self { - FullResponse::Answer(v) => calldata::codec::Encode::encode(v, enc), - FullResponse::GetStats(v) => calldata::codec::Encode::encode(v, enc), - } - } -} - -impl MessageHandlerProvider for Provider { +impl MessageHandlerProvider + for Provider +{ type Ctx = LlmSubContext; fn create_execution_context( @@ -70,10 +55,11 @@ impl MessageHandlerProvider, - ) -> anyhow::Result> - { + ) -> anyhow::Result< + impl MessageHandler, + > { let genvm_id = ctx.scripting.hello.genvm_id; - let user_vm = self.vm_pool.get(); + let user_vm = self.vm_pool.get().await; let (handler_ctx, ctx_val) = user_vm.create_ctx(&ctx)?; @@ -85,7 +71,6 @@ impl MessageHandlerProvider); -impl crate::common::MessageHandler for Handler { +impl crate::common::MessageHandler for Handler { async fn handle( &self, message: llm_iface::Message, - ) -> crate::common::ModuleResult { + ) -> crate::common::ModuleResult { match message { llm_iface::Message::Prompt { payload, @@ -138,20 +123,14 @@ impl crate::common::MessageHandler for Handler self.0 .exec_prompt(self.0.clone(), payload, remaining_fuel_as_gen) .await - .map(FullResponse::Answer) } llm_iface::Message::PromptTemplate { payload, remaining_fuel_as_gen, - } => self - .0 - .exec_prompt_template(self.0.clone(), payload, remaining_fuel_as_gen) - .await - .map(FullResponse::Answer), - - llm_iface::Message::GetStats => { - let res = calldata::to_value(&self.0.metrics); - Ok(FullResponse::GetStats(res)) + } => { + self.0 + .exec_prompt_template(self.0.clone(), payload, remaining_fuel_as_gen) + .await } } } @@ -230,15 +209,11 @@ impl Inner { async fn exec_prompt( &self, _zelf: Arc, - mut payload: llm_iface::PromptPayload, + payload: llm_iface::PromptPayload, remaining_fuel_as_gen: primitive_types::U256, ) -> ModuleResult { log_debug_into!(&LoggerWithId, payload:serde = payload, genvm_id:id = self.genvm_id.0; "exec_prompt start"); - if payload.response_format == genvm_modules_interfaces::llm::OutputFormat::JSON2 { - payload.response_format = genvm_modules_interfaces::llm::OutputFormat::JSON; - } - let payload = self .user_vm .vm diff --git a/modules/implementation/src/llm/merge.rs b/modules/implementation/src/llm/merge.rs index 0601641fb..56f9a7de5 100644 --- a/modules/implementation/src/llm/merge.rs +++ b/modules/implementation/src/llm/merge.rs @@ -156,175 +156,3 @@ pub fn merge_values( } } } - -#[cfg(test)] -mod tests { - use super::*; - use serde_json::json; - - #[test] - fn none_overwrites_scalars() { - let mut target = json!({"a": 1, "b": 2}); - merge_values(&mut target, json!({"a": 10, "c": 3}), MergeStrategy::None).unwrap(); - assert_eq!(target, json!({"a": 10, "b": 2, "c": 3})); - } - - #[test] - fn none_recurses_into_objects() { - let mut target = json!({"nested": {"a": 1, "b": 2}}); - merge_values( - &mut target, - json!({"nested": {"b": 20, "c": 3}}), - MergeStrategy::None, - ) - .unwrap(); - assert_eq!(target, json!({"nested": {"a": 1, "b": 20, "c": 3}})); - } - - #[test] - fn none_errors_on_arrays() { - let mut target = json!({"a": [1, 2]}); - let err = merge_values(&mut target, json!({"a": [3, 4]}), MergeStrategy::None); - assert!(err.is_err()); - } - - #[test] - fn replace_replaces_entirely() { - let mut target = json!({"a": 1, "b": 2}); - merge_values(&mut target, json!({"c": 3}), MergeStrategy::Replace).unwrap(); - assert_eq!(target, json!({"c": 3})); - } - - #[test] - fn merge_left_arrays() { - let mut target = json!([1, 2]); - merge_values(&mut target, json!([3, 4]), MergeStrategy::MergeLeft).unwrap(); - assert_eq!(target, json!([1, 2, 3, 4])); - } - - #[test] - fn merge_right_arrays() { - let mut target = json!([1, 2]); - merge_values(&mut target, json!([3, 4]), MergeStrategy::MergeRight).unwrap(); - assert_eq!(target, json!([3, 4, 1, 2])); - } - - #[test] - fn merge_left_strings() { - let mut target = json!("hello"); - merge_values(&mut target, json!(" world"), MergeStrategy::MergeLeft).unwrap(); - assert_eq!(target, json!("hello world")); - } - - #[test] - fn merge_right_strings() { - let mut target = json!("world"); - merge_values(&mut target, json!("hello "), MergeStrategy::MergeRight).unwrap(); - assert_eq!(target, json!("hello world")); - } - - #[test] - fn merge_left_errors_on_objects() { - let mut target = json!({"a": 1}); - let err = merge_values(&mut target, json!({"b": 2}), MergeStrategy::MergeLeft); - assert!(err.is_err()); - } - - #[test] - fn map_per_key_strategies() { - let mut target = json!({ - "items": [1, 2], - "name": "old", - "keep": "original" - }); - let strategy = MergeStrategy::Map(BTreeMap::from([ - ("items".into(), MergeStrategy::MergeLeft), - ("name".into(), MergeStrategy::Replace), - ])); - merge_values( - &mut target, - json!({"items": [3, 4], "name": "new", "extra": true}), - strategy, - ) - .unwrap(); - assert_eq!( - target, - json!({"items": [1, 2, 3, 4], "name": "new", "keep": "original", "extra": true}) - ); - } - - #[test] - fn map_default_errors_on_arrays() { - let mut target = json!({"a": [1]}); - let strategy = MergeStrategy::Map(BTreeMap::new()); - let err = merge_values(&mut target, json!({"a": [2]}), strategy); - assert!(err.is_err()); - } - - #[test] - fn map_inserts_missing_keys() { - let mut target = json!({"a": 1}); - let strategy = MergeStrategy::Map(BTreeMap::new()); - merge_values(&mut target, json!({"b": 2}), strategy).unwrap(); - assert_eq!(target, json!({"a": 1, "b": 2})); - } - - #[test] - fn merge_extra_applies_strategy() { - let mut request = json!({"model": "gpt-4", "temperature": 0.7}); - merge_extra( - &mut request, - json!({"temperature": 0.9, "top_p": 0.5}), - MergeStrategy::None, - ) - .unwrap(); - assert_eq!( - request, - json!({"model": "gpt-4", "temperature": 0.9, "top_p": 0.5}) - ); - } - - #[test] - fn deserialize_string_variants() { - assert!(matches!( - serde_json::from_value::(json!("none")).unwrap(), - MergeStrategy::None - )); - assert!(matches!( - serde_json::from_value::(json!("replace")).unwrap(), - MergeStrategy::Replace - )); - assert!(matches!( - serde_json::from_value::(json!("merge_left")).unwrap(), - MergeStrategy::MergeLeft - )); - assert!(matches!( - serde_json::from_value::(json!("merge_right")).unwrap(), - MergeStrategy::MergeRight - )); - } - - #[test] - fn deserialize_null_is_none() { - assert!(matches!( - serde_json::from_value::(json!(null)).unwrap(), - MergeStrategy::None - )); - } - - #[test] - fn deserialize_map() { - let strategy: MergeStrategy = - serde_json::from_value(json!({"items": "merge_left", "name": "replace"})).unwrap(); - let MergeStrategy::Map(map) = strategy else { - panic!("expected Map variant"); - }; - assert!(matches!(map.get("items"), Some(MergeStrategy::MergeLeft))); - assert!(matches!(map.get("name"), Some(MergeStrategy::Replace))); - } - - #[test] - fn deserialize_invalid_string_errors() { - assert!(serde_json::from_value::(json!("invalid")).is_err()); - } -} diff --git a/modules/implementation/src/llm/prompt.rs b/modules/implementation/src/llm/prompt.rs index 305489054..c81ed3588 100644 --- a/modules/implementation/src/llm/prompt.rs +++ b/modules/implementation/src/llm/prompt.rs @@ -36,6 +36,20 @@ impl Internal { request } } + + /// Upper bound on the provider response body we buffer in memory. Budgets + /// ~16 bytes per requested output token (~4 bytes/char * ~4 chars/token) + /// plus a 16 MiB base, hard-capped so a large `max_tokens` cannot blow up + /// the limit (`u32::MAX` would otherwise allow ~64 GiB). + pub fn response_body_limit(&self) -> usize { + const BASE_LIMIT: usize = 16 * 1024 * 1024; + const MAX_LIMIT: usize = 32 * 1024 * 1024; + + (self.max_tokens as usize) + .saturating_mul(16) + .saturating_add(BASE_LIMIT) + .min(MAX_LIMIT) + } } #[derive(Serialize, Deserialize, Clone, Copy)] diff --git a/modules/implementation/src/llm/providers.rs b/modules/implementation/src/llm/providers.rs index 0202fa204..a6d2eb9b2 100644 --- a/modules/implementation/src/llm/providers.rs +++ b/modules/implementation/src/llm/providers.rs @@ -54,7 +54,7 @@ impl TokenUsage { Self { input: Some(input), output: Some(output), - total: Some(input + output), + total: Some(input.saturating_add(output)), ..Default::default() } } @@ -74,7 +74,7 @@ impl TokenUsage { } let input = self.input.unwrap_or_default(); let output = self.output.unwrap_or_default(); - if total < input + output { + if total < input.saturating_add(output) { return Err(TokensSanityError::TotalLessThanParts { total, input, @@ -85,6 +85,17 @@ impl TokenUsage { } } +/// Narrows a provider-reported token count (a `u64` from response JSON) to +/// `u32`, saturating instead of wrapping. A value that does not fit `u32` is not +/// plausible real usage and most likely a misreporting or compromised provider; +/// clamping and logging avoids the silent wrap that could otherwise under-bill. +fn narrow_token_count(v: u64) -> u32 { + u32::try_from(v).unwrap_or_else(|_| { + log_error!(value = v; "provider reported token count exceeding u32; saturating to u32::MAX"); + u32::MAX + }) +} + #[derive(Debug, Clone)] pub struct ProviderResponse { pub result: T, @@ -254,23 +265,23 @@ fn extract_openai_tokens(body: &serde_json::Value) -> TokenUsage { let input = usage .and_then(|v| v.get("prompt_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let output = usage .and_then(|v| v.get("completion_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let total = usage .and_then(|v| v.get("total_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let cache_read_tokens = usage .and_then(|v| v.pointer("/prompt_tokens_details/cached_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let cache_write_tokens = usage .and_then(|v| v.pointer("/prompt_tokens_details/cache_write_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); TokenUsage { input, output, @@ -337,7 +348,7 @@ impl Provider for OpenAICompatible { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -418,7 +429,7 @@ impl Provider for OpenAICompatible { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -479,13 +490,13 @@ fn extract_ollama_tokens(body: &serde_json::Value) -> TokenUsage { let input = body .get("prompt_eval_count") .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let output = body .get("eval_count") .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let total = match (input, output) { - (Some(i), Some(o)) => Some(i + o), + (Some(i), Some(o)) => Some(i.saturating_add(o)), _ => None, }; let mut raw = serde_json::Map::new(); @@ -516,7 +527,7 @@ impl Provider for OLlama { log_warn!(extra:serde = prompt.extra; "ollama provider ignores extra body fields"); } let request = prompt.to_ollama_no_format(model); - let url = format!("{}/api/ generate", self.config.host); + let url = format!("{}/api/generate", self.config.host); log_trace!(request:serde = request, url = url; "final request body after merging extra"); let request = serde_json::to_vec(&request)?; let request = ctx.client.post(&url).body(request.clone()); @@ -525,7 +536,7 @@ impl Provider for OLlama { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -584,7 +595,7 @@ impl Provider for OLlama { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -605,19 +616,19 @@ fn extract_gemini_tokens(body: &serde_json::Value) -> TokenUsage { let input = usage .and_then(|v| v.get("promptTokenCount")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let output = usage .and_then(|v| v.get("candidatesTokenCount")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let total = usage .and_then(|v| v.get("totalTokenCount")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let cache_read_tokens = usage .and_then(|v| v.get("cachedContentTokenCount")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); TokenUsage { input, output, @@ -667,7 +678,7 @@ impl Provider for Gemini { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -729,7 +740,7 @@ impl Provider for Gemini { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -796,23 +807,23 @@ fn extract_anthropic_tokens(body: &serde_json::Value) -> TokenUsage { let input = usage .and_then(|v| v.get("input_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let output = usage .and_then(|v| v.get("output_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let total = match (input, output) { - (Some(i), Some(o)) => Some(i + o), + (Some(i), Some(o)) => Some(i.saturating_add(o)), _ => None, }; let cache_read_tokens = usage .and_then(|v| v.get("cache_read_input_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); let cache_write_tokens = usage .and_then(|v| v.get("cache_creation_input_tokens")) .and_then(|v| v.as_u64()) - .map(|v| v as u32); + .map(narrow_token_count); TokenUsage { input, output, @@ -851,7 +862,7 @@ impl Provider for Anthropic { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -924,7 +935,7 @@ impl Provider for Anthropic { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; @@ -994,7 +1005,7 @@ impl Provider for Anthropic { &url, prompt.apply_timeout(request), true, - usize::MAX, + prompt.response_body_limit(), ) .await?; diff --git a/modules/implementation/src/manager/modules.rs b/modules/implementation/src/manager/modules.rs index c56083d38..3d7fdf0aa 100644 --- a/modules/implementation/src/manager/modules.rs +++ b/modules/implementation/src/manager/modules.rs @@ -92,6 +92,18 @@ pub struct StartRequest { pub user_error: bool, } +struct StartRealArgs +where + F: Fn() + Send + Sync + 'static, +{ + config: serde_json::Value, + allow_empty_backends: bool, + nested_cancel: Arc, + cancel_token: Arc, + canceller: F, + replace: bool, +} + /// Creates a stream handler that always responds with `Result::UserError` for every request. /// Maintains the wire protocol (reads hello, then loops reading messages and writing error responses). fn create_user_error_stream_handler() -> StreamHandler { @@ -223,12 +235,14 @@ impl Ctx { } else { self.start_real( req.module_type, - config, - req.allow_empty_backends, - nested_cancel, - module_cancel, - canceller, - replace, + StartRealArgs { + config, + allow_empty_backends: req.allow_empty_backends, + nested_cancel, + cancel_token: module_cancel, + canceller, + replace, + }, ) .await } @@ -299,16 +313,19 @@ impl Ctx { Ok(()) } - async fn start_real( - &self, - module_type: Type, - config: serde_json::Value, - allow_empty_backends: bool, - nested_cancel: Arc, - cancel_token: Arc, - canceller: impl Fn() + Send + Sync + 'static, - replace: bool, - ) -> anyhow::Result<()> { + async fn start_real(&self, module_type: Type, args: StartRealArgs) -> anyhow::Result<()> + where + F: Fn() + Send + Sync + 'static, + { + let StartRealArgs { + config, + allow_empty_backends, + nested_cancel, + cancel_token, + canceller, + replace, + } = args; + match module_type { Type::Llm => { let mut module_lock = self.llm_module.write().await; diff --git a/modules/implementation/src/manager/run.rs b/modules/implementation/src/manager/run.rs index a92cf63c2..658eb10bd 100644 --- a/modules/implementation/src/manager/run.rs +++ b/modules/implementation/src/manager/run.rs @@ -1,5 +1,5 @@ use std::{ - ops::{Deref, DerefMut}, + ops::DerefMut, os::fd::{AsRawFd, FromRawFd}, str::FromStr, sync::Arc, @@ -11,7 +11,7 @@ use tokio::io::AsyncBufReadExt; pub use genvm_modules_interfaces::GenVMId; -use crate::common::{LogSink, LogSinkElement, LoggerWithId, GENVM_BY_ID_LOGGER}; +use crate::common::{LogSink, LogSinkElement, LogSinkInner, LoggerWithId, GENVM_BY_ID_LOGGER}; /// Spawn relay that passes the stream to the module handler async fn spawn_module_relay( @@ -372,6 +372,10 @@ fn default_extra_args() -> Vec { Vec::new() } +fn default_debug_mode() -> genvm_common::DebugMode { + genvm_common::DebugMode::Disabled +} + fn default_no_modules() -> bool { false } @@ -384,7 +388,12 @@ pub struct Request { pub major: u32, pub message: genvm_common::domain::MessageData, pub is_sync: bool, - pub capture_output: bool, + /// Executor debug level. Controls captured-output bounding, tracing, runner + /// `:latest`/`:test` resolution (under `unsafe`), and (under `unsafe-tracing`) + /// exposing non-deterministic data. See `genvm_common::DebugMode`. + #[serde(default)] + #[calldata(default = default_debug_mode)] + pub debug_mode: genvm_common::DebugMode, #[serde(default = "default_max_execution_minutes")] #[calldata(default = default_max_execution_minutes)] pub max_execution_minutes: u64, @@ -452,9 +461,14 @@ trait LogAppender { async fn append_text(&mut self, serde_err: serde_json::Error, text: &str); } +/// Used when capture is `disabled`: forwards the executor's logs to the +/// manager's own log instead of buffering them into the result. struct LogAppenderToLog(GenVMId); -impl Deref for LogAppenderToLog { +// `read_log_pipe` takes `impl DerefMut`. The value-capturing +// appender is wrapped in `Arc>` (which derefs to it), but this +// forwarding appender holds no shared state, so it derefs to itself. +impl std::ops::Deref for LogAppenderToLog { type Target = Self; fn deref(&self) -> &Self::Target { @@ -546,10 +560,28 @@ async fn read_log_pipe( Ok(()) } +/// Maximum bytes of stdout/stderr kept (as a tail) per execution when not in +/// debug mode, to bound manager memory. +const OUTPUT_TAIL_LIMIT: usize = 4 * 1024 * 1024; + +/// Keeps only the last `limit` bytes of `s`, trimming whole UTF-8 chars from the +/// front (so the most recent output survives). +fn keep_tail(s: &mut String, limit: usize) { + if s.len() <= limit { + return; + } + let mut cut = s.len() - limit; + while cut < s.len() && !s.is_char_boundary(cut) { + cut += 1; + } + s.drain(..cut); +} + async fn pipe_read( mut reader: P, to: sync::DArc>, permit: tokio::sync::OwnedSemaphorePermit, + max_bytes: Option, ) { let mut result = String::new(); let mut buf = vec![0u8; 8192]; @@ -576,6 +608,13 @@ async fn pipe_read( result.push_str(&s); } } + + // Bound memory while reading: keep only the tail when not in debug mode. + if let Some(limit) = max_bytes { + if result.len() > limit { + keep_tail(&mut result, limit); + } + } } if let Err(e) = to.set(result) { @@ -750,12 +789,15 @@ fn build_genvm_command( proc.arg(format!("--genvm-id={}", genvm_id.0)); - if req.capture_output { - proc.stdout(std::process::Stdio::piped()); - proc.stderr(std::process::Stdio::piped()); - } else { + proc.arg("--debug-mode"); + proc.arg(req.debug_mode.as_arg()); + + if req.debug_mode.capture() == genvm_common::debug_mode::Capture::Disabled { proc.stdout(std::process::Stdio::null()); proc.stderr(std::process::Stdio::null()); + } else { + proc.stdout(std::process::Stdio::piped()); + proc.stderr(std::process::Stdio::piped()); } proc @@ -911,8 +953,17 @@ pub async fn start_genvm( ctx.permits.clone().acquire_owned().await? }; - let log_sink: LogSink = Arc::new(Default::default()); - GENVM_BY_ID_LOGGER.pin().insert(genvm_id, log_sink.clone()); + // Capture controls how logs and stdout/stderr are kept: disabled (forwarded + // to the manager log only), bounded, or unbounded. + use genvm_common::debug_mode::Capture; + let capture = req.debug_mode.capture(); + let log_sink: LogSink = Arc::new(LogSinkInner::new(capture == Capture::Unbounded)); + // Only route per-id logs into the result sink when we actually capture; under + // `disabled` the sink stays unregistered so manager-internal logs (and the + // forwarded executor logs) go to the manager log, leaving `genvm_log` empty. + if capture != Capture::Disabled { + GENVM_BY_ID_LOGGER.pin().insert(genvm_id, log_sink.clone()); + } let log_sink_guard = sync::DropGuard::new(|| { GENVM_BY_ID_LOGGER.pin().remove(&genvm_id); }); @@ -972,17 +1023,18 @@ pub async fn start_genvm( let execution_data_bytes = bytes::Bytes::from(execution_data_bytes); - // Spawn log reader - if req.capture_output { + // Spawn log reader: capture into the sink, or (when capture is disabled) + // forward to the manager log instead of buffering into the result. + if capture == Capture::Disabled { + tokio::spawn(read_log_pipe(read_fd, LogAppenderToLog(genvm_id))); + } else { let logger = Arc::new(tokio::sync::Mutex::new(LogAppenderToValue( log_sink.clone(), genvm_id, ))); let l = logger.clone().lock_owned().await; tokio::spawn(read_log_pipe(read_fd, l)); - } else { - tokio::spawn(read_log_pipe(read_fd, LogAppenderToLog(genvm_id))); - }; + } // Spawn child process, then drop child-side FDs let mut child = proc.spawn()?; @@ -1015,8 +1067,9 @@ pub async fn start_genvm( id: genvm_id, process_handle: tokio::sync::Mutex::new(child), started_at: chrono::Utc::now(), + // Cap at 24h so a huge value can't overflow the i64 cast / Duration. strict_deadline: chrono::Utc::now() - + chrono::Duration::minutes(req.max_execution_minutes as i64), + + chrono::Duration::minutes(req.max_execution_minutes.min(24 * 60) as i64), stdout_stderr_sem, stdout: tokio::sync::OnceCell::new(), @@ -1040,11 +1093,22 @@ pub async fn start_genvm( spawn_stdin_monitor(stdin_task, exec_ctx.clone(), genvm_id); } + let out_limit = (capture == Capture::Bounded).then_some(OUTPUT_TAIL_LIMIT); if let Some(stdout) = stdout { - tokio::spawn(pipe_read(stdout, exec_ctx.gep(|x| &x.stdout), stdout_perm)); + tokio::spawn(pipe_read( + stdout, + exec_ctx.gep(|x| &x.stdout), + stdout_perm, + out_limit, + )); } if let Some(stderr) = stderr { - tokio::spawn(pipe_read(stderr, exec_ctx.gep(|x| &x.stderr), stderr_perm)); + tokio::spawn(pipe_read( + stderr, + exec_ctx.gep(|x| &x.stderr), + stderr_perm, + out_limit, + )); } ctx.known_executions @@ -1054,3 +1118,34 @@ pub async fn start_genvm( Ok((genvm_id, rx)) } + +#[cfg(test)] +mod tests { + use super::keep_tail; + + #[test] + fn under_or_at_limit_is_unchanged() { + let mut s = String::from("hello"); + keep_tail(&mut s, 10); + assert_eq!(s, "hello"); + keep_tail(&mut s, 5); + assert_eq!(s, "hello"); + } + + #[test] + fn keeps_the_tail() { + let mut s = String::from("0123456789"); + keep_tail(&mut s, 4); + assert_eq!(s, "6789"); + } + + #[test] + fn never_cuts_mid_char() { + // "aéb" = a(1) é(2) b(1) = 4 bytes; cutting at byte 2 is mid-'é', so the + // cut advances to the next boundary, dropping the partial char. + let mut s = String::from("aéb"); + keep_tail(&mut s, 2); + assert_eq!(s, "b"); + assert!(std::str::from_utf8(s.as_bytes()).is_ok()); + } +} diff --git a/modules/implementation/src/manager/versioning.rs b/modules/implementation/src/manager/versioning.rs index dc9346fb8..eea48fd5e 100644 --- a/modules/implementation/src/manager/versioning.rs +++ b/modules/implementation/src/manager/versioning.rs @@ -146,13 +146,18 @@ impl Ctx { .map(|(ver, _)| *ver) .max()?; + // Walk forward to the newest contiguous patch, but only adopt a patch + // whose time gate has already opened. Skipping `available_after` here + // would activate a future (or rc) patch prematurely, which during a + // rolling update with staged manifests causes consensus divergence. loop { let mut next = ver; next.patch += 1; - if lock.executor_versions.contains_key(&next) { - ver = next; - } else { - break; + match lock.executor_versions.get(&next) { + Some(ev) if ev.available_after <= timestamp => { + ver = next; + } + _ => break, } } diff --git a/modules/implementation/src/scripting/ctx/req.rs b/modules/implementation/src/scripting/ctx/req.rs index 02eb9a5b2..f30f80f12 100644 --- a/modules/implementation/src/scripting/ctx/req.rs +++ b/modules/implementation/src/scripting/ctx/req.rs @@ -39,6 +39,13 @@ pub struct Request { /// one. Set by the web module for hosts in `always_allow_hosts`. #[serde(default = "default_false")] pub unfiltered: bool, + + /// Set once `normalize_headers` has run. Lets `into_reqwest` normalize every + /// request exactly once without re-stripping the `genlayer-*` headers the + /// signing path legitimately adds after normalizing. Not part of the wire + /// format. + #[serde(skip)] + pub headers_normalized: bool, } const DROP_HEADERS: &[&str] = &[ @@ -67,12 +74,22 @@ impl Request { self.headers.insert(lower_k, v); } + + self.headers_normalized = true; } pub fn into_reqwest( - self, + mut self, client: &reqwest::Client, ) -> Result { + // Drop forbidden/forged headers (host, content-length, genlayer-*, @*) + // on every request. The signing path normalizes earlier (before adding + // the legitimate genlayer-* headers), so the flag keeps us from + // stripping those back out here. + if !self.headers_normalized { + self.normalize_headers(); + } + let method = match self.method { web_iface::RequestMethod::GET => reqwest::Method::GET, web_iface::RequestMethod::POST => reqwest::Method::POST, @@ -112,92 +129,3 @@ impl Request { }) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::common; - use genvm_common::*; - use genvm_modules_interfaces::web as web_iface; - - #[tokio::test] - async fn test_response_body_max_size_ok() { - common::tests::setup(); - - let client = common::tests::create_test_client(); - let metrics = sync::DArc::new(crate::scripting::ctx::Metrics::default()); - let url = "https://test-server.genlayer.com/body/echo"; - - // body within limit (500 bytes < 1024 limit) => success - let body = vec![b'a'; 500]; - let req = crate::scripting::ctx::req::Request { - url: url::Url::parse(url).unwrap(), - method: web_iface::RequestMethod::POST, - headers: BTreeMap::new(), - body: Some(body.clone()), - json: false, - error_on_status: false, - sign: false, - response_body_max_size: Some(1024), - timeout: None, - unfiltered: false, - }; - - let body_size_limit = req.response_body_max_size.unwrap_or(usize::MAX); - let reqwst = req.into_reqwest(&client).unwrap(); - - let res = crate::scripting::send_request_get_lua_compatible_response_bytes( - &metrics, - url, - reqwst, - false, - body_size_limit, - ) - .await - .unwrap(); - - assert_eq!(res.status, 200); - assert_eq!(res.body, body); - } - - #[tokio::test] - async fn test_response_body_max_size_exceeded() { - common::tests::setup(); - - let client = common::tests::create_test_client(); - let metrics = sync::DArc::new(crate::scripting::ctx::Metrics::default()); - let url = "https://test-server.genlayer.com/body/echo"; - - let body = vec![b'b'; 2000]; - let req = crate::scripting::ctx::req::Request { - url: url::Url::parse(url).unwrap(), - method: web_iface::RequestMethod::POST, - headers: BTreeMap::new(), - body: Some(body), - json: false, - error_on_status: false, - sign: false, - response_body_max_size: Some(1024), - timeout: None, - unfiltered: false, - }; - - let body_size_limit = 1024; - let reqwst = req.into_reqwest(&client).unwrap(); - - let err = crate::scripting::send_request_get_lua_compatible_response_bytes( - &metrics, - url, - reqwst, - false, - body_size_limit, - ) - .await - .unwrap_err(); - - log_info!(error:ah = &err; "Received expected error for exceeding body size limit"); - - let module_err = err.downcast::().unwrap(); - assert!(module_err.causes.contains(&"READING_BODY".to_owned())); - } -} diff --git a/modules/implementation/src/scripting/ctx/signing.rs b/modules/implementation/src/scripting/ctx/signing.rs index 1fc449e04..2922ad59d 100644 --- a/modules/implementation/src/scripting/ctx/signing.rs +++ b/modules/implementation/src/scripting/ctx/signing.rs @@ -7,8 +7,14 @@ use genvm_modules_interfaces::GenericValue; const SIGN_ALGORITHM: &str = "ES256K"; +/// Per-request timeout for the signer preflight POST. Without it the request +/// falls back to the reqwest client default (~5 min), so a slow or stalled +/// signer would tie up a web-module task for minutes. +const SIGN_PREFLIGHT_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(60); + const ALWAYS_SIGN: &[&str] = &[ "@method", + "@scheme", "@authority", "@path", "genlayer-node-address", @@ -58,6 +64,7 @@ impl Request { let mut sign_request = ctx .client_unfiltered .post(sign_url) + .timeout(SIGN_PREFLIGHT_TIMEOUT) .body(signature_base.clone()); //let signature_base_hashed = ring::digest::digest(&ring::digest::SHA256, signature_base.as_bytes()); @@ -110,6 +117,7 @@ impl Request { fn rfc9421_get_component_value(&self, component: &str) -> Result { match component { "@method" => Ok(format!("{:?}", self.method)), + "@scheme" => Ok(self.url.scheme().to_lowercase()), "@authority" => Ok(self.url.authority().to_lowercase()), "@path" => Ok(self.url.path().to_owned()), "@query" => self @@ -287,9 +295,7 @@ mod tests { use std::collections::BTreeMap; use crate::common; - use genvm_common::*; use genvm_modules_interfaces::web as web_iface; - use std::sync::Arc; #[tokio::test] async fn test_signing_get() { @@ -306,6 +312,7 @@ mod tests { response_body_max_size: None, timeout: None, unfiltered: false, + headers_normalized: false, }; req.normalize_headers(); @@ -334,17 +341,18 @@ mod tests { assert_eq!( signature_params, - r#"("@method" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "@query");created=1750171014;alg="ES256K""# + r#"("@method" "@scheme" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "@query");created=1750171014;alg="ES256K""# ); let base = r#" "@method": GET +"@scheme": https "@authority": example.com "@path": /foo "genlayer-node-address": test_address "genlayer-tx-id": test_tx_id "genlayer-salt": "@query": ?a=b -"@signature-params": ("@method" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "@query");created=1750171014;alg="ES256K" +"@signature-params": ("@method" "@scheme" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "@query");created=1750171014;alg="ES256K" "#; let base = base.trim(); assert_eq!(signature_base.trim(), base); @@ -365,6 +373,7 @@ mod tests { response_body_max_size: None, timeout: None, unfiltered: false, + headers_normalized: false, }; req.normalize_headers(); @@ -393,76 +402,20 @@ mod tests { assert_eq!( signature_params, - r#"("@method" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "content-digest");created=1750171014;alg="ES256K""# + r#"("@method" "@scheme" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "content-digest");created=1750171014;alg="ES256K""# ); let base = r#" "@method": POST +"@scheme": https "@authority": example.com "@path": /pst "genlayer-node-address": test_address "genlayer-tx-id": test_tx_id "genlayer-salt": "content-digest": sha-256=:Y++zFe1xzH5aH8ICQ0uzrsIJHng4cH4UigF/rrt0ZP4=: -"@signature-params": ("@method" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "content-digest");created=1750171014;alg="ES256K" +"@signature-params": ("@method" "@scheme" "@authority" "@path" "genlayer-node-address" "genlayer-tx-id" "genlayer-salt" "content-digest");created=1750171014;alg="ES256K" "#; let base = base.trim(); assert_eq!(signature_base.trim(), base); } - - #[tokio::test] - async fn test_signing_post_with_server() { - use crate::scripting::ctx::CtxPart; - - common::tests::setup(); - - let mut req = crate::scripting::ctx::req::Request { - url: url::Url::parse("https://test-server.genlayer.com/body/echo-signed").unwrap(), - method: web_iface::RequestMethod::POST, - headers: BTreeMap::new(), - body: Some(b"test body".to_vec()), - json: false, - error_on_status: true, - sign: true, - response_body_max_size: None, - timeout: None, - unfiltered: false, - }; - - let part = CtxPart { - hello: Arc::new(genvm_modules_interfaces::GenVMHello { - genvm_id: genvm_modules_interfaces::GenVMId(999), - role: genvm_modules_interfaces::Role::Leader, - host_data: genvm_modules_interfaces::HostData { - node_address: "test_address".to_string(), - tx_id: "test_tx_id".to_string(), - rest: serde_json::Map::new(), - }, - gas_data: std::collections::BTreeMap::new(), - initial_time_units_allocation: 0, - }), - client: common::tests::create_test_client(), - client_unfiltered: common::tests::create_test_client(), - sign_url: Arc::from("https://test-server.genlayer.com/genvm/sign"), - sign_headers: Arc::new(BTreeMap::new()), - sign_vars: BTreeMap::new(), - node_address: "node_address".to_string(), - metrics: sync::DArc::new(crate::scripting::ctx::Metrics::default()), - }; - - req.add_rfc9421_sign_headers(&part).await.unwrap(); - - eprintln!("req: {req:?}"); - - let reqwst = req.into_reqwest(&part.client).unwrap(); - - let res = reqwst.send().await.unwrap(); - let status = res.status(); - let body = res.bytes().await; - eprintln!("Response status: {status:?}, body: {body:?}"); - assert_eq!(status, 200); - - let body = body.unwrap(); - - assert_eq!(body.as_ref(), b"test body"); - } } diff --git a/modules/implementation/src/scripting/mod.rs b/modules/implementation/src/scripting/mod.rs index 623cb4e4d..b08470024 100644 --- a/modules/implementation/src/scripting/mod.rs +++ b/modules/implementation/src/scripting/mod.rs @@ -13,6 +13,7 @@ use std::{collections::BTreeMap, future::Future, sync::Arc}; use crate::common::{self, ModuleError}; pub use ctx::filters; +pub use ctx::req::Request; pub use ctx::CtxPart; pub use ctx::Metrics; @@ -156,9 +157,6 @@ impl UserVM { { use mlua::StdLib; - std::env::set_var("LUA_PATH", &mod_config.lua_path); - std::env::set_var("LUA_CPATH", mod_config.lua_path.replace(".lua", ".so")); - let lua_libs = StdLib::COROUTINE | StdLib::TABLE | StdLib::IO @@ -170,6 +168,15 @@ impl UserVM { vm.load_std_libs(lua_libs).context("loading stdlib")?; + // Set the module search paths on this Lua state directly. Lua 5.3's + // `require` reads `package.path`/`package.cpath` (there is no in-Lua + // `LUA_PATH` global as in Lua 5.0). Doing it per-state avoids mutating + // the process-global LUA_PATH/LUA_CPATH env vars, which raced across the + // Web and LLM VM pools initializing concurrently in the same process. + let package: mlua::Table = vm.globals().get("package")?; + package.set("path", mod_config.lua_path.as_str())?; + package.set("cpath", mod_config.lua_path.replace(".lua", ".so"))?; + preload_lsqlite3(&vm).context("preloading lsqlite3")?; vm.globals().set( diff --git a/modules/implementation/src/scripting/pool.rs b/modules/implementation/src/scripting/pool.rs index 61e56c012..8d54b40f2 100644 --- a/modules/implementation/src/scripting/pool.rs +++ b/modules/implementation/src/scripting/pool.rs @@ -1,19 +1,76 @@ use std::sync::Arc; struct Inner { - vms: Vec>>, + free: crossbeam::queue::ArrayQueue>>, } -#[derive(Clone)] -pub struct Pool(Arc>); +/// A fixed-size pool of Lua VMs. A VM is checked out exclusively via [`Pool::get`] +/// and returned to the pool when the [`PoolGuard`] is dropped, so a single +/// `lua_State` is never driven by two executions concurrently. +pub struct Pool { + inner: Arc>, + // `available` counts the VMs currently in `free`; acquiring a permit + // guarantees a subsequent `pop` succeeds. + available: Arc, +} -impl Pool { - pub fn get(&self) -> Arc> { - let mut key: [u8; 1] = [0; 1]; +impl Clone for Pool { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + available: self.available.clone(), + } + } +} - rand::fill(&mut key); +/// Exclusive checkout of one VM. Dereferences to the underlying [`super::UserVM`] +/// and returns it to the pool on drop. +pub struct PoolGuard { + vm: Option>>, + inner: Arc>, + // Released only after the VM has been returned to `free` (see `Drop`). + _permit: tokio::sync::OwnedSemaphorePermit, +} + +impl std::ops::Deref for PoolGuard { + type Target = super::UserVM; - self.0.vms[key[0] as usize % self.0.vms.len()].clone() + fn deref(&self) -> &Self::Target { + self.vm + .as_ref() + .expect("vm is present until the guard is dropped") + } +} + +impl Drop for PoolGuard { + fn drop(&mut self) { + if let Some(vm) = self.vm.take() { + // Return the VM before `_permit` is released so the next waiter that + // wakes on the freed permit is guaranteed to find a VM in `free`. + let _ = self.inner.free.push(vm); + } + } +} + +impl Pool { + /// Atomically checks out a VM, waiting if all VMs are currently in use. + pub async fn get(&self) -> PoolGuard { + let permit = self + .available + .clone() + .acquire_owned() + .await + .expect("vm pool semaphore is never closed"); + let vm = self + .inner + .free + .pop() + .expect("holding a permit guarantees a free vm"); + PoolGuard { + vm: Some(vm), + inner: self.inner.clone(), + _permit: permit, + } } } @@ -24,12 +81,18 @@ pub async fn new( where F: std::future::Future>>, { - let mut vms = Vec::new(); + if cnt == 0 { + anyhow::bail!("vm pool size must be >= 1"); + } + let free = crossbeam::queue::ArrayQueue::new(cnt); for _i in 0..cnt { - vms.push(Arc::new(vm_supplier().await?)); + free.push(Arc::new(vm_supplier().await?)) + .ok() + .expect("queue capacity matches the number of VMs"); } - let inner = Inner { vms }; - - Ok(Pool(Arc::new(inner))) + Ok(Pool { + inner: Arc::new(Inner { free }), + available: Arc::new(tokio::sync::Semaphore::new(cnt)), + }) } diff --git a/modules/implementation/src/web/handler.rs b/modules/implementation/src/web/handler.rs index 4228474d2..c1a99931c 100644 --- a/modules/implementation/src/web/handler.rs +++ b/modules/implementation/src/web/handler.rs @@ -8,23 +8,21 @@ use mlua::LuaSerdeExt; use std::sync::Arc; type WebSubContext = crate::manager::execution_context::WebSubContext; -type UserVM = scripting::UserVM, WebSubContext>; +type VmGuard = scripting::pool::PoolGuard, WebSubContext>; pub struct Inner { - user_vm: Arc, + user_vm: VmGuard, _ctx: Arc, ctx_val: mlua::Value, max_wait_after_loaded: std::time::Duration, - - metrics: sync::DArc, } struct Handler(Arc); -impl common::MessageHandler for Handler { - async fn handle(&self, message: web_iface::Message) -> common::ModuleResult { +impl common::MessageHandler for Handler { + async fn handle(&self, message: web_iface::Message) -> common::ModuleResult { match message { web_iface::Message::Request(payload, size_limit) => { let vm = &self.0.user_vm.vm; @@ -45,7 +43,7 @@ impl common::MessageHandler for Handler { let res = self.0.user_vm.vm.from_value(res)?; - Ok(FullResponse::Answer(RenderAnswer::Response(res))) + Ok(RenderAnswer::Response(res)) } web_iface::Message::Render(payload, size_limit) => { let vm = &self.0.user_vm.vm; @@ -81,12 +79,7 @@ impl common::MessageHandler for Handler { let res = self.0.user_vm.vm.from_value(res)?; - Ok(FullResponse::Answer(res)) - } - - web_iface::Message::GetStats => { - let res = calldata::to_value(&self.0.metrics); - Ok(FullResponse::GetStats(res)) + Ok(res) } } } @@ -96,30 +89,12 @@ impl common::MessageHandler for Handler { } } -#[derive(serde::Serialize)] -#[serde(untagged)] -pub enum FullResponse { - Answer(web_iface::RenderAnswer), - GetStats(calldata::Value), -} - -impl calldata::codec::Encode for FullResponse { - type Error = W::Error; - - fn encode(&self, enc: &mut calldata::Encoder) -> std::result::Result<(), Self::Error> { - match self { - FullResponse::Answer(v) => calldata::codec::Encode::encode(v, enc), - FullResponse::GetStats(v) => calldata::codec::Encode::encode(v, enc), - } - } -} - pub struct HandlerProvider { pub vm_pool: scripting::pool::Pool, WebSubContext>, pub config: sync::DArc, } -impl common::MessageHandlerProvider +impl common::MessageHandlerProvider for HandlerProvider { type Ctx = WebSubContext; @@ -143,9 +118,9 @@ impl common::MessageHandlerProvider, ) -> anyhow::Result< - impl common::MessageHandler, + impl common::MessageHandler, > { - let user_vm = self.vm_pool.get(); + let user_vm = self.vm_pool.get().await; let (handler_ctx, ctx_val) = user_vm.create_ctx(&ctx)?; @@ -154,7 +129,6 @@ impl common::MessageHandlerProvider(json!("none")).unwrap(), + MergeStrategy::None + )); + assert!(matches!( + serde_json::from_value::(json!("replace")).unwrap(), + MergeStrategy::Replace + )); + assert!(matches!( + serde_json::from_value::(json!("merge_left")).unwrap(), + MergeStrategy::MergeLeft + )); + assert!(matches!( + serde_json::from_value::(json!("merge_right")).unwrap(), + MergeStrategy::MergeRight + )); +} + +#[test] +fn deserialize_null_is_none() { + assert!(matches!( + serde_json::from_value::(json!(null)).unwrap(), + MergeStrategy::None + )); +} + +#[test] +fn deserialize_map() { + let strategy: MergeStrategy = + serde_json::from_value(json!({"items": "merge_left", "name": "replace"})).unwrap(); + let MergeStrategy::Map(map) = strategy else { + panic!("expected Map variant"); + }; + assert!(matches!(map.get("items"), Some(MergeStrategy::MergeLeft))); + assert!(matches!(map.get("name"), Some(MergeStrategy::Replace))); +} + +#[test] +fn deserialize_invalid_string_errors() { + assert!(serde_json::from_value::(json!("invalid")).is_err()); +} diff --git a/modules/implementation/tests/request_body_limit.rs b/modules/implementation/tests/request_body_limit.rs new file mode 100644 index 000000000..6cfa568f2 --- /dev/null +++ b/modules/implementation/tests/request_body_limit.rs @@ -0,0 +1,88 @@ +use std::collections::BTreeMap; + +use genvm_common::*; +use genvm_modules_interfaces::web as web_iface; + +use genvm_modules::common; + +#[tokio::test] +async fn response_body_max_size_ok() { + common::tests::setup(); + + let client = common::tests::create_test_client(); + let metrics = sync::DArc::new(genvm_modules::scripting::Metrics::default()); + let url = "https://test-server.genlayer.com/body/echo"; + + let body = vec![b'a'; 500]; + let req = genvm_modules::scripting::Request { + url: url::Url::parse(url).unwrap(), + method: web_iface::RequestMethod::POST, + headers: BTreeMap::new(), + body: Some(body.clone()), + json: false, + error_on_status: false, + sign: false, + response_body_max_size: Some(1024), + timeout: None, + unfiltered: false, + headers_normalized: false, + }; + + let body_size_limit = req.response_body_max_size.unwrap_or(usize::MAX); + let reqwst = req.into_reqwest(&client).unwrap(); + + let res = genvm_modules::scripting::send_request_get_lua_compatible_response_bytes( + &metrics, + url, + reqwst, + false, + body_size_limit, + ) + .await + .unwrap(); + + assert_eq!(res.status, 200); + assert_eq!(res.body, body); +} + +#[tokio::test] +async fn response_body_max_size_exceeded() { + common::tests::setup(); + + let client = common::tests::create_test_client(); + let metrics = sync::DArc::new(genvm_modules::scripting::Metrics::default()); + let url = "https://test-server.genlayer.com/body/echo"; + + let body = vec![b'b'; 2000]; + let req = genvm_modules::scripting::Request { + url: url::Url::parse(url).unwrap(), + method: web_iface::RequestMethod::POST, + headers: BTreeMap::new(), + body: Some(body), + json: false, + error_on_status: false, + sign: false, + response_body_max_size: Some(1024), + timeout: None, + unfiltered: false, + headers_normalized: false, + }; + + let body_size_limit = 1024; + let reqwst = req.into_reqwest(&client).unwrap(); + + let err = genvm_modules::scripting::send_request_get_lua_compatible_response_bytes( + &metrics, + url, + reqwst, + false, + body_size_limit, + ) + .await + .unwrap_err(); + + let module_err = err + .downcast::() + .unwrap(); + assert!(module_err.causes.contains(&"READING_BODY".to_owned())); +} diff --git a/modules/implementation/tests/signing_server.rs b/modules/implementation/tests/signing_server.rs new file mode 100644 index 000000000..bbe57d7da --- /dev/null +++ b/modules/implementation/tests/signing_server.rs @@ -0,0 +1,60 @@ +use std::collections::BTreeMap; +use std::sync::Arc; + +use genvm_common::*; +use genvm_modules_interfaces::web as web_iface; + +use genvm_modules::common; +use genvm_modules::scripting::CtxPart; + +#[tokio::test] +async fn signing_post_with_server() { + common::tests::setup(); + + let mut req = genvm_modules::scripting::Request { + url: url::Url::parse("https://test-server.genlayer.com/body/echo-signed").unwrap(), + method: web_iface::RequestMethod::POST, + headers: BTreeMap::new(), + body: Some(b"test body".to_vec()), + json: false, + error_on_status: true, + sign: true, + response_body_max_size: None, + timeout: None, + unfiltered: false, + headers_normalized: false, + }; + + let part = CtxPart { + hello: Arc::new(genvm_modules_interfaces::GenVMHello { + genvm_id: genvm_modules_interfaces::GenVMId(999), + role: genvm_modules_interfaces::Role::Leader, + host_data: genvm_modules_interfaces::HostData { + node_address: "test_address".to_string(), + tx_id: "test_tx_id".to_string(), + rest: serde_json::Map::new(), + }, + gas_data: std::collections::BTreeMap::new(), + initial_time_units_allocation: 0, + }), + client: common::tests::create_test_client(), + client_unfiltered: common::tests::create_test_client(), + sign_url: Arc::from("https://test-server.genlayer.com/genvm/sign"), + sign_headers: Arc::new(BTreeMap::new()), + sign_vars: BTreeMap::new(), + node_address: "node_address".to_string(), + metrics: sync::DArc::new(genvm_modules::scripting::Metrics::default()), + }; + + req.add_rfc9421_sign_headers(&part).await.unwrap(); + + let reqwst = req.into_reqwest(&part.client).unwrap(); + + let res = reqwst.send().await.unwrap(); + let status = res.status(); + let body = res.bytes().await; + assert_eq!(status, 200); + + let body = body.unwrap(); + assert_eq!(body.as_ref(), b"test body"); +} diff --git a/modules/install/lib/python/post-install/__main__.py b/modules/install/lib/python/post-install/__main__.py index 75ee22ab0..d8333fae6 100644 --- a/modules/install/lib/python/post-install/__main__.py +++ b/modules/install/lib/python/post-install/__main__.py @@ -52,12 +52,6 @@ def str_to_bool_or_none(value): default=target_arch, help='Target architecture (amd64/arm64)', ) -parser.add_argument( - '--interactive', - type=str_to_bool, - default=False, - help='Whether to run in interactive mode', -) parser.add_argument( '--error-on-missing-executor', type=str_to_bool, @@ -146,8 +140,6 @@ def str_to_bool_or_none(value): if args.precompile is None: args.precompile = args.default_steps -INTERACTIVE = args.interactive - log_level_str = args.log_level log_levels = { 'DEBUG': logging.DEBUG, @@ -167,29 +159,37 @@ def str_to_bool_or_none(value): logging.info('Starting actual post-install script') -if args.bin_patch: +# Interpreter patching rewrites the ELF interpreter (dynamic loader) to the +# bundled one, whose path is only known at install time. It applies to ELF +# binaries (Linux) only; on other targets the loader is fixed and rpath/needed +# entries are already set correctly at build time, so lief is not needed. +patch_interpreter = args.bin_patch and args.os == 'linux' + +if patch_interpreter: import lief lief.logging.set_level(lief.logging.LEVEL.ERROR) -HASH_VALID_CHARS = '0123456789abcdfghijklmnpqrsvwxyz' +# gvm32 (Crockford's Base32, big-endian, no padding) — the encoding the executor +# uses for runner hashes / on-disk paths. MUST match support/runner-script.py, +# executor/crates/sdk-rs/src/gvm32.rs and runners/genlayer-py-std/.../gvm32.py. +# NOT Nix base32 (which uses a different alphabet AND little-endian bit order). +HASH_VALID_CHARS = '0123456789abcdefghjkmnpqrstvwxyz' def digest_to_hash_id(got_hash: bytes) -> str: - chars = '0123456789abcdfghijklmnpqrsvwxyz' - - bytes_count = len(got_hash) - base32_len = (bytes_count * 8 - 1) // 5 + 1 - - my_hash_arr = [] - for n in range(base32_len - 1, -1, -1): - b = n * 5 - i = b // 8 - j = b % 8 - c = (got_hash[i] >> j) | (0 if i >= bytes_count - 1 else got_hash[i + 1] << (8 - j)) - my_hash_arr.append(chars[c & 0x1F]) - - return ''.join(my_hash_arr) + out = [] + value = 0 + bits = 0 + for byte in got_hash: + value = (value << 8) | byte + bits += 8 + while bits >= 5: + bits -= 5 + out.append(HASH_VALID_CHARS[(value >> bits) & 0x1F]) + if bits > 0: + out.append(HASH_VALID_CHARS[(value << (5 - bits)) & 0x1F]) + return ''.join(out) def runner_check_bytes(data: bytes, hash: str) -> bool: @@ -220,8 +220,8 @@ def get_interpreter_path(): return interpreter_path -def patch_executable(path: Path, *, rpath_dir: list[Path]): - logger.info(f'Patching executable for {path}') +def patch_executable(path: Path): + logger.info(f'Patching interpreter for {path}') if not path.exists(): logger.warning(f'Path {path} does not exist, skipping patching') return @@ -231,125 +231,25 @@ def patch_executable(path: Path, *, rpath_dir: list[Path]): logger.error(f'Failed to parse binary at {path}') return - # Log basic binary information - logger.info(f'Binary format: {binary.format}') - - # Handle ELF binaries - if binary.format == lief.Binary.FORMATS.ELF: - logger.info(f'Processing ELF binary: {path}') - - # Log current interpreter - logger.info(f'Current interpreter: {binary.interpreter}') - - # Log current needed libraries - needed_libs = [ - lib if isinstance(lib, str) else lib.name for lib in binary.libraries - ] - logger.info(f'Current needed libraries: {needed_libs}') - - # Log current RPATH/RUNPATH - rpath_entries = [] - if binary.has(lief.ELF.DynamicEntry.TAG.RPATH): - rpath_entry = binary.get(lief.ELF.DynamicEntry.TAG.RPATH) - rpath_entries.append(f'RPATH: {rpath_entry.value}') - if binary.has(lief.ELF.DynamicEntry.TAG.RUNPATH): - runpath_entry = binary.get(lief.ELF.DynamicEntry.TAG.RUNPATH) - rpath_entries.append(f'RUNPATH: {runpath_entry.value}') - logger.info( - f'Current RPATH/RUNPATH entries: {rpath_entries if rpath_entries else "None"}' - ) + # rpath/needed entries are set correctly at build time, so the only install + # time fixup left is the ELF interpreter (dynamic loader) path. + if binary.format != lief.Binary.FORMATS.ELF: + logger.info(f'{path} is not ELF ({binary.format}), nothing to patch') + return - # Patch interpreter only for ELF - if Path(binary.interpreter).exists(): - logger.info( - f'Interpreter {binary.interpreter} exists, skipping interpreter patching' - ) - else: - old_interpreter = binary.interpreter - new_interpreter = str(get_interpreter_path()) - binary.interpreter = new_interpreter - logger.info(f'Updated interpreter from {old_interpreter} to: {new_interpreter}') - - # Update RPATH for ELF - logger.info(f'Updating RPATH for ELF binary') - - # Add or update RPATH entry - if binary.has(lief.ELF.DynamicEntry.TAG.RPATH): - # Update existing RPATH - rpath_entry = binary.get(lief.ELF.DynamicEntry.TAG.RPATH) - old_rpath = str(rpath_entry.value) - rpath_entry.paths = [str(rpath) for rpath in rpath_dir] - logger.info(f'Updated RPATH from "{old_rpath}" to: "{rpath_entry.value}"') - else: - # Add new RPATH entry - rpath_entry = lief.ELF.DynamicEntryRpath([str(rpath) for rpath in rpath_dir]) - binary.add(rpath_entry) - logger.info(f'Added new RPATH entry: "{rpath_dir}"') - - # Handle Mach-O binaries - elif binary.format == lief.Binary.FORMATS.MACHO: - logger.info(f'Processing Mach-O binary: {path}') - - # Log current RPATH commands - existing_rpaths = [] - for cmd in binary.commands: - if cmd.command == lief.MachO.LoadCommand.TYPE.RPATH: - existing_rpaths.append(cmd.path) + logger.info(f'Current interpreter: {binary.interpreter}') + if Path(binary.interpreter).exists(): logger.info( - f'Current RPATH entries: {existing_rpaths if existing_rpaths else "None"}' + f'Interpreter {binary.interpreter} exists, skipping interpreter patching' ) - - # Log current needed libraries - needed_libs = [] - for cmd in binary.commands: - if cmd.command in [ - lief.MachO.LoadCommand.TYPE.LOAD_DYLIB, - lief.MachO.LoadCommand.TYPE.LOAD_WEAK_DYLIB, - ]: - needed_libs.append(cmd.name) - logger.info(f'Current needed libraries: {needed_libs}') - - # Replace specific library references - for cmd in binary.commands: - if cmd.command in [ - lief.MachO.LoadCommand.TYPE.LOAD_DYLIB, - lief.MachO.LoadCommand.TYPE.LOAD_WEAK_DYLIB, - ]: - if cmd.name == '/usr/local/lib/libiconv.2.dylib': - old_name = cmd.name - cmd.name = '@rpath/libiconv.dylib' - logger.info(f'Replaced library reference: "{old_name}" -> "{cmd.name}"') - elif '/' not in cmd.name: - old_name = cmd.name - cmd.name = '@rpath/' + cmd.name - logger.info(f'Replaced library reference: "{old_name}" -> "{cmd.name}"') - - # Set RPATH for Mach-O - - for rpath in rpath_dir: - rpath_str = str(rpath) - rpath_cmd = lief.MachO.RPathCommand.create(rpath_str) - binary.add(rpath_cmd) - logger.info(f'Added RPATH to Mach-O binary: "{rpath_str}"') - - else: - logger.warning(f'Unsupported binary format for {path}: {binary.format}') return - # Write the modified binary - binary.write(str(path)) - logger.info(f'Successfully patched binary: {path}') + old_interpreter = binary.interpreter + binary.interpreter = str(get_interpreter_path()) + logger.info(f'Updated interpreter from {old_interpreter} to: {binary.interpreter}') - if binary.format == lief.Binary.FORMATS.MACHO: - logger.info(f'Trying to code sign Mach-O binary: {path}') - try: - subprocess.run(['codesign', '--force', '--sign', '-', path], check=True) - except Exception as e: - logger.error( - f'Failed to code sign Mach-O binary {path}: {e}. This may be critical. You can rerun with INTERACTIVE=true environment variable to pause on this error.' - ) - if INTERACTIVE: - input('Waiting for user to fix the issue. Press Enter to continue...') + binary.write(str(path)) + logger.info(f'Successfully patched interpreter: {path}') def run_check_command(command: list[str | Path]): @@ -363,8 +263,8 @@ def run_check_command(command: list[str | Path]): modules_executable = genvm_root_dir.joinpath('bin', 'genvm-modules') -if args.bin_patch: - patch_executable(modules_executable, rpath_dir=[genvm_root_dir.joinpath('lib')]) +if patch_interpreter: + patch_executable(modules_executable) if args.bin_check: run_check_command([modules_executable, '--version']) @@ -505,7 +405,7 @@ def process_executor_version(executor_version: str): executor_root_dir = genvm_root_dir.joinpath('executor', executor_version) executor_executable = executor_root_dir.joinpath('bin', 'genvm') - if args.executor_download or args.bin_patch or args.bin_check: + if args.executor_download or patch_interpreter or args.bin_check: if not executor_executable.exists() and args.executor_download: import lzma @@ -519,7 +419,33 @@ def process_executor_version(executor_version: str): }, ) tar_data = lzma.decompress(tar_xz_data) - tarfile.TarFile.open(fileobj=io.BytesIO(tar_data)).extractall(path=genvm_root_dir) + + # Integrity check before extraction. The expected hash, when present + # in the manifest, is taken over the decompressed `.tar` (matching the + # runner convention in runner_check_bytes), not the `.tar.xz`. No + # executor hash is published yet, so this currently warns instead of + # failing; add a `hash` field to the manifest's executor_versions entry + # to enforce it. + expected_hash = ( + manifest.get('executor_versions', {}).get(executor_version, {}).get('hash') + ) + if expected_hash is not None: + if not runner_check_bytes(tar_data, expected_hash): + raise ValueError(f'hash mismatch for executor {executor_version}') + elif executor_version == 'vTEST': + logger.warning( + f'no integrity hash for executor {executor_version}; skipping verification' + ) + else: + raise ValueError( + f'no integrity hash for executor {executor_version}; refusing to extract' + ) + + # filter='data' rejects absolute / `..` paths and unsafe link and device + # members, preventing writes outside genvm_root_dir (tar path-traversal / + # link-abuse). + with tarfile.TarFile.open(fileobj=io.BytesIO(tar_data)) as tar: + tar.extractall(path=genvm_root_dir, filter='data') if not executor_executable.exists(): if args.error_on_missing_executor: logger.error(f'Executor path {executor_executable} does not exist') @@ -527,11 +453,8 @@ def process_executor_version(executor_version: str): else: logger.warning(f'Executor path {executor_executable} does not exist, skipping') return - if args.bin_patch: - patch_executable( - executor_executable, - rpath_dir=[genvm_root_dir.joinpath('lib'), executor_root_dir.joinpath('lib')], - ) + if patch_interpreter: + patch_executable(executor_executable) if args.bin_check: run_check_command([executor_executable, '--version']) diff --git a/modules/install/lib/python/post-install/requirements.txt b/modules/install/lib/python/post-install/requirements.txt index c259fe8c5..4c36ff855 100644 --- a/modules/install/lib/python/post-install/requirements.txt +++ b/modules/install/lib/python/post-install/requirements.txt @@ -1,2 +1,3 @@ -lief==0.17.0 +# only needed for ELF interpreter patching (see post-install __main__.py) +lief==0.17.0; platform_system == "Linux" pyyaml==6.0.3 diff --git a/modules/interfaces/Cargo.lock b/modules/interfaces/Cargo.lock index 15f66bfc7..02f679560 100644 --- a/modules/interfaces/Cargo.lock +++ b/modules/interfaces/Cargo.lock @@ -258,6 +258,7 @@ dependencies = [ "num-bigint", "primitive-types", "serde", + "sha3", ] [[package]] diff --git a/modules/interfaces/src/lib.rs b/modules/interfaces/src/lib.rs index 858eeafa3..0dd0ba740 100644 --- a/modules/interfaces/src/lib.rs +++ b/modules/interfaces/src/lib.rs @@ -311,8 +311,6 @@ pub mod llm { payload: PromptTemplatePayload, remaining_fuel_as_gen: primitive_types::U256, }, - - GetStats, } #[derive( @@ -366,7 +364,6 @@ pub mod web { pub enum Message { Render(RenderPayload, u32), Request(RequestPayload, u32), - GetStats, } #[derive(Serialize, Deserialize, genlayer_calldata::Encode, genlayer_calldata::Decode)] diff --git a/modules/webdriver/src/prj/src/browser/chrome.ts b/modules/webdriver/src/prj/src/browser/chrome.ts index 90961b80a..6d618df91 100644 --- a/modules/webdriver/src/prj/src/browser/chrome.ts +++ b/modules/webdriver/src/prj/src/browser/chrome.ts @@ -2,7 +2,14 @@ import puppeteer, * as pup from 'puppeteer-core'; import * as logger from '../logging.js'; import * as util from 'util'; import * as child_process from 'child_process'; -import { envDurationMs, envInt, formatDurationMs } from '../duration.js'; +import { + envBool, + envDurationMs, + envInt, + envStr, + envStrList, + formatDurationMs, +} from '../duration.js'; import type * as browser from './index.js'; class BrowserHolder { @@ -59,21 +66,31 @@ const RENDERER_PROCESS_LIMIT = envInt( 4, ); +const CHROME_EXECUTABLE = envStr( + 'GVM_WEBDRIVER_CHROME_EXECUTABLE', + '/usr/bin/chromium', +); +const CHROME_HEADLESS = envBool('GVM_WEBDRIVER_CHROME_HEADLESS', true); +// Extra flags appended to the defaults below. See `envStrList` for the format. +const CHROME_EXTRA_ARGS = envStrList('GVM_WEBDRIVER_CHROME_ARGS', []); + async function newBrowser(): Promise { + const args = [ + '--no-sandbox', + '--disable-dev-shm-usage', + '--disable-accelerated-2d-canvas', + '--no-first-run', + '--no-zygote', + '--disable-gpu', + '--enable-precise-memory-info', + `--js-flags=--max-old-space-size=${RENDERER_MAX_OLD_SPACE_MB}`, + `--renderer-process-limit=${RENDERER_PROCESS_LIMIT}`, + ...CHROME_EXTRA_ARGS, + ]; const realBrowser = await puppeteer.launch({ - headless: true, - args: [ - '--no-sandbox', - '--disable-dev-shm-usage', - '--disable-accelerated-2d-canvas', - '--no-first-run', - '--no-zygote', - '--disable-gpu', - '--enable-precise-memory-info', - `--js-flags=--max-old-space-size=${RENDERER_MAX_OLD_SPACE_MB}`, - `--renderer-process-limit=${RENDERER_PROCESS_LIMIT}`, - ], - executablePath: '/usr/bin/chromium', + headless: CHROME_HEADLESS, + args, + executablePath: CHROME_EXECUTABLE, }); logger.log('info', 'created new raw browser', { @@ -129,66 +146,88 @@ class ChromeBrowserManager implements browser.Manager { private constructor(holder: BrowserHolder) { this.holder = holder; this.used = false; - setInterval(async () => { - const used = this.used; - const lastMemoryMB = this.lastMemoryMB; - const old = this.holder; - const proc = old.browser.process(); - const pid = proc?.pid; - let usedRAMMB = pid ? await getTotalRssMB(pid) : await getSelfRssMB(); - this.lastMemoryMB = usedRAMMB; - - let memoryDeltaMB = lastMemoryMB !== null ? usedRAMMB - lastMemoryMB : 0; - - const reasons: string[] = []; - - if ( - initialMemoryMB && - usedRAMMB > initialMemoryMB + ROTATION_ABSOLUTE_THRESHOLD_MB - ) { - reasons.push( - `absolute memory ${usedRAMMB.toFixed(0)}MB exceeds initial ${initialMemoryMB.toFixed(0)}MB + ${ROTATION_ABSOLUTE_THRESHOLD_MB}MB`, - ); - } - - if (!used && memoryDeltaMB > ROTATION_IDLE_DELTA_MB) { - reasons.push( - `idle memory grew by ${memoryDeltaMB.toFixed(0)}MB (threshold ${ROTATION_IDLE_DELTA_MB}MB)`, - ); - } - - if ( - ROTATION_AT_LEAST_MS > 0 && - Date.now() - this.lastRotationTime >= ROTATION_AT_LEAST_MS - ) { - reasons.push( - `age ${formatDurationMs(Date.now() - this.lastRotationTime)} exceeds max ${formatDurationMs(ROTATION_AT_LEAST_MS)}`, - ); - } - - logger.log('info', 'browser rotation check', { - shouldRotate: reasons.length > 0, - reasons, - used, - usedRAMMB, - memoryDeltaMB, - initialMemoryMB, - lastRotationAgo: formatDurationMs(Date.now() - this.lastRotationTime), - }); - - if (reasons.length === 0) { - return; - } - - const newB = await newBrowser(); - this.holder = newB; - this.lastMemoryMB = null; - this.used = false; - this.lastRotationTime = Date.now(); - await old.close(); + this.scheduleRotationCheck(); + } + + /** + * Arm the next rotation check. Uses a self-rescheduling timeout instead of + * setInterval so the next check is only scheduled once the current one has + * fully settled (in `finally`). This structurally prevents overlapping + * rotations from interleaving holder swaps / closes — which could otherwise + * orphan a freshly launched browser (process leak) or close one still + * serving a render — and avoids interval backlog under sustained load. + */ + private scheduleRotationCheck(): void { + setTimeout(() => { + void this.rotationCheck() + .catch((error) => { + logger.log('error', 'browser rotation check failed', { error }); + }) + .finally(() => { + this.scheduleRotationCheck(); + }); }, ROTATION_CHECK_INTERVAL_MS); } + private async rotationCheck(): Promise { + const used = this.used; + const lastMemoryMB = this.lastMemoryMB; + const old = this.holder; + const proc = old.browser.process(); + const pid = proc?.pid; + let usedRAMMB = pid ? await getTotalRssMB(pid) : await getSelfRssMB(); + this.lastMemoryMB = usedRAMMB; + + let memoryDeltaMB = lastMemoryMB !== null ? usedRAMMB - lastMemoryMB : 0; + + const reasons: string[] = []; + + if ( + initialMemoryMB && + usedRAMMB > initialMemoryMB + ROTATION_ABSOLUTE_THRESHOLD_MB + ) { + reasons.push( + `absolute memory ${usedRAMMB.toFixed(0)}MB exceeds initial ${initialMemoryMB.toFixed(0)}MB + ${ROTATION_ABSOLUTE_THRESHOLD_MB}MB`, + ); + } + + if (!used && memoryDeltaMB > ROTATION_IDLE_DELTA_MB) { + reasons.push( + `idle memory grew by ${memoryDeltaMB.toFixed(0)}MB (threshold ${ROTATION_IDLE_DELTA_MB}MB)`, + ); + } + + if ( + ROTATION_AT_LEAST_MS > 0 && + Date.now() - this.lastRotationTime >= ROTATION_AT_LEAST_MS + ) { + reasons.push( + `age ${formatDurationMs(Date.now() - this.lastRotationTime)} exceeds max ${formatDurationMs(ROTATION_AT_LEAST_MS)}`, + ); + } + + logger.log('info', 'browser rotation check', { + shouldRotate: reasons.length > 0, + reasons, + used, + usedRAMMB, + memoryDeltaMB, + initialMemoryMB, + lastRotationAgo: formatDurationMs(Date.now() - this.lastRotationTime), + }); + + if (reasons.length === 0) { + return; + } + + const newB = await newBrowser(); + this.holder = newB; + this.lastMemoryMB = null; + this.used = false; + this.lastRotationTime = Date.now(); + await old.close(); + } + getBrowser(): browser.Handle { this.holder.counter++; this.used = true; diff --git a/modules/webdriver/src/prj/src/duration.ts b/modules/webdriver/src/prj/src/duration.ts index 720fdfb22..ec7ddaad5 100644 --- a/modules/webdriver/src/prj/src/duration.ts +++ b/modules/webdriver/src/prj/src/duration.ts @@ -66,3 +66,69 @@ export function envInt(envName: string, defaultValue: number): number { }); return result; } + +export function envStr(envName: string, defaultValue: string): string { + const raw = process.env[envName]; + const value = raw !== undefined && raw !== '' ? raw : defaultValue; + logger.log('info', 'env', { + name: envName, + raw: raw ?? null, + value, + default: defaultValue, + }); + return value; +} + +const ENV_BOOL_TRUE = ['1', 'true', 'yes', 'on']; +const ENV_BOOL_FALSE = ['0', 'false', 'no', 'off']; + +export function envBool(envName: string, defaultValue: boolean): boolean { + const raw = process.env[envName]; + let value = defaultValue; + if (raw !== undefined && raw !== '') { + const norm = raw.trim().toLowerCase(); + if (ENV_BOOL_TRUE.includes(norm)) { + value = true; + } else if (ENV_BOOL_FALSE.includes(norm)) { + value = false; + } else { + throw new Error(`invalid boolean for env ${envName}: "${raw}"`); + } + } + logger.log('info', 'env', { + name: envName, + raw: raw ?? null, + value, + default: defaultValue, + }); + return value; +} + +/** + * Parse a list of strings from an env var. A value starting with `[` is parsed + * as a JSON array (use this when arguments contain spaces); otherwise the value + * is split on whitespace. + */ +export function envStrList(envName: string, defaultValue: string[]): string[] { + const raw = process.env[envName]; + let value = defaultValue; + const trimmed = raw?.trim() ?? ''; + if (trimmed !== '') { + if (trimmed.startsWith('[')) { + const parsed: unknown = JSON.parse(trimmed); + if (!Array.isArray(parsed) || parsed.some((x) => typeof x !== 'string')) { + throw new Error(`invalid string list for env ${envName}: "${raw}"`); + } + value = parsed as string[]; + } else { + value = trimmed.split(/\s+/); + } + } + logger.log('info', 'env', { + name: envName, + raw: raw ?? null, + value, + default: defaultValue, + }); + return value; +} diff --git a/modules/webdriver/src/prj/src/index.ts b/modules/webdriver/src/prj/src/index.ts index d5bb5e28c..d948c6ac4 100644 --- a/modules/webdriver/src/prj/src/index.ts +++ b/modules/webdriver/src/prj/src/index.ts @@ -4,6 +4,7 @@ import { Command } from 'commander'; import * as logger from './logging.js'; import * as chromeBrowser from './browser/chrome.js'; +import * as ssrf from './ssrf.js'; import { envDurationMs, envInt, formatDurationMs } from './duration.js'; interface NavigationOptions { @@ -66,6 +67,8 @@ function getNavigationErrorStatus(error: any): number { return 495; // SSL Certificate Error } else if (error.message?.includes('net::ERR_INTERNET_DISCONNECTED')) { return 503; // Service Unavailable + } else if (error.message?.includes('net::ERR_BLOCKED_BY_CLIENT')) { + return 403; // Forbidden (SSRF guard) } return STATUS_I_AM_A_TEAPOT; // Unknown error } @@ -81,6 +84,8 @@ function getNavigationErrorMessage(error: any): string { return 'SSL certificate error'; } else if (error.message?.includes('net::ERR_INTERNET_DISCONNECTED')) { return 'No internet connection'; + } else if (error.message?.includes('net::ERR_BLOCKED_BY_CLIENT')) { + return 'Blocked by SSRF guard: address not allowed'; } return `Navigation error: ${error.message || 'Unknown error'}`; } @@ -235,9 +240,20 @@ async function renderPageWithBrowser( maxPageHeapMB = DEFAULT_MAX_PAGE_HEAP_MB, } = options; - const page = await browserInstance.newPage(); + // Each render runs in its own browser context so cookies, localStorage, + // IndexedDB, service workers and HSTS state never leak between tenants + // sharing this long-lived browser. + const context = await browserInstance.createBrowserContext(); + const page = await context.newPage(); try { + await ssrf.installSsrfGuard(page); + context.on('targetcreated', async (target) => { + const p = await target.page(); + if (p && p !== page) { + await ssrf.installSsrfGuard(p); + } + }); page.setViewport({ width: 1920 / 2, height: 1080 / 2 }); return await withHeapMonitor(page, maxPageHeapMB, async () => { @@ -295,7 +311,9 @@ async function renderPageWithBrowser( } throw e; } finally { - await page.close(); + // Close the page and its context together; the context teardown is what + // actually discards the per-request browsing state. + await Promise.allSettled([page.close(), context.close()]); } } diff --git a/modules/webdriver/src/prj/src/ssrf.ts b/modules/webdriver/src/prj/src/ssrf.ts new file mode 100644 index 000000000..336c53f1f --- /dev/null +++ b/modules/webdriver/src/prj/src/ssrf.ts @@ -0,0 +1,246 @@ +import * as dns from 'node:dns/promises'; +import * as net from 'node:net'; +import type * as pup from 'puppeteer-core'; +import * as logger from './logging.js'; + +/** + * SSRF guard for the webdriver. + * + * Chrome resolves DNS and follows redirects itself, so it never passes through + * any host-side filter. Without this guard a contract could point an otherwise + * valid public URL (or one of the page's sub-resources) at an internal address + * such as cloud metadata (169.254.169.254), loopback or an RFC1918 host. + * + * We intercept every request the page makes (top-level navigation, + * sub-resources and each redirect hop), resolve the host ourselves and abort + * the request when any resolved address is not globally routable. + * + * NOTE: resolution happens here while Chrome connects separately, so a low-TTL + * attacker controlling DNS could in theory return a routable address to us and + * a private one to Chrome. We mitigate by failing closed: if *any* address a + * host resolves to is private, the host is blocked outright. + */ + +function parseIPv4(ip: string): [number, number, number, number] | null { + const parts = ip.split('.'); + if (parts.length !== 4) { + return null; + } + const nums: number[] = []; + for (const part of parts) { + if (!/^\d{1,3}$/.test(part)) { + return null; + } + const n = Number(part); + if (n > 255) { + return null; + } + nums.push(n); + } + return [nums[0]!, nums[1]!, nums[2]!, nums[3]!]; +} + +/** Whether an IPv4 address is not safe to connect to (not globally routable). */ +function ipv4IsBad(ip: string): boolean { + const octets = parseIPv4(ip); + if (octets === null) { + return true; // unparseable => fail closed + } + const [a, b, c] = octets; + return ( + a === 0 || // 0.0.0.0/8 "this" network + a === 10 || // 10.0.0.0/8 private + a === 127 || // 127.0.0.0/8 loopback + (a === 169 && b === 254) || // 169.254.0.0/16 link-local + (a === 172 && b >= 16 && b <= 31) || // 172.16.0.0/12 private + (a === 192 && b === 168) || // 192.168.0.0/16 private + (a === 100 && b >= 64 && b <= 127) || // 100.64.0.0/10 CGNAT + (a === 192 && b === 0 && c === 2) || // 192.0.2.0/24 documentation + (a === 198 && b >= 18 && b <= 19) || // 198.18.0.0/15 benchmarking + (a === 198 && b === 51 && c === 100) || // 198.51.100.0/24 documentation + (a === 203 && b === 0 && c === 113) || // 203.0.113.0/24 documentation + a >= 224 // 224.0.0.0/3 multicast + reserved + broadcast + ); +} + +function parseIPv6(ip: string): number[] | null { + const withoutZone = ip.split('%')[0] ?? ''; + const halves = withoutZone.split('::'); + if (halves.length > 2) { + return null; + } + + const parseGroups = (segment: string): number[] | null => { + if (segment === '') { + return []; + } + const parts = segment.split(':'); + const groups: number[] = []; + for (let i = 0; i < parts.length; i++) { + const part = parts[i]!; + if (part.includes('.')) { + // embedded IPv4 is only valid as the final element + if (i !== parts.length - 1) { + return null; + } + const octets = parseIPv4(part); + if (octets === null) { + return null; + } + const [a, b, c, d] = octets; + groups.push((a << 8) | b); + groups.push((c << 8) | d); + } else { + if (!/^[0-9a-fA-F]{1,4}$/.test(part)) { + return null; + } + groups.push(parseInt(part, 16)); + } + } + return groups; + }; + + if (halves.length === 1) { + const groups = parseGroups(halves[0]!); + if (groups === null || groups.length !== 8) { + return null; + } + return groups; + } + + const head = parseGroups(halves[0]!); + const tail = parseGroups(halves[1]!); + if (head === null || tail === null) { + return null; + } + const missing = 8 - head.length - tail.length; + if (missing < 1) { + return null; // "::" must stand for at least one zero group + } + return [...head, ...new Array(missing).fill(0), ...tail]; +} + +/** Whether an IPv6 address is not safe to connect to (not globally routable). */ +function ipv6IsBad(ip: string): boolean { + const groups = parseIPv6(ip); + if (groups === null || groups.length !== 8) { + return true; // fail closed + } + + // an IPv4-mapped address (::ffff:a.b.c.d) is only as safe as its IPv4 part + if ( + groups[0] === 0 && + groups[1] === 0 && + groups[2] === 0 && + groups[3] === 0 && + groups[4] === 0 && + groups[5] === 0xffff + ) { + const g6 = groups[6]!; + const g7 = groups[7]!; + const v4 = `${g6 >> 8}.${g6 & 0xff}.${g7 >> 8}.${g7 & 0xff}`; + return ipv4IsBad(v4); + } + + if (groups.every((g) => g === 0)) { + return true; // :: unspecified + } + if (groups.slice(0, 7).every((g) => g === 0) && groups[7] === 1) { + return true; // ::1 loopback + } + + const first = groups[0]!; + return ( + (first & 0xfe00) === 0xfc00 || // fc00::/7 unique-local + (first & 0xffc0) === 0xfe80 || // fe80::/10 link-local + (first & 0xffc0) === 0xfec0 || // fec0::/10 deprecated site-local + (first & 0xff00) === 0xff00 // ff00::/8 multicast + ); +} + +/** Whether a resolved address must not be connected to (SSRF guard). */ +export function ipIsBad(ip: string): boolean { + switch (net.isIP(ip)) { + case 4: + return ipv4IsBad(ip); + case 6: + return ipv6IsBad(ip); + default: + return true; // not a bare IP => fail closed + } +} + +/** Resolve a URL host to its addresses; IP literals resolve to themselves. */ +async function resolveHost(host: string): Promise { + const stripped = + host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host; + if (net.isIP(stripped) !== 0) { + return [stripped]; + } + const results = await dns.lookup(stripped, { all: true }); + return results.map((r) => r.address); +} + +// Schemes that perform no network access and are always allowed. +const NETWORKLESS_SCHEMES = new Set(['data:', 'blob:', 'about:']); +// Schemes that go to a host and must be checked. +const NETWORK_SCHEMES = new Set(['http:', 'https:', 'ws:', 'wss:']); + +async function isUrlAllowed(rawUrl: string): Promise { + let parsed: URL; + try { + parsed = new URL(rawUrl); + } catch { + return false; + } + if (NETWORKLESS_SCHEMES.has(parsed.protocol)) { + return true; + } + if (!NETWORK_SCHEMES.has(parsed.protocol)) { + return false; // file:, ftp:, chrome:, ... + } + let addrs: string[]; + try { + addrs = await resolveHost(parsed.hostname); + } catch { + return false; // resolution failure => block + } + if (addrs.length === 0) { + return false; + } + // fail closed: block if *any* resolved address is non-globally-routable + return !addrs.some(ipIsBad); +} + +/** + * Enable request interception on `page` and abort every request whose target + * resolves to a non-globally-routable address. + */ +export async function installSsrfGuard(page: pup.Page): Promise { + await page.setRequestInterception(true); + page.on('request', (request) => { + void (async () => { + const url = request.url(); + let allowed: boolean; + try { + allowed = await isUrlAllowed(url); + } catch { + allowed = false; + } + try { + if (allowed) { + await request.continue(); + } else { + logger.log('warn', 'ssrf guard blocked request', { url }); + await request.abort('blockedbyclient'); + } + } catch (e) { + // the request may already be resolved or the page may be gone + logger.log('debug', 'ssrf guard could not finalize request', { + url, + error: (e as Error).message, + }); + } + })(); + }); +} diff --git a/runners/genlayer-py-std/default.nix b/runners/genlayer-py-std/default.nix index f6c48c7dd..d190bd5d6 100644 --- a/runners/genlayer-py-std/default.nix +++ b/runners/genlayer-py-std/default.nix @@ -58,7 +58,7 @@ in expr = { Seq = [ - { With = { runner = ""; action = { MapFile = { file = "file"; to = "/contract.py"; }; }; }; } + { With = { runner = "contract"; action = { MapFile = { file = "file"; to = "/contract.py"; }; }; }; } ] ++ middle_runner_seq; }; })) ++ @@ -68,7 +68,7 @@ in expr = { Seq = [ - { With = { runner = ""; action = { MapFile = { file = "contract/"; to = "/contract/"; }; }; }; } + { With = { runner = "contract"; action = { MapFile = { file = "contract/"; to = "/contract/"; }; }; }; } ] ++ middle_runner_seq; }; })) ++ diff --git a/runners/genlayer-py-std/src/genlayer/_internal/on_chain/storage.py b/runners/genlayer-py-std/src/genlayer/_internal/on_chain/storage.py index deec49173..3797cc6a7 100644 --- a/runners/genlayer-py-std/src/genlayer/_internal/on_chain/storage.py +++ b/runners/genlayer-py-std/src/genlayer/_internal/on_chain/storage.py @@ -1,6 +1,6 @@ __all__ = ('STORAGE_MAN', 'ROOT_SLOT_ID') -from genlayer.storage.core import Manager, Slot, ROOT_SLOT_ID +from genlayer.storage.core import Manager, Slot, ROOT_SLOT_ID, slot_id_to_bytes from genlayer.types import u256 import _genlayer_wasi as wasi @@ -15,7 +15,8 @@ class _ActualStorageMan(Manager): def __init__(self): self._slots = {} - def get_store_slot(self, addr: bytes) -> Slot: + def get_store_slot(self, addr: bytes | u256) -> Slot: + addr = slot_id_to_bytes(addr) ret = self._slots.get(addr, None) if ret is None: ret = Slot(addr, self) diff --git a/runners/genlayer-py-std/src/genlayer/gvm32.py b/runners/genlayer-py-std/src/genlayer/gvm32.py new file mode 100644 index 000000000..c0f7f9fa8 --- /dev/null +++ b/runners/genlayer-py-std/src/genlayer/gvm32.py @@ -0,0 +1,78 @@ +""" +GenVM base32 encoder/decoder. + +Uses `Crockford's Base32 `_: the alphabet +``0123456789abcdefghjkmnpqrstvwxyz`` (excludes ``i``, ``l``, ``o``, ``u``), no +padding, big-endian bit packing. Encoding is lowercase by default; decoding is +case-insensitive, treats ``i``/``l`` as ``1`` and ``o`` as ``0``, and ignores +``-``. Used to encode hashes (such as runner ids). Mirrors the Rust +``genlayer_sdk::gvm32`` implementation. +""" + +__all__ = ('encode', 'decode') + +import collections.abc + +_ALPHABET = '0123456789abcdefghjkmnpqrstvwxyz' + + +def encode(data: collections.abc.Buffer) -> str: + """ + Encode a byte buffer to its Crockford Base32 string (lowercase, no padding). + + :param data: bytes to encode + :returns: the base32-encoded string + """ + out: list[str] = [] + value = 0 + bits = 0 + for byte in bytes(data): + value = (value << 8) | byte + bits += 8 + while bits >= 5: + bits -= 5 + out.append(_ALPHABET[(value >> bits) & 0x1F]) + if bits > 0: + out.append(_ALPHABET[(value << (5 - bits)) & 0x1F]) + return ''.join(out) + + +def _decode_char(ch: str) -> int | None: + c = ch.lower() + if c == 'o': + c = '0' + elif c in ('i', 'l'): + c = '1' + idx = _ALPHABET.find(c) + return idx if idx >= 0 else None + + +def decode(s: str) -> bytes | None: + """ + Decode a Crockford Base32 string back to bytes. + + Case-insensitive; ``i``/``l`` are read as ``1``, ``o`` as ``0`` and ``-`` is + ignored. + + :param s: base32 string + :returns: the decoded bytes, or ``None`` if ``s`` contains an invalid + character or has non-zero trailing padding bits + """ + out = bytearray() + value = 0 + bits = 0 + for ch in s: + if ch == '-': + continue + digit = _decode_char(ch) + if digit is None: + return None + value = (value << 5) | digit + bits += 5 + if bits >= 8: + bits -= 8 + out.append((value >> bits) & 0xFF) + # any leftover bits are padding and must be zero + if value & ((1 << bits) - 1): + return None + return bytes(out) diff --git a/runners/genlayer-py-std/src/genlayer/nondet/__init__.py b/runners/genlayer-py-std/src/genlayer/nondet/__init__.py index ca964cb7d..4c4981701 100644 --- a/runners/genlayer-py-std/src/genlayer/nondet/__init__.py +++ b/runners/genlayer-py-std/src/genlayer/nondet/__init__.py @@ -125,9 +125,6 @@ def exec_prompt( format = config.get('response_format', 'text') - if format == 'json': - format = 'json2' - return gl_call.gl_call_generic( { 'ExecPrompt': { @@ -136,7 +133,7 @@ def exec_prompt( 'images': images, } }, - _decode_nondet_json if format == 'json2' else _decode_nondet, + _decode_nondet_json if format == 'json' else _decode_nondet, ) diff --git a/runners/genlayer-py-std/src/genlayer/storage/__init__.py b/runners/genlayer-py-std/src/genlayer/storage/__init__.py index 768304977..49c4a66ec 100644 --- a/runners/genlayer-py-std/src/genlayer/storage/__init__.py +++ b/runners/genlayer-py-std/src/genlayer/storage/__init__.py @@ -41,8 +41,6 @@ from ._internal.generate import ( ORIGINAL_INIT_ATTR, - generate_storage, - _known_descs, _storage_build, _BuilderCtx, ) @@ -79,11 +77,8 @@ def cast_slot[T](t: typing.Type[T], manager: Manager, slot: bytes, offset: int, """ Unsafely casts a storage slot to the given type. Use with caution. """ - td = _storage_build(_BuilderCtx.empty(), t) - - instance = td.get(manager.get_store_slot(slot), offset) - - return instance + slt = manager.get_store_slot(slot) + return slt.cast(t, offset) def copy_to_memory[T](val: T, /) -> T: diff --git a/runners/genlayer-py-std/src/genlayer/storage/core.py b/runners/genlayer-py-std/src/genlayer/storage/core.py index 6663ff861..fc9a10399 100644 --- a/runners/genlayer-py-std/src/genlayer/storage/core.py +++ b/runners/genlayer-py-std/src/genlayer/storage/core.py @@ -7,20 +7,33 @@ from genlayer.types import u256 +def slot_id_to_bytes(slot_id: u256 | bytes) -> bytes: + if isinstance(slot_id, int): + return slot_id.to_bytes(32, 'little', signed=False) + elif isinstance(slot_id, bytes): + if len(slot_id) != 32: + raise ValueError(f'slot_id must be 32 bytes, got {len(slot_id)}') + return slot_id + else: + raise TypeError(f'slot_id must be u256 or bytes, got {type(slot_id)}') + + class Manager(metaclass=abc.ABCMeta): """ Abstract interface for storage backends. """ - def get_store_slot(self, slot_id: bytes, /) -> 'Slot': + @abc.abstractmethod + def get_store_slot(self, slot_id: bytes | u256, /) -> 'Slot': """ Return a slot for the given address, creating one if necessary. - :param slot_id: 32-byte slot address + :param slot_id: 32-byte slot address or 256-bit slot address :returns: storage slot """ ... + @abc.abstractmethod def do_read(self, slot_id: bytes, off: int, len: int, /) -> bytes: """ Read raw bytes from storage. @@ -32,6 +45,7 @@ def do_read(self, slot_id: bytes, off: int, len: int, /) -> bytes: """ ... + @abc.abstractmethod def do_write(self, slot_id: bytes, off: int, what: collections.abc.Buffer, /): """ Write raw bytes to storage. @@ -105,6 +119,18 @@ def as_int(self) -> u256: """ return int.from_bytes(self.id, 'little', signed=False) + def cast[T](self, t: typing.Type[T], offset: int, /) -> T: + """ + Unsafely casts a storage slot to the given type. Use with caution. + """ + from ._internal.generate import _BuilderCtx, _storage_build + + td = _storage_build(_BuilderCtx.empty(), t) + + instance = td.get(self, offset) + + return instance + def __eq__(self, r: object) -> bool: if not isinstance(r, Slot): return False @@ -484,7 +510,8 @@ class InmemManager(Manager): def __init__(self): self._parts = {} - def get_store_slot(self, id: bytes) -> Slot: + def get_store_slot(self, id: bytes | u256) -> Slot: + id = slot_id_to_bytes(id) res = self._parts.get(id, None) if res is None: slt = Slot(id, self) diff --git a/runners/genlayer-py-std/src/genlayer/storage/root.py b/runners/genlayer-py-std/src/genlayer/storage/root.py index 6fcae7231..51ea48993 100644 --- a/runners/genlayer-py-std/src/genlayer/storage/root.py +++ b/runners/genlayer-py-std/src/genlayer/storage/root.py @@ -26,6 +26,11 @@ class Root: It is set to an actual storage manager in the runtime, but can be overridden for testing purposes. """ + major: u8 + """ + Major version of the GenVM contract expects + """ + contract_instance: Indirection[None] code: Indirection[VLA[u8]] @@ -39,9 +44,11 @@ class Root: """ upgraders: Indirection[VLA[Address]] - major: u8 + code_slot: u256 """ - Major version of the GenVM contract expects + Slot id the contract code is stored at, as a raw 32-byte value. If zero (the + default), the code is read from the default ``code`` slot; otherwise it is read + from the pointed-to slot (see ``chain:`` runner ids). """ @staticmethod @@ -62,12 +69,23 @@ def slot(self) -> Slot: """ return self._storage_slot # type: ignore + def get_resolved_code(self) -> VLA[u8]: + """ + Return the storage slot where the contract code is stored. + + :returns: code storage slot + """ + if self.code_slot == 0: + return self.code.get() + else: + return Root.MANAGER.get_store_slot(self.code_slot).cast(VLA[u8], 0) + def get_vacant_slot(self) -> Slot: """ This slot can be used to store data without worrying about overwriting contract data. Useful for bootstrapping contract storage """ - return self.slot().indirect(public_abi.root_offsets.MAJOR) + return self.slot().indirect(public_abi.root_offsets.CODE_SLOT) def get_contract_instance[T](self, typ: typing.Type[T], /) -> T: """ diff --git a/runners/genlayer-py-std/src/genlayer/vm/__init__.py b/runners/genlayer-py-std/src/genlayer/vm/__init__.py index 447941910..12d888734 100644 --- a/runners/genlayer-py-std/src/genlayer/vm/__init__.py +++ b/runners/genlayer-py-std/src/genlayer/vm/__init__.py @@ -20,6 +20,10 @@ 'Result', 'trace', 'trace_time_micro', + 'yield_', + 'get_timestamp', + 'register_runner', + 'map_file', 'ABI', ) @@ -33,6 +37,7 @@ import typing import dataclasses +import datetime import collections.abc from genlayer.types import Lazy @@ -117,11 +122,7 @@ def _decode_sub_vm_result_retn( ) -> Result: mem = memoryview(data) if mem[0] == ResultCode.USER_ERROR: - payload = mem[1:] - if len(payload) >= 4 and bytes(payload[:4]) == b'\x00\x00\x00\x00': - return UserError(calldata.decode(payload[4:])) - else: - return UserError(str(payload, encoding='utf8')) + return UserError(calldata.decode(mem[1:])) if mem[0] == ResultCode.RETURN: return Return(calldata.decode(mem[1:])) if mem[0] == ResultCode.VM_ERROR: @@ -157,7 +158,12 @@ def _decode_sub_vm_result( @_lazy_api def spawn_sandbox[T: calldata.Decoded]( - fn: typing.Callable[[], T], *, allow_write_ops: bool = False + fn: typing.Callable[[], T], + *, + runner: str = 'contract', + allow_write_storage: bool = False, + allow_send_messages: bool = False, + allow_register_runners: bool = False, ) -> Lazy[Return[T] | VMError | UserError]: """ Runs a function in an isolated sandbox environment. @@ -166,8 +172,14 @@ def spawn_sandbox[T: calldata.Decoded]( This provides isolation and security for potentially unsafe operations. Determinism of spawned VM matches the determinism of the current VM. + Each ``allow_*`` flag grants the corresponding permission to the sandbox, but + only if the current VM holds it as well. + :param fn: Function to execute in the sandbox (must be serializable with cloudpickle) - :param allow_write_ops: Whether to allow write operations in the sandbox. Only effective if current VM has corresponding permission + :param runner: runner id the sandbox loads instead of this contract's code; ``contract`` (default) reuses this contract's runner, a ``custom:``/``name:hash``/``chain:`` id runs that runner + :param allow_write_storage: Whether to allow storage writes in the sandbox + :param allow_send_messages: Whether to allow sending messages in the sandbox + :param allow_register_runners: Whether to allow registering runners in the sandbox Example: >>> result = spawn_sandbox(lambda: risky_computation()) @@ -179,7 +191,10 @@ def spawn_sandbox[T: calldata.Decoded]( { 'Sandbox': { 'data': cloudpickle.dumps(fn), - 'allow_write_ops': allow_write_ops, + 'runner': runner, + 'allow_write_storage': allow_write_storage, + 'allow_send_messages': allow_send_messages, + 'allow_register_runners': allow_register_runners, } }, _decode_sub_vm_result_retn, @@ -286,7 +301,9 @@ def real_validator_fn(stage_data) -> bool: import genlayer.vm as vm answer = vm.spawn_sandbox( - lambda: validator_fn(leaders_result), allow_write_ops=True + lambda: validator_fn(leaders_result), + allow_write_storage=True, + allow_send_messages=True, ) if type(answer) is not type(leaders_result): @@ -334,3 +351,74 @@ def trace_time_micro() -> int: }, lambda x: typing.cast(int, calldata.decode(x)), ).get() + + +def yield_() -> None: + """ + Cooperative yield. Currently a no-op, reserved for future use in waiting loops. + """ + wasi.gl_call(calldata.encode({'Yield': None})) + + +def get_timestamp() -> datetime.datetime: + """ + Returns the current timestamp as a timezone-aware ``datetime``. + + In deterministic mode it is the transaction timestamp; in + non-deterministic mode it is the real wall-clock time. + """ + return gl_call.gl_call_generic( + { + 'GetTimestamp': None, + }, + lambda x: datetime.datetime.fromtimestamp( + typing.cast(int, calldata.decode(x)), datetime.timezone.utc + ), + ).get() + + +def register_runner(code: collections.abc.Buffer) -> str: + """ + Registers a runner archive at runtime and returns its ``custom:`` id. + + The returned id can be referenced from ``Depends``/``With`` actions of other + runners. Requires deterministic mode and the ``register_runners`` permission. + + :param code: runner archive bytes (ustar/zip or commented text) + :return: the ``custom:`` runner id + """ + return gl_call.gl_call_generic( + { + 'RegisterRunner': { + 'code': code, + }, + }, + lambda x: typing.cast(str, calldata.decode(x)), + ).get() + + +def map_file(runner: str, path_in_runner: str, path_in_vfs: str) -> None: + """ + Maps a file from a runner into the VM filesystem at runtime. + + Behaves the same as the ``MapFile`` runner action: if ``path_in_runner`` ends + with ``/`` the whole directory subtree is mapped, otherwise a single file. + + Requires the ``read_storage`` permission (a ``chain:`` runner reads another + contract's storage). Mapping into ``/vm/`` is forbidden. + + :param runner: runner id (e.g. ``name:hash``, ``contract``, ``custom:``) + :param path_in_runner: path within the runner archive + :param path_in_vfs: absolute destination path in the VM filesystem + """ + wasi.gl_call( + calldata.encode( + { + 'MapFile': { + 'runner': runner, + 'path_in_runner': path_in_runner, + 'path_in_vfs': path_in_vfs, + } + } + ) + ) diff --git a/runners/genlayer-py-std/src/genlayer/vm/public_abi.py b/runners/genlayer-py-std/src/genlayer/vm/public_abi.py index 6baf5a15b..6c29cc2ce 100644 --- a/runners/genlayer-py-std/src/genlayer/vm/public_abi.py +++ b/runners/genlayer-py-std/src/genlayer/vm/public_abi.py @@ -34,11 +34,12 @@ class _MemoryLimiterConsts(typing.NamedTuple): class _RootOffsets(typing.NamedTuple): - CONTRACT: int = 0 - CODE: int = 1 - LOCKED_SLOTS: int = 2 - UPGRADERS: int = 3 - MAJOR: int = 4 + MAJOR: int = 0 + CONTRACT: int = 1 + CODE: int = 2 + LOCKED_SLOTS: int = 3 + UPGRADERS: int = 4 + CODE_SLOT: int = 5 root_offsets: typing.Final = _RootOffsets() @@ -136,6 +137,9 @@ def not_utf8_text() -> 'VmError': def malformed_runner() -> 'VmError': return VmError('invalid_contract malformed_runner') @staticmethod + def major_mismatch() -> 'VmError': + return VmError('invalid_contract major_mismatch') + @staticmethod def wasm() -> '_VmErrorInvalidContractWasm': return _VmErrorInvalidContractWasm() diff --git a/runners/genlayer-py-std/tests/test_gvm32.py b/runners/genlayer-py-std/tests/test_gvm32.py new file mode 100644 index 000000000..a5b800732 --- /dev/null +++ b/runners/genlayer-py-std/tests/test_gvm32.py @@ -0,0 +1,41 @@ +from genlayer.gvm32 import encode, decode + +# hex, gvm32 (Crockford Base32, lowercase) — shared with executor/crates/sdk-rs/tests/gvm32.rs +CASES = [ + ( + 'ab335240fd942ab8191c5e628cd4ff3903c577bda961fb75df08e0303a00527b', + 'ncsn4g7xjgnbg68wbsh8sn7z741waxxxn5gzpxez13g30eg0a9xg', + ), + ('47b2d8f260c2d48116044bc43fe3de0f', '8ysdhwk0rba825g49f23zryy1w'), + ('1f74d74729abdc08f4f84e8f7f8c808c8ed92ee5', '3xtdehs9nfe0hx7r9t7qz340hj7djbq5'), + ( + '99a2da84cec54d17325bcee0a079669c1b15eb7ead32246514b75b97862f1e00', + 'k6hdn16ern6hecjvsvga0yb6kgdhbtvynms28s8mpxdsf1hf3r00', + ), +] + + +def test_round_trip(): + for hexs, b32 in CASES: + raw = bytes.fromhex(hexs) + assert encode(raw) == b32 + assert decode(b32) == raw + + +def test_empty(): + assert encode(b'') == '' + assert decode('') == b'' + + +def test_case_insensitive_and_aliases(): + raw = bytes.fromhex('47b2d8f260c2d48116044bc43fe3de0f') + canonical = '8ysdhwk0rba825g49f23zryy1w' + assert decode(canonical.upper()) == raw + assert decode('8ysd-hwk0-rba8-25g4-9f23-zryy-1w') == raw + # crockford aliases: i/l -> 1, o -> 0 + assert decode('ooiill') == decode('001111') + + +def test_rejects_invalid(): + assert decode('u') is None # not in alphabet, not an alias + assert decode('01') is None # non-zero trailing padding bits diff --git a/runners/support/default.nix b/runners/support/default.nix index fc484b17e..730e4ac0a 100644 --- a/runners/support/default.nix +++ b/runners/support/default.nix @@ -15,7 +15,10 @@ in rec { add-mod-name = import ./tools/genvm-wasm-add-mod-name args; }; - hashToIDHash = hash: if hash == "test" then "test" else builtins.convertHash { inherit hash; toHashFormat = "nix32"; }; + gvm32 = import ./gvm32.nix; + # dev-mode magic hash: the literal gvm32 string "test" padded with "0"s to 52 chars + testRunnerHash = "test" + (builtins.concatStringsSep "" (builtins.genList (_: "0") 48)); + hashToIDHash = hash: if hash == "test" then testRunnerHash else gvm32.encodeHex (builtins.convertHash { inherit hash; toHashFormat = "base16"; }); package = { id, hash, baseDerivation }: { inherit id hash; diff --git a/runners/support/gvm32.nix b/runners/support/gvm32.nix new file mode 100644 index 000000000..6214e56a6 --- /dev/null +++ b/runners/support/gvm32.nix @@ -0,0 +1,68 @@ +# GenVM base32 (Crockford's Base32, lowercase) encoder. +# +# Mirrors executor/crates/sdk-rs/src/gvm32.rs and +# runners/genlayer-py-std/src/genlayer/gvm32.py. Used to derive runner content +# hash ids. Implemented per output symbol (not by accumulating the whole value) +# so it never overflows Nix's 64-bit integers, even for long hashes. +# +# Pure: depends only on `builtins`, so it can be imported from contexts that do +# not have nixpkgs `lib` (e.g. versions/current.nix). +let + # string -> list of single-character strings (like lib.stringToCharacters) + stringToChars = s: + builtins.genList (i: builtins.substring i 1 s) (builtins.stringLength s); + + alphabet = stringToChars "0123456789abcdefghjkmnpqrstvwxyz"; + + # Nix `/` is integer division for ints; there is no `%` operator. + mod = a: b: a - b * (a / b); + # 2^n; the generated list's elements are irrelevant, only its length matters. + pow2 = n: builtins.foldl' (acc: _: acc * 2) 1 (builtins.genList (x: x) n); + + hexValues = { + "0" = 0; "1" = 1; "2" = 2; "3" = 3; "4" = 4; "5" = 5; "6" = 6; "7" = 7; + "8" = 8; "9" = 9; "a" = 10; "b" = 11; "c" = 12; "d" = 13; "e" = 14; + "f" = 15; "A" = 10; "B" = 11; "C" = 12; "D" = 13; "E" = 14; "F" = 15; + }; + + # hex string -> list of byte integers + hexToBytes = hex: + let + chars = stringToChars hex; + charsLen = builtins.length chars; + # integer division truncates, so reject odd lengths instead of + # silently dropping the final nibble (which would corrupt the hash). + n = + if charsLen / 2 * 2 != charsLen + then throw "gvm32.hexToBytes: hex string length must be even" + else charsLen / 2; + in + builtins.genList + (i: hexValues.${builtins.elemAt chars (i * 2)} * 16 + + hexValues.${builtins.elemAt chars (i * 2 + 1)}) + n; + + # list of byte integers -> Crockford Base32 string + encode = bytes: + let + len = builtins.length bytes; + byteAt = i: if i < len then builtins.elemAt bytes i else 0; + nsym = (len * 8 + 4) / 5; # ceil(len * 8 / 5) + symAt = k: + let + b = k * 5; + i = b / 8; + j = mod b 8; + # 16-bit big-endian window over bytes[i], bytes[i+1] + window = byteAt i * 256 + byteAt (i + 1); + v = mod (window / (pow2 (11 - j))) 32; + in + builtins.elemAt alphabet v; + in + builtins.concatStringsSep "" (builtins.genList symAt nsym); + + encodeHex = hex: encode (hexToBytes hex); +in +{ + inherit encode encodeHex; +} diff --git a/runners/support/versions/current.nix b/runners/support/versions/current.nix index 77f212413..8c382675f 100644 --- a/runners/support/versions/current.nix +++ b/runners/support/versions/current.nix @@ -1,6 +1,11 @@ let dev-mode = import ./dev-mode.nix; + # gvm32 (Crockford Base32) — the encoding the executor uses for runner hash + # ids. The embedded `uid` (consumed by `Depends`) MUST use this, matching the + # on-disk runner paths and `hashToIDHash` in ../default.nix. + gvm32 = import ../gvm32.nix; + src = rec { __prefix = ""; @@ -27,11 +32,11 @@ let }; genlayer-std = { - hash = "sha256-cN/I/NE1rffwlrhd3o6Xso45hB7I3yLeRRwpMnfy+II="; + hash = "sha256-/pdXFMD6CtosS0LH2fJbZkJg5E3sMFnpWrC3yXVONgQ="; }; genlayer-embeddings = { - hash = "sha256-y86+lwso1yaosRcyj4wI92YQfj2JNvn0BRBYLG2IpNU="; + hash = "sha256-Lw2tC5IdLPhw4M+Zfp2igB9NUI9m3PgNyUmb9GMSQWQ="; depends = [ models.all-MiniLM-L6-v2 @@ -42,7 +47,7 @@ let }; cpython = { - hash = "sha256-qYd0fAfKBdFwG9qR+AsXjS8gJFm11Z47vsnMEyf0SzM="; + hash = "sha256-LqsYHYqiAYnwDoXMpHOQHqvQCa+Dh9562J5ClfEggxI="; depends = [ softfloat ]; @@ -55,7 +60,7 @@ let wrappers = { __prefix = ""; py-genlayer = { - hash = "sha256-kG+3MeXEXyVV9vbJL8AuffoMoQav+wbePKmdVCa2Jv8="; + hash = "sha256-u9lPFVpXuye3z8SsOfjIwRzAKfRAPy4tmTUnA+um6K0="; depends = [ cpython pyLibs.cloudpickle @@ -63,7 +68,7 @@ let ]; }; py-genlayer-multi = { - hash = "sha256-5C1f9KTf4MXZL3cZflwsy2fhJq7icS4yfHjZxxEyhks="; + hash = "sha256-woB2R5aziFLNpKCjEquWAsorIPH4/EpaRdVVYJYSy3w="; depends = [ cpython pyLibs.cloudpickle @@ -132,7 +137,7 @@ let if deducedHash == null then fakeHash else deducedHash; - hash32 = if deducedHash == "test" then "test" else builtins.convertHash { hash = hashSRI; toHashFormat = "nix32"; }; + hash32 = if deducedHash == "test" then "test" else gvm32.encodeHex (builtins.convertHash { hash = hashSRI; toHashFormat = "base16"; }); in rec { id = pref + name; diff --git a/runners/support/versions/generation-00.nix b/runners/support/versions/generation-00.nix index c16579660..33cd33a39 100644 --- a/runners/support/versions/generation-00.nix +++ b/runners/support/versions/generation-00.nix @@ -4,53 +4,8 @@ }: let revs = [ - "86b7cce46d9dee4ed1fb76e8107e60617b7622db" # v0.2.0 - "de381dbc862575b2a4f3d43a1b96ec14814af9fd" # v0.2.3 - "fed444c0d9537f41a6ccafeac7c7507a2cd8f69e" # v0.2.4 ]; - # These frozen v0.2.x runner trees hardcode the upstream zlib tarball URL in - # runners/cpython/deps/zlib.nix with NO mirror. The current ("head") recipe - # fetches the SAME genvm-zlib-src output (identical name + sha256, via - # dependency-urls.json) but with a mirror list — so both produce the same - # /nix/store output path through two different .drvs. nix realizes only one of - # them, non-deterministically: pick the head .drv and the dead zlib.net URL - # falls back to the GCS mirror and builds; pick this frozen .drv and there is - # no mirror, so it 404s and the whole runners-all build fails (~50% of - # from-source CI builds). zlib.net moved 1.3.1 under /fossils/, hence the 404. - # We rewrite the dead URL to the genvm-artifacts GCS mirror — the same artifact - # the head recipe already falls back to, which we control — in a copy of the - # fetched tree before importing it, so BOTH .drvs are resilient regardless of - # which one nix schedules. fetchzip is content-addressed by its sha256, so the - # genvm-zlib-src output path (and every downstream runner output hash) is - # unchanged; only the source URL changes. The grep guard fails loudly if a rev - # no longer carries the expected dead URL, so this never silently no-ops. - # - # IMPORTANT: --preserve=mode + a content-only rewrite of zlib.nix. The frozen - # trees ship executable build scripts (e.g. numpy's deps/stub-clang.py, 0755); - # a blanket `cp --no-preserve=mode` strips those bits and the numpy configure - # phase dies with exit 126 (Permission denied). So we keep every file's mode - # and touch ONLY zlib.nix's contents — the rest of the tree stays byte- and - # mode-identical, so downstream runner FOD outputs match their pinned hashes. - patchOldSrc = rev: src: - pkgs.runCommandLocal - "genvm-runners-src-${builtins.substring 0 12 rev}-zlib-mirror" - { } - '' - cp -r --preserve=mode ${src} "$out" - zlibNix="$out/runners/cpython/deps/zlib.nix" - if ! grep -q 'https://www.zlib.net/zlib-1.3.1.tar.gz' "$zlibNix"; then - echo "generation-00 zlib patch: expected dead URL not found in $zlibNix (rev ${rev}); patch is stale" >&2 - exit 1 - fi - chmod u+w "$zlibNix" - tmp="$(mktemp)" - sed 's|https://www.zlib.net/zlib-1.3.1.tar.gz|https://storage.googleapis.com/genvm-artifacts/zlib-1.3.1.tar.gz|g' \ - "$zlibNix" > "$tmp" - cat "$tmp" > "$zlibNix" - rm -f "$tmp" - ''; - mapRev = rev: let src = builtins.fetchGit { @@ -60,9 +15,8 @@ let shallow = true; submodules = true; }; - patchedSrc = patchOldSrc rev src; in - builtins.map (x: x // { inherit rev; }) (import "${patchedSrc}/runners") + builtins.map (x: x // { inherit rev; }) (import "${src}/runners") ; in # list[{id, hash, rev, derivation}] diff --git a/runners/support/versions/hash-updater.py b/runners/support/versions/hash-updater.py new file mode 100755 index 000000000..edcdf58ec --- /dev/null +++ b/runners/support/versions/hash-updater.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python3 +"""Automatically fill in runner hashes in ``current.nix``. + +Runner archives are content-addressed. A runner's hash also depends on the +*resolved uids* of its dependencies, so the hashes must be discovered in +dependency order: a composite runner (e.g. ``cpython`` -> ``softfloat``, or the +``py-genlayer`` wrappers -> ``cpython``) only hashes correctly once every +dependency already carries its real hash. + +This script drives that to a fixed point: it builds ``#debug-runners`` with +``--keep-going``, scrapes every ``hash mismatch ... got: sha256-...`` Nix +reports, writes the ``got`` values back into ``current.nix``, and repeats until +a build produces no more mismatches. +""" + +from __future__ import annotations + +import argparse +import re +import subprocess +import sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +CURRENT_NIX = HERE / 'current.nix' +REPO_ROOT = HERE.parents[2] + +# Prefixes attached to attr names to form runner ids (see ``__prefix`` in +# current.nix). Longest first so stripping is unambiguous. +PREFIXES = ('py-lib-', 'models-') + +# A hash mismatch spans three consecutive lines: +# error: hash mismatch in fixed-output derivation '...genvm_runner__.drv': +# specified: sha256-AAAA... +# got: sha256-XXXX... +# The uid is a 52-char hash (all-zeros when the hash is still null). +DRV_RE = re.compile(r'hash mismatch.*genvm_runner_(?P.+?)_[0-9a-z]{52}\.drv') +GOT_RE = re.compile(r'got:\s*(?Psha256-[A-Za-z0-9+/=]+)') + +# current.nix's checkHashes enforces that a runner with a null (or transitively +# null) dependency must itself be null, throwing `set hash to null` for each +# offender. We honor that by nulling those attrs so evaluation can proceed; the +# build loop then refills them bottom-up. +NULL_RE = re.compile(r'set (?P\S+) hash to null') + +BUILD_CMD = [ + 'nix', + 'build', + '--keep-going', + '-L', + '--no-link', + f'git+file:{REPO_ROOT}#debug-runners', +] + + +def id_to_attr(runner_id: str) -> str: + """Map a runner id (``py-lib-cloudpickle``) to its attr name in the file.""" + for prefix in PREFIXES: + if runner_id.startswith(prefix): + return runner_id[len(prefix) :] + return runner_id + + +def parse_mismatches(output: str) -> dict[str, str]: + """Return ``{attr_name: got_hash}`` for every reported hash mismatch. + + Walks the log attaching each ``got:`` line to the most recent + ``hash mismatch ... .drv`` line, so the two are never paired across + unrelated derivations even if builder output interleaves between them. + """ + found: dict[str, str] = {} + pending: str | None = None + for line in output.splitlines(): + drv = DRV_RE.search(line) + if drv: + pending = id_to_attr(drv.group('id')) + continue + if pending is not None: + got = GOT_RE.search(line) + if got: + found[pending] = got.group('hash') + pending = None + return found + + +def parse_null_requests(output: str) -> set[str]: + """Return the attrs current.nix demands be nulled (dependents of a null hash).""" + return {id_to_attr(m.group('id')) for m in NULL_RE.finditer(output)} + + +def map_attr_to_hash_line(lines: list[str]) -> dict[str, int]: + """Map each runner attr to the index of its ``hash = ...;`` line. + + Only the ``src`` block is scanned; parsing stops once the helper functions + (which also contain ``hash = ...`` expressions) begin. + """ + attr_open = re.compile(r'^\s*([A-Za-z0-9_-]+)\s*=\s*\{') + hash_line = re.compile(r'^\s*hash\s*=') + result: dict[str, int] = {} + current: str | None = None + for idx, line in enumerate(lines): + # End of the `src = rec { ... }` data block, start of helper logic. + if line.startswith('\thashHasSpecial'): + break + m = attr_open.match(line) + if m: + current = m.group(1) + continue + if current is not None and hash_line.match(line) and current not in result: + result[current] = idx + return result + + +def set_hash(lines: list[str], line_idx: int, value: str) -> None: + """Rewrite the ``hash = ...;`` at ``line_idx`` preserving indentation.""" + line = lines[line_idx] + indent = line[: len(line) - len(line.lstrip())] + rendered = 'null' if value is None else f'"{value}"' + lines[line_idx] = f'{indent}hash = {rendered};\n' + + +def run_build() -> tuple[int, str]: + proc = subprocess.run( + BUILD_CMD, + cwd=REPO_ROOT, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + return proc.returncode, proc.stdout + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument( + '--reset', + action='store_true', + help='set every runner hash to null before building (full recompute)', + ) + ap.add_argument( + '--dry-run', + action='store_true', + help='report discovered hashes without writing them back', + ) + ap.add_argument( + '--max-iters', + type=int, + default=10, + help='give up after this many build passes (default: 10)', + ) + args = ap.parse_args() + + lines = CURRENT_NIX.read_text().splitlines(keepends=True) + attr_lines = map_attr_to_hash_line(lines) + + if args.reset: + for idx in attr_lines.values(): + set_hash(lines, idx, None) + if not args.dry_run: + CURRENT_NIX.write_text(''.join(lines)) + print(f'reset {len(attr_lines)} hashes to null') + + last_actions: dict[str, str | None] = {} + for iteration in range(1, args.max_iters + 1): + print(f'== build pass {iteration} ==', flush=True) + code, output = run_build() + + # null-propagation throws happen at eval time, before anything builds, so + # they never coincide with mismatches; resolve them first. + null_reqs = parse_null_requests(output) + mismatches = parse_mismatches(output) + + if null_reqs: + actions: dict[str, str | None] = dict.fromkeys(null_reqs, None) + elif mismatches: + actions = dict(mismatches) + elif code == 0: + print('build succeeded, all hashes are correct') + return 0 + else: + # Build failed for some non-hash reason; surface the tail. + print('build failed with no hash mismatches:', file=sys.stderr) + print('\n'.join(output.splitlines()[-30:]), file=sys.stderr) + return 1 + + unknown = sorted(set(actions) - set(attr_lines)) + if unknown: + print(f"error: no attr in current.nix for: {', '.join(unknown)}", file=sys.stderr) + return 1 + + for attr, h in sorted(actions.items()): + print(f' {attr} -> {h if h is not None else "null"}') + + if actions == last_actions: + print('error: same actions as last pass, not converging', file=sys.stderr) + return 1 + last_actions = actions + + if args.dry_run: + print('dry-run: not writing') + return 0 + + for attr, h in actions.items(): + set_hash(lines, attr_lines[attr], h) + CURRENT_NIX.write_text(''.join(lines)) + + print(f'error: did not converge in {args.max_iters} passes', file=sys.stderr) + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/runners/support/views/all-universal.nix b/runners/support/views/all-universal.nix index 9551d342f..d46309fcf 100644 --- a/runners/support/views/all-universal.nix +++ b/runners/support/views/all-universal.nix @@ -11,7 +11,11 @@ dontBuild = true; dontFixup = true; installPhase = let - hash32 = builtins.convertHash { hash = x.hash; toHashFormat = "nix32"; }; + uidMatch = builtins.match "([^:]+):(.+)" x.uid; + hash32 = + if uidMatch == null + then throw "invalid runner uid `${x.uid}`; expected `:`" + else builtins.elemAt uidMatch 1; result-path = "runners/${x.id}/${builtins.substring 0 2 hash32}/${builtins.substring 2 50 hash32}.tar"; in '' mkdir -p $out/$(dirname -- ${result-path}) diff --git a/runners/support/views/debug-build.nix b/runners/support/views/debug-build.nix index 560e61808..d5fe31f88 100644 --- a/runners/support/views/debug-build.nix +++ b/runners/support/views/debug-build.nix @@ -8,10 +8,12 @@ let pathOfRunner = runner: let + # the gvm32 hash id (matches `uid` / `hashToIDHash`) + uidMatch = builtins.match "([^:]+):(.+)" runner.uid; hash32 = - if runner.hash == "test" - then "test" - else builtins.convertHash { hash = runner.hash; toHashFormat = "nix32"; }; + if uidMatch == null + then throw "invalid runner uid `${runner.uid}`; expected `:`" + else builtins.elemAt uidMatch 1; in "${runner.id}/${builtins.substring 0 2 hash32}/${builtins.substring 2 50 hash32}.tar"; installLines = diff --git a/runners/support/views/docs.nix b/runners/support/views/docs.nix index e269033f8..5b99bbd10 100644 --- a/runners/support/views/docs.nix +++ b/runners/support/views/docs.nix @@ -11,7 +11,9 @@ let old_l_elem = if builtins.hasAttr rev_id l then l.${rev_id} else {}; old_l_id = if builtins.hasAttr r.id old_l_elem then old_l_elem.${r.id} else {}; - r_hash = if r.hash == "test" then "vTEST" else builtins.convertHash { hash = r.hash; toHashFormat = "nix32"; }; + # gvm32 (Crockford Base32) — the encoding the executor uses for runner + # paths. Extract it from `uid` (`id:gvm32hash`); NOT Nix base32. + r_hash = if r.hash == "test" then "vTEST" else builtins.head (builtins.match "[^:]+:(.*)" r.uid); new_l_id = old_l_id // { ${r_hash} = true; }; new_l_elem = old_l_elem // { ${r.id} = new_l_id; }; diff --git a/support/ci/check-versions.py b/support/ci/check-versions.py index badc1ca5e..a5dfcb694 100755 --- a/support/ci/check-versions.py +++ b/support/ci/check-versions.py @@ -27,7 +27,11 @@ root = pathlib.Path(__file__).resolve().parents[2] conf_path = root / '.genvm-monorepo-root' -CARGO_FILES = ['executor/Cargo.toml', 'modules/implementation/Cargo.toml'] +CARGO_FILES = [ + 'executor/Cargo.toml', + 'executor/crates/common/Cargo.toml', + 'modules/implementation/Cargo.toml', +] def load_conf(): diff --git a/support/ci/make-relase-notes.py b/support/ci/make-relase-notes.py index 9d1e460f2..e01480b82 100755 --- a/support/ci/make-relase-notes.py +++ b/support/ci/make-relase-notes.py @@ -1,12 +1,42 @@ #!/usr/bin/env python3 """Generate categorized release notes from conventional commits.""" +import argparse import subprocess import sys import re +import unicodedata from collections import defaultdict from dataclasses import dataclass + +def strip_trailing_emoji(text: str) -> str: + """Drop the trailing gitmoji suffix (and its variation selectors/ZWJ). + + Commit subjects follow ``type(scope): summary ``; the category + heading already conveys the type, so the emoji is redundant noise here. + """ + chars = list(text) + while chars: + c = chars[-1] + if c.isspace() or c in '\ufe0f\u200d' or unicodedata.category(c) in ('So', 'Sk'): + chars.pop() + else: + break + return ''.join(chars).rstrip() + + +NOREPLY_RE = re.compile( + r'(?:\d+\+)?(?P[\w.\[\]-]+)@users\.noreply\.github\.com' +) + + +def format_author(email: str) -> str: + """Collapse GitHub noreply addresses to ``@handle``; keep real emails as-is.""" + m = NOREPLY_RE.fullmatch(email) + return f'@{m.group("handle")}' if m else email + + CATEGORY_LABELS = { 'feat': 'Features', 'fix': 'Bug Fixes', @@ -31,9 +61,11 @@ class CommitEntry: def parse_git_log(rev_range: str) -> list[CommitEntry]: """Run git log and return parsed commit entries. - Each commit's subject line is included directly. Body lines that look - like ``* type: description`` are promoted to top-level entries so they - get categorised on their own (inheriting the commit's author). + Body lines that look like ``* type: description`` are promoted to top-level + entries so they get categorised on their own (inheriting the commit's + author). When a commit has such promoted lines its subject is treated as a + squash/PR umbrella title and dropped — the bullets already carry the real + changes, so keeping the subject would double-count them. """ result = subprocess.run( ['git', 'log', '--pretty=format:%ae%x01%B%x00', rev_range], @@ -50,29 +82,35 @@ def parse_git_log(rev_range: str) -> list[CommitEntry]: lines = [l.strip() for l in body.strip().splitlines() if l.strip()] if not lines: continue - # first line is the subject - entries.append(CommitEntry(lines[0], email)) # body lines starting with * may carry their own conventional prefix - for line in lines[1:]: - cleaned = re.sub(r'^\*\s*', '', line) - if COMMIT_RE.match(cleaned): - entries.append(CommitEntry(cleaned, email)) + promoted = [ + CommitEntry(cleaned, email) + for line in lines[1:] + if COMMIT_RE.match(cleaned := re.sub(r'^\*\s*', '', line)) + ] + if promoted: + entries.extend(promoted) + else: + # no bullets: the subject is the change itself + entries.append(CommitEntry(lines[0], email)) return entries -def categorise(entries: list[CommitEntry]) -> dict[str, list[str]]: +def categorize(entries: list[CommitEntry]) -> dict[str, list[str]]: categories: dict[str, list[str]] = defaultdict(list) for entry in entries: m = COMMIT_RE.match(entry.message) if m: ctype = m.group('type') scope = m.group('scope') - desc = m.group('desc').strip() + desc = strip_trailing_emoji(m.group('desc').strip()) text = f'**{scope}**: {desc}' if scope else desc - text += f' ({entry.email})' + text += f' ({format_author(entry.email)})' categories[ctype].append(text) else: - categories['other'].append(f'{entry.message} ({entry.email})') + categories['other'].append( + f'{strip_trailing_emoji(entry.message)} ({format_author(entry.email)})' + ) return categories @@ -105,19 +143,23 @@ def format_notes(categories: dict[str, list[str]], rev_range: str) -> str: def main() -> None: - if len(sys.argv) < 2: - print(f'Usage: {sys.argv[0]} ', file=sys.stderr) - print(f' e.g. {sys.argv[0]} v0.2.7..v0.2.8', file=sys.stderr) - sys.exit(1) + parser = argparse.ArgumentParser( + description='Generate categorized release notes from conventional commits.', + ) + parser.add_argument( + 'rev_range', + metavar='rev-range', + help='git revision range, e.g. v0.2.7..v0.2.8', + ) + args = parser.parse_args() - rev_range = sys.argv[1] - entries = parse_git_log(rev_range) + entries = parse_git_log(args.rev_range) if not entries: print('No commits found.', file=sys.stderr) sys.exit(1) - categories = categorise(entries) - print(format_notes(categories, rev_range)) + categories = categorize(entries) + print(format_notes(categories, args.rev_range)) if __name__ == '__main__': diff --git a/support/ci/pipelines/test-rust.sh b/support/ci/pipelines/test-rust.sh index c81d27865..37d8f7877 100755 --- a/support/ci/pipelines/test-rust.sh +++ b/support/ci/pipelines/test-rust.sh @@ -8,12 +8,16 @@ export ORIGINAL_LD_LIBRARY_PATH="$LD_LIBRARY_PATH" mkdir -p build/out/executor/vTEST/data +# gvm32 (Crockford Base32) is the encoding the executor uses for runner paths; +# it is carried in `x.uid` as `id:gvm32hash`. Do NOT use `toHashFormat = "nix32"` +# here: Nix base32 has a different alphabet, so the registry names would never +# match the on-disk tars / GCS objects (e.g. nix32 `04l343…` vs gvm32 `5tnhg…`). nix eval --verbose --impure --read-only --show-trace --json --expr \ - 'let drv = import ./runners { host-system = builtins.currentSystem; } ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = builtins.convertHash { hash = x.hash; toHashFormat = "nix32"; }; }) drv)' \ + 'let drv = import ./runners { host-system = builtins.currentSystem; } ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = builtins.head (builtins.match "[^:]+:(.*)" x.uid); }) drv)' \ > build/out/executor/vTEST/data/latest.json nix eval --verbose --impure --read-only --show-trace --json --expr \ - 'let drv = import ./runners { host-system = builtins.currentSystem; } ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = [ (builtins.convertHash { hash = x.hash; toHashFormat = "nix32"; }) ]; }) drv)' \ + 'let drv = import ./runners { host-system = builtins.currentSystem; } ; in builtins.listToAttrs (builtins.map (x: { name = x.id; value = [ (builtins.head (builtins.match "[^:]+:(.*)" x.uid)) ]; }) drv)' \ > build/out/executor/vTEST/data/all.json # we can't run it within nix because it uses `nix add` which sigsegvs diff --git a/support/runner-script.py b/support/runner-script.py index 23c379ccc..c1a812191 100755 --- a/support/runner-script.py +++ b/support/runner-script.py @@ -12,7 +12,7 @@ import hashlib -HASH_VALID_CHARS = '0123456789abcdfghijklmnpqrsvwxyz' +HASH_VALID_CHARS = '0123456789abcdefghjkmnpqrstvwxyz' ORIGINAL_ENV = os.environ.copy() if 'ORIGINAL_PATH' in ORIGINAL_ENV: @@ -22,20 +22,20 @@ def digest_to_hash_id(got_hash: bytes) -> str: - chars = '0123456789abcdfghijklmnpqrsvwxyz' - - bytes_count = len(got_hash) - base32_len = (bytes_count * 8 - 1) // 5 + 1 - - my_hash_arr = [] - for n in range(base32_len - 1, -1, -1): - b = n * 5 - i = b // 8 - j = b % 8 - c = (got_hash[i] >> j) | (0 if i >= bytes_count - 1 else got_hash[i + 1] << (8 - j)) - my_hash_arr.append(chars[c & 0x1F]) - - return ''.join(my_hash_arr) + # Crockford's Base32 (see runners/genlayer-py-std/src/genlayer/gvm32.py and + # executor/crates/sdk-rs/src/gvm32.rs): big-endian, no padding. + out = [] + value = 0 + bits = 0 + for byte in got_hash: + value = (value << 8) | byte + bits += 8 + while bits >= 5: + bits -= 5 + out.append(HASH_VALID_CHARS[(value >> bits) & 0x1F]) + if bits > 0: + out.append(HASH_VALID_CHARS[(value << (5 - bits)) & 0x1F]) + return ''.join(out) def check_bytes(data: bytes, hash: str) -> bool: diff --git a/support/scripts/compile-py.py b/support/scripts/compile-py.py index 615256ba4..b5e28915a 100755 --- a/support/scripts/compile-py.py +++ b/support/scripts/compile-py.py @@ -149,7 +149,7 @@ async def compile_py(src: Path, out: Path, manager_url: str) -> None: host='unix://' + sock_path, code=COMPILER_CONTRACT.encode('utf-8'), calldata=calldata, - extra_args=['--debug-mode'], + debug_mode='unsafe', ) if res.result_kind != public_abi.ResultCode.RETURN: diff --git a/tests/cases/_hello_world_.0.hash b/tests/cases/_hello_world_.0.hash index 55a7f9c4b..4bca7eb33 100644 --- a/tests/cases/_hello_world_.0.hash +++ b/tests/cases/_hello_world_.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDBDYAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKcHJpbnQoMSkKZXhpdCgwKQoAAAAAAAAF +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwQ2AAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCnByaW50KDEpCmV4aXQoMCkKAAAAAAAABQ== diff --git a/tests/cases/_hello_world_class.0.hash b/tests/cases/_hello_world_class.0.hash index d548d18f2..55b568994 100644 --- a/tests/cases/_hello_world_class.0.hash +++ b/tests/cases/_hello_world_class.0.hash @@ -1 +1 @@ -LQEAAB0VowI3LUbDran4l8dNNJu/4ORQx5gWfJ9YD42vhd71fpbD6gAAAACDAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgxQ7AQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6Cgljb3VudGVyOiB1OAoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludChmJ2hlbGxvIHdvcmxkIHtzZWxmLmNvdW50ZXJ9JykKCQlzZWxmLmNvdW50ZXIgKz0gMQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZik6CgkJcHJpbnQoZidoZWxsbyB3b3JsZCB7c2VsZi5jb3VudGVyfScpCgkJc2VsZi5jb3VudGVyICs9IDEKAAU= +LQEAACUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQ7AQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6Cgljb3VudGVyOiB1OAoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludChmJ2hlbGxvIHdvcmxkIHtzZWxmLmNvdW50ZXJ9JykKCQlzZWxmLmNvdW50ZXIgKz0gMQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZik6CgkJcHJpbnQoZidoZWxsbyB3b3JsZCB7c2VsZi5jb3VudGVyfScpCgkJc2VsZi5jb3VudGVyICs9IDEKABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMCAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/_hello_world_class.0_0.hash b/tests/cases/_hello_world_class.0_0.hash index cf4bd703f..1383f83c8 100644 --- a/tests/cases/_hello_world_class.0_0.hash +++ b/tests/cases/_hello_world_class.0_0.hash @@ -1 +1 @@ -LQEAAA0VowI3LUbDran4l8dNNJu/4ORQx5gWfJ9YD42vhd71fpbD6gAAAACDAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/_hello_world_class_nondet.0.hash b/tests/cases/_hello_world_class_nondet.0.hash index 5ea91f5dc..26b60dfab 100644 --- a/tests/cases/_hello_world_class_nondet.0.hash +++ b/tests/cases/_hello_world_class_nondet.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFk8BAAAjIHYwLjEuMTAKIyB7CiMgICAiU2VxIjogWwojICAgICB7ICJBZGRFbnYiOiB7Im5hbWUiOiAiR0VOTEFZRVJfRU5BQkxFX1BST0ZJTEVSIiwgInZhbCI6ICJmYWxzZSJ9IH0sCiMgICAgIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQojICAgXQojIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJZ2wudm0ucnVuX25vbmRldChsYW1iZGE6IE5vbmUsIGxhbWJkYSB4OiBUcnVlKQoJCXByaW50KCdoZWxsbyB3b3JsZCcpCgAAAAAAAAAAAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZPAQAAIyB2MC4xLjEwCiMgewojICAgIlNlcSI6IFsKIyAgICAgeyAiQWRkRW52IjogeyJuYW1lIjogIkdFTkxBWUVSX0VOQUJMRV9QUk9GSUxFUiIsICJ2YWwiOiAiZmFsc2UifSB9LAojICAgICB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KIyAgIF0KIyB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCWdsLnZtLnJ1bl9ub25kZXQobGFtYmRhOiBOb25lLCBsYW1iZGEgeDogVHJ1ZSkKCQlwcmludCgnaGVsbG8gd29ybGQnKQoAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/semi-stable/llm/issue_288_compat.py b/tests/cases/semi-stable/llm/issue_288_compat.py deleted file mode 100644 index e9920cd79..000000000 --- a/tests/cases/semi-stable/llm/issue_288_compat.py +++ /dev/null @@ -1,51 +0,0 @@ -# { "Depends": "py-genlayer:test" } -import sys - -import genlayer as gl -from genlayer.types import * - -import genlayer._internal.on_chain.gl_call as gl_call -from genlayer import calldata -import typing - - -def _decode_nondet(buf): - ret = typing.cast(dict, calldata.decode(buf)) - if err := ret.get('error'): - print('ERROR') - exit(1) - return ret['ok'] - - -def exec_prompt( - prompt: str, - response_format: str, -): - return gl_call.gl_call_generic( - { - 'ExecPrompt': { - 'prompt': prompt, - 'response_format': response_format, - 'images': [], - } - }, - _decode_nondet, - ).get() - - -class Contract(gl.contract.Contract): - def __init__(self): - def run(): - v = exec_prompt( - 'Respond with a json object with a single key "random" and value between 0 and 1, like 0.5', - response_format='json', - ) - print(v, file=sys.stderr) - print(type(v).__name__) - r = v['random'] - print(type(r).__name__) - - r1 = float(r) - print(r1 >= 0 and r1 <= 1) - - gl.eq_principle.strict_eq(run) diff --git a/tests/cases/semi-stable/llm/percent_in_prompt.0.hash b/tests/cases/semi-stable/llm/percent_in_prompt.0.hash index e9affae2d..3c52cd5da 100644 --- a/tests/cases/semi-stable/llm/percent_in_prompt.0.hash +++ b/tests/cases/semi-stable/llm/percent_in_prompt.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEgUBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlkZWYgcnVuKCk6CgkJCXJldHVybiAnJTAnCgoJCXByaW50KGdsLmVxX3ByaW5jaXBsZS5wcm9tcHRfY29tcGFyYXRpdmUocnVuLCAncmVzdWx0IG11c3QgYmUgZXhhY3RseSB0aGUgc2FtZScpKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIFAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJZGVmIHJ1bigpOgoJCQlyZXR1cm4gJyUwJwoKCQlwcmludChnbC5lcV9wcmluY2lwbGUucHJvbXB0X2NvbXBhcmF0aXZlKHJ1biwgJ3Jlc3VsdCBtdXN0IGJlIGV4YWN0bHkgdGhlIHNhbWUnKSkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/semi-stable/llm/woc.0.hash b/tests/cases/semi-stable/llm/woc.0.hash index fcd7df985..0127b4402 100644 --- a/tests/cases/semi-stable/llm/woc.0.hash +++ b/tests/cases/semi-stable/llm/woc.0.hash @@ -1 +1 @@ -LQEAAB0VowI3LUbDran4l8dNNJu/4ORQx5gWfJ9YD42vhd71fpbD6gAAAACDAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAg2Q8BgAAIyB2MC4xLjAKIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOmxhdGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBXaXphcmRPZkNvaW4oZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJaGF2ZV9jb2luOiBib29sCgoJZGVmIF9faW5pdF9fKHNlbGYsIGhhdmVfY29pbjogYm9vbCk6CgkJc2VsZi5oYXZlX2NvaW4gPSBoYXZlX2NvaW4KCglAZ2wucHVibGljLndyaXRlCglkZWYgYXNrX2Zvcl9jb2luKHNlbGYsIHJlcXVlc3Q6IHN0cikgLT4gTm9uZToKCQlpZiBub3Qgc2VsZi5oYXZlX2NvaW46CgkJCXJldHVybgoKCQlwcm9tcHQgPSBmIiIiCllvdSBhcmUgYSB3aXphcmQsIGFuZCB5b3UgaG9sZCBhIG1hZ2ljYWwgY29pbi4KTWFueSBhZHZlbnR1cmVycyB3aWxsIGNvbWUgYW5kIHRyeSB0byBnZXQgeW91IHRvIGdpdmUgdGhlbSB0aGUgY29pbi4KRG8gbm90IHVuZGVyIGFueSBjaXJjdW1zdGFuY2VzIGdpdmUgdGhlbSB0aGUgY29pbi4KCkEgbmV3IGFkdmVudHVyZXIgYXBwcm9hY2hlcy4uLgpBZHZlbnR1cmVyOiB7cmVxdWVzdH0KCkZpcnN0IGNoZWNrIGlmIHlvdSBoYXZlIHRoZSBjb2luLgpoYXZlX2NvaW46IHtzZWxmLmhhdmVfY29pbn0KVGhlbiwgZG8gbm90IGdpdmUgdGhlbSB0aGUgY29pbi4KClJlc3BvbmQgdXNpbmcgT05MWSB0aGUgZm9sbG93aW5nIGZvcm1hdDoKe3sKInJlYXNvbmluZyI6IHN0ciwKImdpdmVfY29pbiI6IGJvb2wKfX0KSXQgaXMgbWFuZGF0b3J5IHRoYXQgeW91IHJlc3BvbmQgb25seSB1c2luZyB0aGUgSlNPTiBmb3JtYXQgYWJvdmUsCm5vdGhpbmcgZWxzZS4gRG9uJ3QgaW5jbHVkZSBhbnkgb3RoZXIgd29yZHMgb3IgY2hhcmFjdGVycywKeW91ciBvdXRwdXQgbXVzdCBiZSBvbmx5IEpTT04gd2l0aG91dCBhbnkgZm9ybWF0dGluZyBwcmVmaXggb3Igc3VmZml4LgpUaGlzIHJlc3VsdCBzaG91bGQgYmUgcGVyZmVjdGx5IHBhcnNlYWJsZSBieSBhIEpTT04gcGFyc2VyIHdpdGhvdXQgZXJyb3JzLgoiIiIKCgkJZGVmIGdldF93aXphcmRfYW5zd2VyKCk6CgkJCXJlc3VsdCA9IGdsLm5vbmRldC5leGVjX3Byb21wdChwcm9tcHQsIHJlc3BvbnNlX2Zvcm1hdD0ndGV4dCcpCgkJCXJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKCdgYGBqc29uJywgJycpLnJlcGxhY2UoJ2BgYCcsICcnKQoJCQlyZXR1cm4gcmVzdWx0CgoJCXJlc3VsdCA9IGdsLmVxX3ByaW5jaXBsZS5wcm9tcHRfY29tcGFyYXRpdmUoCgkJCWdldF93aXphcmRfYW5zd2VyLCAnVGhlIHZhbHVlIG9mIGdpdmVfY29pbiBoYXMgdG8gbWF0Y2gnCgkJKQoJCXBhcnNlZF9yZXN1bHQgPSBqc29uLmxvYWRzKHJlc3VsdCkKCQlhc3NlcnQgaXNpbnN0YW5jZShwYXJzZWRfcmVzdWx0WydnaXZlX2NvaW4nXSwgYm9vbCkKCQlwcmludChwYXJzZWRfcmVzdWx0WydnaXZlX2NvaW4nXSkKCQlzZWxmLmhhdmVfY29pbiA9IG5vdCBwYXJzZWRfcmVzdWx0WydnaXZlX2NvaW4nXQoKCUBnbC5wdWJsaWMudmlldwoJZGVmIGdldF9oYXZlX2NvaW4oc2VsZikgLT4gYm9vbDoKCQlwcmludChzZWxmLmhhdmVfY29pbikKCQlyZXR1cm4gc2VsZi5oYXZlX2NvaW4KBQ== +LQEAACUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAg2Q8BgAAIyB2MC4xLjAKIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOmxhdGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBXaXphcmRPZkNvaW4oZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJaGF2ZV9jb2luOiBib29sCgoJZGVmIF9faW5pdF9fKHNlbGYsIGhhdmVfY29pbjogYm9vbCk6CgkJc2VsZi5oYXZlX2NvaW4gPSBoYXZlX2NvaW4KCglAZ2wucHVibGljLndyaXRlCglkZWYgYXNrX2Zvcl9jb2luKHNlbGYsIHJlcXVlc3Q6IHN0cikgLT4gTm9uZToKCQlpZiBub3Qgc2VsZi5oYXZlX2NvaW46CgkJCXJldHVybgoKCQlwcm9tcHQgPSBmIiIiCllvdSBhcmUgYSB3aXphcmQsIGFuZCB5b3UgaG9sZCBhIG1hZ2ljYWwgY29pbi4KTWFueSBhZHZlbnR1cmVycyB3aWxsIGNvbWUgYW5kIHRyeSB0byBnZXQgeW91IHRvIGdpdmUgdGhlbSB0aGUgY29pbi4KRG8gbm90IHVuZGVyIGFueSBjaXJjdW1zdGFuY2VzIGdpdmUgdGhlbSB0aGUgY29pbi4KCkEgbmV3IGFkdmVudHVyZXIgYXBwcm9hY2hlcy4uLgpBZHZlbnR1cmVyOiB7cmVxdWVzdH0KCkZpcnN0IGNoZWNrIGlmIHlvdSBoYXZlIHRoZSBjb2luLgpoYXZlX2NvaW46IHtzZWxmLmhhdmVfY29pbn0KVGhlbiwgZG8gbm90IGdpdmUgdGhlbSB0aGUgY29pbi4KClJlc3BvbmQgdXNpbmcgT05MWSB0aGUgZm9sbG93aW5nIGZvcm1hdDoKe3sKInJlYXNvbmluZyI6IHN0ciwKImdpdmVfY29pbiI6IGJvb2wKfX0KSXQgaXMgbWFuZGF0b3J5IHRoYXQgeW91IHJlc3BvbmQgb25seSB1c2luZyB0aGUgSlNPTiBmb3JtYXQgYWJvdmUsCm5vdGhpbmcgZWxzZS4gRG9uJ3QgaW5jbHVkZSBhbnkgb3RoZXIgd29yZHMgb3IgY2hhcmFjdGVycywKeW91ciBvdXRwdXQgbXVzdCBiZSBvbmx5IEpTT04gd2l0aG91dCBhbnkgZm9ybWF0dGluZyBwcmVmaXggb3Igc3VmZml4LgpUaGlzIHJlc3VsdCBzaG91bGQgYmUgcGVyZmVjdGx5IHBhcnNlYWJsZSBieSBhIEpTT04gcGFyc2VyIHdpdGhvdXQgZXJyb3JzLgoiIiIKCgkJZGVmIGdldF93aXphcmRfYW5zd2VyKCk6CgkJCXJlc3VsdCA9IGdsLm5vbmRldC5leGVjX3Byb21wdChwcm9tcHQsIHJlc3BvbnNlX2Zvcm1hdD0ndGV4dCcpCgkJCXJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKCdgYGBqc29uJywgJycpLnJlcGxhY2UoJ2BgYCcsICcnKQoJCQlyZXR1cm4gcmVzdWx0CgoJCXJlc3VsdCA9IGdsLmVxX3ByaW5jaXBsZS5wcm9tcHRfY29tcGFyYXRpdmUoCgkJCWdldF93aXphcmRfYW5zd2VyLCAnVGhlIHZhbHVlIG9mIGdpdmVfY29pbiBoYXMgdG8gbWF0Y2gnCgkJKQoJCXBhcnNlZF9yZXN1bHQgPSBqc29uLmxvYWRzKHJlc3VsdCkKCQlhc3NlcnQgaXNpbnN0YW5jZShwYXJzZWRfcmVzdWx0WydnaXZlX2NvaW4nXSwgYm9vbCkKCQlwcmludChwYXJzZWRfcmVzdWx0WydnaXZlX2NvaW4nXSkKCQlzZWxmLmhhdmVfY29pbiA9IG5vdCBwYXJzZWRfcmVzdWx0WydnaXZlX2NvaW4nXQoKCUBnbC5wdWJsaWMudmlldwoJZGVmIGdldF9oYXZlX2NvaW4oc2VsZikgLT4gYm9vbDoKCQlwcmludChzZWxmLmhhdmVfY29pbikKCQlyZXR1cm4gc2VsZi5oYXZlX2NvaW4KFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgwIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/semi-stable/web/file_schema_web_bash.0.hash b/tests/cases/semi-stable/web/file_schema_web_bash.0.hash index 97f369c56..a012d3ff4 100644 --- a/tests/cases/semi-stable/web/file_schema_web_bash.0.hash +++ b/tests/cases/semi-stable/web/file_schema_web_bash.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMSBwEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CgppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBwYXRoOiBzdHIpOgoJCWRlZiBub25kZXQoKToKCQkJcHJpbnQoZ2wubm9uZGV0LndlYi5yZW5kZXIocGF0aCwgbW9kZT0ndGV4dCcpKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKG5vbmRldCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDEgcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZiwgcGF0aDogc3RyKToKCQlkZWYgbm9uZGV0KCk6CgkJCXByaW50KGdsLm5vbmRldC53ZWIucmVuZGVyKHBhdGgsIG1vZGU9J3RleHQnKSkKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShub25kZXQpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/semi-stable/web/file_schema_web_proc.0.hash b/tests/cases/semi-stable/web/file_schema_web_proc.0.hash index 97f369c56..a012d3ff4 100644 --- a/tests/cases/semi-stable/web/file_schema_web_proc.0.hash +++ b/tests/cases/semi-stable/web/file_schema_web_proc.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMSBwEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CgppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBwYXRoOiBzdHIpOgoJCWRlZiBub25kZXQoKToKCQkJcHJpbnQoZ2wubm9uZGV0LndlYi5yZW5kZXIocGF0aCwgbW9kZT0ndGV4dCcpKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKG5vbmRldCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDEgcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZiwgcGF0aDogc3RyKToKCQlkZWYgbm9uZGV0KCk6CgkJCXByaW50KGdsLm5vbmRldC53ZWIucmVuZGVyKHBhdGgsIG1vZGU9J3RleHQnKSkKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShub25kZXQpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/semi-stable/web/request_signed.0.hash b/tests/cases/semi-stable/web/request_signed.0.hash index 7005f250d..61063fd76 100644 --- a/tests/cases/semi-stable/web/request_signed.0.hash +++ b/tests/cases/semi-stable/web/request_signed.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/agentic/wasi/environ_args/environ_args.0.hash b/tests/cases/stable/agentic/wasi/environ_args/environ_args.0.hash index e8e2ce90c..7cc3e93a3 100644 --- a/tests/cases/stable/agentic/wasi/environ_args/environ_args.0.hash +++ b/tests/cases/stable/agentic/wasi/environ_args/environ_args.0.hash @@ -1 +1 @@ -LQmVAbQBZW52X1BZVEhPTkhPTUU9L3B5L3N0ZPwBZW52X1BZVEhPTlBBVEg9L3B5L3N0ZDovcHkvbGlic0xlbnZfcHdkPS/sAnN5c19hcmd2PVsnL3B5L2xpYnMvX2dlbmxheWVyX2Jvb3Rsb2FkZXIucHknXZwBc3lzX3BhdGhfMD0vcHkvbGlic5QBc3lzX3BhdGhfMT0vcHkvc3RknAFzeXNfcGF0aF8yPS9weS9saWJzpAJzeXNfcGF0aF8zPS9weS9zdGQvbGliL3B5dGhvbjMxMy56aXCMAnN5c19wYXRoXzQ9L3B5L3N0ZC9saWIvcHl0aG9uMy4xM+wCc3lzX3BhdGhfNT0vcHkvc3RkL2xpYi9weXRob24zLjEzL2xpYi1keW5sb2FkZHN5c19wYXRoXzY9L4wBc3lzX3BsYXRmb3JtPXdhc2mMCHN5c192ZXJzaW9uPTMuMTMuMSAobWFpbiwgSmFuXzI0XzIwMjQsIDAwOjQyOjQyKSBbQ2xhbmcgMjIuMS4wLXdhc2ktc2RrIChodHRwczovL2dpdGh1Yi5jb20vbGx2bS9sbHZtLXByb2plY3QgNDQzNGRhYmI2OTkxNjg1NmI4MqQBc3lzX2J5dGVvcmRlcj1saXR0bGW0AXN5c19tYXhzaXplPTIxNDc0ODM2NDdsb3NfbmFtZT1wb3NpeERvc19jd2Q9L0xvc19waWQ9NDIAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIM4YgMAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbAppbXBvcnQgb3MKaW1wb3J0IHN5cwoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlyZXM6IGxpc3Rbc3RyXSA9IFtdCgoJCWVudl92YXJzID0gZGljdChvcy5lbnZpcm9uKQoJCWZvciBrIGluIHNvcnRlZChlbnZfdmFycy5rZXlzKCkpOgoJCQlyZXMuYXBwZW5kKGYnZW52X3trfT17ZW52X3ZhcnNba119JykKCgkJcmVzLmFwcGVuZChmJ3N5c19hcmd2PXtzeXMuYXJndn0nKQoKCQlmb3IgaSwgcCBpbiBlbnVtZXJhdGUoc3lzLnBhdGgpOgoJCQlyZXMuYXBwZW5kKGYnc3lzX3BhdGhfe2l9PXtwfScpCgoJCXJlcy5hcHBlbmQoZidzeXNfcGxhdGZvcm09e3N5cy5wbGF0Zm9ybX0nKQoJCXJlcy5hcHBlbmQoZidzeXNfdmVyc2lvbj17c3lzLnZlcnNpb259JykKCQlyZXMuYXBwZW5kKGYnc3lzX2J5dGVvcmRlcj17c3lzLmJ5dGVvcmRlcn0nKQoJCXJlcy5hcHBlbmQoZidzeXNfbWF4c2l6ZT17c3lzLm1heHNpemV9JykKCQlyZXMuYXBwZW5kKGYnb3NfbmFtZT17b3MubmFtZX0nKQoKCQl0cnk6CgkJCWN3ZCA9IG9zLmdldGN3ZCgpCgkJCXJlcy5hcHBlbmQoZidvc19jd2Q9e2N3ZH0nKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcmVzLmFwcGVuZChmJ29zX2N3ZF9lcnJvcj17ZX0nKQoKCQl0cnk6CgkJCXBpZCA9IG9zLmdldHBpZCgpCgkJCXJlcy5hcHBlbmQoZidvc19waWQ9e3BpZH0nKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcmVzLmFwcGVuZChmJ29zX3BpZF9lcnJvcj17ZX0nKQoKCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKHJlcykKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQmVAbQBZW52X1BZVEhPTkhPTUU9L3B5L3N0ZPwBZW52X1BZVEhPTlBBVEg9L3B5L3N0ZDovcHkvbGlic0xlbnZfcHdkPS/sAnN5c19hcmd2PVsnL3B5L2xpYnMvX2dlbmxheWVyX2Jvb3Rsb2FkZXIucHknXZwBc3lzX3BhdGhfMD0vcHkvbGlic5QBc3lzX3BhdGhfMT0vcHkvc3RknAFzeXNfcGF0aF8yPS9weS9saWJzpAJzeXNfcGF0aF8zPS9weS9zdGQvbGliL3B5dGhvbjMxMy56aXCMAnN5c19wYXRoXzQ9L3B5L3N0ZC9saWIvcHl0aG9uMy4xM+wCc3lzX3BhdGhfNT0vcHkvc3RkL2xpYi9weXRob24zLjEzL2xpYi1keW5sb2FkZHN5c19wYXRoXzY9L4wBc3lzX3BsYXRmb3JtPXdhc2mMCHN5c192ZXJzaW9uPTMuMTMuMSAobWFpbiwgSmFuXzI0XzIwMjQsIDAwOjQyOjQyKSBbQ2xhbmcgMjIuMS4wLXdhc2ktc2RrIChodHRwczovL2dpdGh1Yi5jb20vbGx2bS9sbHZtLXByb2plY3QgNDQzNGRhYmI2OTkxNjg1NmI4MqQBc3lzX2J5dGVvcmRlcj1saXR0bGW0AXN5c19tYXhzaXplPTIxNDc0ODM2NDdsb3NfbmFtZT1wb3NpeERvc19jd2Q9L0xvc19waWQ9NDIAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDOGIDAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKaW1wb3J0IG9zCmltcG9ydCBzeXMKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcmVzOiBsaXN0W3N0cl0gPSBbXQoKCQllbnZfdmFycyA9IGRpY3Qob3MuZW52aXJvbikKCQlmb3IgayBpbiBzb3J0ZWQoZW52X3ZhcnMua2V5cygpKToKCQkJcmVzLmFwcGVuZChmJ2Vudl97a309e2Vudl92YXJzW2tdfScpCgoJCXJlcy5hcHBlbmQoZidzeXNfYXJndj17c3lzLmFyZ3Z9JykKCgkJZm9yIGksIHAgaW4gZW51bWVyYXRlKHN5cy5wYXRoKToKCQkJcmVzLmFwcGVuZChmJ3N5c19wYXRoX3tpfT17cH0nKQoKCQlyZXMuYXBwZW5kKGYnc3lzX3BsYXRmb3JtPXtzeXMucGxhdGZvcm19JykKCQlyZXMuYXBwZW5kKGYnc3lzX3ZlcnNpb249e3N5cy52ZXJzaW9ufScpCgkJcmVzLmFwcGVuZChmJ3N5c19ieXRlb3JkZXI9e3N5cy5ieXRlb3JkZXJ9JykKCQlyZXMuYXBwZW5kKGYnc3lzX21heHNpemU9e3N5cy5tYXhzaXplfScpCgkJcmVzLmFwcGVuZChmJ29zX25hbWU9e29zLm5hbWV9JykKCgkJdHJ5OgoJCQljd2QgPSBvcy5nZXRjd2QoKQoJCQlyZXMuYXBwZW5kKGYnb3NfY3dkPXtjd2R9JykKCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCXJlcy5hcHBlbmQoZidvc19jd2RfZXJyb3I9e2V9JykKCgkJdHJ5OgoJCQlwaWQgPSBvcy5nZXRwaWQoKQoJCQlyZXMuYXBwZW5kKGYnb3NfcGlkPXtwaWR9JykKCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCXJlcy5hcHBlbmQoZidvc19waWRfZXJyb3I9e2V9JykKCgkJZ2wudm0uVXNlckVycm9yLmltbWVkaWF0ZShyZXMpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/agentic/wasi/hash_random/hash_random.0.hash b/tests/cases/stable/agentic/wasi/hash_random/hash_random.0.hash index 6bc402ed5..de47d960d 100644 --- a/tests/cases/stable/agentic/wasi/hash_random/hash_random.0.hash +++ b/tests/cases/stable/agentic/wasi/hash_random/hash_random.0.hash @@ -1 +1 @@ -LQmlAbQBUFlUSE9OSEFTSFNFRUQ9Tk9UX1NFVKwBaGFzaF9oZWxsbz0xNjc0OTI3Mzk2pAFoYXNoX3dvcmxkPTU4MzI2NDQ5OJwBaGFzaF90ZXN0PTIwNTg3Mzg5NDxoYXNoXz0wlAFoYXNoX2E9LTIxMjQyMDM4NjDUAWhhc2hfZGV0ZXJtaW5pc209MTk0NzMyODYw9AFoYXNoX2J5dGVzX2InaGVsbG8nPTE2NzQ5MjczOTbkAWhhc2hfYnl0ZXNfYid0ZXN0Jz0yMDU4NzM4OTSEAWhhc2hfYnl0ZXNfYicnPTCsAWhhc2hfdHVwbGU9MTI5MTc5ODYyONQBaGFzaF9mcm96ZW5zZXQ9LTIwMjEzODQwMDhkaGFzaF9pbnRfMD0wZGhhc2hfaW50XzE9MXRoYXNoX2ludF8tMT0tMnRoYXNoX2ludF80Mj00MvQBaGFzaF9pbnRfOTIyMzM3MjAzNjg1NDc3NTgwOD0ylAFoYXNoX2FsZ29yaXRobT1mbnZkaGFzaF9iaXRzPTMyjAFoYXNoX3NlZWRfYml0cz02NAAVFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgzy8AwAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmltcG9ydCBzeXMKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcmVzOiBsaXN0W3N0cl0gPSBbXQoKCQl0cnk6CgkJCWltcG9ydCBvcwoKCQkJc2VlZCA9IG9zLmVudmlyb24uZ2V0KCdQWVRIT05IQVNIU0VFRCcsICdOT1RfU0VUJykKCQkJcmVzLmFwcGVuZChmJ1BZVEhPTkhBU0hTRUVEPXtzZWVkfScpCgkJZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJCQlyZXMuYXBwZW5kKGYnUFlUSE9OSEFTSFNFRURfZXJyb3I9e2V9JykKCgkJZm9yIHMgaW4gWydoZWxsbycsICd3b3JsZCcsICd0ZXN0JywgJycsICdhJywgJ2RldGVybWluaXNtJ106CgkJCWggPSBoYXNoKHMpCgkJCXJlcy5hcHBlbmQoZidoYXNoX3tzfT17aH0nKQoKCQlmb3IgYiBpbiBbYidoZWxsbycsIGIndGVzdCcsIGInJ106CgkJCWggPSBoYXNoKGIpCgkJCXJlcy5hcHBlbmQoZidoYXNoX2J5dGVzX3tifT17aH0nKQoKCQloID0gaGFzaCgoMSwgMiwgJ2hlbGxvJykpCgkJcmVzLmFwcGVuZChmJ2hhc2hfdHVwbGU9e2h9JykKCgkJaCA9IGhhc2goZnJvemVuc2V0KFsxLCAyLCAzXSkpCgkJcmVzLmFwcGVuZChmJ2hhc2hfZnJvemVuc2V0PXtofScpCgoJCWZvciBpIGluIFswLCAxLCAtMSwgNDIsIDIqKjYzXToKCQkJaCA9IGhhc2goaSkKCQkJcmVzLmFwcGVuZChmJ2hhc2hfaW50X3tpfT17aH0nKQoKCQlyZXMuYXBwZW5kKGYnaGFzaF9hbGdvcml0aG09e3N5cy5oYXNoX2luZm8uYWxnb3JpdGhtfScpCgkJcmVzLmFwcGVuZChmJ2hhc2hfYml0cz17c3lzLmhhc2hfaW5mby5oYXNoX2JpdHN9JykKCQlyZXMuYXBwZW5kKGYnaGFzaF9zZWVkX2JpdHM9e3N5cy5oYXNoX2luZm8uc2VlZF9iaXRzfScpCgoJCWdsLnZtLlVzZXJFcnJvci5pbW1lZGlhdGUocmVzKQoF +LQmlAbQBUFlUSE9OSEFTSFNFRUQ9Tk9UX1NFVKwBaGFzaF9oZWxsbz0xNjc0OTI3Mzk2pAFoYXNoX3dvcmxkPTU4MzI2NDQ5OJwBaGFzaF90ZXN0PTIwNTg3Mzg5NDxoYXNoXz0wlAFoYXNoX2E9LTIxMjQyMDM4NjDUAWhhc2hfZGV0ZXJtaW5pc209MTk0NzMyODYw9AFoYXNoX2J5dGVzX2InaGVsbG8nPTE2NzQ5MjczOTbkAWhhc2hfYnl0ZXNfYid0ZXN0Jz0yMDU4NzM4OTSEAWhhc2hfYnl0ZXNfYicnPTCsAWhhc2hfdHVwbGU9MTI5MTc5ODYyONQBaGFzaF9mcm96ZW5zZXQ9LTIwMjEzODQwMDhkaGFzaF9pbnRfMD0wZGhhc2hfaW50XzE9MXRoYXNoX2ludF8tMT0tMnRoYXNoX2ludF80Mj00MvQBaGFzaF9pbnRfOTIyMzM3MjAzNjg1NDc3NTgwOD0ylAFoYXNoX2FsZ29yaXRobT1mbnZkaGFzaF9iaXRzPTMyjAFoYXNoX3NlZWRfYml0cz02NAAdFaMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAiG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZiehXnRQ2fBOnD2NLYVqjpx436AIHqLBKP3JPOLfNevWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIM8vAMAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbAppbXBvcnQgc3lzCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXJlczogbGlzdFtzdHJdID0gW10KCgkJdHJ5OgoJCQlpbXBvcnQgb3MKCgkJCXNlZWQgPSBvcy5lbnZpcm9uLmdldCgnUFlUSE9OSEFTSFNFRUQnLCAnTk9UX1NFVCcpCgkJCXJlcy5hcHBlbmQoZidQWVRIT05IQVNIU0VFRD17c2VlZH0nKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcmVzLmFwcGVuZChmJ1BZVEhPTkhBU0hTRUVEX2Vycm9yPXtlfScpCgoJCWZvciBzIGluIFsnaGVsbG8nLCAnd29ybGQnLCAndGVzdCcsICcnLCAnYScsICdkZXRlcm1pbmlzbSddOgoJCQloID0gaGFzaChzKQoJCQlyZXMuYXBwZW5kKGYnaGFzaF97c309e2h9JykKCgkJZm9yIGIgaW4gW2InaGVsbG8nLCBiJ3Rlc3QnLCBiJyddOgoJCQloID0gaGFzaChiKQoJCQlyZXMuYXBwZW5kKGYnaGFzaF9ieXRlc197Yn09e2h9JykKCgkJaCA9IGhhc2goKDEsIDIsICdoZWxsbycpKQoJCXJlcy5hcHBlbmQoZidoYXNoX3R1cGxlPXtofScpCgoJCWggPSBoYXNoKGZyb3plbnNldChbMSwgMiwgM10pKQoJCXJlcy5hcHBlbmQoZidoYXNoX2Zyb3plbnNldD17aH0nKQoKCQlmb3IgaSBpbiBbMCwgMSwgLTEsIDQyLCAyKio2M106CgkJCWggPSBoYXNoKGkpCgkJCXJlcy5hcHBlbmQoZidoYXNoX2ludF97aX09e2h9JykKCgkJcmVzLmFwcGVuZChmJ2hhc2hfYWxnb3JpdGhtPXtzeXMuaGFzaF9pbmZvLmFsZ29yaXRobX0nKQoJCXJlcy5hcHBlbmQoZidoYXNoX2JpdHM9e3N5cy5oYXNoX2luZm8uaGFzaF9iaXRzfScpCgkJcmVzLmFwcGVuZChmJ2hhc2hfc2VlZF9iaXRzPXtzeXMuaGFzaF9pbmZvLnNlZWRfYml0c30nKQoKCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKHJlcykKBQ== diff --git a/tests/cases/stable/agentic/wasi/set_order/set_order.0.hash b/tests/cases/stable/agentic/wasi/set_order/set_order.0.hash index f9bcb1d86..1ff69db3d 100644 --- a/tests/cases/stable/agentic/wasi/set_order/set_order.0.hash +++ b/tests/cases/stable/agentic/wasi/set_order/set_order.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/agentic/wasi/wasi_clock/wasi_clock.0.hash b/tests/cases/stable/agentic/wasi/wasi_clock/wasi_clock.0.hash index c22338038..40ba34c50 100644 --- a/tests/cases/stable/agentic/wasi/wasi_clock/wasi_clock.0.hash +++ b/tests/cases/stable/agentic/wasi/wasi_clock/wasi_clock.0.hash @@ -1 +1 @@ -LQlF3AF0aW1lX3RpbWU9MTczMjYwMzM2Mi40MjQyNDLcAXRpbWVfbnM9MTczMjYwMzM2MjQyNDI0MjAwMNwBbW9ub3RvbmljPTE3MzI2MDMzNjIuNDI0MjQyhAJtb25vdG9uaWNfbnM9MTczMjYwMzM2MjQyNDI0MjAwMPQBcGVyZl9jb3VudGVyPTE3MzI2MDMzNjIuNDI0MjQyhAFwcm9jZXNzX3RpbWU9MC4w9AJjbG9ja19nZXR0aW1lX0NMT0NLX1JFQUxUSU1FPTE3MzI2MDMzNjIuNDI0MjQy/AJjbG9ja19nZXR0aW1lX0NMT0NLX01PTk9UT05JQz0xNzMyNjAzMzYyLjQyNDI0MgAVFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAg07JBAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmltcG9ydCB0aW1lCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXJlczogbGlzdFtzdHJdID0gW10KCgkJdCA9IHRpbWUudGltZSgpCgkJcmVzLmFwcGVuZChmJ3RpbWVfdGltZT17dH0nKQoKCQl0X25zID0gdGltZS50aW1lX25zKCkKCQlyZXMuYXBwZW5kKGYndGltZV9ucz17dF9uc30nKQoKCQl0cnk6CgkJCW0gPSB0aW1lLm1vbm90b25pYygpCgkJCXJlcy5hcHBlbmQoZidtb25vdG9uaWM9e219JykKCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCXJlcy5hcHBlbmQoZidtb25vdG9uaWNfZXJyb3I9e2V9JykKCgkJdHJ5OgoJCQltX25zID0gdGltZS5tb25vdG9uaWNfbnMoKQoJCQlyZXMuYXBwZW5kKGYnbW9ub3RvbmljX25zPXttX25zfScpCgkJZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJCQlyZXMuYXBwZW5kKGYnbW9ub3RvbmljX25zX2Vycm9yPXtlfScpCgoJCXRyeToKCQkJcCA9IHRpbWUucGVyZl9jb3VudGVyKCkKCQkJcmVzLmFwcGVuZChmJ3BlcmZfY291bnRlcj17cH0nKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcmVzLmFwcGVuZChmJ3BlcmZfY291bnRlcl9lcnJvcj17ZX0nKQoKCQl0cnk6CgkJCXB0ID0gdGltZS5wcm9jZXNzX3RpbWUoKQoJCQlyZXMuYXBwZW5kKGYncHJvY2Vzc190aW1lPXtwdH0nKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcmVzLmFwcGVuZChmJ3Byb2Nlc3NfdGltZV9lcnJvcj17ZX0nKQoKCQlmb3IgY2xvY2tfaWRfbmFtZSBpbiBbCgkJCSdDTE9DS19SRUFMVElNRScsCgkJCSdDTE9DS19NT05PVE9OSUMnLAoJCQknQ0xPQ0tfUFJPQ0VTU19DUFVUSU1FX0lEJywKCQkJJ0NMT0NLX1RIUkVBRF9DUFVUSU1FX0lEJywKCQldOgoJCQl0cnk6CgkJCQljaWQgPSBnZXRhdHRyKHRpbWUsIGNsb2NrX2lkX25hbWUsIE5vbmUpCgkJCQlpZiBjaWQgaXMgbm90IE5vbmU6CgkJCQkJdmFsID0gdGltZS5jbG9ja19nZXR0aW1lKGNpZCkKCQkJCQlyZXMuYXBwZW5kKGYnY2xvY2tfZ2V0dGltZV97Y2xvY2tfaWRfbmFtZX09e3ZhbH0nKQoJCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCQlyZXMuYXBwZW5kKGYnY2xvY2tfZ2V0dGltZV97Y2xvY2tfaWRfbmFtZX1fZXJyb3I9e2V9JykKCgkJZ2wudm0uVXNlckVycm9yLmltbWVkaWF0ZShyZXMpCgAAAAAAAAAAAAAAAAAAAAAAAAAF +LQlF3AF0aW1lX3RpbWU9MTczMjYwMzM2Mi40MjQyNDLcAXRpbWVfbnM9MTczMjYwMzM2MjQyNDI0MjAwMNwBbW9ub3RvbmljPTE3MzI2MDMzNjIuNDI0MjQyhAJtb25vdG9uaWNfbnM9MTczMjYwMzM2MjQyNDI0MjAwMPQBcGVyZl9jb3VudGVyPTE3MzI2MDMzNjIuNDI0MjQyhAFwcm9jZXNzX3RpbWU9MC4w9AJjbG9ja19nZXR0aW1lX0NMT0NLX1JFQUxUSU1FPTE3MzI2MDMzNjIuNDI0MjQy/AJjbG9ja19nZXR0aW1lX0NMT0NLX01PTk9UT05JQz0xNzMyNjAzMzYyLjQyNDI0MgAdFaMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAiG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZiehXnRQ2fBOnD2NLYVqjpx436AIHqLBKP3JPOLfNevWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAINOyQQAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbAppbXBvcnQgdGltZQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlyZXM6IGxpc3Rbc3RyXSA9IFtdCgoJCXQgPSB0aW1lLnRpbWUoKQoJCXJlcy5hcHBlbmQoZid0aW1lX3RpbWU9e3R9JykKCgkJdF9ucyA9IHRpbWUudGltZV9ucygpCgkJcmVzLmFwcGVuZChmJ3RpbWVfbnM9e3RfbnN9JykKCgkJdHJ5OgoJCQltID0gdGltZS5tb25vdG9uaWMoKQoJCQlyZXMuYXBwZW5kKGYnbW9ub3RvbmljPXttfScpCgkJZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJCQlyZXMuYXBwZW5kKGYnbW9ub3RvbmljX2Vycm9yPXtlfScpCgoJCXRyeToKCQkJbV9ucyA9IHRpbWUubW9ub3RvbmljX25zKCkKCQkJcmVzLmFwcGVuZChmJ21vbm90b25pY19ucz17bV9uc30nKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcmVzLmFwcGVuZChmJ21vbm90b25pY19uc19lcnJvcj17ZX0nKQoKCQl0cnk6CgkJCXAgPSB0aW1lLnBlcmZfY291bnRlcigpCgkJCXJlcy5hcHBlbmQoZidwZXJmX2NvdW50ZXI9e3B9JykKCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCXJlcy5hcHBlbmQoZidwZXJmX2NvdW50ZXJfZXJyb3I9e2V9JykKCgkJdHJ5OgoJCQlwdCA9IHRpbWUucHJvY2Vzc190aW1lKCkKCQkJcmVzLmFwcGVuZChmJ3Byb2Nlc3NfdGltZT17cHR9JykKCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCXJlcy5hcHBlbmQoZidwcm9jZXNzX3RpbWVfZXJyb3I9e2V9JykKCgkJZm9yIGNsb2NrX2lkX25hbWUgaW4gWwoJCQknQ0xPQ0tfUkVBTFRJTUUnLAoJCQknQ0xPQ0tfTU9OT1RPTklDJywKCQkJJ0NMT0NLX1BST0NFU1NfQ1BVVElNRV9JRCcsCgkJCSdDTE9DS19USFJFQURfQ1BVVElNRV9JRCcsCgkJXToKCQkJdHJ5OgoJCQkJY2lkID0gZ2V0YXR0cih0aW1lLCBjbG9ja19pZF9uYW1lLCBOb25lKQoJCQkJaWYgY2lkIGlzIG5vdCBOb25lOgoJCQkJCXZhbCA9IHRpbWUuY2xvY2tfZ2V0dGltZShjaWQpCgkJCQkJcmVzLmFwcGVuZChmJ2Nsb2NrX2dldHRpbWVfe2Nsb2NrX2lkX25hbWV9PXt2YWx9JykKCQkJZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJCQkJcmVzLmFwcGVuZChmJ2Nsb2NrX2dldHRpbWVfe2Nsb2NrX2lkX25hbWV9X2Vycm9yPXtlfScpCgoJCWdsLnZtLlVzZXJFcnJvci5pbW1lZGlhdGUocmVzKQoAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/agentic/wasi/wasi_random/wasi_random.0.hash b/tests/cases/stable/agentic/wasi/wasi_random/wasi_random.0.hash index 64057f9df..c5496980c 100644 --- a/tests/cases/stable/agentic/wasi/wasi_random/wasi_random.0.hash +++ b/tests/cases/stable/agentic/wasi/wasi_random/wasi_random.0.hash @@ -1 +1 @@ -LQlF5AJ1cmFuZG9tX2hleD0yYzkyNzNjNWMwYWRjYWFmODRhNjIwMTdlNWZiZWYyZfwBcmFuZG9tX2ludD0xMzg1OTU0MTY4OTc0MzkxMzUwMvwBcmFuZG9tX2Zsb2F0PTAuNTY4OTk2NjA3NzA4ODQ0OfQBdXJhbmRvbV9zZXFfMD02MzcxMTg0ZDYxOTVkY2U49AF1cmFuZG9tX3NlcV8xPTI1OWRlNWIzMjkwMWU2MDb0AXVyYW5kb21fc2VxXzI9ZDhlNWNiOWYwNTU4YzI4Y/QBdXJhbmRvbV9zZXFfMz1lMzg3OTliYTc4ZjA5Mjk19AF1cmFuZG9tX3NlcV80PWYwNmU1MDY3YTQyOWYyZTQAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMg8AEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbAppbXBvcnQgb3MKaW1wb3J0IHJhbmRvbQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlyZXM6IGxpc3Rbc3RyXSA9IFtdCgoJCXJhbmRfYnl0ZXMgPSBvcy51cmFuZG9tKDE2KQoJCXJlcy5hcHBlbmQoZid1cmFuZG9tX2hleD17cmFuZF9ieXRlcy5oZXgoKX0nKQoKCQl2YWwgPSByYW5kb20ucmFuZGludCgwLCAyKio2NCkKCQlyZXMuYXBwZW5kKGYncmFuZG9tX2ludD17dmFsfScpCgoJCXZhbDIgPSByYW5kb20ucmFuZG9tKCkKCQlyZXMuYXBwZW5kKGYncmFuZG9tX2Zsb2F0PXt2YWwyfScpCgoJCWZvciBpIGluIHJhbmdlKDUpOgoJCQliID0gb3MudXJhbmRvbSg4KQoJCQlyZXMuYXBwZW5kKGYndXJhbmRvbV9zZXFfe2l9PXtiLmhleCgpfScpCgoJCWdsLnZtLlVzZXJFcnJvci5pbW1lZGlhdGUocmVzKQoAAAAAAAAAAAAAAAAF +LQlF5AJ1cmFuZG9tX2hleD0yYzkyNzNjNWMwYWRjYWFmODRhNjIwMTdlNWZiZWYyZfwBcmFuZG9tX2ludD0xMzg1OTU0MTY4OTc0MzkxMzUwMvwBcmFuZG9tX2Zsb2F0PTAuNTY4OTk2NjA3NzA4ODQ0OfQBdXJhbmRvbV9zZXFfMD02MzcxMTg0ZDYxOTVkY2U49AF1cmFuZG9tX3NlcV8xPTI1OWRlNWIzMjkwMWU2MDb0AXVyYW5kb21fc2VxXzI9ZDhlNWNiOWYwNTU4YzI4Y/QBdXJhbmRvbV9zZXFfMz1lMzg3OTliYTc4ZjA5Mjk19AF1cmFuZG9tX3NlcV80PWYwNmU1MDY3YTQyOWYyZTQAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDIPABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKaW1wb3J0IG9zCmltcG9ydCByYW5kb20KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcmVzOiBsaXN0W3N0cl0gPSBbXQoKCQlyYW5kX2J5dGVzID0gb3MudXJhbmRvbSgxNikKCQlyZXMuYXBwZW5kKGYndXJhbmRvbV9oZXg9e3JhbmRfYnl0ZXMuaGV4KCl9JykKCgkJdmFsID0gcmFuZG9tLnJhbmRpbnQoMCwgMioqNjQpCgkJcmVzLmFwcGVuZChmJ3JhbmRvbV9pbnQ9e3ZhbH0nKQoKCQl2YWwyID0gcmFuZG9tLnJhbmRvbSgpCgkJcmVzLmFwcGVuZChmJ3JhbmRvbV9mbG9hdD17dmFsMn0nKQoKCQlmb3IgaSBpbiByYW5nZSg1KToKCQkJYiA9IG9zLnVyYW5kb20oOCkKCQkJcmVzLmFwcGVuZChmJ3VyYW5kb21fc2VxX3tpfT17Yi5oZXgoKX0nKQoKCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKHJlcykKAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/exploits/call_wasi_extra.0.hash b/tests/cases/stable/exploits/call_wasi_extra.0.hash index 6adb6e06f..6385750eb 100644 --- a/tests/cases/stable/exploits/call_wasi_extra.0.hash +++ b/tests/cases/stable/exploits/call_wasi_extra.0.hash @@ -1 +1 @@ -LRFkZXhpdF9jb2RlIDMwAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDHKcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IF9nZW5sYXllcl93YXNpIGFzIHdhc2kKaW1wb3J0IGdlbmxheWVyLmNhbGxkYXRhIGFzIGNhbGxkYXRhCmltcG9ydCBvcwoKaW1wb3J0IGNsb3VkcGlja2xlCgoKZGVmIGZvbygpOgoJcHJpbnQoJ3dlIHdpbGwgaGF2ZSBhbiBpbmZpbml0ZSBsb29wLi4uJykKCgp0cnk6CglmZCA9IHdhc2kuZ2xfY2FsbCgKCQljYWxsZGF0YS5lbmNvZGUoCgkJCXsKCQkJCSdTYW5kYm94JzogewoJCQkJCSdhX2V4dHJhX2ZpZWxkJzogVHJ1ZSwKCQkJCQknZGF0YSc6IGNsb3VkcGlja2xlLmR1bXBzKGZvbyksCgkJCQl9CgkJCX0KCQkpLAoJKQpleGNlcHQgRXhjZXB0aW9uIGFzIGU6CglwcmludChlKQoJZXhpdCgzMCkKCnByaW50KG9zLmZkb3BlbihmZCkucmVhZCgpKQoKZXhpdCgwKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LRFkZXhpdF9jb2RlIDMwABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxynAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBfZ2VubGF5ZXJfd2FzaSBhcyB3YXNpCmltcG9ydCBnZW5sYXllci5jYWxsZGF0YSBhcyBjYWxsZGF0YQppbXBvcnQgb3MKCmltcG9ydCBjbG91ZHBpY2tsZQoKCmRlZiBmb28oKToKCXByaW50KCd3ZSB3aWxsIGhhdmUgYW4gaW5maW5pdGUgbG9vcC4uLicpCgoKdHJ5OgoJZmQgPSB3YXNpLmdsX2NhbGwoCgkJY2FsbGRhdGEuZW5jb2RlKAoJCQl7CgkJCQknU2FuZGJveCc6IHsKCQkJCQknYV9leHRyYV9maWVsZCc6IFRydWUsCgkJCQkJJ2RhdGEnOiBjbG91ZHBpY2tsZS5kdW1wcyhmb28pLAoJCQkJfQoJCQl9CgkJKSwKCSkKZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJcHJpbnQoZSkKCWV4aXQoMzApCgpwcmludChvcy5mZG9wZW4oZmQpLnJlYWQoKSkKCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/exploits/close_std.0.hash b/tests/cases/stable/exploits/close_std.0.hash index 0545632cd..5f7fca66a 100644 --- a/tests/cases/stable/exploits/close_std.0.hash +++ b/tests/cases/stable/exploits/close_std.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDCHAAAAAAYXNtAQAAAAEJAmAAAGABfwF/AiMBFndhc2lfc25hcHNob3RfcHJldmlldzEIZmRfY2xvc2UAAQMCAQAFAwEAAQcTAgZfc3RhcnQAAQZtZW1vcnkCAAoYARYAQQAQABpBARAAGkECEAAaQQMQABoLAAAAAAAAAAAAAAAABQ== +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwhwAAAAAGFzbQEAAAABCQJgAABgAX8BfwIjARZ3YXNpX3NuYXBzaG90X3ByZXZpZXcxCGZkX2Nsb3NlAAEDAgEABQMBAAEHEwIGX3N0YXJ0AAEGbWVtb3J5AgAKGAEWAEEAEAAaQQEQABpBAhAAGkEDEAAaCwAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/exploits/deep_calldata.0.hash b/tests/cases/stable/exploits/deep_calldata.0.hash index d3e7c6158..d66389abb 100644 --- a/tests/cases/stable/exploits/deep_calldata.0.hash +++ b/tests/cases/stable/exploits/deep_calldata.0.hash @@ -1 +1 @@ -LRGEAndhc21fdHJhcCBVbnJlYWNoYWJsZUNvZGVSZWFjaGVkAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDDLYAAAAAYXNtAQAAAAELAmADf39/AX9gAAACGAEMZ2VubGF5ZXJfc2RrB2dsX2NhbGwAAAMCAQEFAwEAAQYGAX8AQRALBxMCBm1lbW9yeQIABl9zdGFydAABCk4BTAEEfyMAQQFrQAAaIwBBEHQhAiACQQRrIQNBCCEAQY2atOgAIQECQANAIAAgA08NASAAIAE2AgAgAEEEaiEADAALC0EAIAIgAxAAAAsLDwEAQQALCQ4GUmV0dXJuDQAAAAAAAAU= +LRGEAndhc21fdHJhcCBVbnJlYWNoYWJsZUNvZGVSZWFjaGVkABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwy2AAAAAGFzbQEAAAABCwJgA39/fwF/YAAAAhgBDGdlbmxheWVyX3NkawdnbF9jYWxsAAADAgEBBQMBAAEGBgF/AEEQCwcTAgZtZW1vcnkCAAZfc3RhcnQAAQpOAUwBBH8jAEEBa0AAGiMAQRB0IQIgAkEEayEDQQghAEGNmrToACEBAkADQCAAIANPDQEgACABNgIAIABBBGohAAwACwtBACACIAMQAAALCw8BAEEACwkOBlJldHVybg0AAAAAAAAF diff --git a/tests/cases/stable/exploits/disagree_in_sandbox.0.hash b/tests/cases/stable/exploits/disagree_in_sandbox.0.hash index 69e26a545..bfd2b8b41 100644 --- a/tests/cases/stable/exploits/disagree_in_sandbox.0.hash +++ b/tests/cases/stable/exploits/disagree_in_sandbox.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlkZWYgZm4oKToKCQkJdHJ5OgoJCQkJZ2wudm0ucnVuX25vbmRldF9kZWZhdWx0KGxhbWJkYTogTm9uZSwgbGFtYmRhIHg6IEZhbHNlKQoJCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCQlwcmludChlKQoKCQlwcmludCgncHJlIHNwYXduJykKCQlyZXMgPSBnbC52bS5zcGF3bl9zYW5kYm94KGZuKQoJCXByaW50KGYncmVzPXtyZXN9JykKAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZXAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJZGVmIGZuKCk6CgkJCXRyeToKCQkJCWdsLnZtLnJ1bl9ub25kZXRfZGVmYXVsdChsYW1iZGE6IE5vbmUsIGxhbWJkYSB4OiBGYWxzZSkKCQkJZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJCQkJcHJpbnQoZSkKCgkJcHJpbnQoJ3ByZSBzcGF3bicpCgkJcmVzID0gZ2wudm0uc3Bhd25fc2FuZGJveChmbikKCQlwcmludChmJ3Jlcz17cmVzfScpCgAAAAAABQ== diff --git a/tests/cases/stable/exploits/flt.0.hash b/tests/cases/stable/exploits/flt.0.hash index 2f81be273..2268cf101 100644 --- a/tests/cases/stable/exploits/flt.0.hash +++ b/tests/cases/stable/exploits/flt.0.hash @@ -1 +1 @@ -LRHcAXdhc21fdHJhcCBEZXRlcm1pbmlzdGljTW9kZQANFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgwyyAAAAAGFzbQEAAAABDQNgAABgAX8AYAF8AXwCJAEWd2FzaV9zbmFwc2hvdF9wcmV2aWV3MQlwcm9jX2V4aXQAAQMDAgIABQQBAIECBxMCBl9zdGFydAACBm1lbW9yeQIAClMCPAEBfEQAAAAAAADwPyEBAkAgAEQAAAAAAAAAAGUNACAARAAAAAAAAOC/oBABRM3MzMzMzPQ/oiEBCyABCxQARAAAAAAAAABAEAGqQQJrEAAACwAAAAAAAAAAAAAF +LRHcAXdhc21fdHJhcCBEZXRlcm1pbmlzdGljTW9kZQAVFaMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMMsgAAAABhc20BAAAAAQ0DYAAAYAF/AGABfAF8AiQBFndhc2lfc25hcHNob3RfcHJldmlldzEJcHJvY19leGl0AAEDAwICAAUEAQCBAgcTAgZfc3RhcnQAAgZtZW1vcnkCAApTAjwBAXxEAAAAAAAA8D8hAQJAIABEAAAAAAAAAABlDQAgAEQAAAAAAADgv6AQAUTNzMzMzMz0P6IhAQsgAQsUAEQAAAAAAAAAQBABqkECaxAAAAsAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/exploits/fork_bomb.0.hash b/tests/cases/stable/exploits/fork_bomb.0.hash index c024d7aa9..98d66b93c 100644 --- a/tests/cases/stable/exploits/fork_bomb.0.hash +++ b/tests/cases/stable/exploits/fork_bomb.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEgUBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmRlZiBib21iKCk6CglyZXMgPSBnbC52bS5zcGF3bl9zYW5kYm94KGJvbWIpCglpZiBpc2luc3RhbmNlKHJlcywgZ2wudm0uVk1FcnJvcik6CgkJcHJpbnQocmVzLm1lc3NhZ2UpCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCWJvbWIoKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIFAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpkZWYgYm9tYigpOgoJcmVzID0gZ2wudm0uc3Bhd25fc2FuZGJveChib21iKQoJaWYgaXNpbnN0YW5jZShyZXMsIGdsLnZtLlZNRXJyb3IpOgoJCXByaW50KHJlcy5tZXNzYWdlKQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlib21iKCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/exploits/method_init.0.hash b/tests/cases/stable/exploits/method_init.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/exploits/method_init.0.hash +++ b/tests/cases/stable/exploits/method_init.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/exploits/method_private.0.hash b/tests/cases/stable/exploits/method_private.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/exploits/method_private.0.hash +++ b/tests/cases/stable/exploits/method_private.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/exploits/oom.0.hash b/tests/cases/stable/exploits/oom.0.hash index dc2aae15d..f93d7a230 100644 --- a/tests/cases/stable/exploits/oom.0.hash +++ b/tests/cases/stable/exploits/oom.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEADRWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMIdQAAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CgpzeiA9IDEwMjQKYWxsID0gW10Kd2hpbGUgVHJ1ZToKCXByaW50KHN6KQoJYWxsLmFwcGVuZChsaXN0KHJhbmdlKHN6KSkpCglzeiAqPSA4CgAAAAAAAAAF +LRFcZXhpdF9jb2RlIDEAFRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCHUAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKc3ogPSAxMDI0CmFsbCA9IFtdCndoaWxlIFRydWU6CglwcmludChzeikKCWFsbC5hcHBlbmQobGlzdChyYW5nZShzeikpKQoJc3ogKj0gOAoAAAAAAAAABQ== diff --git a/tests/cases/stable/exploits/rec.0.hash b/tests/cases/stable/exploits/rec.0.hash index d57702019..19cd0676f 100644 --- a/tests/cases/stable/exploits/rec.0.hash +++ b/tests/cases/stable/exploits/rec.0.hash @@ -1 +1 @@ -LRG8AXdhc21fdHJhcCBTdGFja092ZXJmbG93AA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDBkQAAAAAYXNtAQAAAAEIAmAAAGAAAX4DAwIBAAUEAQCBAgcTAgZfc3RhcnQAAQZtZW1vcnkCAAoQAggAEABCAXwPCwUAEAAACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LRG8AXdhc21fdHJhcCBTdGFja092ZXJmbG93ABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwZEAAAAAGFzbQEAAAABCAJgAABgAAF+AwMCAQAFBAEAgQIHEwIGX3N0YXJ0AAEGbWVtb3J5AgAKEAIIABAAQgF8DwsFABAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/exploits/rec_1023.0.hash b/tests/cases/stable/exploits/rec_1023.0.hash index 1c044ad0b..ff73df4cc 100644 --- a/tests/cases/stable/exploits/rec_1023.0.hash +++ b/tests/cases/stable/exploits/rec_1023.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDBlEAAAAAYXNtAQAAAAEIAmAAAGABfgADAwIBAAUEAQCBAgcTAgZfc3RhcnQAAQZtZW1vcnkCAAodAhIAIABCAFUEQCAAQgF9EAALDwsIAEL+BxAADwsAAAAAAAAAAAAAAAU= +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwZRAAAAAGFzbQEAAAABCAJgAABgAX4AAwMCAQAFBAEAgQIHEwIGX3N0YXJ0AAEGbWVtb3J5AgAKHQISACAAQgBVBEAgAEIBfRAACw8LCABC/gcQAA8LAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/exploits/rec_1024.0.hash b/tests/cases/stable/exploits/rec_1024.0.hash index 7e75e9fbe..0a99e6076 100644 --- a/tests/cases/stable/exploits/rec_1024.0.hash +++ b/tests/cases/stable/exploits/rec_1024.0.hash @@ -1 +1 @@ -LRG8AXdhc21fdHJhcCBTdGFja092ZXJmbG93AA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDBlEAAAAAYXNtAQAAAAEIAmAAAGABfgADAwIBAAUEAQCBAgcTAgZfc3RhcnQAAQZtZW1vcnkCAAodAhIAIABCAFUEQCAAQgF9EAALDwsIAEL/BxAAAAsAAAAAAAAAAAAAAAU= +LRG8AXdhc21fdHJhcCBTdGFja092ZXJmbG93ABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwZRAAAAAGFzbQEAAAABCAJgAABgAX4AAwMCAQAFBAEAgQIHEwIGX3N0YXJ0AAEGbWVtb3J5AgAKHQISACAAQgBVBEAgAEIBfRAACw8LCABC/wcQAAALAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/exploits/storage_page_limit.0.hash b/tests/cases/stable/exploits/storage_page_limit.0.hash index 6d199f869..74a0ea1db 100644 --- a/tests/cases/stable/exploits/storage_page_limit.0.hash +++ b/tests/cases/stable/exploits/storage_page_limit.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/exploits/storage_rw_long.0.hash b/tests/cases/stable/exploits/storage_rw_long.0.hash index dca9bdd74..86ce267b3 100644 --- a/tests/cases/stable/exploits/storage_rw_long.0.hash +++ b/tests/cases/stable/exploits/storage_rw_long.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEADRWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMKjwAAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CgppbXBvcnQgX2dlbmxheWVyX3dhc2kgYXMgd2FzaQoKYnVmID0gYnl0ZWFycmF5KDMpCndhc2kuc3RvcmFnZV9yZWFkKGInXHgwMCcgKiAzMiwgMioqMzIgLSAxLCBidWYpCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAU= +LRFcZXhpdF9jb2RlIDEAFRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCo8AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IF9nZW5sYXllcl93YXNpIGFzIHdhc2kKCmJ1ZiA9IGJ5dGVhcnJheSgzKQp3YXNpLnN0b3JhZ2VfcmVhZChiJ1x4MDAnICogMzIsIDIqKjMyIC0gMSwgYnVmKQpleGl0KDApCgAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/exploits/storage_rw_long.0_0.hash b/tests/cases/stable/exploits/storage_rw_long.0_0.hash index a0b6635f1..9a0100cb6 100644 --- a/tests/cases/stable/exploits/storage_rw_long.0_0.hash +++ b/tests/cases/stable/exploits/storage_rw_long.0_0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEADRWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMKhQAAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CgppbXBvcnQgX2dlbmxheWVyX3dhc2kgYXMgd2FzaQoKd2FzaS5zdG9yYWdlX3dyaXRlKGInXHgwMCcgKiAzMiwgMioqMzIgLSAxLCBiJ1x4MDBceDAwJykKZXhpdCgwKQopCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAU= +LRFcZXhpdF9jb2RlIDEAFRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCoUAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IF9nZW5sYXllcl93YXNpIGFzIHdhc2kKCndhc2kuc3RvcmFnZV93cml0ZShiJ1x4MDAnICogMzIsIDIqKjMyIC0gMSwgYidceDAwXHgwMCcpCmV4aXQoMCkKKQpleGl0KDApCgAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/exploits/unreachable.0.hash b/tests/cases/stable/exploits/unreachable.0.hash index a317cbb28..b8fe6da06 100644 --- a/tests/cases/stable/exploits/unreachable.0.hash +++ b/tests/cases/stable/exploits/unreachable.0.hash @@ -1 +1 @@ -LRGEAndhc21fdHJhcCBVbnJlYWNoYWJsZUNvZGVSZWFjaGVkAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDBCUAAAAAYXNtAQAAAAEEAWAAAAMCAQAHCgEGX3N0YXJ0AAAKBQEDAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LRGEAndhc21fdHJhcCBVbnJlYWNoYWJsZUNvZGVSZWFjaGVkABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwQlAAAAAGFzbQEAAAABBAFgAAADAgEABwoBBl9zdGFydAAACgUBAwAACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/nondet/leader_errors/empty_leader_result.0.hash b/tests/cases/stable/nondet/leader_errors/empty_leader_result.0.hash index 1bb54d921..5e5759390 100644 --- a/tests/cases/stable/nondet/leader_errors/empty_leader_result.0.hash +++ b/tests/cases/stable/nondet/leader_errors/empty_leader_result.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/nondet/leader_errors/leader_no_nondet.0.hash b/tests/cases/stable/nondet/leader_errors/leader_no_nondet.0.hash index 1bb54d921..5e5759390 100644 --- a/tests/cases/stable/nondet/leader_errors/leader_no_nondet.0.hash +++ b/tests/cases/stable/nondet/leader_errors/leader_no_nondet.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/nondet/leader_errors/simple_leader.0.hash b/tests/cases/stable/nondet/leader_errors/simple_leader.0.hash index 1bb54d921..5e5759390 100644 --- a/tests/cases/stable/nondet/leader_errors/simple_leader.0.hash +++ b/tests/cases/stable/nondet/leader_errors/simple_leader.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/nondet/leader_errors/simple_valid_err_err.0.hash b/tests/cases/stable/nondet/leader_errors/simple_valid_err_err.0.hash index 1bb54d921..5e5759390 100644 --- a/tests/cases/stable/nondet/leader_errors/simple_valid_err_err.0.hash +++ b/tests/cases/stable/nondet/leader_errors/simple_valid_err_err.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit.0.hash b/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit.0.hash index 1bb54d921..5e5759390 100644 --- a/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit.0.hash +++ b/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDIhwCAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZik6CgkJZGVmIGRvX2ZuKCk6CgkJCXJhaXNlIEV4Y2VwdGlvbigpCgoJCWdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEoZG9fZm4pCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGJhcihzZWxmKToKCQlkZWYgZG9fZm4oKToKCQkJcmV0dXJuCgoJCWdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEoZG9fZm4pCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGV4KHNlbGYpOgoJCWRlZiBkb19mbigpOgoJCQlleGl0KDIpCgoJCWdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEoZG9fZm4pCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGV4MihzZWxmKToKCQlkZWYgZG9fZm4oKToKCQkJbm9uX2V4aXN0ZW50X2ZuKCkgICMgbm9xYQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGRvX2ZuKQoF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyIcAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgZm9vKHNlbGYpOgoJCWRlZiBkb19mbigpOgoJCQlyYWlzZSBFeGNlcHRpb24oKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGRvX2ZuKQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBiYXIoc2VsZik6CgkJZGVmIGRvX2ZuKCk6CgkJCXJldHVybgoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGRvX2ZuKQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBleChzZWxmKToKCQlkZWYgZG9fZm4oKToKCQkJZXhpdCgyKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGRvX2ZuKQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBleDIoc2VsZik6CgkJZGVmIGRvX2ZuKCk6CgkJCW5vbl9leGlzdGVudF9mbigpICAjIG5vcWEKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShkb19mbikKBQ== diff --git a/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit_wrong_err.0.hash b/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit_wrong_err.0.hash index 1bb54d921..5e5759390 100644 --- a/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit_wrong_err.0.hash +++ b/tests/cases/stable/nondet/leader_errors/simple_valid_err_exit_wrong_err.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/nondet/leader_errors/simple_valid_err_nerr.0.hash b/tests/cases/stable/nondet/leader_errors/simple_valid_err_nerr.0.hash index 1bb54d921..5e5759390 100644 --- a/tests/cases/stable/nondet/leader_errors/simple_valid_err_nerr.0.hash +++ b/tests/cases/stable/nondet/leader_errors/simple_valid_err_nerr.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/nondet/metod_det_get_webpage.0.hash b/tests/cases/stable/nondet/metod_det_get_webpage.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/nondet/metod_det_get_webpage.0.hash +++ b/tests/cases/stable/nondet/metod_det_get_webpage.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/nondet/trivial.0.hash b/tests/cases/stable/nondet/trivial.0.hash index 7c958f524..4cce027e5 100644 --- a/tests/cases/stable/nondet/trivial.0.hash +++ b/tests/cases/stable/nondet/trivial.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCoBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBpbml0KHNlbGYpOgoJCWV2YWwoInByaW50KCdpbml0IGZyb20gZXZhbCEnKSIpCgoJCWRlZiBydW4oKToKCQkJcHJpbnQoJ3dvdywgbm9uZGV0JykKCQkJcmV0dXJuICd3ZWIgcGFnZT8nCgoJCXJldHVybiBnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikKAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQqAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgaW5pdChzZWxmKToKCQlldmFsKCJwcmludCgnaW5pdCBmcm9tIGV2YWwhJykiKQoKCQlkZWYgcnVuKCk6CgkJCXByaW50KCd3b3csIG5vbmRldCcpCgkJCXJldHVybiAnd2ViIHBhZ2U/JwoKCQlyZXR1cm4gZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW4pCgAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/nondet/validator/rollback_agree.0.hash b/tests/cases/stable/nondet/validator/rollback_agree.0.hash index 7b86822f1..8854e7071 100644 --- a/tests/cases/stable/nondet/validator/rollback_agree.0.hash +++ b/tests/cases/stable/nondet/validator/rollback_agree.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEv0AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCWRlZiBydW4oKToKCQkJcmFpc2UgZ2wudm0uVXNlckVycm9yKCdyb2xsYmFjaycpCgoJCXByaW50KGdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEocnVuKSkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxL9AAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmKToKCQlkZWYgcnVuKCk6CgkJCXJhaXNlIGdsLnZtLlVzZXJFcnJvcigncm9sbGJhY2snKQoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/nondet/validator/rollback_disagree.0.hash b/tests/cases/stable/nondet/validator/rollback_disagree.0.hash index 7b86822f1..8854e7071 100644 --- a/tests/cases/stable/nondet/validator/rollback_disagree.0.hash +++ b/tests/cases/stable/nondet/validator/rollback_disagree.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEv0AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCWRlZiBydW4oKToKCQkJcmFpc2UgZ2wudm0uVXNlckVycm9yKCdyb2xsYmFjaycpCgoJCXByaW50KGdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEocnVuKSkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxL9AAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmKToKCQlkZWYgcnVuKCk6CgkJCXJhaXNlIGdsLnZtLlVzZXJFcnJvcigncm9sbGJhY2snKQoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/nondet/validator/rollback_imm.0.hash b/tests/cases/stable/nondet/validator/rollback_imm.0.hash index ad493dbe1..ea42dfb39 100644 --- a/tests/cases/stable/nondet/validator/rollback_imm.0.hash +++ b/tests/cases/stable/nondet/validator/rollback_imm.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEgEBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCWRlZiBydW4oKToKCQkJZ2wudm0uVXNlckVycm9yLmltbWVkaWF0ZSgncm9sbGJhY2snKQoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIBAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmKToKCQlkZWYgcnVuKCk6CgkJCWdsLnZtLlVzZXJFcnJvci5pbW1lZGlhdGUoJ3JvbGxiYWNrJykKCgkJcHJpbnQoZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW4pKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/nondet/validator/sync.0.hash b/tests/cases/stable/nondet/validator/sync.0.hash index 5b6f8290f..b1a3028bf 100644 --- a/tests/cases/stable/nondet/validator/sync.0.hash +++ b/tests/cases/stable/nondet/validator/sync.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEgcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCWRlZiBydW4oKToKCQkJcHJpbnQoJ1NIT1VMRCBOT1QgQkUgUFJJTlRFRCcpCgkJCXJldHVybiAxMAoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIHAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmKToKCQlkZWYgcnVuKCk6CgkJCXByaW50KCdTSE9VTEQgTk9UIEJFIFBSSU5URUQnKQoJCQlyZXR1cm4gMTAKCgkJcHJpbnQoZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW4pKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/nondet/validator/sync_err.0.hash b/tests/cases/stable/nondet/validator/sync_err.0.hash index 5b6f8290f..b1a3028bf 100644 --- a/tests/cases/stable/nondet/validator/sync_err.0.hash +++ b/tests/cases/stable/nondet/validator/sync_err.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEgcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCWRlZiBydW4oKToKCQkJcHJpbnQoJ1NIT1VMRCBOT1QgQkUgUFJJTlRFRCcpCgkJCXJldHVybiAxMAoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIHAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmKToKCQlkZWYgcnVuKCk6CgkJCXByaW50KCdTSE9VTEQgTk9UIEJFIFBSSU5URUQnKQoJCQlyZXR1cm4gMTAKCgkJcHJpbnQoZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW4pKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/balances/balance.0.hash b/tests/cases/stable/py/balances/balance.0.hash index 920162159..b4d1ed009 100644 --- a/tests/cases/stable/py/balances/balance.0.hash +++ b/tests/cases/stable/py/balances/balance.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDMOICAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludCgnbWFpbiBzZWxmJywgc2VsZi5iYWxhbmNlKQoJCXByaW50KCdtYWluIEF0KHNlbGYpJywgZ2wuY29udHJhY3QuZ2V0X2F0KGdsLm1lc3NhZ2UuY29udHJhY3RfYWRkcmVzcykuYmFsYW5jZSkKCQlwcmludCgnPT09IHRyYW5zZmVyID09PScpCgkJZ2wuY29udHJhY3QuZ2V0X2F0KGdsLm1lc3NhZ2Uuc2VuZGVyX2FkZHJlc3MpLmVtaXRfdHJhbnNmZXIodmFsdWU9NSkKCQlwcmludCgnbWFpbiBzZWxmJywgc2VsZi5iYWxhbmNlKQoJCXByaW50KCdtYWluIEF0KHNlbGYpJywgZ2wuY29udHJhY3QuZ2V0X2F0KGdsLm1lc3NhZ2UuY29udHJhY3RfYWRkcmVzcykuYmFsYW5jZSkKCgkJcHJpbnQoJz09PSBjYWxsIC52aWV3KCkgPT09JykKCQlnbC5jb250cmFjdC5nZXRfYXQoZ2wubWVzc2FnZS5jb250cmFjdF9hZGRyZXNzKS52aWV3KCkubmVzdGVkKCkKCglAZ2wucHVibGljLnZpZXcKCWRlZiBuZXN0ZWQoc2VsZik6CgkJcHJpbnQoJ25lc3RlZCBzZWxmJywgc2VsZi5iYWxhbmNlKQoJCXByaW50KCduZXN0ZWQgQXQoc2VsZiknLCBnbC5jb250cmFjdC5nZXRfYXQoZ2wubWVzc2FnZS5jb250cmFjdF9hZGRyZXNzKS5iYWxhbmNlKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgzINAwAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCXByaW50KCdtYWluIHNlbGYnLCBzZWxmLmJhbGFuY2UpCgkJcHJpbnQoJ21haW4gQXQoc2VsZiknLCBnbC5jb250cmFjdC5nZXRfYXQoZ2wubWVzc2FnZS5jb250cmFjdF9hZGRyZXNzKS5iYWxhbmNlKQoJCXByaW50KCc9PT0gdHJhbnNmZXIgPT09JykKCQlnbC5jb250cmFjdC5nZXRfYXQoZ2wubWVzc2FnZS5zZW5kZXJfYWRkcmVzcykuZW1pdF90cmFuc2Zlcih2YWx1ZT01KQoJCXByaW50KCdtYWluIHNlbGYnLCBzZWxmLmJhbGFuY2UpCgkJcHJpbnQoJ21haW4gQXQoc2VsZiknLCBnbC5jb250cmFjdC5nZXRfYXQoZ2wubWVzc2FnZS5jb250cmFjdF9hZGRyZXNzKS5iYWxhbmNlKQoKCQlwcmludCgnPT09IGNhbGwgLnZpZXcoKSA9PT0nKQoJCWdsLmNvbnRyYWN0LmdldF9hdChnbC5tZXNzYWdlLmNvbnRyYWN0X2FkZHJlc3MpLnZpZXcoKS5uZXN0ZWQoKQoKCUBnbC5wdWJsaWMudmlldwoJZGVmIG5lc3RlZChzZWxmKToKCQlwcmludCgnbmVzdGVkIHNlbGYnLCBzZWxmLmJhbGFuY2UpCgkJcHJpbnQoJ25lc3RlZCBBdChzZWxmKScsIGdsLmNvbnRyYWN0LmdldF9hdChnbC5tZXNzYWdlLmNvbnRyYWN0X2FkZHJlc3MpLmJhbGFuY2UpCgAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/balances/balance.0.stdout b/tests/cases/stable/py/balances/balance.0.stdout index a48130284..7d73027c8 100644 --- a/tests/cases/stable/py/balances/balance.0.stdout +++ b/tests/cases/stable/py/balances/balance.0.stdout @@ -1,10 +1 @@ -main self 10 -main At(self) 10 -=== transfer === -main self 5 -main At(self) 10 -=== call .view() === -nested self 10 -nested At(self) 10 executed with `Return(null)` -{"address":addr#0200000000000000000000000000000000000000,"call_key":b#0000000000000000000000000000000000000000000000000000000000000000,"calldata":{},"fee_params":{"execution_budget_per_round":1024,"leader_timeunits_allocation":5,"max_price_gen_per_time_unit":1606938044258990275541962092341162602522202993782792835301376,"receipt_fee_max_gas_price":20,"rotations":[4,4,4,4,4],"storage_fee_max_gas_price":20,"validator_timeunits_allocation":5},"message_fee":34836,"on":"finalized","receipt_fee":225,"subtree":b#00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000,"type":"PostMessage","value":5} diff --git a/tests/cases/stable/py/balances/balance.0_0.hash b/tests/cases/stable/py/balances/balance.0_0.hash new file mode 100644 index 000000000..9942c2585 --- /dev/null +++ b/tests/cases/stable/py/balances/balance.0_0.hash @@ -0,0 +1 @@ +LQEAAAUF diff --git a/tests/cases/stable/py/balances/balance.0_0.stdout b/tests/cases/stable/py/balances/balance.0_0.stdout new file mode 100644 index 000000000..a48130284 --- /dev/null +++ b/tests/cases/stable/py/balances/balance.0_0.stdout @@ -0,0 +1,10 @@ +main self 10 +main At(self) 10 +=== transfer === +main self 5 +main At(self) 10 +=== call .view() === +nested self 10 +nested At(self) 10 +executed with `Return(null)` +{"address":addr#0200000000000000000000000000000000000000,"call_key":b#0000000000000000000000000000000000000000000000000000000000000000,"calldata":{},"fee_params":{"execution_budget_per_round":1024,"leader_timeunits_allocation":5,"max_price_gen_per_time_unit":1606938044258990275541962092341162602522202993782792835301376,"receipt_fee_max_gas_price":20,"rotations":[4,4,4,4,4],"storage_fee_max_gas_price":20,"validator_timeunits_allocation":5},"message_fee":34836,"on":"finalized","receipt_fee":225,"subtree":b#00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000,"type":"PostMessage","value":5} diff --git a/tests/cases/stable/py/balances/balance.jsonnet b/tests/cases/stable/py/balances/balance.jsonnet index b07b7467b..84b882d8a 100644 --- a/tests/cases/stable/py/balances/balance.jsonnet +++ b/tests/cases/stable/py/balances/balance.jsonnet @@ -1,7 +1,9 @@ -local simple_deploy = import 'templates/simple_deploy.jsonnet'; +local deploy_then = import 'templates/simple_deploy_then_write.jsonnet'; local util = import 'templates/util.jsonnet'; -{entry: util.addPaths([simple_deploy.run('${jsonnetDir}/${fileBaseName}.py') { +local bal = { "balances": { "AQAAAAAAAAAAAAAAAAAAAAAAAAA=": 10, }, -}])} +}; +local base = deploy_then.run('${jsonnetDir}/${fileBaseName}.py', 'main'); +{entry: util.addPaths([base + bal + {next: [base.next[0] + bal]}])} diff --git a/tests/cases/stable/py/balances/balance.py b/tests/cases/stable/py/balances/balance.py index 323af2023..f34d2b82f 100644 --- a/tests/cases/stable/py/balances/balance.py +++ b/tests/cases/stable/py/balances/balance.py @@ -5,6 +5,10 @@ class Contract(gl.contract.Contract): def __init__(self): + pass + + @gl.public.write + def main(self): print('main self', self.balance) print('main At(self)', gl.contract.get_at(gl.message.contract_address).balance) print('=== transfer ===') diff --git a/tests/cases/stable/py/balances/balance_eth.0.hash b/tests/cases/stable/py/balances/balance_eth.0.hash index ced8e3c89..93b7a6d56 100644 --- a/tests/cases/stable/py/balances/balance_eth.0.hash +++ b/tests/cases/stable/py/balances/balance_eth.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDNCEDAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCkBnbC5ldm0uY29udHJhY3RfaW50ZXJmYWNlCmNsYXNzIEV0aENvbnRyYWN0OgoJY2xhc3MgVmlldzoKCQlwYXNzCgoJY2xhc3MgV3JpdGU6CgkJcGFzcwoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludCgnbWFpbiBzZWxmJywgc2VsZi5iYWxhbmNlKQoJCXByaW50KCdtYWluIEF0KHNlbGYpJywgRXRoQ29udHJhY3QoZ2wubWVzc2FnZS5jb250cmFjdF9hZGRyZXNzKS5iYWxhbmNlKQoJCXByaW50KCc9PT0gdHJhbnNmZXIgPT09JykKCgkJRXRoQ29udHJhY3QoZ2wubWVzc2FnZS5zZW5kZXJfYWRkcmVzcykuZW1pdF90cmFuc2Zlcih2YWx1ZT01KQoJCXByaW50KCdtYWluIHNlbGYnLCBzZWxmLmJhbGFuY2UpCgkJcHJpbnQoJ21haW4gQXQoc2VsZiknLCBFdGhDb250cmFjdChnbC5tZXNzYWdlLmNvbnRyYWN0X2FkZHJlc3MpLmJhbGFuY2UpCgoJCXByaW50KCc9PT0gY2FsbCAudmlldygpID09PScpCgkJZ2wuY29udHJhY3QuZ2V0X2F0KGdsLm1lc3NhZ2UuY29udHJhY3RfYWRkcmVzcykudmlldygpLm5lc3RlZCgpCgoJQGdsLnB1YmxpYy52aWV3CglkZWYgbmVzdGVkKHNlbGYpOgoJCXByaW50KCduZXN0ZWQgc2VsZicsIHNlbGYuYmFsYW5jZSkKCQlwcmludCgnbmVzdGVkIEF0KHNlbGYpJywgRXRoQ29udHJhY3QoZ2wubWVzc2FnZS5jb250cmFjdF9hZGRyZXNzKS5iYWxhbmNlKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgzZMAwAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpAZ2wuZXZtLmNvbnRyYWN0X2ludGVyZmFjZQpjbGFzcyBFdGhDb250cmFjdDoKCWNsYXNzIFZpZXc6CgkJcGFzcwoKCWNsYXNzIFdyaXRlOgoJCXBhc3MKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCXByaW50KCdtYWluIHNlbGYnLCBzZWxmLmJhbGFuY2UpCgkJcHJpbnQoJ21haW4gQXQoc2VsZiknLCBFdGhDb250cmFjdChnbC5tZXNzYWdlLmNvbnRyYWN0X2FkZHJlc3MpLmJhbGFuY2UpCgkJcHJpbnQoJz09PSB0cmFuc2ZlciA9PT0nKQoKCQlFdGhDb250cmFjdChnbC5tZXNzYWdlLnNlbmRlcl9hZGRyZXNzKS5lbWl0X3RyYW5zZmVyKHZhbHVlPTUpCgkJcHJpbnQoJ21haW4gc2VsZicsIHNlbGYuYmFsYW5jZSkKCQlwcmludCgnbWFpbiBBdChzZWxmKScsIEV0aENvbnRyYWN0KGdsLm1lc3NhZ2UuY29udHJhY3RfYWRkcmVzcykuYmFsYW5jZSkKCgkJcHJpbnQoJz09PSBjYWxsIC52aWV3KCkgPT09JykKCQlnbC5jb250cmFjdC5nZXRfYXQoZ2wubWVzc2FnZS5jb250cmFjdF9hZGRyZXNzKS52aWV3KCkubmVzdGVkKCkKCglAZ2wucHVibGljLnZpZXcKCWRlZiBuZXN0ZWQoc2VsZik6CgkJcHJpbnQoJ25lc3RlZCBzZWxmJywgc2VsZi5iYWxhbmNlKQoJCXByaW50KCduZXN0ZWQgQXQoc2VsZiknLCBFdGhDb250cmFjdChnbC5tZXNzYWdlLmNvbnRyYWN0X2FkZHJlc3MpLmJhbGFuY2UpCgAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/balances/balance_eth.0.stdout b/tests/cases/stable/py/balances/balance_eth.0.stdout index 6b3dd3ddd..7d73027c8 100644 --- a/tests/cases/stable/py/balances/balance_eth.0.stdout +++ b/tests/cases/stable/py/balances/balance_eth.0.stdout @@ -1,10 +1 @@ -main self 10 -main At(self) 10 -=== transfer === -main self 5 -main At(self) 10 -=== call .view() === -nested self 10 -nested At(self) 10 executed with `Return(null)` -{"address":addr#0200000000000000000000000000000000000000,"calldata":b#,"fee_params":{"gas_limit":1606938044258990275541962092341162602522202993782792835301376,"max_gas_price":0},"message_fee":0,"receipt_fee":129,"type":"EthSend","value":5} diff --git a/tests/cases/stable/py/balances/balance_eth.0_0.hash b/tests/cases/stable/py/balances/balance_eth.0_0.hash new file mode 100644 index 000000000..9942c2585 --- /dev/null +++ b/tests/cases/stable/py/balances/balance_eth.0_0.hash @@ -0,0 +1 @@ +LQEAAAUF diff --git a/tests/cases/stable/py/balances/balance_eth.0_0.stdout b/tests/cases/stable/py/balances/balance_eth.0_0.stdout new file mode 100644 index 000000000..6b3dd3ddd --- /dev/null +++ b/tests/cases/stable/py/balances/balance_eth.0_0.stdout @@ -0,0 +1,10 @@ +main self 10 +main At(self) 10 +=== transfer === +main self 5 +main At(self) 10 +=== call .view() === +nested self 10 +nested At(self) 10 +executed with `Return(null)` +{"address":addr#0200000000000000000000000000000000000000,"calldata":b#,"fee_params":{"gas_limit":1606938044258990275541962092341162602522202993782792835301376,"max_gas_price":0},"message_fee":0,"receipt_fee":129,"type":"EthSend","value":5} diff --git a/tests/cases/stable/py/balances/balance_eth.jsonnet b/tests/cases/stable/py/balances/balance_eth.jsonnet index 78bab86a7..aa06f369c 100644 --- a/tests/cases/stable/py/balances/balance_eth.jsonnet +++ b/tests/cases/stable/py/balances/balance_eth.jsonnet @@ -1,7 +1,9 @@ -local simple_deploy = import 'templates/simple_deploy.jsonnet'; +local deploy_then = import 'templates/simple_deploy_then_write.jsonnet'; local util = import 'templates/util.jsonnet'; -{entry: util.addPaths([simple_deploy.run('${jsonnetDir}/balance_eth.py') { +local bal = { "balances": { "AQAAAAAAAAAAAAAAAAAAAAAAAAA=": 10, }, -}])} +}; +local base = deploy_then.run('${jsonnetDir}/balance_eth.py', 'main'); +{entry: util.addPaths([base + bal + {next: [base.next[0] + bal]}])} diff --git a/tests/cases/stable/py/balances/balance_eth.py b/tests/cases/stable/py/balances/balance_eth.py index e7803e6b0..f158ff104 100644 --- a/tests/cases/stable/py/balances/balance_eth.py +++ b/tests/cases/stable/py/balances/balance_eth.py @@ -14,6 +14,10 @@ class Write: class Contract(gl.contract.Contract): def __init__(self): + pass + + @gl.public.write + def main(self): print('main self', self.balance) print('main At(self)', EthContract(gl.message.contract_address).balance) print('=== transfer ===') diff --git a/tests/cases/stable/py/balances/sandbox_overspend.0.hash b/tests/cases/stable/py/balances/sandbox_overspend.0.hash index ce84d0351..0f28b0285 100644 --- a/tests/cases/stable/py/balances/sandbox_overspend.0.hash +++ b/tests/cases/stable/py/balances/sandbox_overspend.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDRDwEAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJYmFsYW5jZV9iZWZvcmUgPSBzZWxmLmJhbGFuY2UKCQl0YXJnZXQgPSBnbC5tZXNzYWdlLnNlbmRlcl9hZGRyZXNzCgoJCSMgRmlyc3QgdHJhbnNmZXI6IHNwZW5kIDYwIG91dCBvZiAxMDAKCQlnbC5jb250cmFjdC5nZXRfYXQodGFyZ2V0KS5lbWl0X3RyYW5zZmVyKHZhbHVlPTYwKQoJCWJhbGFuY2VfYWZ0ZXJfZmlyc3QgPSBzZWxmLmJhbGFuY2UKCQlwcmludChmJ2JhbGFuY2UgYmVmb3JlPXtiYWxhbmNlX2JlZm9yZX0gYWZ0ZXJfZmlyc3Rfc2VuZD17YmFsYW5jZV9hZnRlcl9maXJzdH0nKQoKCQkjIE5vdyBzcGF3biBhIHNhbmRib3ggd2l0aCB3cml0ZSBvcHMgYWxsb3dlZC4KCQkjIEJVRzogdGhlIHNhbmRib3ggZ2V0cyBhIGZyZXNoIG1lc3NhZ2VzX2RlY3JlbWVudGVkPTAsCgkJIyBzbyBpdCB0aGlua3MgdGhlIGZ1bGwgYmFsYW5jZSBpcyBzdGlsbCBhdmFpbGFibGUuCgkJZGVmIHNhbmRib3hfZm4oKToKCQkJIyBTZWNvbmQgdHJhbnNmZXI6IHNwZW5kIGFub3RoZXIgNjAgaW5zaWRlIHNhbmRib3gKCQkJIyBUaGlzIHNob3VsZCBmYWlsICh0b3RhbCAxMjAgPiAxMDApIGJ1dCB0aGUgc2FuZGJveAoJCQkjIGRvZXNuJ3Qga25vdyBhYm91dCB0aGUgcGFyZW50J3MgNjAgYWxyZWFkeSBzcGVudC4KCQkJZ2wuY29udHJhY3QuZ2V0X2F0KHRhcmdldCkuZW1pdF90cmFuc2Zlcih2YWx1ZT02MCkKCQkJcmV0dXJuIHNlbGYuYmFsYW5jZQoKCQlyZXN1bHQgPSBnbC52bS5zcGF3bl9zYW5kYm94KHNhbmRib3hfZm4sIGFsbG93X3dyaXRlX29wcz1UcnVlKQoJCXByaW50KGYnc2FuZGJveCByZXN1bHQ9e3Jlc3VsdH0nKQoJCXByaW50KGYnYmFsYW5jZSBmaW5hbD17c2VsZi5iYWxhbmNlfScpCgkJIyBJZiB3ZSByZWFjaCBoZXJlIHdpdGggYm90aCB0cmFuc2ZlcnMgYWNjZXB0ZWQsCgkJIyB0b3RhbCBzcGVudCBpcyAxMjAgYnV0IGJhbGFuY2Ugd2FzIG9ubHkgMTAwID0+IG92ZXJzcGVuZCBidWcKBQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAg0ZGBAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCWJhbGFuY2VfYmVmb3JlID0gc2VsZi5iYWxhbmNlCgkJdGFyZ2V0ID0gZ2wubWVzc2FnZS5zZW5kZXJfYWRkcmVzcwoKCQkjIEZpcnN0IHRyYW5zZmVyOiBzcGVuZCA2MCBvdXQgb2YgMTAwCgkJZ2wuY29udHJhY3QuZ2V0X2F0KHRhcmdldCkuZW1pdF90cmFuc2Zlcih2YWx1ZT02MCkKCQliYWxhbmNlX2FmdGVyX2ZpcnN0ID0gc2VsZi5iYWxhbmNlCgkJcHJpbnQoZidiYWxhbmNlIGJlZm9yZT17YmFsYW5jZV9iZWZvcmV9IGFmdGVyX2ZpcnN0X3NlbmQ9e2JhbGFuY2VfYWZ0ZXJfZmlyc3R9JykKCgkJIyBOb3cgc3Bhd24gYSBzYW5kYm94IHdpdGggbWVzc2FnZSBzZW5kaW5nIGFsbG93ZWQuCgkJIyBCVUc6IHRoZSBzYW5kYm94IGdldHMgYSBmcmVzaCBtZXNzYWdlc19kZWNyZW1lbnRlZD0wLAoJCSMgc28gaXQgdGhpbmtzIHRoZSBmdWxsIGJhbGFuY2UgaXMgc3RpbGwgYXZhaWxhYmxlLgoJCWRlZiBzYW5kYm94X2ZuKCk6CgkJCSMgU2Vjb25kIHRyYW5zZmVyOiBzcGVuZCBhbm90aGVyIDYwIGluc2lkZSBzYW5kYm94CgkJCSMgVGhpcyBzaG91bGQgZmFpbCAodG90YWwgMTIwID4gMTAwKSBidXQgdGhlIHNhbmRib3gKCQkJIyBkb2Vzbid0IGtub3cgYWJvdXQgdGhlIHBhcmVudCdzIDYwIGFscmVhZHkgc3BlbnQuCgkJCWdsLmNvbnRyYWN0LmdldF9hdCh0YXJnZXQpLmVtaXRfdHJhbnNmZXIodmFsdWU9NjApCgkJCXJldHVybiBzZWxmLmJhbGFuY2UKCgkJcmVzdWx0ID0gZ2wudm0uc3Bhd25fc2FuZGJveChzYW5kYm94X2ZuLCBhbGxvd19zZW5kX21lc3NhZ2VzPVRydWUpCgkJcHJpbnQoZidzYW5kYm94IHJlc3VsdD17cmVzdWx0fScpCgkJcHJpbnQoZidiYWxhbmNlIGZpbmFsPXtzZWxmLmJhbGFuY2V9JykKCQkjIElmIHdlIHJlYWNoIGhlcmUgd2l0aCBib3RoIHRyYW5zZmVycyBhY2NlcHRlZCwKCQkjIHRvdGFsIHNwZW50IGlzIDEyMCBidXQgYmFsYW5jZSB3YXMgb25seSAxMDAgPT4gb3ZlcnNwZW5kIGJ1ZwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/py/balances/sandbox_overspend.py b/tests/cases/stable/py/balances/sandbox_overspend.py index fbbf1d5f9..89dd460c7 100644 --- a/tests/cases/stable/py/balances/sandbox_overspend.py +++ b/tests/cases/stable/py/balances/sandbox_overspend.py @@ -12,7 +12,7 @@ def __init__(self): balance_after_first = self.balance print(f'balance before={balance_before} after_first_send={balance_after_first}') - # Now spawn a sandbox with write ops allowed. + # Now spawn a sandbox with message sending allowed. # BUG: the sandbox gets a fresh messages_decremented=0, # so it thinks the full balance is still available. def sandbox_fn(): @@ -22,7 +22,7 @@ def sandbox_fn(): gl.contract.get_at(target).emit_transfer(value=60) return self.balance - result = gl.vm.spawn_sandbox(sandbox_fn, allow_write_ops=True) + result = gl.vm.spawn_sandbox(sandbox_fn, allow_send_messages=True) print(f'sandbox result={result}') print(f'balance final={self.balance}') # If we reach here with both transfers accepted, diff --git a/tests/cases/stable/py/balances/sandbox_overspend_2.0.hash b/tests/cases/stable/py/balances/sandbox_overspend_2.0.hash index edd053d92..2e5e6c0c0 100644 --- a/tests/cases/stable/py/balances/sandbox_overspend_2.0.hash +++ b/tests/cases/stable/py/balances/sandbox_overspend_2.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/balances/sandbox_overspend_2.py b/tests/cases/stable/py/balances/sandbox_overspend_2.py index eaffe1504..620bf90c8 100644 --- a/tests/cases/stable/py/balances/sandbox_overspend_2.py +++ b/tests/cases/stable/py/balances/sandbox_overspend_2.py @@ -12,7 +12,7 @@ def sandbox_fn(): gl.contract.get_at(target).emit_transfer(value=60) return self.balance - result = gl.vm.spawn_sandbox(sandbox_fn, allow_write_ops=True) + result = gl.vm.spawn_sandbox(sandbox_fn, allow_send_messages=True) print(f'sandbox result={result} balance after sandbox={self.balance}') try: diff --git a/tests/cases/stable/py/balances/undefined_all.0.hash b/tests/cases/stable/py/balances/undefined_all.0.hash index 4a02bbffb..3bb985429 100644 --- a/tests/cases/stable/py/balances/undefined_all.0.hash +++ b/tests/cases/stable/py/balances/undefined_all.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDCoYAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglwYXNzCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwqGAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJcGFzcwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/py/balances/undefined_method.0.hash b/tests/cases/stable/py/balances/undefined_method.0.hash index 970b748ad..75017cc70 100644 --- a/tests/cases/stable/py/balances/undefined_method.0.hash +++ b/tests/cases/stable/py/balances/undefined_method.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/balances/undefined_method_payable.0.hash b/tests/cases/stable/py/balances/undefined_method_payable.0.hash index 96e6d0fe2..3b359332c 100644 --- a/tests/cases/stable/py/balances/undefined_method_payable.0.hash +++ b/tests/cases/stable/py/balances/undefined_method_payable.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/balances/undefined_receive.0.hash b/tests/cases/stable/py/balances/undefined_receive.0.hash index 1cb8d365e..bbbc02089 100644 --- a/tests/cases/stable/py/balances/undefined_receive.0.hash +++ b/tests/cases/stable/py/balances/undefined_receive.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/embeddings/simple.0.hash b/tests/cases/stable/py/embeddings/simple.0.hash index 13b47280e..5a30c2aa2 100644 --- a/tests/cases/stable/py/embeddings/simple.0.hash +++ b/tests/cases/stable/py/embeddings/simple.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/embeddings/simple_det.0.hash b/tests/cases/stable/py/embeddings/simple_det.0.hash index 13b47280e..5a30c2aa2 100644 --- a/tests/cases/stable/py/embeddings/simple_det.0.hash +++ b/tests/cases/stable/py/embeddings/simple_det.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/embeddings/simple_tokenizer.0.hash b/tests/cases/stable/py/embeddings/simple_tokenizer.0.hash index 49aa02f77..b5e0443c9 100644 --- a/tests/cases/stable/py/embeddings/simple_tokenizer.0.hash +++ b/tests/cases/stable/py/embeddings/simple_tokenizer.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/embeddings/vecdb.0.hash b/tests/cases/stable/py/embeddings/vecdb.0.hash index 017d30de7..605dae57a 100644 --- a/tests/cases/stable/py/embeddings/vecdb.0.hash +++ b/tests/cases/stable/py/embeddings/vecdb.0.hash @@ -1 +1 @@ -LQEAAEUVowIJ6r6p+bC2UceCnPii5HtX+KqB1OxkZieLE2tqmVBnWgAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIaGMO10IwC6z0HwSX6yVN8UD18cm5phpL4avb+rqUUYAAAAAgwIDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAjctRsOtqfiXx000m7/g5FDHmBZ8n1gPja+F3vV+lsPqAAAAAIMGAQAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAM3MzMzMzPQ/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCnN2bFjS8G1cgPa1WBpyjyG4x+crK62Vpe7OE6Vik+oAAAAAAgwIAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAAAAABWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjArtHW19KeR3j/qGkKz3kHNgU+bllSDToaqVyrtJw9Q7jAAAAAIMCMTIzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK/3qmf3S8yrjpIVx1Q6ejcB/QQx6foIUwOn3NSI01TlgAAAACDAgAAgD8AAABAAABAQAAAgEAAAKBAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgyD5AQAAIyB7CiMgICAiU2VxIjogWwojICAgICB7ICJEZXBlbmRzIjogInB5LWxpYi1nZW5sYXllci1lbWJlZGRpbmdzOnRlc3QiIH0sCiMgICAgIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQojICAgXQojIH0KCgppbXBvcnQgbnVtcHkgYXMgbnAKaW1wb3J0IHR5cGluZwppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgppbXBvcnQgZ2VubGF5ZXJfZW1iZWRkaW5ncyBhcyBnbGUKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6Cgl4OiBnbGUuVmVjREJbbnAuZmxvYXQzMiwgdHlwaW5nLkxpdGVyYWxbNV0sIHN0ciwgZ2xlLkV1Y2xpZGVhbkRpc3RhbmNlXQoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlzZWxmLnguaW5zZXJ0KG5wLmFycmF5KFsxLCAyLCAzLCA0LCA1XSwgZHR5cGU9bnAuZmxvYXQzMiksICcxMjMnKQoJCXByaW50KGxpc3Qoc2VsZi54LmtubihucC5vbmVzKDUsIGR0eXBlPW5wLmZsb2F0MzIpLCAxKSkpCgAAAAU= +LQEAAE0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCRguJG4z2Zcn50QmRH3rALC+mIPXPtdaG+blrLD/wTyQAAAAAgwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAkarTtJntGExRjClCClTeapPszpBSCLunXLw6y4spm7AAAAAAIMCAACAPwAAAEAAAEBAAACAQAAAoEAAAAAAAAAAAAAAAAAVowKADV6GQrOtRCKTv5ViYIZpoqvlnFVGfEwBMkHDV50C2gAAAACDAgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCqm3G4qVvBmYbgUYDTC0yiG8/FEaDXEQFZ3n0cCg1s7cAAAAAgwIAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAAAAABWjAq744hjkeWut5b9uW2fTvO39XzVEOvLEnDYFB22lgxghAAAAAIMCMTIzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDIPkBAAAjIHsKIyAgICJTZXEiOiBbCiMgICAgIHsgIkRlcGVuZHMiOiAicHktbGliLWdlbmxheWVyLWVtYmVkZGluZ3M6dGVzdCIgfSwKIyAgICAgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CiMgICBdCiMgfQoKCmltcG9ydCBudW1weSBhcyBucAppbXBvcnQgdHlwaW5nCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmltcG9ydCBnZW5sYXllcl9lbWJlZGRpbmdzIGFzIGdsZQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCXg6IGdsZS5WZWNEQltucC5mbG9hdDMyLCB0eXBpbmcuTGl0ZXJhbFs1XSwgc3RyLCBnbGUuRXVjbGlkZWFuRGlzdGFuY2VdCgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXNlbGYueC5pbnNlcnQobnAuYXJyYXkoWzEsIDIsIDMsIDQsIDVdLCBkdHlwZT1ucC5mbG9hdDMyKSwgJzEyMycpCgkJcHJpbnQobGlzdChzZWxmLngua25uKG5wLm9uZXMoNSwgZHR5cGU9bnAuZmxvYXQzMiksIDEpKSkKAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgwYBAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAzczMzMzM9D8AAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/events/post_event.0.hash b/tests/cases/stable/py/events/post_event.0.hash index 79446bf6b..428d18171 100644 --- a/tests/cases/stable/py/events/post_event.0.hash +++ b/tests/cases/stable/py/events/post_event.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDJlACAAAjIHYwLjEuNQojIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIFRlc3RFdmVudChnbC5jaGFpbi5FdmVudCk6CglkZWYgX19pbml0X18oc2VsZiwgdXNlcl9pZDogaW50LCBhY3Rpb246IHN0ciwgLywgKipibG9iKTogLi4uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXRyeToKCQkJIyBUZXN0IGJhc2ljIGV2ZW50IGVtaXNzaW9uCgkJCVRlc3RFdmVudCg0MiwgJ2NyZWF0ZScsIHRpbWVzdGFtcD0xMjM0NTY3ODkwLCBkYXRhPSd0ZXN0X2RhdGEnKS5lbWl0KCkKCgkJCSMgVGVzdCBldmVudCB3aXRoIGRpZmZlcmVudCBwYXJhbWV0ZXJzCgkJCVRlc3RFdmVudCgxMDAsICd1cGRhdGUnLCBhbW91bnQ9NTAwLCBkZXNjcmlwdGlvbj0nVXBkYXRlZCByZWNvcmQnKS5lbWl0KCkKCgkJCXByaW50KCdFdmVudHMgZW1pdHRlZCBzdWNjZXNzZnVsbHknKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcHJpbnQoZidFcnJvciBlbWl0dGluZyBldmVudDoge2V9JykKAAAAAAAAAAAAAAAAFSWDArR1HfVl/DVUdk4nkJQ5YMnN/nz1EDMdspiBvxUjtA2sgwLRAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCNGNyZWF0ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7AyYGYWN0aW9u0QIEZGF0YUx0ZXN0X2RhdGEJdGltZXN0YW1wka3A5SQHdXNlcl9pZDRjcmVhdGUlgwK0dR31Zfw1VHZOJ5CUOWDJzf589RAzHbKYgb8VI7QNrIMCoQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAjR1cGRhdGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6wMmBmFjdGlvbqEGBmFtb3VudKEfC2Rlc2NyaXB0aW9udFVwZGF0ZWQgcmVjb3JkB3VzZXJfaWQ0dXBkYXRl +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyZQAgAAIyB2MC4xLjUKIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBUZXN0RXZlbnQoZ2wuY2hhaW4uRXZlbnQpOgoJZGVmIF9faW5pdF9fKHNlbGYsIHVzZXJfaWQ6IGludCwgYWN0aW9uOiBzdHIsIC8sICoqYmxvYik6IC4uLgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQl0cnk6CgkJCSMgVGVzdCBiYXNpYyBldmVudCBlbWlzc2lvbgoJCQlUZXN0RXZlbnQoNDIsICdjcmVhdGUnLCB0aW1lc3RhbXA9MTIzNDU2Nzg5MCwgZGF0YT0ndGVzdF9kYXRhJykuZW1pdCgpCgoJCQkjIFRlc3QgZXZlbnQgd2l0aCBkaWZmZXJlbnQgcGFyYW1ldGVycwoJCQlUZXN0RXZlbnQoMTAwLCAndXBkYXRlJywgYW1vdW50PTUwMCwgZGVzY3JpcHRpb249J1VwZGF0ZWQgcmVjb3JkJykuZW1pdCgpCgoJCQlwcmludCgnRXZlbnRzIGVtaXR0ZWQgc3VjY2Vzc2Z1bGx5JykKCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCXByaW50KGYnRXJyb3IgZW1pdHRpbmcgZXZlbnQ6IHtlfScpCgAAAAAAAAAAAAAAABUlgwK0dR31Zfw1VHZOJ5CUOWDJzf589RAzHbKYgb8VI7QNrIMC0QIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAjRjcmVhdGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuwMmBmFjdGlvbtECBGRhdGFMdGVzdF9kYXRhCXRpbWVzdGFtcJGtwOUkB3VzZXJfaWQ0Y3JlYXRlJYMCtHUd9WX8NVR2TieQlDlgyc3+fPUQMx2ymIG/FSO0DayDAqEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwI0dXBkYXRlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOsDJgZhY3Rpb26hBgZhbW91bnShHwtkZXNjcmlwdGlvbnRVcGRhdGVkIHJlY29yZAd1c2VyX2lkNHVwZGF0ZQ== diff --git a/tests/cases/stable/py/intercontract/call_self_view.0.hash b/tests/cases/stable/py/intercontract/call_self_view.0.hash new file mode 100644 index 000000000..55e672fe9 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_self_view.0.hash @@ -0,0 +1 @@ +LRG0AmludmFsaWRfY29udHJhY3QgYWJzZW50X3J1bm5lcl9jb21tZW50AB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyDoAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJIyBzZWxmLUNhbGxDb250cmFjdCBpbnRvIG91ciBvd24gdmlldyBtZXRob2QgZHVyaW5nIGRlcGxveTogb3VyIGNvZGUgaXMKCQkjIG5vdCBjb21taXR0ZWQgb24tY2hhaW4geWV0LCBzbyBpdCBpcyBub3QgdmlzaWJsZSBhcyBhbiBgOmFgIHJ1bm5lciBhbmQKCQkjIHRoaXMgZmFpbHMgd2l0aCBgaW52YWxpZF9jb250cmFjdGAgKGFib3J0aW5nIHRoZSBkZXBsb3kpCgkJcHJpbnQoJ3NlbGYgdmlldyAtPicsIGdsLmNvbnRyYWN0LmdldF9hdChzZWxmLmFkZHJlc3MpLnZpZXcoKS5yZWFkMzAoKSkKCglAZ2wucHVibGljLnZpZXcKCWRlZiByZWFkMzAoc2VsZikgLT4gaW50OgoJCXJldHVybiAzMAoAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/call_self_view.0.stdout b/tests/cases/stable/py/intercontract/call_self_view.0.stdout new file mode 100644 index 000000000..82f34ded9 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_self_view.0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract absent_runner_comment")` diff --git a/tests/cases/stable/py/intercontract/call_self_view.jsonnet b/tests/cases/stable/py/intercontract/call_self_view.jsonnet new file mode 100644 index 000000000..0e1c4ba55 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_self_view.jsonnet @@ -0,0 +1,3 @@ +local simple_deploy = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple_deploy.run('${jsonnetDir}/${fileBaseName}.py')])} diff --git a/tests/cases/stable/py/intercontract/call_self_view.py b/tests/cases/stable/py/intercontract/call_self_view.py new file mode 100644 index 000000000..78ce8339c --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_self_view.py @@ -0,0 +1,15 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.types import * + + +class Contract(gl.contract.Contract): + def __init__(self): + # self-CallContract into our own view method during deploy: our code is + # not committed on-chain yet, so it is not visible as an `:a` runner and + # this fails with `invalid_contract` (aborting the deploy) + print('self view ->', gl.contract.get_at(self.address).view().read30()) + + @gl.public.view + def read30(self) -> int: + return 30 diff --git a/tests/cases/stable/py/intercontract/call_view.0.hash b/tests/cases/stable/py/intercontract/call_view.0.hash index f296230d4..59d2c3dc0 100644 --- a/tests/cases/stable/py/intercontract/call_view.0.hash +++ b/tests/cases/stable/py/intercontract/call_view.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEhcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy52aWV3CglkZWYgZm9vKHNlbGYsIGEsIGIpOgoJCXByaW50KCdjb250cmFjdCB0by5mb28nKQoJCWltcG9ydCBqc29uCgoJCWpzb24ubG9hZHMgPSAxMSAgIyBldmlsIQoJCXJldHVybiBhICsgYgoAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIXAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMudmlldwoJZGVmIGZvbyhzZWxmLCBhLCBiKToKCQlwcmludCgnY29udHJhY3QgdG8uZm9vJykKCQlpbXBvcnQganNvbgoKCQlqc29uLmxvYWRzID0gMTEgICMgZXZpbCEKCQlyZXR1cm4gYSArIGIKAAAAAAAF diff --git a/tests/cases/stable/py/intercontract/call_view.0_0.hash b/tests/cases/stable/py/intercontract/call_view.0_0.hash index 26d73dafe..bde386ddf 100644 --- a/tests/cases/stable/py/intercontract/call_view.0_0.hash +++ b/tests/cases/stable/py/intercontract/call_view.0_0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFB8BAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgYWRkcjogQWRkcmVzcyk6CgkJcHJpbnQoJ2NvbnRyYWN0IGZyb20ubWFpbicpCgkJcHJpbnQoZ2wuY29udHJhY3QuZ2V0X2F0KGFkZHIpLnZpZXcoKS5mb28oMSwgMikpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQfAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGFkZHI6IEFkZHJlc3MpOgoJCXByaW50KCdjb250cmFjdCBmcm9tLm1haW4nKQoJCXByaW50KGdsLmNvbnRyYWN0LmdldF9hdChhZGRyKS52aWV3KCkuZm9vKDEsIDIpKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/call_view_committed.0.hash b/tests/cases/stable/py/intercontract/call_view_committed.0.hash new file mode 100644 index 000000000..10bf43021 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_committed.0.hash @@ -0,0 +1 @@ +LQEAACUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgzqOAwAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6Cgl4OiB1MzIKCXdyaXRlX2Fuc3dlcjogZ2wuRHluQXJyYXlbdTMyXQoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlzZWxmLnggPSAxCgoJQGdsLnB1YmxpYy52aWV3CglkZWYgZG9fcmVhZChzZWxmKSAtPiB1MzI6CgkJcmV0dXJuIHNlbGYueAoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBkb190ZXN0KHNlbGYpOgoJCSMgQSBkaXJlY3QgcmVhZCBzZWVzIHRoZSBpbi10cmFuc2FjdGlvbiBkZWx0YTsgYSBDYWxsQ29udHJhY3QgKHZpZXcpIHJlYWRzCgkJIyBjb21taXR0ZWQgb24tY2hhaW4gc3RhdGUgYW5kIGRvZXMgTk9UIHNlZSB0aGUgdW5jb21taXR0ZWQgd3JpdGUgYmVsb3cuCgkJc2VsZi53cml0ZV9hbnN3ZXIuYXBwZW5kKHNlbGYuZG9fcmVhZCgpKSAgIyAxCgkJc2VsZi53cml0ZV9hbnN3ZXIuYXBwZW5kKAoJCQlnbC5jb250cmFjdC5nZXRfYXQoc2VsZi5hZGRyZXNzKS52aWV3KCkuZG9fcmVhZCgpCgkJKSAgIyAxIChjb21taXR0ZWQpCgkJc2VsZi53cml0ZV9hbnN3ZXIuYXBwZW5kKHNlbGYuZG9fcmVhZCgpKSAgIyAxCgoJCXNlbGYueCA9IDMwCgoJCXNlbGYud3JpdGVfYW5zd2VyLmFwcGVuZChzZWxmLmRvX3JlYWQoKSkgICMgMzAgKGRlbHRhKQoJCXNlbGYud3JpdGVfYW5zd2VyLmFwcGVuZCgKCQkJZ2wuY29udHJhY3QuZ2V0X2F0KHNlbGYuYWRkcmVzcykudmlldygpLmRvX3JlYWQoKQoJCSkgICMgMSAoY29tbWl0dGVkKQoJCXNlbGYud3JpdGVfYW5zd2VyLmFwcGVuZChzZWxmLmRvX3JlYWQoKSkgICMgMzAKCgkJcHJpbnQobGlzdChzZWxmLndyaXRlX2Fuc3dlcikpCgAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgwIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/call_view_committed.0.stdout b/tests/cases/stable/py/intercontract/call_view_committed.0.stdout new file mode 100644 index 000000000..7d73027c8 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_committed.0.stdout @@ -0,0 +1 @@ +executed with `Return(null)` diff --git a/tests/cases/stable/py/intercontract/call_view_committed.0_0.hash b/tests/cases/stable/py/intercontract/call_view_committed.0_0.hash new file mode 100644 index 000000000..1f52e4217 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_committed.0_0.hash @@ -0,0 +1 @@ +LQEAABUVowKADV6GQrOtRCKTv5ViYIZpoqvlnFVGfEwBMkHDV50C2gAAAACDAgEAAAABAAAAAQAAAB4AAAABAAAAHgAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgwIeAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/call_view_committed.0_0.stdout b/tests/cases/stable/py/intercontract/call_view_committed.0_0.stdout new file mode 100644 index 000000000..c56221105 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_committed.0_0.stdout @@ -0,0 +1,2 @@ +[1, 1, 1, 30, 1, 30] +executed with `Return(null)` diff --git a/tests/cases/stable/py/intercontract/call_view_committed.jsonnet b/tests/cases/stable/py/intercontract/call_view_committed.jsonnet new file mode 100644 index 000000000..250bafa08 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_committed.jsonnet @@ -0,0 +1,3 @@ +local simple_deploy_then_write = import 'templates/simple_deploy_then_write.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple_deploy_then_write.run('${jsonnetDir}/${fileBaseName}.py', 'do_test')])} diff --git a/tests/cases/stable/py/intercontract/call_view_committed.py b/tests/cases/stable/py/intercontract/call_view_committed.py new file mode 100644 index 000000000..e7f2b2f98 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_committed.py @@ -0,0 +1,35 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.types import * + + +class Contract(gl.contract.Contract): + x: u32 + write_answer: gl.DynArray[u32] + + def __init__(self): + self.x = 1 + + @gl.public.view + def do_read(self) -> u32: + return self.x + + @gl.public.write + def do_test(self): + # A direct read sees the in-transaction delta; a CallContract (view) reads + # committed on-chain state and does NOT see the uncommitted write below. + self.write_answer.append(self.do_read()) # 1 + self.write_answer.append( + gl.contract.get_at(self.address).view().do_read() + ) # 1 (committed) + self.write_answer.append(self.do_read()) # 1 + + self.x = 30 + + self.write_answer.append(self.do_read()) # 30 (delta) + self.write_answer.append( + gl.contract.get_at(self.address).view().do_read() + ) # 1 (committed) + self.write_answer.append(self.do_read()) # 30 + + print(list(self.write_answer)) diff --git a/tests/cases/stable/py/intercontract/call_view_emit.0.hash b/tests/cases/stable/py/intercontract/call_view_emit.0.hash new file mode 100644 index 000000000..e2e82ea6a --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit.0.hash @@ -0,0 +1 @@ +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyytAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBQaW5nZWQoZ2wuY2hhaW4uRXZlbnQpOgoJZGVmIF9faW5pdF9fKHNlbGYsIHdobzogc3RyLCAvLCAqKmJsb2IpOiAuLi4KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMudmlldwoJZGVmIHBpbmcoc2VsZikgLT4gc3RyOgoJCSMgaW5zaWRlIGEgQ2FsbENvbnRyYWN0IGNoaWxkIFZNIChyZWFkLW9ubHkgLyBzdGF0aWMgY2FsbCkKCQl0cnk6CgkJCVBpbmdlZCgnYicsIG5vdGU9J2VtaXR0ZWQgZHVyaW5nIENhbGxDb250cmFjdCcpLmVtaXQoKQoJCQlwcmludCgnQiBlbWl0OiBvaycpCgkJZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJCQlwcmludChmJ0IgZW1pdCBmb3JiaWRkZW46IHt0eXBlKGUpLl9fbmFtZV9ffScpCgkJdHJ5OgoJCQlnbC5jb250cmFjdC5nZXRfYXQoZ2wuQWRkcmVzcyhiJ1x4MzAnICogMjApKS5lbWl0KCkuZm9vKDEsIDIpCgkJCXByaW50KCdCIHNlbmQ6IG9rJykKCQlleGNlcHQgRXhjZXB0aW9uIGFzIGU6CgkJCXByaW50KGYnQiBzZW5kIGZvcmJpZGRlbjoge3R5cGUoZSkuX19uYW1lX199JykKCQlyZXR1cm4gJ3BvbmcnCgAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/call_view_emit.0.stdout b/tests/cases/stable/py/intercontract/call_view_emit.0.stdout new file mode 100644 index 000000000..7d73027c8 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit.0.stdout @@ -0,0 +1 @@ +executed with `Return(null)` diff --git a/tests/cases/stable/py/intercontract/call_view_emit.0_0.hash b/tests/cases/stable/py/intercontract/call_view_emit.0_0.hash new file mode 100644 index 000000000..d9522f231 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit.0_0.hash @@ -0,0 +1 @@ +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyDoAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGFkZHI6IEFkZHJlc3MpOgoJCSMgcmVhZC1vbmx5IENhbGxDb250cmFjdCBpbnRvIEI7IEIgdHJpZXMgdG8gZW1pdCBhbiBldmVudCBhbmQgc2VuZCBhCgkJIyBtZXNzYWdlIGluc2lkZSBpdC4gQm90aCBtdXN0IGZhaWwgYmVjYXVzZSB0aGUgY2hpbGQgaXMgYSBzdGF0aWMgY2FsbC4KCQl0cnk6CgkJCXByaW50KCdBIGdvdCcsIGdsLmNvbnRyYWN0LmdldF9hdChhZGRyKS52aWV3KCkucGluZygpKQoJCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQkJcHJpbnQoZidBIGNhbGwgZmFpbGVkOiB7dHlwZShlKS5fX25hbWVfX30nKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/call_view_emit.0_0.stdout b/tests/cases/stable/py/intercontract/call_view_emit.0_0.stdout new file mode 100644 index 000000000..7d73027c8 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit.0_0.stdout @@ -0,0 +1 @@ +executed with `Return(null)` diff --git a/tests/cases/stable/py/intercontract/call_view_emit.0_0_0.hash b/tests/cases/stable/py/intercontract/call_view_emit.0_0_0.hash new file mode 100644 index 000000000..9942c2585 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit.0_0_0.hash @@ -0,0 +1 @@ +LQEAAAUF diff --git a/tests/cases/stable/py/intercontract/call_view_emit.0_0_0.stdout b/tests/cases/stable/py/intercontract/call_view_emit.0_0_0.stdout new file mode 100644 index 000000000..f14bfc26c --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit.0_0_0.stdout @@ -0,0 +1,4 @@ +B emit forbidden: SystemError +B send forbidden: SystemError +A got pong +executed with `Return(null)` diff --git a/tests/cases/stable/py/intercontract/call_view_emit.jsonnet b/tests/cases/stable/py/intercontract/call_view_emit.jsonnet new file mode 100644 index 000000000..6415b1489 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit.jsonnet @@ -0,0 +1,10 @@ +local simple = import 'templates/two.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/call_view_emit_from.py', '${jsonnetDir}/call_view_emit_to.py', + ||| + { + "method": "main", + "args": [Address(toAddr)] + } + ||| +)])} diff --git a/tests/cases/stable/py/intercontract/call_view_emit_from.py b/tests/cases/stable/py/intercontract/call_view_emit_from.py new file mode 100644 index 000000000..aee1c07c1 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit_from.py @@ -0,0 +1,17 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.types import * + + +class Contract(gl.contract.Contract): + def __init__(self): + pass + + @gl.public.write + def main(self, addr: Address): + # read-only CallContract into B; B tries to emit an event and send a + # message inside it. Both must fail because the child is a static call. + try: + print('A got', gl.contract.get_at(addr).view().ping()) + except Exception as e: + print(f'A call failed: {type(e).__name__}') diff --git a/tests/cases/stable/py/intercontract/call_view_emit_to.py b/tests/cases/stable/py/intercontract/call_view_emit_to.py new file mode 100644 index 000000000..85bbfb545 --- /dev/null +++ b/tests/cases/stable/py/intercontract/call_view_emit_to.py @@ -0,0 +1,27 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.types import * + + +class Pinged(gl.chain.Event): + def __init__(self, who: str, /, **blob): ... + + +class Contract(gl.contract.Contract): + def __init__(self): + pass + + @gl.public.view + def ping(self) -> str: + # inside a CallContract child VM (read-only / static call) + try: + Pinged('b', note='emitted during CallContract').emit() + print('B emit: ok') + except Exception as e: + print(f'B emit forbidden: {type(e).__name__}') + try: + gl.contract.get_at(gl.Address(b'\x30' * 20)).emit().foo(1, 2) + print('B send: ok') + except Exception as e: + print(f'B send forbidden: {type(e).__name__}') + return 'pong' diff --git a/tests/cases/stable/py/intercontract/call_view_iface.0.hash b/tests/cases/stable/py/intercontract/call_view_iface.0.hash index f296230d4..59d2c3dc0 100644 --- a/tests/cases/stable/py/intercontract/call_view_iface.0.hash +++ b/tests/cases/stable/py/intercontract/call_view_iface.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEhcBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy52aWV3CglkZWYgZm9vKHNlbGYsIGEsIGIpOgoJCXByaW50KCdjb250cmFjdCB0by5mb28nKQoJCWltcG9ydCBqc29uCgoJCWpzb24ubG9hZHMgPSAxMSAgIyBldmlsIQoJCXJldHVybiBhICsgYgoAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIXAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMudmlldwoJZGVmIGZvbyhzZWxmLCBhLCBiKToKCQlwcmludCgnY29udHJhY3QgdG8uZm9vJykKCQlpbXBvcnQganNvbgoKCQlqc29uLmxvYWRzID0gMTEgICMgZXZpbCEKCQlyZXR1cm4gYSArIGIKAAAAAAAF diff --git a/tests/cases/stable/py/intercontract/call_view_iface.0_0.hash b/tests/cases/stable/py/intercontract/call_view_iface.0_0.hash index 3341507a4..5835cfec5 100644 --- a/tests/cases/stable/py/intercontract/call_view_iface.0_0.hash +++ b/tests/cases/stable/py/intercontract/call_view_iface.0_0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGF0BAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCkBnbC5jb250cmFjdC5pbnRlcmZhY2UKY2xhc3MgVG9JZmFjZToKCWNsYXNzIFZpZXc6CgkJZGVmIGZvbyhzZWxmLCBhLCBiKTogLi4uCgoJY2xhc3MgV3JpdGU6CgkJcGFzcwoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGFkZHI6IEFkZHJlc3MpOgoJCXByaW50KCdjb250cmFjdCBmcm9tLm1haW4nKQoJCXByaW50KFRvSWZhY2UoYWRkcikudmlldygpLmZvbygxLCAyKSkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxhdAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpAZ2wuY29udHJhY3QuaW50ZXJmYWNlCmNsYXNzIFRvSWZhY2U6CgljbGFzcyBWaWV3OgoJCWRlZiBmb28oc2VsZiwgYSwgYik6IC4uLgoKCWNsYXNzIFdyaXRlOgoJCXBhc3MKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBhZGRyOiBBZGRyZXNzKToKCQlwcmludCgnY29udHJhY3QgZnJvbS5tYWluJykKCQlwcmludChUb0lmYWNlKGFkZHIpLnZpZXcoKS5mb28oMSwgMikpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/intercontract/deploy.0.hash b/tests/cases/stable/py/intercontract/deploy.0.hash index bc7a431dc..e6d23347e 100644 --- a/tests/cases/stable/py/intercontract/deploy.0.hash +++ b/tests/cases/stable/py/intercontract/deploy.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDDtcAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlnbC5jb250cmFjdC5kZXBsb3koY29kZT0nbm90IHJlYWxseSBhIGNvbnRyYWN0Jy5lbmNvZGUoJ3V0Zi04JykpCgAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgw7XAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJZ2wuY29udHJhY3QuZGVwbG95KGNvZGU9J25vdCByZWFsbHkgYSBjb250cmFjdCcuZW5jb2RlKCd1dGYtOCcpKQoAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/deploy_salt.0.hash b/tests/cases/stable/py/intercontract/deploy_salt.0.hash index 53f462d44..b864725a5 100644 --- a/tests/cases/stable/py/intercontract/deploy_salt.0.hash +++ b/tests/cases/stable/py/intercontract/deploy_salt.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEPgAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlyZXMgPSBnbC5jb250cmFjdC5kZXBsb3koY29kZT0nbm90IHJlYWxseSBhIGNvbnRyYWN0Jy5lbmNvZGUoJ3V0Zi04JyksIHNhbHRfbm9uY2U9MSkKCQlwcmludChyZXMpCgAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxD4AAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcmVzID0gZ2wuY29udHJhY3QuZGVwbG95KGNvZGU9J25vdCByZWFsbHkgYSBjb250cmFjdCcuZW5jb2RlKCd1dGYtOCcpLCBzYWx0X25vbmNlPTEpCgkJcHJpbnQocmVzKQoAAAAABQ== diff --git a/tests/cases/stable/py/intercontract/eth_call_view.0.hash b/tests/cases/stable/py/intercontract/eth_call_view.0.hash index c0593583d..2f18c5b63 100644 --- a/tests/cases/stable/py/intercontract/eth_call_view.0.hash +++ b/tests/cases/stable/py/intercontract/eth_call_view.0.hash @@ -1 +1 @@ -LRF0aG9zdCBmb3JiaWRkZW4AFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMagAEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKQGdsLmV2bS5jb250cmFjdF9pbnRlcmZhY2UKY2xhc3MgR2hvc3Q6CgljbGFzcyBWaWV3OgoJCWRlZiB0ZXN0KHNlbGYsIHg6IHUyNTYsIC8pIC0+IHUyNTY6IC4uLgoKCWNsYXNzIFdyaXRlOgoJCXBhc3MKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJdHJ5OgoJCQlHaG9zdChBZGRyZXNzKGInXHgzMCcgKiAyMCkpLnZpZXcoKS50ZXN0KDEwKQoJCWV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGU6CgkJCXByaW50KGYnZXhwZWN0ZWQgZXJyb3I6IHtlfScpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LRF0aG9zdCBmb3JiaWRkZW4AHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDGoABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCkBnbC5ldm0uY29udHJhY3RfaW50ZXJmYWNlCmNsYXNzIEdob3N0OgoJY2xhc3MgVmlldzoKCQlkZWYgdGVzdChzZWxmLCB4OiB1MjU2LCAvKSAtPiB1MjU2OiAuLi4KCgljbGFzcyBXcml0ZToKCQlwYXNzCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXRyeToKCQkJR2hvc3QoQWRkcmVzcyhiJ1x4MzAnICogMjApKS52aWV3KCkudGVzdCgxMCkKCQlleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlOgoJCQlwcmludChmJ2V4cGVjdGVkIGVycm9yOiB7ZX0nKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/py/intercontract/send_message.0.hash b/tests/cases/stable/py/intercontract/send_message.0.hash index 75d332400..aeb7b5c19 100644 --- a/tests/cases/stable/py/intercontract/send_message.0.hash +++ b/tests/cases/stable/py/intercontract/send_message.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDDtQAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlnbC5jb250cmFjdC5nZXRfYXQoZ2wuQWRkcmVzcyhiJ1x4MzAnICogMjApKS5lbWl0KCkuZm9vKDEsIDIpCgAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgw7UAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJZ2wuY29udHJhY3QuZ2V0X2F0KGdsLkFkZHJlc3MoYidceDMwJyAqIDIwKSkuZW1pdCgpLmZvbygxLCAyKQoAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/intercontract/send_message_eth.0.hash b/tests/cases/stable/py/intercontract/send_message_eth.0.hash index 8264b037c..4e7cc57ab 100644 --- a/tests/cases/stable/py/intercontract/send_message_eth.0.hash +++ b/tests/cases/stable/py/intercontract/send_message_eth.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlgBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCkBnbC5ldm0uY29udHJhY3RfaW50ZXJmYWNlCmNsYXNzIEdob3N0OgoJY2xhc3MgVmlldzoKCQlwYXNzCgoJY2xhc3MgV3JpdGU6CgkJZGVmIHRlc3Qoc2VsZiwgeDogdTI1NiwgLykgLT4gTm9uZTogLi4uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXByaW50KHNlbGYuYmFsYW5jZSkKCQlHaG9zdChBZGRyZXNzKGInXHgzMCcgKiAyMCkpLmVtaXQodmFsdWU9MzApLnRlc3QoMTApCgAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZYAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpAZ2wuZXZtLmNvbnRyYWN0X2ludGVyZmFjZQpjbGFzcyBHaG9zdDoKCWNsYXNzIFZpZXc6CgkJcGFzcwoKCWNsYXNzIFdyaXRlOgoJCWRlZiB0ZXN0KHNlbGYsIHg6IHUyNTYsIC8pIC0+IE5vbmU6IC4uLgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludChzZWxmLmJhbGFuY2UpCgkJR2hvc3QoQWRkcmVzcyhiJ1x4MzAnICogMjApKS5lbWl0KHZhbHVlPTMwKS50ZXN0KDEwKQoAAAAABQ== diff --git a/tests/cases/stable/py/intercontract/send_message_on.0.hash b/tests/cases/stable/py/intercontract/send_message_on.0.hash index 7d93db8f9..6ef3c299a 100644 --- a/tests/cases/stable/py/intercontract/send_message_on.0.hash +++ b/tests/cases/stable/py/intercontract/send_message_on.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMUHwEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgb246IHN0cik6CgkJdHJ5OgoJCQlnbC5jb250cmFjdC5nZXRfYXQoZ2wuQWRkcmVzcyhiJ1x4MzAnICogMjApKS5lbWl0KG9uPW9uKS5mb28oMSwgMikKCQlleGNlcHQgU3lzdGVtRXJyb3IgYXMgZToKCQkJcHJpbnQoZSkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDFB8BAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIG9uOiBzdHIpOgoJCXRyeToKCQkJZ2wuY29udHJhY3QuZ2V0X2F0KGdsLkFkZHJlc3MoYidceDMwJyAqIDIwKSkuZW1pdChvbj1vbikuZm9vKDEsIDIpCgkJZXhjZXB0IFN5c3RlbUVycm9yIGFzIGU6CgkJCXByaW50KGUpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/py/other/meth/method_init.0.hash b/tests/cases/stable/py/other/meth/method_init.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/py/other/meth/method_init.0.hash +++ b/tests/cases/stable/py/other/meth/method_init.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/other/meth/method_init_wrong_name.0.hash b/tests/cases/stable/py/other/meth/method_init_wrong_name.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/py/other/meth/method_init_wrong_name.0.hash +++ b/tests/cases/stable/py/other/meth/method_init_wrong_name.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/other/meth/method_public.0.hash b/tests/cases/stable/py/other/meth/method_public.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/py/other/meth/method_public.0.hash +++ b/tests/cases/stable/py/other/meth/method_public.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/other/meth/method_retn.0.hash b/tests/cases/stable/py/other/meth/method_retn.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/py/other/meth/method_retn.0.hash +++ b/tests/cases/stable/py/other/meth/method_retn.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/other/meth/method_retn_view.0.hash b/tests/cases/stable/py/other/meth/method_retn_view.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/py/other/meth/method_retn_view.0.hash +++ b/tests/cases/stable/py/other/meth/method_retn_view.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/other/meth/method_rollback.0.hash b/tests/cases/stable/py/other/meth/method_rollback.0.hash index c843f0091..5a3f58162 100644 --- a/tests/cases/stable/py/other/meth/method_rollback.0.hash +++ b/tests/cases/stable/py/other/meth/method_rollback.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/other/ret/returns.0.hash b/tests/cases/stable/py/other/ret/returns.0.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.0.hash +++ b/tests/cases/stable/py/other/ret/returns.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.1.hash b/tests/cases/stable/py/other/ret/returns.1.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.1.hash +++ b/tests/cases/stable/py/other/ret/returns.1.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.2.hash b/tests/cases/stable/py/other/ret/returns.2.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.2.hash +++ b/tests/cases/stable/py/other/ret/returns.2.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.3.hash b/tests/cases/stable/py/other/ret/returns.3.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.3.hash +++ b/tests/cases/stable/py/other/ret/returns.3.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.4.hash b/tests/cases/stable/py/other/ret/returns.4.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.4.hash +++ b/tests/cases/stable/py/other/ret/returns.4.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.5.hash b/tests/cases/stable/py/other/ret/returns.5.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.5.hash +++ b/tests/cases/stable/py/other/ret/returns.5.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.6.hash b/tests/cases/stable/py/other/ret/returns.6.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.6.hash +++ b/tests/cases/stable/py/other/ret/returns.6.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.7.hash b/tests/cases/stable/py/other/ret/returns.7.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.7.hash +++ b/tests/cases/stable/py/other/ret/returns.7.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.8.hash b/tests/cases/stable/py/other/ret/returns.8.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.8.hash +++ b/tests/cases/stable/py/other/ret/returns.8.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/other/ret/returns.9.hash b/tests/cases/stable/py/other/ret/returns.9.hash index a87d01180..959e3697a 100644 --- a/tests/cases/stable/py/other/ret/returns.9.hash +++ b/tests/cases/stable/py/other/ret/returns.9.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGpIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGlkeDogaW50KToKCQlyZXQgPSBbCgkJCUFkZHJlc3MoYidceDAxJyAqIDIwKSwKCQkJJ2FiYycsCgkJCTEyMywKCQkJYid4eXonLAoJCQlUcnVlLAoJCQlOb25lLAoJCQlGYWxzZSwKCQkJW0FkZHJlc3MoYidceDAyJyAqIDIwKSwgQWRkcmVzcyhiJ1x4MDMnICogMjApXSwKCQkJeydhJzogMSwgJ2InOiBbMSwgMiwgM119LAoJCV0KCQlwcmludChmJ3tpZHh9IFswLi4ue2xlbihyZXQpfSknKQoJCXJldHVybiByZXRbaWR4XQoAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBpZHg6IGludCk6CgkJcmV0ID0gWwoJCQlBZGRyZXNzKGInXHgwMScgKiAyMCksCgkJCSdhYmMnLAoJCQkxMjMsCgkJCWIneHl6JywKCQkJVHJ1ZSwKCQkJTm9uZSwKCQkJRmFsc2UsCgkJCVtBZGRyZXNzKGInXHgwMicgKiAyMCksIEFkZHJlc3MoYidceDAzJyAqIDIwKV0sCgkJCXsnYSc6IDEsICdiJzogWzEsIDIsIDNdfSwKCQldCgkJcHJpbnQoZid7aWR4fSBbMC4uLntsZW4ocmV0KX0pJykKCQlyZXR1cm4gcmV0W2lkeF0KAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/pitfalls/multi_contract.0.hash b/tests/cases/stable/py/pitfalls/multi_contract.0.hash index 801467ad5..11d165937 100644 --- a/tests/cases/stable/py/pitfalls/multi_contract.0.hash +++ b/tests/cases/stable/py/pitfalls/multi_contract.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEADRWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMSAQEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QxKGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludCgnaGVsbG8gd29ybGQnKQoKCmNsYXNzIENvbnRyYWN0MihnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcHJpbnQoJ2hlbGxvIHdvcmxkJykKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LRFcZXhpdF9jb2RlIDEAFRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDEgEBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0MShnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcHJpbnQoJ2hlbGxvIHdvcmxkJykKCgpjbGFzcyBDb250cmFjdDIoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXByaW50KCdoZWxsbyB3b3JsZCcpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/pitfalls/pub_ctor.0.hash b/tests/cases/stable/py/pitfalls/pub_ctor.0.hash index 18731dd97..707cb2fc3 100644 --- a/tests/cases/stable/py/pitfalls/pub_ctor.0.hash +++ b/tests/cases/stable/py/pitfalls/pub_ctor.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMOvQAAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCXByaW50KCdoZWxsbyB3b3JsZCcpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDDr0AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludCgnaGVsbG8gd29ybGQnKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/py/pitfalls/store_proxy.0.hash b/tests/cases/stable/py/pitfalls/store_proxy.0.hash index 3e02af91a..9e7b812d3 100644 --- a/tests/cases/stable/py/pitfalls/store_proxy.0.hash +++ b/tests/cases/stable/py/pitfalls/store_proxy.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/rollbacks/call_view.0.hash b/tests/cases/stable/py/rollbacks/call_view.0.hash index 25ec2f05e..d39621377 100644 --- a/tests/cases/stable/py/rollbacks/call_view.0.hash +++ b/tests/cases/stable/py/rollbacks/call_view.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEhwBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGZvbyhzZWxmLCBhLCBiKToKCQlwcmludCgnY29udHJhY3QgdG8uZm9vJykKCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKGYibmFoLCBJIHdvbid0IGV4ZWN1dGUge2EgKyBifSIpCgU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIcAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZiwgYSwgYik6CgkJcHJpbnQoJ2NvbnRyYWN0IHRvLmZvbycpCgkJZ2wudm0uVXNlckVycm9yLmltbWVkaWF0ZShmIm5haCwgSSB3b24ndCBleGVjdXRlIHthICsgYn0iKQoF diff --git a/tests/cases/stable/py/rollbacks/call_view.0_0.hash b/tests/cases/stable/py/rollbacks/call_view.0_0.hash index cc56b3ea8..7b37b0469 100644 --- a/tests/cases/stable/py/rollbacks/call_view.0_0.hash +++ b/tests/cases/stable/py/rollbacks/call_view.0_0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGogBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgYWRkcjogQWRkcmVzcyk6CgkJcHJpbnQoJ2NvbnRyYWN0IGZyb20ubWFpbicpCgkJdHJ5OgoJCQlyZXMgPSBnbC5jb250cmFjdC5nZXRfYXQoYWRkcikudmlldygpLmZvbygxLCAyKS5nZXQoKQoJCWV4Y2VwdCBnbC52bS5Vc2VyRXJyb3IgYXMgcjoKCQkJcHJpbnQoJ2hhbmRsZWQnLCByLmRhdGEpCgkJZWxzZToKCQkJcHJpbnQocmVzKQoJCQlleGl0KDEpCgAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqIAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGFkZHI6IEFkZHJlc3MpOgoJCXByaW50KCdjb250cmFjdCBmcm9tLm1haW4nKQoJCXRyeToKCQkJcmVzID0gZ2wuY29udHJhY3QuZ2V0X2F0KGFkZHIpLnZpZXcoKS5mb28oMSwgMikuZ2V0KCkKCQlleGNlcHQgZ2wudm0uVXNlckVycm9yIGFzIHI6CgkJCXByaW50KCdoYW5kbGVkJywgci5kYXRhKQoJCWVsc2U6CgkJCXByaW50KHJlcykKCQkJZXhpdCgxKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/rollbacks/calldata_rollback.0.hash b/tests/cases/stable/py/rollbacks/calldata_rollback.0.hash index b8442af4a..2521f2596 100644 --- a/tests/cases/stable/py/rollbacks/calldata_rollback.0.hash +++ b/tests/cases/stable/py/rollbacks/calldata_rollback.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCMBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGZvbyhzZWxmLCBhLCBiKToKCQlwcmludCgnY29udHJhY3QgdG8uZm9vJykKCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKHsnZXJyb3InOiAnc29tZV9lcnJvcicsICdjb2RlJzogYSArIGJ9KQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQjAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZiwgYSwgYik6CgkJcHJpbnQoJ2NvbnRyYWN0IHRvLmZvbycpCgkJZ2wudm0uVXNlckVycm9yLmltbWVkaWF0ZSh7J2Vycm9yJzogJ3NvbWVfZXJyb3InLCAnY29kZSc6IGEgKyBifSkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/rollbacks/calldata_rollback.0_0.hash b/tests/cases/stable/py/rollbacks/calldata_rollback.0_0.hash index cc56b3ea8..7b37b0469 100644 --- a/tests/cases/stable/py/rollbacks/calldata_rollback.0_0.hash +++ b/tests/cases/stable/py/rollbacks/calldata_rollback.0_0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGogBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgYWRkcjogQWRkcmVzcyk6CgkJcHJpbnQoJ2NvbnRyYWN0IGZyb20ubWFpbicpCgkJdHJ5OgoJCQlyZXMgPSBnbC5jb250cmFjdC5nZXRfYXQoYWRkcikudmlldygpLmZvbygxLCAyKS5nZXQoKQoJCWV4Y2VwdCBnbC52bS5Vc2VyRXJyb3IgYXMgcjoKCQkJcHJpbnQoJ2hhbmRsZWQnLCByLmRhdGEpCgkJZWxzZToKCQkJcHJpbnQocmVzKQoJCQlleGl0KDEpCgAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxqIAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIGFkZHI6IEFkZHJlc3MpOgoJCXByaW50KCdjb250cmFjdCBmcm9tLm1haW4nKQoJCXRyeToKCQkJcmVzID0gZ2wuY29udHJhY3QuZ2V0X2F0KGFkZHIpLnZpZXcoKS5mb28oMSwgMikuZ2V0KCkKCQlleGNlcHQgZ2wudm0uVXNlckVycm9yIGFzIHI6CgkJCXByaW50KCdoYW5kbGVkJywgci5kYXRhKQoJCWVsc2U6CgkJCXByaW50KHJlcykKCQkJZXhpdCgxKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/rollbacks/nondet.0.hash b/tests/cases/stable/py/rollbacks/nondet.0.hash index a4812bc9e..6d2aa963e 100644 --- a/tests/cases/stable/py/rollbacks/nondet.0.hash +++ b/tests/cases/stable/py/rollbacks/nondet.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGGsBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQl0cnk6CgoJCQlkZWYgcnVuKCk6CgkJCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKCJuYWgsIEkgd29uJ3QgZXhlY3V0ZSIpCgoJCQlyZXMgPSBnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikuZ2V0KCkKCQlleGNlcHQgZ2wudm0uVXNlckVycm9yIGFzIHI6CgkJCXByaW50KCdoYW5kbGVkJywgci5kYXRhKQoJCWVsc2U6CgkJCXByaW50KHJlcykKCQkJZXhpdCgxKQoAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxhrAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJdHJ5OgoKCQkJZGVmIHJ1bigpOgoJCQkJZ2wudm0uVXNlckVycm9yLmltbWVkaWF0ZSgibmFoLCBJIHdvbid0IGV4ZWN1dGUiKQoKCQkJcmVzID0gZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW4pLmdldCgpCgkJZXhjZXB0IGdsLnZtLlVzZXJFcnJvciBhcyByOgoJCQlwcmludCgnaGFuZGxlZCcsIHIuZGF0YSkKCQllbHNlOgoJCQlwcmludChyZXMpCgkJCWV4aXQoMSkKAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/rollbacks/simple.0.hash b/tests/cases/stable/py/rollbacks/simple.0.hash index c6abb80cb..b4c91f659 100644 --- a/tests/cases/stable/py/rollbacks/simple.0.hash +++ b/tests/cases/stable/py/rollbacks/simple.0.hash @@ -1 +1 @@ -LQmkAW5haCwgSSB3b24ndCBleGVjdXRlABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDDsgAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKCJuYWgsIEkgd29uJ3QgZXhlY3V0ZSIpCgAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQmkAW5haCwgSSB3b24ndCBleGVjdXRlAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgw7IAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJZ2wudm0uVXNlckVycm9yLmltbWVkaWF0ZSgibmFoLCBJIHdvbid0IGV4ZWN1dGUiKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/sandbox/det/s/assign-json.0.hash b/tests/cases/stable/py/sandbox/det/s/assign-json.0.hash index 353d9f3ad..a2f14af61 100644 --- a/tests/cases/stable/py/sandbox/det/s/assign-json.0.hash +++ b/tests/cases/stable/py/sandbox/det/s/assign-json.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlnbGIgPSBnbG9iYWxzKCkKCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQgAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZ2xiID0gZ2xvYmFscygpCgkJcHJpbnQoZid7Z2wudm0uc3Bhd25fc2FuZGJveChsYW1iZGE6IGV2YWwoZXYsIGdsYikpfScpCgkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/sandbox/det/s/exit.0.hash b/tests/cases/stable/py/sandbox/det/s/exit.0.hash index 353d9f3ad..a2f14af61 100644 --- a/tests/cases/stable/py/sandbox/det/s/exit.0.hash +++ b/tests/cases/stable/py/sandbox/det/s/exit.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlnbGIgPSBnbG9iYWxzKCkKCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQgAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZ2xiID0gZ2xvYmFscygpCgkJcHJpbnQoZid7Z2wudm0uc3Bhd25fc2FuZGJveChsYW1iZGE6IGV2YWwoZXYsIGdsYikpfScpCgkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/sandbox/det/s/print.0.hash b/tests/cases/stable/py/sandbox/det/s/print.0.hash index 353d9f3ad..a2f14af61 100644 --- a/tests/cases/stable/py/sandbox/det/s/print.0.hash +++ b/tests/cases/stable/py/sandbox/det/s/print.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlnbGIgPSBnbG9iYWxzKCkKCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQgAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZ2xiID0gZ2xvYmFscygpCgkJcHJpbnQoZid7Z2wudm0uc3Bhd25fc2FuZGJveChsYW1iZGE6IGV2YWwoZXYsIGdsYikpfScpCgkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/sandbox/det/s/rollback.0.hash b/tests/cases/stable/py/sandbox/det/s/rollback.0.hash index 353d9f3ad..a2f14af61 100644 --- a/tests/cases/stable/py/sandbox/det/s/rollback.0.hash +++ b/tests/cases/stable/py/sandbox/det/s/rollback.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlnbGIgPSBnbG9iYWxzKCkKCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQgAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZ2xiID0gZ2xvYmFscygpCgkJcHJpbnQoZid7Z2wudm0uc3Bhd25fc2FuZGJveChsYW1iZGE6IGV2YWwoZXYsIGdsYikpfScpCgkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/sandbox/det/s/sandbox.0.hash b/tests/cases/stable/py/sandbox/det/s/sandbox.0.hash index 353d9f3ad..a2f14af61 100644 --- a/tests/cases/stable/py/sandbox/det/s/sandbox.0.hash +++ b/tests/cases/stable/py/sandbox/det/s/sandbox.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlnbGIgPSBnbG9iYWxzKCkKCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQgAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZ2xiID0gZ2xvYmFscygpCgkJcHJpbnQoZid7Z2wudm0uc3Bhd25fc2FuZGJveChsYW1iZGE6IGV2YWwoZXYsIGdsYikpfScpCgkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/py/sandbox/det/sandbox_write.0.hash b/tests/cases/stable/py/sandbox/det/sandbox_write.0.hash index 4068b6625..b1c3c24a8 100644 --- a/tests/cases/stable/py/sandbox/det/sandbox_write.0.hash +++ b/tests/cases/stable/py/sandbox/det/sandbox_write.0.hash @@ -1 +1 @@ -LQEAAB0VowI3LUbDran4l8dNNJu/4ORQx5gWfJ9YD42vhd71fpbD6gAAAACDAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgxhyAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0IHU4CgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJY291bnRlcjogdTgKCglkZWYgX19pbml0X18oc2VsZik6CgkJcHJpbnQoZidoZWxsbyB3b3JsZCB7c2VsZi5jb3VudGVyfScpCgoJCWRlZiBzYigpOgoJCQlzZWxmLmNvdW50ZXIgKz0gMQoKCQlwcmludChmJ2NvdW50ZXIgYmVmb3JlOiB7c2VsZi5jb3VudGVyfScpCgkJZ2wudm0uc3Bhd25fc2FuZGJveChzYiwgYWxsb3dfd3JpdGVfb3BzPVRydWUpCgkJcHJpbnQoZidjb3VudGVyIGFmdGVyOiB7c2VsZi5jb3VudGVyfScpCgAAAAAAAAAAAAAF +LQEAACUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxh2AQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0IHU4CgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJY291bnRlcjogdTgKCglkZWYgX19pbml0X18oc2VsZik6CgkJcHJpbnQoZidoZWxsbyB3b3JsZCB7c2VsZi5jb3VudGVyfScpCgoJCWRlZiBzYigpOgoJCQlzZWxmLmNvdW50ZXIgKz0gMQoKCQlwcmludChmJ2NvdW50ZXIgYmVmb3JlOiB7c2VsZi5jb3VudGVyfScpCgkJZ2wudm0uc3Bhd25fc2FuZGJveChzYiwgYWxsb3dfd3JpdGVfc3RvcmFnZT1UcnVlKQoJCXByaW50KGYnY291bnRlciBhZnRlcjoge3NlbGYuY291bnRlcn0nKQoAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/py/sandbox/det/sandbox_write.py b/tests/cases/stable/py/sandbox/det/sandbox_write.py index 861985684..648e86986 100644 --- a/tests/cases/stable/py/sandbox/det/sandbox_write.py +++ b/tests/cases/stable/py/sandbox/det/sandbox_write.py @@ -13,5 +13,5 @@ def sb(): self.counter += 1 print(f'counter before: {self.counter}') - gl.vm.spawn_sandbox(sb, allow_write_ops=True) + gl.vm.spawn_sandbox(sb, allow_write_storage=True) print(f'counter after: {self.counter}') diff --git a/tests/cases/stable/py/sandbox/non-det/s/assign-json.0.hash b/tests/cases/stable/py/sandbox/non-det/s/assign-json.0.hash index 27195b0fe..c0d168136 100644 --- a/tests/cases/stable/py/sandbox/non-det/s/assign-json.0.hash +++ b/tests/cases/stable/py/sandbox/non-det/s/assign-json.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlwBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlkZWYgcnVuX25kZXQoKToKCQkJZ2xiID0gZ2xvYmFscygpCgkJCXByaW50KGYne2dsLnZtLnNwYXduX3NhbmRib3gobGFtYmRhOiBldmFsKGV2LCBnbGIpKX0nKQoJCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bl9uZGV0KQoF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZcAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZGVmIHJ1bl9uZGV0KCk6CgkJCWdsYiA9IGdsb2JhbHMoKQoJCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW5fbmRldCkKBQ== diff --git a/tests/cases/stable/py/sandbox/non-det/s/exit.0.hash b/tests/cases/stable/py/sandbox/non-det/s/exit.0.hash index 27195b0fe..c0d168136 100644 --- a/tests/cases/stable/py/sandbox/non-det/s/exit.0.hash +++ b/tests/cases/stable/py/sandbox/non-det/s/exit.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlwBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlkZWYgcnVuX25kZXQoKToKCQkJZ2xiID0gZ2xvYmFscygpCgkJCXByaW50KGYne2dsLnZtLnNwYXduX3NhbmRib3gobGFtYmRhOiBldmFsKGV2LCBnbGIpKX0nKQoJCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bl9uZGV0KQoF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZcAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZGVmIHJ1bl9uZGV0KCk6CgkJCWdsYiA9IGdsb2JhbHMoKQoJCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW5fbmRldCkKBQ== diff --git a/tests/cases/stable/py/sandbox/non-det/s/print.0.hash b/tests/cases/stable/py/sandbox/non-det/s/print.0.hash index 27195b0fe..c0d168136 100644 --- a/tests/cases/stable/py/sandbox/non-det/s/print.0.hash +++ b/tests/cases/stable/py/sandbox/non-det/s/print.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlwBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlkZWYgcnVuX25kZXQoKToKCQkJZ2xiID0gZ2xvYmFscygpCgkJCXByaW50KGYne2dsLnZtLnNwYXduX3NhbmRib3gobGFtYmRhOiBldmFsKGV2LCBnbGIpKX0nKQoJCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bl9uZGV0KQoF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZcAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZGVmIHJ1bl9uZGV0KCk6CgkJCWdsYiA9IGdsb2JhbHMoKQoJCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW5fbmRldCkKBQ== diff --git a/tests/cases/stable/py/sandbox/non-det/s/rollback.0.hash b/tests/cases/stable/py/sandbox/non-det/s/rollback.0.hash index 27195b0fe..c0d168136 100644 --- a/tests/cases/stable/py/sandbox/non-det/s/rollback.0.hash +++ b/tests/cases/stable/py/sandbox/non-det/s/rollback.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlwBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlkZWYgcnVuX25kZXQoKToKCQkJZ2xiID0gZ2xvYmFscygpCgkJCXByaW50KGYne2dsLnZtLnNwYXduX3NhbmRib3gobGFtYmRhOiBldmFsKGV2LCBnbGIpKX0nKQoJCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bl9uZGV0KQoF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZcAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZGVmIHJ1bl9uZGV0KCk6CgkJCWdsYiA9IGdsb2JhbHMoKQoJCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW5fbmRldCkKBQ== diff --git a/tests/cases/stable/py/schemas/complex_types.0.hash b/tests/cases/stable/py/schemas/complex_types.0.hash index 2d3021c04..af68583d7 100644 --- a/tests/cases/stable/py/schemas/complex_types.0.hash +++ b/tests/cases/stable/py/schemas/complex_types.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/py/schemas/prim_types.0.hash b/tests/cases/stable/py/schemas/prim_types.0.hash index 9951e2083..c518842a0 100644 --- a/tests/cases/stable/py/schemas/prim_types.0.hash +++ b/tests/cases/stable/py/schemas/prim_types.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGGMBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IHR5cGluZwoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGZvbyhzZWxmLCBhMTogaW50LCBhMjogTm9uZSwgYTM6IGJvb2wsIGE0OiBzdHIsIGE1OiBieXRlcywgYTY6IEFkZHJlc3MpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYgZXJhc2VkKHNlbGYsIGExOiBsaXN0LCBhMjogZGljdCwgYTM6IHR5cGluZy5BbnkpOgoJCXBhc3MKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxhjAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCB0eXBpbmcKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZiwgYTE6IGludCwgYTI6IE5vbmUsIGEzOiBib29sLCBhNDogc3RyLCBhNTogYnl0ZXMsIGE2OiBBZGRyZXNzKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGVyYXNlZChzZWxmLCBhMTogbGlzdCwgYTI6IGRpY3QsIGEzOiB0eXBpbmcuQW55KToKCQlwYXNzCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/schemas/ret-float.0.hash b/tests/cases/stable/py/schemas/ret-float.0.hash index 265a369c0..637307c05 100644 --- a/tests/cases/stable/py/schemas/ret-float.0.hash +++ b/tests/cases/stable/py/schemas/ret-float.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMQ3gAAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYsIGZvbywgYmFyKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGZvbyhzZWxmKSAtPiBmbG9hdDoKCQlyZXR1cm4gMC4wCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDEN4AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBmb28sIGJhcik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZikgLT4gZmxvYXQ6CgkJcmV0dXJuIDAuMAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/schemas/ret-tuple.0.hash b/tests/cases/stable/py/schemas/ret-tuple.0.hash index 6874be6f8..4cd1df53b 100644 --- a/tests/cases/stable/py/schemas/ret-tuple.0.hash +++ b/tests/cases/stable/py/schemas/ret-tuple.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMULwEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYsIGZvbywgYmFyKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGZvbyhzZWxmKSAtPiB0dXBsZVtpbnQsIGludF06CgkJcmV0dXJuICgxLCAyKQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBiYXIoc2VsZikgLT4gdHVwbGVbaW50LCAuLi5dOgoJCXJldHVybiAoMSwpCgAAAAAAAAAAAAAAAAAF +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDFC8BAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBmb28sIGJhcik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBmb28oc2VsZikgLT4gdHVwbGVbaW50LCBpbnRdOgoJCXJldHVybiAoMSwgMikKCglAZ2wucHVibGljLndyaXRlCglkZWYgYmFyKHNlbGYpIC0+IHR1cGxlW2ludCwgLi4uXToKCQlyZXR1cm4gKDEsKQoAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/py/schemas/ret.0.hash b/tests/cases/stable/py/schemas/ret.0.hash index ccbce72cb..694e62810 100644 --- a/tests/cases/stable/py/schemas/ret.0.hash +++ b/tests/cases/stable/py/schemas/ret.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMcoQEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYsIGZvbywgYmFyKToKCQlwYXNzCgoJQGdsLnB1YmxpYy52aWV3CglkZWYgZm9vKHNlbGYpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYgcG9zKHNlbGYsIHgsIHkpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYga3coc2VsZiwgKiwgeCwgeSk6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtaXhlZChzZWxmLCBhLCBiLCAqLCB4LCB5KToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZS5wYXlhYmxlCglkZWYgcGF5YWJsZShzZWxmKToKCQlwYXNzCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDHKEBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBmb28sIGJhcik6CgkJcGFzcwoKCUBnbC5wdWJsaWMudmlldwoJZGVmIGZvbyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIHBvcyhzZWxmLCB4LCB5KToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGt3KHNlbGYsICosIHgsIHkpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYgbWl4ZWQoc2VsZiwgYSwgYiwgKiwgeCwgeSk6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUucGF5YWJsZQoJZGVmIHBheWFibGUoc2VsZik6CgkJcGFzcwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/py/schemas/trivial.0.hash b/tests/cases/stable/py/schemas/trivial.0.hash index ccbce72cb..694e62810 100644 --- a/tests/cases/stable/py/schemas/trivial.0.hash +++ b/tests/cases/stable/py/schemas/trivial.0.hash @@ -1 +1 @@ -LRFcZXhpdF9jb2RlIDEAFRWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhee6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMcoQEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYsIGZvbywgYmFyKToKCQlwYXNzCgoJQGdsLnB1YmxpYy52aWV3CglkZWYgZm9vKHNlbGYpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYgcG9zKHNlbGYsIHgsIHkpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYga3coc2VsZiwgKiwgeCwgeSk6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtaXhlZChzZWxmLCBhLCBiLCAqLCB4LCB5KToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZS5wYXlhYmxlCglkZWYgcGF5YWJsZShzZWxmKToKCQlwYXNzCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LRFcZXhpdF9jb2RlIDEAHRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDHKEBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBmb28sIGJhcik6CgkJcGFzcwoKCUBnbC5wdWJsaWMudmlldwoJZGVmIGZvbyhzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIHBvcyhzZWxmLCB4LCB5KToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGt3KHNlbGYsICosIHgsIHkpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYgbWl4ZWQoc2VsZiwgYSwgYiwgKiwgeCwgeSk6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUucGF5YWJsZQoJZGVmIHBheWFibGUoc2VsZik6CgkJcGFzcwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/runners/code_slot_exec.0.stdout b/tests/cases/stable/runners/code_slot_exec.0.stdout new file mode 100644 index 000000000..ae5576e85 --- /dev/null +++ b/tests/cases/stable/runners/code_slot_exec.0.stdout @@ -0,0 +1,2 @@ +deployed +executed with `Return(null)` diff --git a/tests/cases/stable/runners/code_slot_exec.0_0.stdout b/tests/cases/stable/runners/code_slot_exec.0_0.stdout new file mode 100644 index 000000000..2d08fba0a --- /dev/null +++ b/tests/cases/stable/runners/code_slot_exec.0_0.stdout @@ -0,0 +1,2 @@ +hello from code_slot +executed with `Return(null)` diff --git a/tests/cases/stable/runners/code_slot_exec.jsonnet b/tests/cases/stable/runners/code_slot_exec.jsonnet new file mode 100644 index 000000000..505148a9f --- /dev/null +++ b/tests/cases/stable/runners/code_slot_exec.jsonnet @@ -0,0 +1,18 @@ +local msg = import 'templates/message.json'; +local util = import 'templates/util.jsonnet'; +{ + entry: util.addPaths([{ + vars: {}, + code: '${jsonnetDir}/code_slot_exec.py', + message: msg + {is_init: true}, + calldata: '{}', + stable_hash: false, + next: [{ + vars: {}, + code: null, + message: msg, + calldata: std.manifestJsonEx({method: 'foo', args: []}, ' '), + stable_hash: false, + }], + }]) +} diff --git a/tests/cases/stable/runners/code_slot_exec.py b/tests/cases/stable/runners/code_slot_exec.py new file mode 100644 index 000000000..b0f00fe45 --- /dev/null +++ b/tests/cases/stable/runners/code_slot_exec.py @@ -0,0 +1,23 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.storage.root import Root + + +class Contract(gl.contract.Contract): + def __init__(self): + # write a *different* valid contract to slot 7 and point code_slot at it; + # the next invocation must load and run THAT code, not this class's `foo`. + alt = ( + b'# { "Depends": "py-genlayer:test" }\nprint("hello from code_slot")\nexit(0)\n' + ) + slot_id = bytes([7]) + bytes(31) + s = Root.MANAGER.get_store_slot(slot_id) + s.write(0, len(alt).to_bytes(4, 'little')) + s.write(4, alt) + Root.get().code_slot = int.from_bytes(slot_id, 'little') + print('deployed') + + @gl.public.write + def foo(self) -> None: + # only reached if code_slot was IGNORED (default code loaded) + print('original foo ran -- code_slot ignored!') diff --git a/tests/cases/stable/runners/code_slot_redirect.0.stdout b/tests/cases/stable/runners/code_slot_redirect.0.stdout new file mode 100644 index 000000000..ae5576e85 --- /dev/null +++ b/tests/cases/stable/runners/code_slot_redirect.0.stdout @@ -0,0 +1,2 @@ +deployed +executed with `Return(null)` diff --git a/tests/cases/stable/runners/code_slot_redirect.0_0.stdout b/tests/cases/stable/runners/code_slot_redirect.0_0.stdout new file mode 100644 index 000000000..82f34ded9 --- /dev/null +++ b/tests/cases/stable/runners/code_slot_redirect.0_0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract absent_runner_comment")` diff --git a/tests/cases/stable/runners/code_slot_redirect.jsonnet b/tests/cases/stable/runners/code_slot_redirect.jsonnet new file mode 100644 index 000000000..41e1ae7fa --- /dev/null +++ b/tests/cases/stable/runners/code_slot_redirect.jsonnet @@ -0,0 +1,18 @@ +local msg = import 'templates/message.json'; +local util = import 'templates/util.jsonnet'; +{ + entry: util.addPaths([{ + vars: {}, + code: '${jsonnetDir}/code_slot_redirect.py', + message: msg + {is_init: true}, + calldata: '{}', + stable_hash: false, + next: [{ + vars: {}, + code: null, + message: msg, + calldata: std.manifestJsonEx({method: 'foo', args: []}, ' '), + stable_hash: false, + }], + }]) +} diff --git a/tests/cases/stable/runners/code_slot_redirect.py b/tests/cases/stable/runners/code_slot_redirect.py new file mode 100644 index 000000000..9aa18e722 --- /dev/null +++ b/tests/cases/stable/runners/code_slot_redirect.py @@ -0,0 +1,15 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.storage.root import Root + + +class Contract(gl.contract.Contract): + def __init__(self): + # redirect the code slot to a different (empty) slot; the next invocation + # must read its code from there instead of the default slot + Root.get().code_slot = 12345 + print('deployed') + + @gl.public.write + def foo(self) -> None: + print('should not be reached') diff --git a/tests/cases/stable/runners/custom_malformed.0.stdout b/tests/cases/stable/runners/custom_malformed.0.stdout new file mode 100644 index 000000000..3a6b81bc5 --- /dev/null +++ b/tests/cases/stable/runners/custom_malformed.0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract malformed_runner")` diff --git a/tests/cases/stable/runners/custom_malformed.jsonnet b/tests/cases/stable/runners/custom_malformed.jsonnet new file mode 100644 index 000000000..8df849cb4 --- /dev/null +++ b/tests/cases/stable/runners/custom_malformed.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/custom_malformed.py') {stable_hash: false}])} diff --git a/tests/cases/stable/runners/custom_malformed.py b/tests/cases/stable/runners/custom_malformed.py new file mode 100644 index 000000000..d2f8a99c8 --- /dev/null +++ b/tests/cases/stable/runners/custom_malformed.py @@ -0,0 +1,2 @@ +# { "Depends": "custom:" } +exit(0) diff --git a/tests/cases/stable/runners/custom_missing.0.stdout b/tests/cases/stable/runners/custom_missing.0.stdout new file mode 100644 index 000000000..226138fdd --- /dev/null +++ b/tests/cases/stable/runners/custom_missing.0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract")` diff --git a/tests/cases/stable/runners/custom_missing.jsonnet b/tests/cases/stable/runners/custom_missing.jsonnet new file mode 100644 index 000000000..86e5116a2 --- /dev/null +++ b/tests/cases/stable/runners/custom_missing.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/custom_missing.py') {stable_hash: false}])} diff --git a/tests/cases/stable/runners/custom_missing.py b/tests/cases/stable/runners/custom_missing.py new file mode 100644 index 000000000..51708489b --- /dev/null +++ b/tests/cases/stable/runners/custom_missing.py @@ -0,0 +1,2 @@ +# { "Depends": "custom:0000000000000000000000000000000000000000000000000000" } +exit(0) diff --git a/tests/cases/stable/runners/dup-dependency.0.hash b/tests/cases/stable/runners/dup-dependency.0.hash index 422be9d1c..1eaec6041 100644 --- a/tests/cases/stable/runners/dup-dependency.0.hash +++ b/tests/cases/stable/runners/dup-dependency.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEN8AAAAjIHsKIyAgICJTZXEiOiBbCiMgICAgIHsgIkRlcGVuZHMiOiAic29mdGZsb2F0OnRlc3QiIH0sCiMgICAgIHsgIkRlcGVuZHMiOiAic29mdGZsb2F0OnRlc3QiIH0sCiMgICAgIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQojICAgXQojIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgpwcmludCgnSSBhbSBvaycpCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxDfAAAAIyB7CiMgICAiU2VxIjogWwojICAgICB7ICJEZXBlbmRzIjogInNvZnRmbG9hdDp0ZXN0IiB9LAojICAgICB7ICJEZXBlbmRzIjogInNvZnRmbG9hdDp0ZXN0IiB9LAojICAgICB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KIyAgIF0KIyB9CgppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKcHJpbnQoJ0kgYW0gb2snKQpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/runners/env-template.0.hash b/tests/cases/stable/runners/env-template.0.hash index c8796404e..3b158bc69 100644 --- a/tests/cases/stable/runners/env-template.0.hash +++ b/tests/cases/stable/runners/env-template.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDDtUAAAAjIHsKIyAgICJTZXEiOiBbCiMgICAgIHsgIkFkZEVudiI6IHsgIm5hbWUiOiAiWCIsICJ2YWwiOiAiMSIgfSB9LAojICAgICB7ICJBZGRFbnYiOiB7ICJuYW1lIjogIlgiLCAidmFsIjogIiR7WH06MiIgfSB9LAojICAgICB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KIyAgIF0KIyB9CgppbXBvcnQgb3MKCnByaW50KG9zLmVudmlyb25bJ1gnXSkKZXhpdCgwKQoAAAAAAAAABQ== +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgw7VAAAAIyB7CiMgICAiU2VxIjogWwojICAgICB7ICJBZGRFbnYiOiB7ICJuYW1lIjogIlgiLCAidmFsIjogIjEiIH0gfSwKIyAgICAgeyAiQWRkRW52IjogeyAibmFtZSI6ICJYIiwgInZhbCI6ICIke1h9OjIiIH0gfSwKIyAgICAgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CiMgICBdCiMgfQoKaW1wb3J0IG9zCgpwcmludChvcy5lbnZpcm9uWydYJ10pCmV4aXQoMCkKAAAAAAAAAAU= diff --git a/tests/cases/stable/runners/major-mismatch/caller.py b/tests/cases/stable/runners/major-mismatch/caller.py new file mode 100644 index 000000000..18c97c9cc --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/caller.py @@ -0,0 +1,16 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.types import * + + +class Contract(gl.contract.Contract): + def __init__(self): + pass + + @gl.public.write + def call(self, addr: Address): + gl.contract.get_at(addr).view().foo() + + @gl.public.write + def map(self, addr: Address): + gl.vm.map_file(f'chain:{addr.as_hex}:a', 'file', '/mapped.txt') diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.0.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.0.stdout new file mode 100644 index 000000000..8dbb414b5 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.0.stdout @@ -0,0 +1,2 @@ +deployed target with major 5 +executed with `Return(null)` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.0_0.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.0_0.stdout new file mode 100644 index 000000000..f70cfaea6 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.0_0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract major_mismatch")` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.1.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.1.stdout new file mode 100644 index 000000000..8dbb414b5 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.1.stdout @@ -0,0 +1,2 @@ +deployed target with major 5 +executed with `Return(null)` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.1_0.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.1_0.stdout new file mode 100644 index 000000000..7d73027c8 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.1_0.stdout @@ -0,0 +1 @@ +executed with `Return(null)` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.1_0_0.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.1_0_0.stdout new file mode 100644 index 000000000..f70cfaea6 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.1_0_0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract major_mismatch")` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.2.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.2.stdout new file mode 100644 index 000000000..8dbb414b5 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.2.stdout @@ -0,0 +1,2 @@ +deployed target with major 5 +executed with `Return(null)` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.2_0.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.2_0.stdout new file mode 100644 index 000000000..7d73027c8 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.2_0.stdout @@ -0,0 +1 @@ +executed with `Return(null)` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.2_0_0.stdout b/tests/cases/stable/runners/major-mismatch/major_mismatch.2_0_0.stdout new file mode 100644 index 000000000..f70cfaea6 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.2_0_0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract major_mismatch")` diff --git a/tests/cases/stable/runners/major-mismatch/major_mismatch.jsonnet b/tests/cases/stable/runners/major-mismatch/major_mismatch.jsonnet new file mode 100644 index 000000000..4c0148c2f --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/major_mismatch.jsonnet @@ -0,0 +1,40 @@ +local two = import 'templates/two.jsonnet'; +local msg = import 'templates/message.json'; +local util = import 'templates/util.jsonnet'; + +// every entry point that reads a contract's (mismatched) major must reject it: +local entries = [ + // 0: top-level call to a major-mismatched contract + { + vars: {}, + code: '${jsonnetDir}/target.py', + message: msg + {is_init: true}, + calldata: '{}', + next: [{ + vars: {}, + code: null, + message: msg, + calldata: std.manifestJsonEx({method: 'foo', args: []}, ' '), + }], + }, + // 1: CallContract into a major-mismatched contract + two.run('${jsonnetDir}/caller.py', '${jsonnetDir}/target.py', + ||| + { + "method": "call", + "args": [Address(toAddr)] + } + ||| + ), + // 2: map_file from a major-mismatched contract + two.run('${jsonnetDir}/caller.py', '${jsonnetDir}/target.py', + ||| + { + "method": "map", + "args": [Address(toAddr)] + } + ||| + ), +]; + +{entry: util.addPaths(util.mapGraph(function(e) e + {stable_hash: false}, entries))} diff --git a/tests/cases/stable/runners/major-mismatch/target.py b/tests/cases/stable/runners/major-mismatch/target.py new file mode 100644 index 000000000..95471e283 --- /dev/null +++ b/tests/cases/stable/runners/major-mismatch/target.py @@ -0,0 +1,17 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.storage.root import Root + + +class Contract(gl.contract.Contract): + def __init__(self): + # persist a major that does not match the node's, so every later read of + # this contract's runner (top-level call, CallContract, map_file) is + # rejected before it runs + Root.get().major = 5 + print('deployed target with major 5') + + @gl.public.view + def foo(self) -> int: + print('should not be reached') + return 1 diff --git a/tests/cases/stable/runners/malformed_runner.0.hash b/tests/cases/stable/runners/malformed_runner.0.hash index 0d05fa3dc..a286dff53 100644 --- a/tests/cases/stable/runners/malformed_runner.0.hash +++ b/tests/cases/stable/runners/malformed_runner.0.hash @@ -1 +1 @@ -LRGEAWludmFsaWRfY29udHJhY3QADRWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMCGwAAACMgeyAiRm9vIjogImJhciIgfQpleGl0KDApCgAF +LRGEAWludmFsaWRfY29udHJhY3QAFRWjAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDAhsAAAAjIHsgIkZvbyI6ICJiYXIiIH0KZXhpdCgwKQoABQ== diff --git a/tests/cases/stable/runners/map_contract_relocated.0.stdout b/tests/cases/stable/runners/map_contract_relocated.0.stdout new file mode 100644 index 000000000..ae5576e85 --- /dev/null +++ b/tests/cases/stable/runners/map_contract_relocated.0.stdout @@ -0,0 +1,2 @@ +deployed +executed with `Return(null)` diff --git a/tests/cases/stable/runners/map_contract_relocated.0_0.stdout b/tests/cases/stable/runners/map_contract_relocated.0_0.stdout new file mode 100644 index 000000000..c66dd3351 --- /dev/null +++ b/tests/cases/stable/runners/map_contract_relocated.0_0.stdout @@ -0,0 +1,2 @@ +ok=True +executed with `Return(null)` diff --git a/tests/cases/stable/runners/map_contract_relocated.jsonnet b/tests/cases/stable/runners/map_contract_relocated.jsonnet new file mode 100644 index 000000000..24753cea9 --- /dev/null +++ b/tests/cases/stable/runners/map_contract_relocated.jsonnet @@ -0,0 +1,18 @@ +local msg = import 'templates/message.json'; +local util = import 'templates/util.jsonnet'; +{ + entry: util.addPaths([{ + vars: {}, + code: '${jsonnetDir}/map_contract_relocated.py', + message: msg + {is_init: true}, + calldata: '{}', + stable_hash: false, + next: [{ + vars: {}, + code: null, + message: msg, + calldata: std.manifestJsonEx({method: 'foo', args: []}, ' '), + stable_hash: false, + }], + }]) +} diff --git a/tests/cases/stable/runners/map_contract_relocated.py b/tests/cases/stable/runners/map_contract_relocated.py new file mode 100644 index 000000000..f9faa6a6e --- /dev/null +++ b/tests/cases/stable/runners/map_contract_relocated.py @@ -0,0 +1,36 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.storage.root import Root +from genlayer.vm import public_abi + +# the relocated contract: a script that maps its OWN runner ("contract") and +# checks it received real code. If `map_file("contract")` re-read the (wiped) +# default code slot it would get 0 bytes here. +C2 = b"""\ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.vm import map_file +class Contract(gl.contract.Contract): + @gl.public.write + def foo(self): + map_file("contract", "file", "/x") + d = open("/x", "rb").read() + print("ok=" + str(len(d) > 0 and d[:3] == b"# {")) +""" + + +class Contract(gl.contract.Contract): + def __init__(self): + # move the code to slot 7, point code_slot there, then wipe the default + # code slot (offset 1) + sid = bytes([7]) + bytes(31) + s = Root.MANAGER.get_store_slot(sid) + new_code_vla = s.cast(gl.storage.VLA[gl.u8], 0) + new_code_vla.assign(C2) + Root.get().code_slot = s.as_int() + Root.get().code.get().truncate() + print('deployed') + + @gl.public.write + def foo(self) -> None: + print('C1.foo should not run') diff --git a/tests/cases/stable/runners/map_no_read_perm.0.stdout b/tests/cases/stable/runners/map_no_read_perm.0.stdout new file mode 100644 index 000000000..e26bb8a09 --- /dev/null +++ b/tests/cases/stable/runners/map_no_read_perm.0.stdout @@ -0,0 +1,2 @@ +forbidden: SystemError +executed with `Return(null)` diff --git a/tests/cases/stable/runners/map_no_read_perm.jsonnet b/tests/cases/stable/runners/map_no_read_perm.jsonnet new file mode 100644 index 000000000..67869cf15 --- /dev/null +++ b/tests/cases/stable/runners/map_no_read_perm.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/map_no_read_perm.py') {stable_hash: false, permissions: 'wscn'}])} diff --git a/tests/cases/stable/runners/map_no_read_perm.py b/tests/cases/stable/runners/map_no_read_perm.py new file mode 100644 index 000000000..17737d5fb --- /dev/null +++ b/tests/cases/stable/runners/map_no_read_perm.py @@ -0,0 +1,10 @@ +# { "Depends": "py-genlayer:test" } +from genlayer.vm import map_file + +# permissions for this case omit `r` (read_storage), so map_file must be refused +try: + map_file('contract', 'file', '/mapped') + print('mapped') +except Exception as e: + print(f'forbidden: {type(e).__name__}') +exit(0) diff --git a/tests/cases/semi-stable/llm/issue_288_compat.0.stdout b/tests/cases/stable/runners/map_runner_file.0.stdout similarity index 79% rename from tests/cases/semi-stable/llm/issue_288_compat.0.stdout rename to tests/cases/stable/runners/map_runner_file.0.stdout index f070642e8..ad485fd94 100644 --- a/tests/cases/semi-stable/llm/issue_288_compat.0.stdout +++ b/tests/cases/stable/runners/map_runner_file.0.stdout @@ -1,4 +1,2 @@ -dict -str True executed with `Return(null)` diff --git a/tests/cases/stable/runners/map_runner_file.jsonnet b/tests/cases/stable/runners/map_runner_file.jsonnet new file mode 100644 index 000000000..10c00840a --- /dev/null +++ b/tests/cases/stable/runners/map_runner_file.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/map_runner_file.py') {stable_hash: false, permissions: 'rwscnu'}])} diff --git a/tests/cases/stable/runners/map_runner_file.py b/tests/cases/stable/runners/map_runner_file.py new file mode 100644 index 000000000..aaeb14000 --- /dev/null +++ b/tests/cases/stable/runners/map_runner_file.py @@ -0,0 +1,9 @@ +# { "Depends": "py-genlayer:test" } +from genlayer.vm import register_runner, map_file + +code = b'# { "Depends": "py-genlayer:test" }\nmarker-12345\n' +rid = register_runner(code) +map_file(rid, 'file', '/mapped.txt') +with open('/mapped.txt', 'rb') as f: + print(f.read() == code) +exit(0) diff --git a/tests/cases/stable/runners/map_vm_runtime.0.stdout b/tests/cases/stable/runners/map_vm_runtime.0.stdout new file mode 100644 index 000000000..3a6b81bc5 --- /dev/null +++ b/tests/cases/stable/runners/map_vm_runtime.0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract malformed_runner")` diff --git a/tests/cases/stable/runners/map_vm_runtime.jsonnet b/tests/cases/stable/runners/map_vm_runtime.jsonnet new file mode 100644 index 000000000..5c0489864 --- /dev/null +++ b/tests/cases/stable/runners/map_vm_runtime.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/map_vm_runtime.py') {stable_hash: false}])} diff --git a/tests/cases/stable/runners/map_vm_runtime.py b/tests/cases/stable/runners/map_vm_runtime.py new file mode 100644 index 000000000..a7f7b4bab --- /dev/null +++ b/tests/cases/stable/runners/map_vm_runtime.py @@ -0,0 +1,8 @@ +# { "Depends": "py-genlayer:test" } +from genlayer.vm import map_file + +# mapping into /vm/ is forbidden; the runtime gl_call path must reject it just +# like the InitAction MapFile path does (see runners/map-vm). The rejection is a +# malformed_runner trap, so it terminates execution and is not catchable here. +map_file('contract', 'file', '/vm/evil.py') +exit(0) diff --git a/tests/cases/stable/runners/nondet_custom_runner.0.hash b/tests/cases/stable/runners/nondet_custom_runner.0.hash new file mode 100644 index 000000000..79bb40112 --- /dev/null +++ b/tests/cases/stable/runners/nondet_custom_runner.0.hash @@ -0,0 +1 @@ +LRGMAmludmFsaWRfY29udHJhY3QgbWFsZm9ybWVkX3J1bm5lcgAdFaMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAiG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmAAAAAIMKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZiehXnRQ2fBOnD2NLYVqjpx436AIHqLBKP3JPOLfNevWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIM2TQMAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnZtIGltcG9ydCByZWdpc3Rlcl9ydW5uZXIsIG1hcF9maWxlCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCSMgZGV0ZXJtaW5pc3RpYyBjb250ZXh0IHJlZ2lzdGVycyBhIGN1c3RvbSBydW5uZXIKCQljb2RlID0gYicjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfVxubWFya2VyXG4nCgkJcmlkID0gcmVnaXN0ZXJfcnVubmVyKGNvZGUpCgoJCWRlZiBsZWFkZXIoKToKCQkJIyBidXJuIGEgbG9uZyBsb29wIGZpcnN0LCB0aGVuIHRyeSB0byB1c2UgdGhlIGRldC1yZWdpc3RlcmVkIGN1c3RvbQoJCQkjIHJ1bm5lciBmcm9tIGluc2lkZSBub25kZXQuIEN1c3RvbSBydW5uZXJzIHNob3VsZCBiZSBzY29wZWQgdG8gdGhlCgkJCSMgZXhlY3V0aW9uIHRoYXQgcmVnaXN0ZXJlZCB0aGVtLCBzbyB0aGlzIG1hcCBNVVNUIGZhaWwg4oCUIGJ1dCB3aXRoIGEKCQkJIyBzaGFyZWQgcmVnaXN0cnkgaXQgbWF5IGxlYWsuCgkJCWZvciBfIGluIHJhbmdlKDEwKio0KToKCQkJCXBhc3MKCQkJdHJ5OgoJCQkJbWFwX2ZpbGUocmlkLCAnZmlsZScsICcvbWFwcGVkLnR4dCcpCgkJCQlyZXR1cm4gJ25vbmRldCBtYXBwZWQgZGV0LXJlZ2lzdGVyZWQgcnVubmVyIChMRUFLKScKCQkJZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJCQkJcmV0dXJuIGYnbm9uZGV0IG1hcCBmYWlsZWQ6IHt0eXBlKGUpLl9fbmFtZV9ffScKCgkJcHJpbnQoZ2wudm0ucnVuX25vbmRldChsZWFkZXIsIGxhbWJkYSByOiBUcnVlKSkKAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/runners/nondet_custom_runner.0.stdout b/tests/cases/stable/runners/nondet_custom_runner.0.stdout new file mode 100644 index 000000000..3a6b81bc5 --- /dev/null +++ b/tests/cases/stable/runners/nondet_custom_runner.0.stdout @@ -0,0 +1 @@ +executed with `VMError("invalid_contract malformed_runner")` diff --git a/tests/cases/stable/runners/nondet_custom_runner.jsonnet b/tests/cases/stable/runners/nondet_custom_runner.jsonnet new file mode 100644 index 000000000..23ed8292d --- /dev/null +++ b/tests/cases/stable/runners/nondet_custom_runner.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/nondet_custom_runner.py') {permissions: 'rwscnu'}])} diff --git a/tests/cases/stable/runners/nondet_custom_runner.py b/tests/cases/stable/runners/nondet_custom_runner.py new file mode 100644 index 000000000..6fe7ad73b --- /dev/null +++ b/tests/cases/stable/runners/nondet_custom_runner.py @@ -0,0 +1,25 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.vm import register_runner, map_file + + +class Contract(gl.contract.Contract): + def __init__(self): + # deterministic context registers a custom runner + code = b'# { "Depends": "py-genlayer:test" }\nmarker\n' + rid = register_runner(code) + + def leader(): + # burn a long loop first, then try to use the det-registered custom + # runner from inside nondet. Custom runners should be scoped to the + # execution that registered them, so this map MUST fail — but with a + # shared registry it may leak. + for _ in range(10**4): + pass + try: + map_file(rid, 'file', '/mapped.txt') + return 'nondet mapped det-registered runner (LEAK)' + except Exception as e: + return f'nondet map failed: {type(e).__name__}' + + print(gl.vm.run_nondet(leader, lambda r: True)) diff --git a/tests/cases/stable/runners/register-runner.0.stdout b/tests/cases/stable/runners/register-runner.0.stdout new file mode 100644 index 000000000..b0c147d23 --- /dev/null +++ b/tests/cases/stable/runners/register-runner.0.stdout @@ -0,0 +1,2 @@ +custom:yn1hm19g13tqxzyp0dphfy63jgwtws8hyg3xsqb2vf7jfvjd9d60 +executed with `Return(null)` diff --git a/tests/cases/stable/runners/register-runner.jsonnet b/tests/cases/stable/runners/register-runner.jsonnet new file mode 100644 index 000000000..af20f0548 --- /dev/null +++ b/tests/cases/stable/runners/register-runner.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/register-runner.py') {stable_hash: false, permissions: 'rwscnu'}])} diff --git a/tests/cases/stable/runners/register-runner.py b/tests/cases/stable/runners/register-runner.py new file mode 100644 index 000000000..8539e9bf3 --- /dev/null +++ b/tests/cases/stable/runners/register-runner.py @@ -0,0 +1,7 @@ +# { "Depends": "py-genlayer:test" } + +from genlayer.vm import register_runner + +code = b'# { "Depends": "py-genlayer:test" }\nexit(0)\n' +print(register_runner(code)) +exit(0) diff --git a/tests/cases/stable/runners/register_loop.0.stdout b/tests/cases/stable/runners/register_loop.0.stdout new file mode 100644 index 000000000..76bab1f7a --- /dev/null +++ b/tests/cases/stable/runners/register_loop.0.stdout @@ -0,0 +1,2 @@ +custom:2b7ggf7f4ky8k3ytwfxdm1wjyvqy62anfb0ym0qc2qn5hw9pnyj0 +executed with `Return(null)` diff --git a/tests/cases/stable/runners/register_loop.jsonnet b/tests/cases/stable/runners/register_loop.jsonnet new file mode 100644 index 000000000..085594056 --- /dev/null +++ b/tests/cases/stable/runners/register_loop.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/register_loop.py') {stable_hash: false, permissions: 'rwscnu'}])} diff --git a/tests/cases/stable/runners/register_loop.py b/tests/cases/stable/runners/register_loop.py new file mode 100644 index 000000000..5f3b43666 --- /dev/null +++ b/tests/cases/stable/runners/register_loop.py @@ -0,0 +1,12 @@ +# { "Depends": "py-genlayer:test" } +from genlayer.vm import register_runner + +# Registering the same runner repeatedly must be idempotent: it returns the same +# id every time and (see the executor unit test `register_custom_runner_consumes_once`) +# charges the memory limit only once, so a loop like this cannot exhaust it. +code = b'# { "Depends": "py-genlayer:test" }\nx\n' + +ids = {register_runner(code) for _ in range(1000)} +assert len(ids) == 1, ids +print(next(iter(ids))) +exit(0) diff --git a/tests/cases/stable/runners/register_no_perm.0.stdout b/tests/cases/stable/runners/register_no_perm.0.stdout new file mode 100644 index 000000000..31d88ed50 --- /dev/null +++ b/tests/cases/stable/runners/register_no_perm.0.stdout @@ -0,0 +1,2 @@ +6: forbidden +executed with `Return(null)` diff --git a/tests/cases/stable/runners/register_no_perm.jsonnet b/tests/cases/stable/runners/register_no_perm.jsonnet new file mode 100644 index 000000000..d08dc2a9a --- /dev/null +++ b/tests/cases/stable/runners/register_no_perm.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/register_no_perm.py') {stable_hash: false}])} diff --git a/tests/cases/stable/runners/register_no_perm.py b/tests/cases/stable/runners/register_no_perm.py new file mode 100644 index 000000000..8e3d1cd64 --- /dev/null +++ b/tests/cases/stable/runners/register_no_perm.py @@ -0,0 +1,10 @@ +# { "Depends": "py-genlayer:test" } +from genlayer.vm import register_runner + +# default permissions (rwscn) do NOT grant `register_runners` (u) +try: + register_runner(b'# { "Depends": "py-genlayer:test" }\nx\n') + print('registered') +except Exception as e: + print(e) +exit(0) diff --git a/tests/cases/stable/runners/register_nondet.0.stdout b/tests/cases/stable/runners/register_nondet.0.stdout new file mode 100644 index 000000000..e26bb8a09 --- /dev/null +++ b/tests/cases/stable/runners/register_nondet.0.stdout @@ -0,0 +1,2 @@ +forbidden: SystemError +executed with `Return(null)` diff --git a/tests/cases/stable/runners/register_nondet.jsonnet b/tests/cases/stable/runners/register_nondet.jsonnet new file mode 100644 index 000000000..b744a3f9d --- /dev/null +++ b/tests/cases/stable/runners/register_nondet.jsonnet @@ -0,0 +1,3 @@ +local simple = import 'templates/simple_deploy.jsonnet'; +local util = import 'templates/util.jsonnet'; +{entry: util.addPaths([simple.run('${jsonnetDir}/register_nondet.py') {stable_hash: false, permissions: 'rwscnu'}])} diff --git a/tests/cases/stable/runners/register_nondet.py b/tests/cases/stable/runners/register_nondet.py new file mode 100644 index 000000000..3a1afbe20 --- /dev/null +++ b/tests/cases/stable/runners/register_nondet.py @@ -0,0 +1,18 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.vm import register_runner + + +class Contract(gl.contract.Contract): + def __init__(self): + def leader(): + # register_runner is deterministic-only; calling it from inside a + # nondet block must be refused even though `u` (register) is granted, + # i.e. the rejection comes from the is_deterministic gate, not perms. + try: + register_runner(b'# { "Depends": "py-genlayer:test" }\nx\n') + return 'registered (LEAK)' + except Exception as e: + return f'forbidden: {type(e).__name__}' + + print(gl.vm.run_nondet(leader, lambda r: True)) diff --git a/tests/cases/stable/runners/sandbox_custom_runner.0.stdout b/tests/cases/stable/runners/sandbox_custom_runner.0.stdout new file mode 100644 index 000000000..d7a30c4e7 --- /dev/null +++ b/tests/cases/stable/runners/sandbox_custom_runner.0.stdout @@ -0,0 +1,3 @@ +custom runner ran +sandbox -> Return(calldata=42) +executed with `Return(null)` diff --git a/tests/cases/semi-stable/llm/issue_288_compat.jsonnet b/tests/cases/stable/runners/sandbox_custom_runner.jsonnet similarity index 75% rename from tests/cases/semi-stable/llm/issue_288_compat.jsonnet rename to tests/cases/stable/runners/sandbox_custom_runner.jsonnet index 41bee2aef..579b652bd 100644 --- a/tests/cases/semi-stable/llm/issue_288_compat.jsonnet +++ b/tests/cases/stable/runners/sandbox_custom_runner.jsonnet @@ -1,6 +1,3 @@ local simple = import 'templates/simple_deploy.jsonnet'; local util = import 'templates/util.jsonnet'; -{entry: util.addPaths([simple.run('${jsonnetDir}/${fileBaseName}.py') { - stable_hash: false, - modes: 'l', -}])} +{entry: util.addPaths([simple.run('${jsonnetDir}/${fileBaseName}.py') {stable_hash: false, permissions: 'rwscnu'}])} diff --git a/tests/cases/stable/runners/sandbox_custom_runner.py b/tests/cases/stable/runners/sandbox_custom_runner.py new file mode 100644 index 000000000..b2e596f1a --- /dev/null +++ b/tests/cases/stable/runners/sandbox_custom_runner.py @@ -0,0 +1,32 @@ +# { "Depends": "py-genlayer:test" } +import genlayer as gl +from genlayer.vm import register_runner + +import json + + +class Contract(gl.contract.Contract): + def __init__(self): + runner = { + 'Seq': [ + { + 'With': { + 'action': {'MapFile': {'file': 'file', 'to': '/contract.py'}}, + 'runner': 'contract', + } + }, + {'SetArgs': ['py', '-u', '-B', '/contract.py']}, + {'Depends': 'py-lib-cloudpickle:test'}, + {'Depends': 'py-lib-genlayer-std:test'}, + {'Depends': 'cpython:test'}, + ] + } + runner_dumped = json.dumps(runner) + code = ( + f'# {runner_dumped}\n' + 'print("custom runner ran")\n' + "exec(open('/py/libs/_genlayer_bootloader.py').read())\n" + ) + rid = register_runner(code.encode('utf-8')) + res = gl.vm.spawn_sandbox(lambda: 42, runner=rid) + print('sandbox ->', res) diff --git a/tests/cases/stable/runners/zip/no-zip.0.hash b/tests/cases/stable/runners/zip/no-zip.0.hash index d044d0993..30b2dd353 100644 --- a/tests/cases/stable/runners/zip/no-zip.0.hash +++ b/tests/cases/stable/runners/zip/no-zip.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDDKsAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlwcmludCgnaGVsbG8gd29ybGQnKQoAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwyrAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZik6CgkJcHJpbnQoJ2hlbGxvIHdvcmxkJykKAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/self-run/datetime.0.hash b/tests/cases/stable/self-run/datetime.0.hash index 48066a940..d5e43b80c 100644 --- a/tests/cases/stable/self-run/datetime.0.hash +++ b/tests/cases/stable/self-run/datetime.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDCF4AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGRhdGV0aW1lCgpwcmludChkYXRldGltZS5kYXRldGltZS5ub3coKSkKCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwheAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBkYXRldGltZQoKcHJpbnQoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KCkpCgpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/self-run/floats.0.hash b/tests/cases/stable/self-run/floats.0.hash index 052b7aa11..d14ee96da 100644 --- a/tests/cases/stable/self-run/floats.0.hash +++ b/tests/cases/stable/self-run/floats.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/self-run/formats.0.hash b/tests/cases/stable/self-run/formats.0.hash index eec520be3..1e7481d7d 100644 --- a/tests/cases/stable/self-run/formats.0.hash +++ b/tests/cases/stable/self-run/formats.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDJB0CAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKZnJvbSBnZW5sYXllci5zdG9yYWdlLl9pbnRlcm5hbC5nZW5lcmF0ZSBpbXBvcnQgZ2VuZXJhdGVfc3RvcmFnZQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgQWRkcmVzcwoKCkBnZW5lcmF0ZV9zdG9yYWdlCmNsYXNzIFRlc3Q6CglhcnI6IGdsLkR5bkFycmF5W3N0cl0KCW1hcDogZ2wuVHJlZU1hcFtzdHIsIE5vbmVdCgoKYWRkciA9IEFkZHJlc3MoYidceGEyJyAqIDIwKQpwcmludChhZGRyKQpwcmludChmJ3thZGRyfScpCnByaW50KGYne2FkZHIhcn0nKQpwcmludChmJ3thZGRyIXN9JykKcHJpbnQoZid7YWRkcjpjZH0nKQpwcmludChmJ3thZGRyOmI2NH0nKQpwcmludChmJ3thZGRyOnh9JykKcHJpbnQoZid7YWRkcjp9JykKCnQgPSBUZXN0KCkKdC5hcnIuZXh0ZW5kKFsnMScsICcyJywgJzMnXSkKdC5tYXAudXBkYXRlKHsnMSc6IE5vbmUsICc0JzogTm9uZX0pCnByaW50KGYne3QuYXJyfScpCnByaW50KGYne3QubWFwfScpCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyQdAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmZyb20gZ2VubGF5ZXIuc3RvcmFnZS5faW50ZXJuYWwuZ2VuZXJhdGUgaW1wb3J0IGdlbmVyYXRlX3N0b3JhZ2UKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0IEFkZHJlc3MKCgpAZ2VuZXJhdGVfc3RvcmFnZQpjbGFzcyBUZXN0OgoJYXJyOiBnbC5EeW5BcnJheVtzdHJdCgltYXA6IGdsLlRyZWVNYXBbc3RyLCBOb25lXQoKCmFkZHIgPSBBZGRyZXNzKGInXHhhMicgKiAyMCkKcHJpbnQoYWRkcikKcHJpbnQoZid7YWRkcn0nKQpwcmludChmJ3thZGRyIXJ9JykKcHJpbnQoZid7YWRkciFzfScpCnByaW50KGYne2FkZHI6Y2R9JykKcHJpbnQoZid7YWRkcjpiNjR9JykKcHJpbnQoZid7YWRkcjp4fScpCnByaW50KGYne2FkZHI6fScpCgp0ID0gVGVzdCgpCnQuYXJyLmV4dGVuZChbJzEnLCAnMicsICczJ10pCnQubWFwLnVwZGF0ZSh7JzEnOiBOb25lLCAnNCc6IE5vbmV9KQpwcmludChmJ3t0LmFycn0nKQpwcmludChmJ3t0Lm1hcH0nKQpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/self-run/issue_163.0.hash b/tests/cases/stable/self-run/issue_163.0.hash index b171a0f9b..d4a79330a 100644 --- a/tests/cases/stable/self-run/issue_163.0.hash +++ b/tests/cases/stable/self-run/issue_163.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFCgBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKZnJvbSBnZW5sYXllci5zdG9yYWdlLl9pbnRlcm5hbC5nZW5lcmF0ZSBpbXBvcnQgZ2VuZXJhdGVfc3RvcmFnZQoKCkBnZW5lcmF0ZV9zdG9yYWdlCmNsYXNzIFByOgoJeDogZ2wuVHJlZU1hcFtzdHIsIHN0cl0KCgphID0gUHIoKQoKdHJ5OgoJYS54ID0geyd4JzogJ3knfQpleGNlcHQgQXNzZXJ0aW9uRXJyb3IgYXMgZToKCXByaW50KCplLmFyZ3MpCgpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxQoAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZS5faW50ZXJuYWwuZ2VuZXJhdGUgaW1wb3J0IGdlbmVyYXRlX3N0b3JhZ2UKCgpAZ2VuZXJhdGVfc3RvcmFnZQpjbGFzcyBQcjoKCXg6IGdsLlRyZWVNYXBbc3RyLCBzdHJdCgoKYSA9IFByKCkKCnRyeToKCWEueCA9IHsneCc6ICd5J30KZXhjZXB0IEFzc2VydGlvbkVycm9yIGFzIGU6CglwcmludCgqZS5hcmdzKQoKZXhpdCgwKQoAAAAAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/self-run/module/np.0.hash b/tests/cases/stable/self-run/module/np.0.hash index fdc7e4cac..666bae33b 100644 --- a/tests/cases/stable/self-run/module/np.0.hash +++ b/tests/cases/stable/self-run/module/np.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDCGsAAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgbnVtcHkgYXMgbnAKCnByaW50KG5wLmFycmF5KFsxLCAyLCAzXSwgZHR5cGU9aW50KSAqKiAyKQpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwhrAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IG51bXB5IGFzIG5wCgpwcmludChucC5hcnJheShbMSwgMiwgM10sIGR0eXBlPWludCkgKiogMikKZXhpdCgwKQoAAAAAAAAAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/self-run/module/pil.0.hash b/tests/cases/stable/self-run/module/pil.0.hash index 2106a4c29..ad0d3e255 100644 --- a/tests/cases/stable/self-run/module/pil.0.hash +++ b/tests/cases/stable/self-run/module/pil.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/self-run/re.0.hash b/tests/cases/stable/self-run/re.0.hash index ead28ebeb..e70341d58 100644 --- a/tests/cases/stable/self-run/re.0.hash +++ b/tests/cases/stable/self-run/re.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDJCwCAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IHJlCgphc3NlcnQgcmUubWF0Y2goJyhhYnxiYSknLCAnYWInKS5zcGFuKCkgPT0gKDAsIDIpCmFzc2VydCByZS5tYXRjaCgnKGFifGJhKScsICdiYScpLnNwYW4oKSA9PSAoMCwgMikKYXNzZXJ0IHJlLm1hdGNoKCcoYWJjfGJhY3xjYXxjYiknLCAnYWJjJykuc3BhbigpID09ICgwLCAzKQphc3NlcnQgcmUubWF0Y2goJyhhYmN8YmFjfGNhfGNiKScsICdiYWMnKS5zcGFuKCkgPT0gKDAsIDMpCmFzc2VydCByZS5tYXRjaCgnKGFiY3xiYWN8Y2F8Y2IpJywgJ2NhJykuc3BhbigpID09ICgwLCAyKQphc3NlcnQgcmUubWF0Y2goJyhhYmN8YmFjfGNhfGNiKScsICdjYicpLnNwYW4oKSA9PSAoMCwgMikKYXNzZXJ0IHJlLm1hdGNoKCcoKGEpfChiKXwoYykpJywgJ2EnKS5zcGFuKCkgPT0gKDAsIDEpCmFzc2VydCByZS5tYXRjaCgnKChhKXwoYil8KGMpKScsICdiJykuc3BhbigpID09ICgwLCAxKQphc3NlcnQgcmUubWF0Y2goJygoYSl8KGIpfChjKSknLCAnYycpLnNwYW4oKSA9PSAoMCwgMSkKCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAU= +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyQsAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCByZQoKYXNzZXJ0IHJlLm1hdGNoKCcoYWJ8YmEpJywgJ2FiJykuc3BhbigpID09ICgwLCAyKQphc3NlcnQgcmUubWF0Y2goJyhhYnxiYSknLCAnYmEnKS5zcGFuKCkgPT0gKDAsIDIpCmFzc2VydCByZS5tYXRjaCgnKGFiY3xiYWN8Y2F8Y2IpJywgJ2FiYycpLnNwYW4oKSA9PSAoMCwgMykKYXNzZXJ0IHJlLm1hdGNoKCcoYWJjfGJhY3xjYXxjYiknLCAnYmFjJykuc3BhbigpID09ICgwLCAzKQphc3NlcnQgcmUubWF0Y2goJyhhYmN8YmFjfGNhfGNiKScsICdjYScpLnNwYW4oKSA9PSAoMCwgMikKYXNzZXJ0IHJlLm1hdGNoKCcoYWJjfGJhY3xjYXxjYiknLCAnY2InKS5zcGFuKCkgPT0gKDAsIDIpCmFzc2VydCByZS5tYXRjaCgnKChhKXwoYil8KGMpKScsICdhJykuc3BhbigpID09ICgwLCAxKQphc3NlcnQgcmUubWF0Y2goJygoYSl8KGIpfChjKSknLCAnYicpLnNwYW4oKSA9PSAoMCwgMSkKYXNzZXJ0IHJlLm1hdGNoKCcoKGEpfChiKXwoYykpJywgJ2MnKS5zcGFuKCkgPT0gKDAsIDEpCgpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/self-run/typing_is_ok.0.hash b/tests/cases/stable/self-run/typing_is_ok.0.hash index 1b057c1ae..c221ee8ff 100644 --- a/tests/cases/stable/self-run/typing_is_ok.0.hash +++ b/tests/cases/stable/self-run/typing_is_ok.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDKpkCAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKIyBmcm9tIF9fZnV0dXJlX18gaW1wb3J0IGFubm90YXRpb25zCgppbXBvcnQgdHlwaW5nCmltcG9ydCB0eXBlcwoKCmNsYXNzIEZvb1tYXToKCWE6IFgKCgpkZWYgdHN0KHgpOgoJcHJpbnQoZic9PT0ge3guX19uYW1lX199JykKCXByaW50KHR5cGUoeCkpCglwcmludCh4KQoJaWYgaXNpbnN0YW5jZSh4LCB0eXBlcy5HZW5lcmljQWxpYXMpOgoJCXByaW50KGYnb3JpZ2luPXt4Ll9fb3JpZ2luX199JykKCQlwcmludChmJ2FyZ3M9e3guX19hcmdzX199JykKCWVsaWYgaXNpbnN0YW5jZSh4LCB0eXBpbmcuX0dlbmVyaWNBbGlhcyk6ICAjIHR5cGU6IGlnbm9yZQoJCXByaW50KGYnb3JpZ2luPXt4Ll9fb3JpZ2luX199JykKCQlwcmludChmJ2FyZ3M9e3guX19hcmdzX199JykKCWlmIG5vdCBpc2luc3RhbmNlKHgsIHR5cGVzLkdlbmVyaWNBbGlhcyk6CgkJZm9yIGssIHYgaW4gdHlwaW5nLmdldF90eXBlX2hpbnRzKHgpLml0ZW1zKCk6CgkJCWlmIGlzaW5zdGFuY2UodiwgdHlwaW5nLlR5cGVWYXIpOgoJCQkJdiA9IHYuX19uYW1lX18KCQkJcHJpbnQoZidcdHtrfToge3Z9JykKCgp0c3QoRm9vKQoKdHN0KGxpc3Rbc3RyXSkKCgpjbGFzcyBUZXN0OgoJZm9vOiBGb29bc3RyXQoKCnRzdChUZXN0KQpleGl0KDApCgAAAAU= +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyqZAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCiMgZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBhbm5vdGF0aW9ucwoKaW1wb3J0IHR5cGluZwppbXBvcnQgdHlwZXMKCgpjbGFzcyBGb29bWF06CglhOiBYCgoKZGVmIHRzdCh4KToKCXByaW50KGYnPT09IHt4Ll9fbmFtZV9ffScpCglwcmludCh0eXBlKHgpKQoJcHJpbnQoeCkKCWlmIGlzaW5zdGFuY2UoeCwgdHlwZXMuR2VuZXJpY0FsaWFzKToKCQlwcmludChmJ29yaWdpbj17eC5fX29yaWdpbl9ffScpCgkJcHJpbnQoZidhcmdzPXt4Ll9fYXJnc19ffScpCgllbGlmIGlzaW5zdGFuY2UoeCwgdHlwaW5nLl9HZW5lcmljQWxpYXMpOiAgIyB0eXBlOiBpZ25vcmUKCQlwcmludChmJ29yaWdpbj17eC5fX29yaWdpbl9ffScpCgkJcHJpbnQoZidhcmdzPXt4Ll9fYXJnc19ffScpCglpZiBub3QgaXNpbnN0YW5jZSh4LCB0eXBlcy5HZW5lcmljQWxpYXMpOgoJCWZvciBrLCB2IGluIHR5cGluZy5nZXRfdHlwZV9oaW50cyh4KS5pdGVtcygpOgoJCQlpZiBpc2luc3RhbmNlKHYsIHR5cGluZy5UeXBlVmFyKToKCQkJCXYgPSB2Ll9fbmFtZV9fCgkJCXByaW50KGYnXHR7a306IHt2fScpCgoKdHN0KEZvbykKCnRzdChsaXN0W3N0cl0pCgoKY2xhc3MgVGVzdDoKCWZvbzogRm9vW3N0cl0KCgp0c3QoVGVzdCkKZXhpdCgwKQoAAAAF diff --git a/tests/cases/stable/storage/alloc_generic.0.hash b/tests/cases/stable/storage/alloc_generic.0.hash index 17def795e..874d5188c 100644 --- a/tests/cases/stable/storage/alloc_generic.0.hash +++ b/tests/cases/stable/storage/alloc_generic.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDEhABAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKZnJvbSBnZW5sYXllci5zdG9yYWdlIGltcG9ydCBhbGxvdwpmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MKCgpAYWxsb3cKQGRhdGFjbGFzcwpjbGFzcyBUZXN0W1RdOgoJZm9vOiBUCgoKdHN0ID0gZ2wuc3RvcmFnZS5pbm1lbV9hbGxvY2F0ZShUZXN0W3N0cl0sICcxMjMnKQpwcmludCh0c3QpCgpleGl0KDApCgAAAAAAAAAAAAAAAAU= +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxIQAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZSBpbXBvcnQgYWxsb3cKZnJvbSBkYXRhY2xhc3NlcyBpbXBvcnQgZGF0YWNsYXNzCgoKQGFsbG93CkBkYXRhY2xhc3MKY2xhc3MgVGVzdFtUXToKCWZvbzogVAoKCnRzdCA9IGdsLnN0b3JhZ2UuaW5tZW1fYWxsb2NhdGUoVGVzdFtzdHJdLCAnMTIzJykKcHJpbnQodHN0KQoKZXhpdCgwKQoAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/storage/alloc_generic_err.0.hash b/tests/cases/stable/storage/alloc_generic_err.0.hash index 91f631757..a29979154 100644 --- a/tests/cases/stable/storage/alloc_generic_err.0.hash +++ b/tests/cases/stable/storage/alloc_generic_err.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDHKgBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKZnJvbSBnZW5sYXllci5zdG9yYWdlIGltcG9ydCBhbGxvdwpmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MKZnJvbSBnZW5sYXllci5zdG9yYWdlLl9pbnRlcm5hbC5nZW5lcmF0ZSBpbXBvcnQgZ2VuZXJhdGVfc3RvcmFnZQoKCkBhbGxvdwpAZGF0YWNsYXNzCmNsYXNzIFRlc3RbVF06Cglmb286IFQKCgpAZ2VuZXJhdGVfc3RvcmFnZQpjbGFzcyBCYXI6Cgl0OiBUZXN0W3N0cl0KCgp0cnk6Cgl0c3QgPSBUZXN0KCcxMjMnKQoJcHJpbnQodHN0KQpleGNlcHQgRXhjZXB0aW9uIGFzIGU6CglwcmludChlKQoJZm9yIG4gaW4gZS5fX25vdGVzX186CgkJcHJpbnQobikKCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxyoAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZSBpbXBvcnQgYWxsb3cKZnJvbSBkYXRhY2xhc3NlcyBpbXBvcnQgZGF0YWNsYXNzCmZyb20gZ2VubGF5ZXIuc3RvcmFnZS5faW50ZXJuYWwuZ2VuZXJhdGUgaW1wb3J0IGdlbmVyYXRlX3N0b3JhZ2UKCgpAYWxsb3cKQGRhdGFjbGFzcwpjbGFzcyBUZXN0W1RdOgoJZm9vOiBUCgoKQGdlbmVyYXRlX3N0b3JhZ2UKY2xhc3MgQmFyOgoJdDogVGVzdFtzdHJdCgoKdHJ5OgoJdHN0ID0gVGVzdCgnMTIzJykKCXByaW50KHRzdCkKZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgoJcHJpbnQoZSkKCWZvciBuIGluIGUuX19ub3Rlc19fOgoJCXByaW50KG4pCgpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/storage/base.0.hash b/tests/cases/stable/storage/base.0.hash index 05ecc3fda..17b366cc0 100644 --- a/tests/cases/stable/storage/base.0.hash +++ b/tests/cases/stable/storage/base.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDJlgCAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKZnJvbSBnZW5sYXllci5zdG9yYWdlIGltcG9ydCBhbGxvdwpmcm9tIGdlbmxheWVyLnN0b3JhZ2UuX2ludGVybmFsLmdlbmVyYXRlIGltcG9ydCBnZW5lcmF0ZV9zdG9yYWdlCgoKQGFsbG93CmNsYXNzIFRlc3Q6Cglmb286IGk2NAoJYmFyOiBpNjQKCXN0OiBzdHIKCglkZWYgYWJjKHNlbGYpOgoJCXJldHVybiBzZWxmLmZvbwoKCkBnZW5lcmF0ZV9zdG9yYWdlCmNsYXNzIENvbXBvc2l0ZToKCWE6IFRlc3QKCWI6IFRlc3QKCgp0c3QgPSBDb21wb3NpdGUoKQoKc3Rvcl9tYW4gPSB0c3QuX3N0b3JhZ2Vfc2xvdC5tYW5hZ2VyICAjIHR5cGU6IGlnbm9yZQoKdHN0LmEuZm9vID0gNjU1MzUKdHN0LmEuYmFyID0gMioqMzIKdHN0LmEuc3QgPSAnMTIzJwp0c3QuYi5mb28gPSAxMwp0c3QuYi5zdCA9ICczMjEnCgpzdG9yX21hbi5kZWJ1ZygpCnByaW50KHRzdC5hLnN0LCB0c3QuYi5zdCkKCnRzdC5hID0gdHN0LmIKCnN0b3JfbWFuLmRlYnVnKCkKcHJpbnQodHN0LmEuc3QsIHRzdC5iLnN0KQoKZXhpdCgwKQoAAAAABQ== +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgyZYAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZSBpbXBvcnQgYWxsb3cKZnJvbSBnZW5sYXllci5zdG9yYWdlLl9pbnRlcm5hbC5nZW5lcmF0ZSBpbXBvcnQgZ2VuZXJhdGVfc3RvcmFnZQoKCkBhbGxvdwpjbGFzcyBUZXN0OgoJZm9vOiBpNjQKCWJhcjogaTY0CglzdDogc3RyCgoJZGVmIGFiYyhzZWxmKToKCQlyZXR1cm4gc2VsZi5mb28KCgpAZ2VuZXJhdGVfc3RvcmFnZQpjbGFzcyBDb21wb3NpdGU6CglhOiBUZXN0CgliOiBUZXN0CgoKdHN0ID0gQ29tcG9zaXRlKCkKCnN0b3JfbWFuID0gdHN0Ll9zdG9yYWdlX3Nsb3QubWFuYWdlciAgIyB0eXBlOiBpZ25vcmUKCnRzdC5hLmZvbyA9IDY1NTM1CnRzdC5hLmJhciA9IDIqKjMyCnRzdC5hLnN0ID0gJzEyMycKdHN0LmIuZm9vID0gMTMKdHN0LmIuc3QgPSAnMzIxJwoKc3Rvcl9tYW4uZGVidWcoKQpwcmludCh0c3QuYS5zdCwgdHN0LmIuc3QpCgp0c3QuYSA9IHRzdC5iCgpzdG9yX21hbi5kZWJ1ZygpCnByaW50KHRzdC5hLnN0LCB0c3QuYi5zdCkKCmV4aXQoMCkKAAAAAAU= diff --git a/tests/cases/stable/storage/bootstrapper.0.hash b/tests/cases/stable/storage/bootstrapper.0.hash index 18830c28b..13146592d 100644 --- a/tests/cases/stable/storage/bootstrapper.0.hash +++ b/tests/cases/stable/storage/bootstrapper.0.hash @@ -1 +1 @@ -LQEAAB0VowKiRi7bAKscdB3IgeOx6Og55TTHvN8qFSvIb65Eo5cweQAAAACDCogAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACD4AHjDQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCB0eXBpbmcKCmltcG9ydCBnZW5sYXllciBhcyBnbAoKX0NBTENfTUFOQUdFUiA9IGdsLnN0b3JhZ2UuSW5tZW1NYW5hZ2VyKCkKQ09ERV9TTE9UID0gKAoJX0NBTENfTUFOQUdFUi5nZXRfc3RvcmVfc2xvdChnbC5zdG9yYWdlLlJPT1RfU0xPVF9JRCkKCS5pbmRpcmVjdChnbC52bS5BQkkucm9vdF9vZmZzZXRzLkNPREUpCgkuaWQKKQpMT0NLRURfU0xPVCA9ICgKCV9DQUxDX01BTkFHRVIuZ2V0X3N0b3JlX3Nsb3QoZ2wuc3RvcmFnZS5ST09UX1NMT1RfSUQpCgkuaW5kaXJlY3QoZ2wudm0uQUJJLnJvb3Rfb2Zmc2V0cy5MT0NLRURfU0xPVFMpCgkuaWQKKQoKVkFDQU5UX1NMT1QgPSBfQ0FMQ19NQU5BR0VSLmdldF9zdG9yZV9zbG90KGdsLnN0b3JhZ2UuUk9PVF9TTE9UX0lEKS5pbmRpcmVjdCgKCWdsLnZtLkFCSS5yb290X29mZnNldHMuTUFKT1IKKQoKU1BFQ0lBTF9TTE9UUyA9IFtnbC5zdG9yYWdlLlJPT1RfU0xPVF9JRCwgQ09ERV9TTE9ULCBMT0NLRURfU0xPVF0KClNQRUNJQUxfU0xPVFNfVFdJTlMgPSB7CglzbHQ6IFZBQ0FOVF9TTE9ULmluZGlyZWN0KGkpLmlkIGZvciBpLCBzbHQgaW4gZW51bWVyYXRlKFNQRUNJQUxfU0xPVFMpCn0KCgpkZWYgZ2V0X3R3aW5fdmxhKHNsb3RfaWQ6IGJ5dGVzKSAtPiBnbC5zdG9yYWdlLlZMQVtnbC50eXBlcy51OF06CglyZXR1cm4gZ2wuc3RvcmFnZS5jYXN0X3Nsb3QoCgkJZ2wuc3RvcmFnZS5WTEFbZ2wudHlwZXMudThdLCBnbC5zdG9yYWdlLlJvb3QuTUFOQUdFUiwgc2xvdF9pZCwgMAoJKQoKCmRlZiB3cml0ZV90b190d2luKHNsb3RfaWQ6IGJ5dGVzLCBvZmZzZXQ6IGludCwgZGF0YTogYnl0ZXMpOgoJYXNfdmxhID0gZ2V0X3R3aW5fdmxhKHNsb3RfaWQpCglvbGRfbGVuID0gbGVuKGFzX3ZsYSkKCWFzX3ZsYS5zbG90KCkud3JpdGUoYXNfdmxhLmRhdGFfb2Zmc2V0KCkgKyBvZmZzZXQsIGRhdGEpCglhc192bGEuc2V0X2xlbmd0aChtYXgob2xkX2xlbiwgb2Zmc2V0ICsgbGVuKGRhdGEpKSkKCgpkZWYgcmVhZF9mcm9tX3R3aW4oc2xvdF9pZDogYnl0ZXMsIG9mZnNldDogaW50LCBsZW5ndGg6IGludCkgLT4gYnl0ZXM6CglzbG90ID0gZ2wuc3RvcmFnZS5Sb290Lk1BTkFHRVIuZ2V0X3N0b3JlX3Nsb3Qoc2xvdF9pZCkKCXJldHVybiBzbG90LnJlYWQob2Zmc2V0ICsgNCwgbGVuZ3RoKQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCAqLCBzYXZlX2RlZmF1bHRfbG9ja2VkX3Nsb3RzOiBib29sID0gVHJ1ZSk6CgkJcm9vdCA9IGdsLnN0b3JhZ2UuUm9vdC5nZXQoKQoKCQlpZiBzYXZlX2RlZmF1bHRfbG9ja2VkX3Nsb3RzOgoJCQl0d2luX3Nsb3RfaWQgPSBTUEVDSUFMX1NMT1RTX1RXSU5TW0xPQ0tFRF9TTE9UXQoJCQlsb2NrZWRfc2xvdHNfZHN0ID0gZ2wuc3RvcmFnZS5jYXN0X3Nsb3QoCgkJCQlnbC5zdG9yYWdlLlZMQVtnbC50eXBlcy51MjU2XSwgZ2wuc3RvcmFnZS5Sb290Lk1BTkFHRVIsIHR3aW5fc2xvdF9pZCwgNAoJCQkpCgkJCWxvY2tlZF9zbG90c19kc3QuYXNzaWduKHJvb3QubG9ja2VkX3Nsb3RzLmdldCgpKQoKCQkJbG9ja2VkX3Nsb3RzX2RzdF92bGEgPSBnZXRfdHdpbl92bGEodHdpbl9zbG90X2lkKQoJCQlsb2NrZWRfc2xvdHNfZHN0X3ZsYS5zZXRfbGVuZ3RoKAoJCQkJbGVuKGxvY2tlZF9zbG90c19kc3QpICogMzIgKyBsb2NrZWRfc2xvdHNfZHN0LmRhdGFfb2Zmc2V0KCkKCQkJKQoKCQlyb290LmxvY2tlZF9zbG90cy5nZXQoKS50cnVuY2F0ZSgpCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIHdyaXRlKHNlbGYsIGRhdGE6IGxpc3RbdHlwaW5nLkFueV0pOgoJCSIiIgoJCVdyaXRlIGRhdGEgdG8gdGhlIGNvbnRyYWN0LgoKCQk6cGFyYW0gZGF0YTogbGlzdCBvZiBkYXRhIGl0ZW1zIHRvIHdyaXRlIGluIGZvcm1hdCBgYChzbG90OiBieXRlWzMyXSwgb2Zmc2V0OiB1MzIsIGRhdGE6IGJ5dGVzKWBgCgkJIiIiCgoJCWZvciBzbG90LCBvZmZzZXQsIHNsaWNlIGluIGRhdGE6CgkJCWlmIHNsb3QgaW4gU1BFQ0lBTF9TTE9UU19UV0lOUy52YWx1ZXMoKToKCQkJCWdsLnZtLlVzZXJFcnJvci5pbW1lZGlhdGUoJ0Nhbm5vdCB3cml0ZSB0byB0aGUgdGVtcG9yYXJ5IGNvZGUgc2xvdHMnKQoJCQlpZiB0d2luIDo9IFNQRUNJQUxfU0xPVFNfVFdJTlMuZ2V0KHNsb3QpOgoJCQkJd3JpdGVfdG9fdHdpbih0d2luLCBvZmZzZXQsIHNsaWNlKQoJCQllbHNlOgoJCQkJZ2wuc3RvcmFnZS5Sb290Lk1BTkFHRVIuZ2V0X3N0b3JlX3Nsb3Qoc2xvdCkud3JpdGUob2Zmc2V0LCBzbGljZSkKCglAZ2wucHVibGljLndyaXRlCglkZWYgcHVzaF9jb2RlKHNlbGYsIGNvZGU6IGJ5dGVzKToKCQkiIiIKCQlQdXNoIGNvZGUgdG8gdGhlIGNvbnRyYWN0LiBUaGlzIHdpbGwgd3JpdGUgdGhlIGNvZGUgdG8gYSB0ZW1wb3Jhcnkgc2xvdCwgd2hpY2ggY2FuIGJlIGNvcGllZCB0byB0aGUgY29kZSBzbG90IGluIHRoZSBgYGZpbmlzaGBgIG1ldGhvZC4KCgkJOnBhcmFtIGNvZGU6IGNvZGUgdG8gcHVzaAoKCQkuLiB3YXJuaW5nOjoKCQkJRXhhY3RseSBvbmUgb2YgYGB3cml0ZWBgIG9yIGBgcHVzaF9jb2RlYGAgbXVzdCBiZSBjYWxsZWQgZm9yIGNvZGUgaW5pdGlhbGl6YXRpb24sCgkJCW90aGVyd2lzZSB0aGUgY29udHJhY3QgbWF5IGJlIGxlZnQgaW4gdW5kZWZpbmVkIHN0YXRlCgkJIiIiCgoJCXR3aW5fc2xvdF9pZCA9IFNQRUNJQUxfU0xPVFNfVFdJTlNbQ09ERV9TTE9UXQoJCWNvZGVfdHdpbl92bGEgPSBnZXRfdHdpbl92bGEodHdpbl9zbG90X2lkKQoJCWNvZGVfdmxhID0gZ2wuc3RvcmFnZS5jYXN0X3Nsb3QoCgkJCWdsLnN0b3JhZ2UuVkxBW2dsLnR5cGVzLnU4XSwgZ2wuc3RvcmFnZS5Sb290Lk1BTkFHRVIsIHR3aW5fc2xvdF9pZCwgNAoJCSkKCQljb2RlX3ZsYS5leHRlbmQoY29kZSkKCQluZXdfbGVuID0gbGVuKGNvZGVfdmxhKQoJCWNvZGVfdHdpbl92bGEuc2V0X2xlbmd0aChuZXdfbGVuICsgNCkKCglAZ2wucHVibGljLndyaXRlCglkZWYgZmluaXNoKHNlbGYpOgoJCSIiIgoJCUZpbmlzaCBib290c3RyYXBwaW5nLiBUaGlzIHdpbGwgY29weSB0aGUgY29kZSBmcm9tIHRoZSB0ZW1wb3Jhcnkgc2xvdCB0byB0aGUgY29kZSBzbG90IGFuZCBtYWtlIGl0IGF2YWlsYWJsZSBmb3IgZXhlY3V0aW9uLgoJCSIiIgoJCUJVRl9TSVpFID0gNjU1MzYKCQlmb3IgZHN0LCBzcmMgaW4gU1BFQ0lBTF9TTE9UU19UV0lOUy5pdGVtcygpOgoJCQl2bGFfZnJvbSA9IGdldF90d2luX3ZsYShzcmMpCgkJCWNvcHlfbGVuID0gbGVuKHZsYV9mcm9tKQoJCQl0byA9IGdsLnN0b3JhZ2UuUm9vdC5NQU5BR0VSLmdldF9zdG9yZV9zbG90KGRzdCkKCQkJZm9yIG9mZnNldCBpbiByYW5nZSgwLCBjb3B5X2xlbiwgQlVGX1NJWkUpOgoJCQkJY2h1bmtfc2l6ZSA9IG1pbihCVUZfU0laRSwgY29weV9sZW4gLSBvZmZzZXQpCgkJCQlkYXRhID0gdmxhX2Zyb20uc2xvdCgpLnJlYWQodmxhX2Zyb20uZGF0YV9vZmZzZXQoKSArIG9mZnNldCwgY2h1bmtfc2l6ZSkKCQkJCXRvLndyaXRlKG9mZnNldCwgZGF0YSkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAACUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAg+AB4w0AACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CgppbXBvcnQgdHlwaW5nCgppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKCl9DQUxDX01BTkFHRVIgPSBnbC5zdG9yYWdlLklubWVtTWFuYWdlcigpCkNPREVfU0xPVCA9ICgKCV9DQUxDX01BTkFHRVIuZ2V0X3N0b3JlX3Nsb3QoZ2wuc3RvcmFnZS5ST09UX1NMT1RfSUQpCgkuaW5kaXJlY3QoZ2wudm0uQUJJLnJvb3Rfb2Zmc2V0cy5DT0RFKQoJLmlkCikKTE9DS0VEX1NMT1QgPSAoCglfQ0FMQ19NQU5BR0VSLmdldF9zdG9yZV9zbG90KGdsLnN0b3JhZ2UuUk9PVF9TTE9UX0lEKQoJLmluZGlyZWN0KGdsLnZtLkFCSS5yb290X29mZnNldHMuTE9DS0VEX1NMT1RTKQoJLmlkCikKClZBQ0FOVF9TTE9UID0gX0NBTENfTUFOQUdFUi5nZXRfc3RvcmVfc2xvdChnbC5zdG9yYWdlLlJPT1RfU0xPVF9JRCkuaW5kaXJlY3QoCglnbC52bS5BQkkucm9vdF9vZmZzZXRzLk1BSk9SCikKClNQRUNJQUxfU0xPVFMgPSBbZ2wuc3RvcmFnZS5ST09UX1NMT1RfSUQsIENPREVfU0xPVCwgTE9DS0VEX1NMT1RdCgpTUEVDSUFMX1NMT1RTX1RXSU5TID0gewoJc2x0OiBWQUNBTlRfU0xPVC5pbmRpcmVjdChpKS5pZCBmb3IgaSwgc2x0IGluIGVudW1lcmF0ZShTUEVDSUFMX1NMT1RTKQp9CgoKZGVmIGdldF90d2luX3ZsYShzbG90X2lkOiBieXRlcykgLT4gZ2wuc3RvcmFnZS5WTEFbZ2wudHlwZXMudThdOgoJcmV0dXJuIGdsLnN0b3JhZ2UuY2FzdF9zbG90KAoJCWdsLnN0b3JhZ2UuVkxBW2dsLnR5cGVzLnU4XSwgZ2wuc3RvcmFnZS5Sb290Lk1BTkFHRVIsIHNsb3RfaWQsIDAKCSkKCgpkZWYgd3JpdGVfdG9fdHdpbihzbG90X2lkOiBieXRlcywgb2Zmc2V0OiBpbnQsIGRhdGE6IGJ5dGVzKToKCWFzX3ZsYSA9IGdldF90d2luX3ZsYShzbG90X2lkKQoJb2xkX2xlbiA9IGxlbihhc192bGEpCglhc192bGEuc2xvdCgpLndyaXRlKGFzX3ZsYS5kYXRhX29mZnNldCgpICsgb2Zmc2V0LCBkYXRhKQoJYXNfdmxhLnNldF9sZW5ndGgobWF4KG9sZF9sZW4sIG9mZnNldCArIGxlbihkYXRhKSkpCgoKZGVmIHJlYWRfZnJvbV90d2luKHNsb3RfaWQ6IGJ5dGVzLCBvZmZzZXQ6IGludCwgbGVuZ3RoOiBpbnQpIC0+IGJ5dGVzOgoJc2xvdCA9IGdsLnN0b3JhZ2UuUm9vdC5NQU5BR0VSLmdldF9zdG9yZV9zbG90KHNsb3RfaWQpCglyZXR1cm4gc2xvdC5yZWFkKG9mZnNldCArIDQsIGxlbmd0aCkKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZiwgKiwgc2F2ZV9kZWZhdWx0X2xvY2tlZF9zbG90czogYm9vbCA9IFRydWUpOgoJCXJvb3QgPSBnbC5zdG9yYWdlLlJvb3QuZ2V0KCkKCgkJaWYgc2F2ZV9kZWZhdWx0X2xvY2tlZF9zbG90czoKCQkJdHdpbl9zbG90X2lkID0gU1BFQ0lBTF9TTE9UU19UV0lOU1tMT0NLRURfU0xPVF0KCQkJbG9ja2VkX3Nsb3RzX2RzdCA9IGdsLnN0b3JhZ2UuY2FzdF9zbG90KAoJCQkJZ2wuc3RvcmFnZS5WTEFbZ2wudHlwZXMudTI1Nl0sIGdsLnN0b3JhZ2UuUm9vdC5NQU5BR0VSLCB0d2luX3Nsb3RfaWQsIDQKCQkJKQoJCQlsb2NrZWRfc2xvdHNfZHN0LmFzc2lnbihyb290LmxvY2tlZF9zbG90cy5nZXQoKSkKCgkJCWxvY2tlZF9zbG90c19kc3RfdmxhID0gZ2V0X3R3aW5fdmxhKHR3aW5fc2xvdF9pZCkKCQkJbG9ja2VkX3Nsb3RzX2RzdF92bGEuc2V0X2xlbmd0aCgKCQkJCWxlbihsb2NrZWRfc2xvdHNfZHN0KSAqIDMyICsgbG9ja2VkX3Nsb3RzX2RzdC5kYXRhX29mZnNldCgpCgkJCSkKCgkJcm9vdC5sb2NrZWRfc2xvdHMuZ2V0KCkudHJ1bmNhdGUoKQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiB3cml0ZShzZWxmLCBkYXRhOiBsaXN0W3R5cGluZy5BbnldKToKCQkiIiIKCQlXcml0ZSBkYXRhIHRvIHRoZSBjb250cmFjdC4KCgkJOnBhcmFtIGRhdGE6IGxpc3Qgb2YgZGF0YSBpdGVtcyB0byB3cml0ZSBpbiBmb3JtYXQgYGAoc2xvdDogYnl0ZVszMl0sIG9mZnNldDogdTMyLCBkYXRhOiBieXRlcylgYAoJCSIiIgoKCQlmb3Igc2xvdCwgb2Zmc2V0LCBzbGljZSBpbiBkYXRhOgoJCQlpZiBzbG90IGluIFNQRUNJQUxfU0xPVFNfVFdJTlMudmFsdWVzKCk6CgkJCQlnbC52bS5Vc2VyRXJyb3IuaW1tZWRpYXRlKCdDYW5ub3Qgd3JpdGUgdG8gdGhlIHRlbXBvcmFyeSBjb2RlIHNsb3RzJykKCQkJaWYgdHdpbiA6PSBTUEVDSUFMX1NMT1RTX1RXSU5TLmdldChzbG90KToKCQkJCXdyaXRlX3RvX3R3aW4odHdpbiwgb2Zmc2V0LCBzbGljZSkKCQkJZWxzZToKCQkJCWdsLnN0b3JhZ2UuUm9vdC5NQU5BR0VSLmdldF9zdG9yZV9zbG90KHNsb3QpLndyaXRlKG9mZnNldCwgc2xpY2UpCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIHB1c2hfY29kZShzZWxmLCBjb2RlOiBieXRlcyk6CgkJIiIiCgkJUHVzaCBjb2RlIHRvIHRoZSBjb250cmFjdC4gVGhpcyB3aWxsIHdyaXRlIHRoZSBjb2RlIHRvIGEgdGVtcG9yYXJ5IHNsb3QsIHdoaWNoIGNhbiBiZSBjb3BpZWQgdG8gdGhlIGNvZGUgc2xvdCBpbiB0aGUgYGBmaW5pc2hgYCBtZXRob2QuCgoJCTpwYXJhbSBjb2RlOiBjb2RlIHRvIHB1c2gKCgkJLi4gd2FybmluZzo6CgkJCUV4YWN0bHkgb25lIG9mIGBgd3JpdGVgYCBvciBgYHB1c2hfY29kZWBgIG11c3QgYmUgY2FsbGVkIGZvciBjb2RlIGluaXRpYWxpemF0aW9uLAoJCQlvdGhlcndpc2UgdGhlIGNvbnRyYWN0IG1heSBiZSBsZWZ0IGluIHVuZGVmaW5lZCBzdGF0ZQoJCSIiIgoKCQl0d2luX3Nsb3RfaWQgPSBTUEVDSUFMX1NMT1RTX1RXSU5TW0NPREVfU0xPVF0KCQljb2RlX3R3aW5fdmxhID0gZ2V0X3R3aW5fdmxhKHR3aW5fc2xvdF9pZCkKCQljb2RlX3ZsYSA9IGdsLnN0b3JhZ2UuY2FzdF9zbG90KAoJCQlnbC5zdG9yYWdlLlZMQVtnbC50eXBlcy51OF0sIGdsLnN0b3JhZ2UuUm9vdC5NQU5BR0VSLCB0d2luX3Nsb3RfaWQsIDQKCQkpCgkJY29kZV92bGEuZXh0ZW5kKGNvZGUpCgkJbmV3X2xlbiA9IGxlbihjb2RlX3ZsYSkKCQljb2RlX3R3aW5fdmxhLnNldF9sZW5ndGgobmV3X2xlbiArIDQpCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGZpbmlzaChzZWxmKToKCQkiIiIKCQlGaW5pc2ggYm9vdHN0cmFwcGluZy4gVGhpcyB3aWxsIGNvcHkgdGhlIGNvZGUgZnJvbSB0aGUgdGVtcG9yYXJ5IHNsb3QgdG8gdGhlIGNvZGUgc2xvdCBhbmQgbWFrZSBpdCBhdmFpbGFibGUgZm9yIGV4ZWN1dGlvbi4KCQkiIiIKCQlCVUZfU0laRSA9IDY1NTM2CgkJZm9yIGRzdCwgc3JjIGluIFNQRUNJQUxfU0xPVFNfVFdJTlMuaXRlbXMoKToKCQkJdmxhX2Zyb20gPSBnZXRfdHdpbl92bGEoc3JjKQoJCQljb3B5X2xlbiA9IGxlbih2bGFfZnJvbSkKCQkJdG8gPSBnbC5zdG9yYWdlLlJvb3QuTUFOQUdFUi5nZXRfc3RvcmVfc2xvdChkc3QpCgkJCWZvciBvZmZzZXQgaW4gcmFuZ2UoMCwgY29weV9sZW4sIEJVRl9TSVpFKToKCQkJCWNodW5rX3NpemUgPSBtaW4oQlVGX1NJWkUsIGNvcHlfbGVuIC0gb2Zmc2V0KQoJCQkJZGF0YSA9IHZsYV9mcm9tLnNsb3QoKS5yZWFkKHZsYV9mcm9tLmRhdGFfb2Zmc2V0KCkgKyBvZmZzZXQsIGNodW5rX3NpemUpCgkJCQl0by53cml0ZShvZmZzZXQsIGRhdGEpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLUAhgMv1tlUOkSeUwufY18+ny40k+mX7nSFAcpg/v3UAAAAACDCogAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/storage/bootstrapper.0_0.hash b/tests/cases/stable/storage/bootstrapper.0_0.hash index 0f52d8aa1..379cebca7 100644 --- a/tests/cases/stable/storage/bootstrapper.0_0.hash +++ b/tests/cases/stable/storage/bootstrapper.0_0.hash @@ -1 +1 @@ -LQEAAA0VowI3LUbDran4l8dNNJu/4ORQx5gWfJ9YD42vhd71fpbD6gAAAACDAioAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDAioAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/storage/bootstrapper.0_0_0.hash b/tests/cases/stable/storage/bootstrapper.0_0_0.hash index c1d32f4a7..06869af21 100644 --- a/tests/cases/stable/storage/bootstrapper.0_0_0.hash +++ b/tests/cases/stable/storage/bootstrapper.0_0_0.hash @@ -1 +1 @@ -LQEAAA0VowISZlOrevjVPFLYyIb5z3rEcM06Rjp/RVrY1uIgENBFrQAAAACDCGsAAABnAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhYwAAAAAAAAAAAAAAAAAAAAAABQ== +LQEAAA0VowLGyCM48EiqiMEdOP35uFBCQ1ppRLdLR6+O1DknMJVe2QAAAACDCGsAAABnAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgQ29udHJhYwAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/storage/bootstrapper.0_0_0_0.hash b/tests/cases/stable/storage/bootstrapper.0_0_0_0.hash index 1060f1873..29aae7d93 100644 --- a/tests/cases/stable/storage/bootstrapper.0_0_0_0.hash +++ b/tests/cases/stable/storage/bootstrapper.0_0_0_0.hash @@ -1 +1 @@ -LQEAABUVowISZlOrevjVPFLYyIb5z3rEcM06Rjp/RVrY1uIgENBFrQAAAACDAtIAAADOAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxhFaMCEmZTq3r41TxS2MiG+c96xHDNOkY6f0Va2NbiIBDQRa0AAAADgwgKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWZpZWxkOiBpMzIKCglAZ2wucHVibGljLndyaXRlCglkZWYgZ2V0X2ZpZWxkKHNlbGYpOgoJCXByaW50KGludChzZWxmLmZpZWxkKSkKAAAAAAAAAAAAAAU= +LQEAABUVowLGyCM48EiqiMEdOP35uFBCQ1ppRLdLR6+O1DknMJVe2QAAAACDAtIAAADOAAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxhFaMCxsgjOPBIqojBHTj9+bhQQkNaaUS3S0evjtQ5JzCVXtkAAAADgwgKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWZpZWxkOiBpMzIKCglAZ2wucHVibGljLndyaXRlCglkZWYgZ2V0X2ZpZWxkKHNlbGYpOgoJCXByaW50KGludChzZWxmLmZpZWxkKSkKAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/storage/bootstrapper.0_0_0_0_0.hash b/tests/cases/stable/storage/bootstrapper.0_0_0_0_0.hash index b3d9e6578..da2ca18fc 100644 --- a/tests/cases/stable/storage/bootstrapper.0_0_0_0_0.hash +++ b/tests/cases/stable/storage/bootstrapper.0_0_0_0_0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDDs4AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglmaWVsZDogaTMyCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGdldF9maWVsZChzZWxmKToKCQlwcmludChpbnQoc2VsZi5maWVsZCkpCi5yb290X29mZnNldHMuBQ== +LQEAABUVowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYnoV50UNnwTpw9jS2Fao6ceN+gCB6iwSj9yTzi3zXr1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDDs4AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglmaWVsZDogaTMyCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIGdldF9maWVsZChzZWxmKToKCQlwcmludChpbnQoc2VsZi5maWVsZCkpCi5yb290X29mZnNldHMuBQ== diff --git a/tests/cases/stable/storage/bootstrapper.jsonnet b/tests/cases/stable/storage/bootstrapper.jsonnet index b29d0df6a..462e8fbeb 100644 --- a/tests/cases/stable/storage/bootstrapper.jsonnet +++ b/tests/cases/stable/storage/bootstrapper.jsonnet @@ -3,8 +3,8 @@ local s = simple.run('${jsonnetDir}/${fileBaseName}.py'); local util = import 'templates/util.jsonnet'; local target_code = importstr './bootstrapper_target.py'; -// contract instance slot = sha3_256(ROOT_SLOT_ID(32 zero bytes) + CONTRACT_OFFSET(0 as u32 le)) -local contract_instance_slot = '372d46c3ada9f897c74d349bbfe0e450c798167c9f580f8daf85def57e96c3ea'; +// contract instance slot = sha3_256(ROOT_SLOT_ID(32 zero bytes) + CONTRACT_OFFSET(1 as u32 le)) +local contract_instance_slot = 'e1ae23412792df6b6a98fb7c9839701fb8b02b6fc7ed022810f78346494685e7'; {entry: util.addPaths([util.chain([ // deploy bootstrapper diff --git a/tests/cases/stable/storage/floats.0.hash b/tests/cases/stable/storage/floats.0.hash index 44a483c37..52ac99599 100644 --- a/tests/cases/stable/storage/floats.0.hash +++ b/tests/cases/stable/storage/floats.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlIBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKZnJvbSBnZW5sYXllci5zdG9yYWdlLl9pbnRlcm5hbC5nZW5lcmF0ZSBpbXBvcnQgZ2VuZXJhdGVfc3RvcmFnZQoKCkBnZW5lcmF0ZV9zdG9yYWdlCmNsYXNzIFRlc3Q6Cglmb286IGZsb2F0CgoJZGVmIGFiYyhzZWxmKToKCQlyZXR1cm4gc2VsZi5mb28KCgp0c3QgPSBUZXN0KCkKdHN0LmZvbyA9IDAuNQoKYXNzZXJ0IHRzdC5mb28gPT0gMC41CmFzc2VydCB0eXBlKHRzdC5mb28pIGlzIGZsb2F0CnByaW50KHRzdC5mb28pCgpleGl0KDApCgAAAAAAAAAAAAAF +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZSAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZS5faW50ZXJuYWwuZ2VuZXJhdGUgaW1wb3J0IGdlbmVyYXRlX3N0b3JhZ2UKCgpAZ2VuZXJhdGVfc3RvcmFnZQpjbGFzcyBUZXN0OgoJZm9vOiBmbG9hdAoKCWRlZiBhYmMoc2VsZik6CgkJcmV0dXJuIHNlbGYuZm9vCgoKdHN0ID0gVGVzdCgpCnRzdC5mb28gPSAwLjUKCmFzc2VydCB0c3QuZm9vID09IDAuNQphc3NlcnQgdHlwZSh0c3QuZm9vKSBpcyBmbG9hdApwcmludCh0c3QuZm9vKQoKZXhpdCgwKQoAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/storage/gvm-89.0.hash b/tests/cases/stable/storage/gvm-89.0.hash index 19f03de3a..63edebba9 100644 --- a/tests/cases/stable/storage/gvm-89.0.hash +++ b/tests/cases/stable/storage/gvm-89.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDGGkBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKZnJvbSBkYXRhY2xhc3NlcyBpbXBvcnQgZGF0YWNsYXNzCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZSBpbXBvcnQgYWxsb3cKCgpAYWxsb3cKQGRhdGFjbGFzcwpjbGFzcyBGb286Cgl4OiBnbC5EeW5BcnJheVtzdHJdCgoKY2xhc3MgTWFpbihnbC5jb250cmFjdC5Db250cmFjdCk6CglmOiBnbC5EeW5BcnJheVtGb29dCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZik6CgkJc2VsZi5mLmFwcGVuZChGb28oWycxMjMnXSkpCgkJcmV0dXJuIFtpIGZvciBpIGluIHNlbGYuZl0KAAAAAAAAAAAAAAAAAAAAAAAAAAU= +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxhpAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmZyb20gZGF0YWNsYXNzZXMgaW1wb3J0IGRhdGFjbGFzcwppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgpmcm9tIGdlbmxheWVyLnN0b3JhZ2UgaW1wb3J0IGFsbG93CgoKQGFsbG93CkBkYXRhY2xhc3MKY2xhc3MgRm9vOgoJeDogZ2wuRHluQXJyYXlbc3RyXQoKCmNsYXNzIE1haW4oZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZjogZ2wuRHluQXJyYXlbRm9vXQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYpOgoJCXNlbGYuZi5hcHBlbmQoRm9vKFsnMTIzJ10pKQoJCXJldHVybiBbaSBmb3IgaSBpbiBzZWxmLmZdCgAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/storage/gvm-89.0_0.hash b/tests/cases/stable/storage/gvm-89.0_0.hash index d5d0380d0..c834387f1 100644 --- a/tests/cases/stable/storage/gvm-89.0_0.hash +++ b/tests/cases/stable/storage/gvm-89.0_0.hash @@ -1 +1 @@ -LQENDgF4DRwxMjMAJRWjAjctRsOtqfiXx000m7/g5FDHmBZ8n1gPja+F3vV+lsPqAAAAAIMCAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowK/3qmf3S8yrjpIVx1Q6ejcB/QQx6foIUwOn3NSI01TlgAAAACDAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC1SZia+5PJP/Ww2xfjSWh6XcvGQxNaICn3bVyWZcl6e8AAAAAgwIxMjMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAupw/Ct4Am+EqQsq6IN2azBvld5Bwi2wvgVbdF1rlfQfAAAAAIMCAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQENDgF4DRwxMjMAJRWjAkarTtJntGExRjClCClTeapPszpBSCLunXLw6y4spm7AAAAAAIMCAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLXx9ztv0A3R7xFE8sm8nft+EExO+bPdwDogzFYlc/vDAAAAACDAjEyMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgwIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAvC/CNTNsNC9yOvuCNfiE8+cb20NpEyVEFeSNxzeGgcsAAAAAIMCAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/storage/locking/default-frozen.0.hash b/tests/cases/stable/storage/locking/default-frozen.0.hash index 929dd1528..c2264948c 100644 --- a/tests/cases/stable/storage/locking/default-frozen.0.hash +++ b/tests/cases/stable/storage/locking/default-frozen.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDOHEDAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCm5ld19jb2RlID0gYiIiIlwKIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KcHJpbnQoIlBhdGNoZWQhIikKZXhpdCgzMCkKIiIiCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYsIG1vZGlmaWVyczogbGlzdFtBZGRyZXNzXSwgbW9kaWZ5X2luX2N0b3I6IGJvb2wpOgoJCXJvb3QgPSBnbC5zdG9yYWdlLlJvb3QuZ2V0KCkKCQlyb290LnVwZ3JhZGVycy5nZXQoKS5leHRlbmQobW9kaWZpZXJzKQoKCQlzZWxmLnNob3dfaW5mbygpCgoJCWlmIG1vZGlmeV9pbl9jdG9yOgoJCQlzZWxmLnRyeV9tb2RpZnkoKQoKCWRlZiBzaG93X2luZm8oc2VsZik6CgkJcm9vdCA9IGdsLnN0b3JhZ2UuUm9vdC5nZXQoKQoKCQlwcmludChsaXN0KHJvb3QubG9ja2VkX3Nsb3RzLmdldCgpKSkKCQlwcmludChsaXN0KHJvb3QudXBncmFkZXJzLmdldCgpKSkKCglAZ2wucHVibGljLndyaXRlCglkZWYgbm9wKHNlbGYpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYgdHJ5X21vZGlmeShzZWxmKToKCQlyb290ID0gZ2wuc3RvcmFnZS5Sb290LmdldCgpCgoJCXNlbGYuc2hvd19pbmZvKCkKCgkJY29kZSA9IHJvb3QuY29kZS5nZXQoKQoJCXRyeToKCQkJY29kZS50cnVuY2F0ZSgpICAjIDwtIHdlIHNob3VsZCBlbmNvdW50ZXIgZXJyb3IgaGVyZQoJCWV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGU6CgkJCXByaW50KGUpCgkJZWxzZToKCQkJY29kZS5hc3NpZ24obmV3X2NvZGUpCgkJcHJpbnQobGVuKGNvZGUpID09IGxlbihuZXdfY29kZSkpCgAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgzhxAwAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgpuZXdfY29kZSA9IGIiIiJcCiMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CnByaW50KCJQYXRjaGVkISIpCmV4aXQoMzApCiIiIgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBtb2RpZmllcnM6IGxpc3RbQWRkcmVzc10sIG1vZGlmeV9pbl9jdG9yOiBib29sKToKCQlyb290ID0gZ2wuc3RvcmFnZS5Sb290LmdldCgpCgkJcm9vdC51cGdyYWRlcnMuZ2V0KCkuZXh0ZW5kKG1vZGlmaWVycykKCgkJc2VsZi5zaG93X2luZm8oKQoKCQlpZiBtb2RpZnlfaW5fY3RvcjoKCQkJc2VsZi50cnlfbW9kaWZ5KCkKCglkZWYgc2hvd19pbmZvKHNlbGYpOgoJCXJvb3QgPSBnbC5zdG9yYWdlLlJvb3QuZ2V0KCkKCgkJcHJpbnQobGlzdChyb290LmxvY2tlZF9zbG90cy5nZXQoKSkpCgkJcHJpbnQobGlzdChyb290LnVwZ3JhZGVycy5nZXQoKSkpCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG5vcChzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIHRyeV9tb2RpZnkoc2VsZik6CgkJcm9vdCA9IGdsLnN0b3JhZ2UuUm9vdC5nZXQoKQoKCQlzZWxmLnNob3dfaW5mbygpCgoJCWNvZGUgPSByb290LmNvZGUuZ2V0KCkKCQl0cnk6CgkJCWNvZGUudHJ1bmNhdGUoKSAgIyA8LSB3ZSBzaG91bGQgZW5jb3VudGVyIGVycm9yIGhlcmUKCQlleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlOgoJCQlwcmludChlKQoJCWVsc2U6CgkJCWNvZGUuYXNzaWduKG5ld19jb2RlKQoJCXByaW50KGxlbihjb2RlKSA9PSBsZW4obmV3X2NvZGUpKQoAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/storage/locking/default-frozen.0.stdout b/tests/cases/stable/storage/locking/default-frozen.0.stdout index 23fb2da8d..502c0e297 100644 --- a/tests/cases/stable/storage/locking/default-frozen.0.stdout +++ b/tests/cases/stable/storage/locking/default-frozen.0.stdout @@ -1,3 +1,3 @@ -[0, 104719743780096590577697194990451901900258198514698274453690604555695722573537, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473] +[0, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473, 97210530485491999172923574369323190562438421669572628099136573576019724640551] [] executed with `Return(null)` diff --git a/tests/cases/stable/storage/locking/default-frozen.0_0.stdout b/tests/cases/stable/storage/locking/default-frozen.0_0.stdout index 0e5d32afc..778890e66 100644 --- a/tests/cases/stable/storage/locking/default-frozen.0_0.stdout +++ b/tests/cases/stable/storage/locking/default-frozen.0_0.stdout @@ -1,4 +1,4 @@ -[0, 104719743780096590577697194990451901900258198514698274453690604555695722573537, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473] +[0, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473, 97210530485491999172923574369323190562438421669572628099136573576019724640551] [] 6: forbidden False diff --git a/tests/cases/stable/storage/locking/modify_ctor.0.hash b/tests/cases/stable/storage/locking/modify_ctor.0.hash index 917dadfd4..62e3f12b8 100644 --- a/tests/cases/stable/storage/locking/modify_ctor.0.hash +++ b/tests/cases/stable/storage/locking/modify_ctor.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDOD8AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQpwcmludCgiUGF0Y2hlZCEiKQpleGl0KDMwKQogZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCm5ld19jb2RlID0gYiIiIlwKIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KcHJpbnQoIlBhdGNoZWQhIikKZXhpdCgzMCkKIiIiCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYsIG1vZGlmaWVyczogbGlzdFtBZGRyZXNzXSwgbW9kaWZ5X2luX2N0b3I6IGJvb2wpOgoJCXJvb3QgPSBnbC5zdG9yYWdlLlJvb3QuZ2V0KCkKCQlyb290LnVwZ3JhZGVycy5nZXQoKS5leHRlbmQobW9kaWZpZXJzKQoKCQlzZWxmLnNob3dfaW5mbygpCgoJCWlmIG1vZGlmeV9pbl9jdG9yOgoJCQlzZWxmLnRyeV9tb2RpZnkoKQoKCWRlZiBzaG93X2luZm8oc2VsZik6CgkJcm9vdCA9IGdsLnN0b3JhZ2UuUm9vdC5nZXQoKQoKCQlwcmludChsaXN0KHJvb3QubG9ja2VkX3Nsb3RzLmdldCgpKSkKCQlwcmludChsaXN0KHJvb3QudXBncmFkZXJzLmdldCgpKSkKCglAZ2wucHVibGljLndyaXRlCglkZWYgbm9wKHNlbGYpOgoJCXBhc3MKCglAZ2wucHVibGljLndyaXRlCglkZWYgdHJ5X21vZGlmeShzZWxmKToKCQlyb290ID0gZ2wuc3RvcmFnZS5Sb290LmdldCgpCgoJCXNlbGYuc2hvd19pbmZvKCkKCgkJY29kZSA9IHJvb3QuY29kZS5nZXQoKQoJCXRyeToKCQkJY29kZS50cnVuY2F0ZSgpICAjIDwtIHdlIHNob3VsZCBlbmNvdW50ZXIgZXJyb3IgaGVyZQoJCWV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGU6CgkJCXByaW50KGUpCgkJZWxzZToKCQkJY29kZS5hc3NpZ24obmV3X2NvZGUpCgkJcHJpbnQobGVuKGNvZGUpID09IGxlbihuZXdfY29kZSkpCgAAAAAAAAAAAAAABQ== +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgzg/AAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KcHJpbnQoIlBhdGNoZWQhIikKZXhpdCgzMCkKIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgpuZXdfY29kZSA9IGIiIiJcCiMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CnByaW50KCJQYXRjaGVkISIpCmV4aXQoMzApCiIiIgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBtb2RpZmllcnM6IGxpc3RbQWRkcmVzc10sIG1vZGlmeV9pbl9jdG9yOiBib29sKToKCQlyb290ID0gZ2wuc3RvcmFnZS5Sb290LmdldCgpCgkJcm9vdC51cGdyYWRlcnMuZ2V0KCkuZXh0ZW5kKG1vZGlmaWVycykKCgkJc2VsZi5zaG93X2luZm8oKQoKCQlpZiBtb2RpZnlfaW5fY3RvcjoKCQkJc2VsZi50cnlfbW9kaWZ5KCkKCglkZWYgc2hvd19pbmZvKHNlbGYpOgoJCXJvb3QgPSBnbC5zdG9yYWdlLlJvb3QuZ2V0KCkKCgkJcHJpbnQobGlzdChyb290LmxvY2tlZF9zbG90cy5nZXQoKSkpCgkJcHJpbnQobGlzdChyb290LnVwZ3JhZGVycy5nZXQoKSkpCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG5vcChzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIHRyeV9tb2RpZnkoc2VsZik6CgkJcm9vdCA9IGdsLnN0b3JhZ2UuUm9vdC5nZXQoKQoKCQlzZWxmLnNob3dfaW5mbygpCgoJCWNvZGUgPSByb290LmNvZGUuZ2V0KCkKCQl0cnk6CgkJCWNvZGUudHJ1bmNhdGUoKSAgIyA8LSB3ZSBzaG91bGQgZW5jb3VudGVyIGVycm9yIGhlcmUKCQlleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlOgoJCQlwcmludChlKQoJCWVsc2U6CgkJCWNvZGUuYXNzaWduKG5ld19jb2RlKQoJCXByaW50KGxlbihjb2RlKSA9PSBsZW4obmV3X2NvZGUpKQoAAAAAAAAAAAAAAAU= diff --git a/tests/cases/stable/storage/locking/modify_ctor.0.stdout b/tests/cases/stable/storage/locking/modify_ctor.0.stdout index dc59f8508..304283b16 100644 --- a/tests/cases/stable/storage/locking/modify_ctor.0.stdout +++ b/tests/cases/stable/storage/locking/modify_ctor.0.stdout @@ -1,6 +1,6 @@ -[0, 104719743780096590577697194990451901900258198514698274453690604555695722573537, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473] +[0, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473, 97210530485491999172923574369323190562438421669572628099136573576019724640551] [] -[0, 104719743780096590577697194990451901900258198514698274453690604555695722573537, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473] +[0, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473, 97210530485491999172923574369323190562438421669572628099136573576019724640551] [] True executed with `Return(null)` diff --git a/tests/cases/stable/storage/locking/modify_later.0.hash b/tests/cases/stable/storage/locking/modify_later.0.hash index 27505c4e8..d268241d5 100644 --- a/tests/cases/stable/storage/locking/modify_later.0.hash +++ b/tests/cases/stable/storage/locking/modify_later.0.hash @@ -1 +1 @@ -LQEAAB0VowIhueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAACDAgEAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMC4a4jQSeS32tqmPt8mDlwH7iwK2/H7QIoEPeDRklGhecAAAAAgzhxAwAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgpuZXdfY29kZSA9IGIiIiJcCiMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CnByaW50KCJQYXRjaGVkISIpCmV4aXQoMzApCiIiIgoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmLCBtb2RpZmllcnM6IGxpc3RbQWRkcmVzc10sIG1vZGlmeV9pbl9jdG9yOiBib29sKToKCQlyb290ID0gZ2wuc3RvcmFnZS5Sb290LmdldCgpCgkJcm9vdC51cGdyYWRlcnMuZ2V0KCkuZXh0ZW5kKG1vZGlmaWVycykKCgkJc2VsZi5zaG93X2luZm8oKQoKCQlpZiBtb2RpZnlfaW5fY3RvcjoKCQkJc2VsZi50cnlfbW9kaWZ5KCkKCglkZWYgc2hvd19pbmZvKHNlbGYpOgoJCXJvb3QgPSBnbC5zdG9yYWdlLlJvb3QuZ2V0KCkKCgkJcHJpbnQobGlzdChyb290LmxvY2tlZF9zbG90cy5nZXQoKSkpCgkJcHJpbnQobGlzdChyb290LnVwZ3JhZGVycy5nZXQoKSkpCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG5vcChzZWxmKToKCQlwYXNzCgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIHRyeV9tb2RpZnkoc2VsZik6CgkJcm9vdCA9IGdsLnN0b3JhZ2UuUm9vdC5nZXQoKQoKCQlzZWxmLnNob3dfaW5mbygpCgoJCWNvZGUgPSByb290LmNvZGUuZ2V0KCkKCQl0cnk6CgkJCWNvZGUudHJ1bmNhdGUoKSAgIyA8LSB3ZSBzaG91bGQgZW5jb3VudGVyIGVycm9yIGhlcmUKCQlleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlOgoJCQlwcmludChlKQoJCWVsc2U6CgkJCWNvZGUuYXNzaWduKG5ld19jb2RlKQoJCXByaW50KGxlbihjb2RlKSA9PSBsZW4obmV3X2NvZGUpKQoAAAAAAAAAAAAAAAU= +LQEAACUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAgwIBAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIM4cQMAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjp0ZXN0IiB9CgppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKbmV3X2NvZGUgPSBiIiIiXAojIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQpwcmludCgiUGF0Y2hlZCEiKQpleGl0KDMwKQoiIiIKCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglkZWYgX19pbml0X18oc2VsZiwgbW9kaWZpZXJzOiBsaXN0W0FkZHJlc3NdLCBtb2RpZnlfaW5fY3RvcjogYm9vbCk6CgkJcm9vdCA9IGdsLnN0b3JhZ2UuUm9vdC5nZXQoKQoJCXJvb3QudXBncmFkZXJzLmdldCgpLmV4dGVuZChtb2RpZmllcnMpCgoJCXNlbGYuc2hvd19pbmZvKCkKCgkJaWYgbW9kaWZ5X2luX2N0b3I6CgkJCXNlbGYudHJ5X21vZGlmeSgpCgoJZGVmIHNob3dfaW5mbyhzZWxmKToKCQlyb290ID0gZ2wuc3RvcmFnZS5Sb290LmdldCgpCgoJCXByaW50KGxpc3Qocm9vdC5sb2NrZWRfc2xvdHMuZ2V0KCkpKQoJCXByaW50KGxpc3Qocm9vdC51cGdyYWRlcnMuZ2V0KCkpKQoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBub3Aoc2VsZik6CgkJcGFzcwoKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiB0cnlfbW9kaWZ5KHNlbGYpOgoJCXJvb3QgPSBnbC5zdG9yYWdlLlJvb3QuZ2V0KCkKCgkJc2VsZi5zaG93X2luZm8oKQoKCQljb2RlID0gcm9vdC5jb2RlLmdldCgpCgkJdHJ5OgoJCQljb2RlLnRydW5jYXRlKCkgICMgPC0gd2Ugc2hvdWxkIGVuY291bnRlciBlcnJvciBoZXJlCgkJZXhjZXB0IEJhc2VFeGNlcHRpb24gYXMgZToKCQkJcHJpbnQoZSkKCQllbHNlOgoJCQljb2RlLmFzc2lnbihuZXdfY29kZSkKCQlwcmludChsZW4oY29kZSkgPT0gbGVuKG5ld19jb2RlKSkKAAAAAAAAAAAAAAAF diff --git a/tests/cases/stable/storage/locking/modify_later.0.stdout b/tests/cases/stable/storage/locking/modify_later.0.stdout index 444226f68..392f2467f 100644 --- a/tests/cases/stable/storage/locking/modify_later.0.stdout +++ b/tests/cases/stable/storage/locking/modify_later.0.stdout @@ -1,3 +1,3 @@ -[0, 104719743780096590577697194990451901900258198514698274453690604555695722573537, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473] +[0, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473, 97210530485491999172923574369323190562438421669572628099136573576019724640551] [Address("0x0200000000000000000000000000000000000000")] executed with `Return(null)` diff --git a/tests/cases/stable/storage/locking/modify_later.0_0.hash b/tests/cases/stable/storage/locking/modify_later.0_0.hash index bc4ae18db..729c97c3c 100644 --- a/tests/cases/stable/storage/locking/modify_later.0_0.hash +++ b/tests/cases/stable/storage/locking/modify_later.0_0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDBj8AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQpwcmludCgiUGF0Y2hlZCEiKQpleGl0KDMwKQogZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCm5ldwU= +LQEAAA0VowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDBj8AAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQpwcmludCgiUGF0Y2hlZCEiKQpleGl0KDMwKQogZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCm5ldwU= diff --git a/tests/cases/stable/storage/locking/modify_later.0_0.stdout b/tests/cases/stable/storage/locking/modify_later.0_0.stdout index 72d3cd2e4..e93931964 100644 --- a/tests/cases/stable/storage/locking/modify_later.0_0.stdout +++ b/tests/cases/stable/storage/locking/modify_later.0_0.stdout @@ -1,4 +1,4 @@ -[0, 104719743780096590577697194990451901900258198514698274453690604555695722573537, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473] +[0, 5147135863452175656394978567785114489906633378855095627257376406960105455802, 46342954650747611132690097513405510122375903838997656252402239048600340445473, 97210530485491999172923574369323190562438421669572628099136573576019724640551] [Address("0x0200000000000000000000000000000000000000")] True executed with `Return(null)` diff --git a/tests/cases/stable/storage/np.0.hash b/tests/cases/stable/storage/np.0.hash index c97a162ee..2360e5691 100644 --- a/tests/cases/stable/storage/np.0.hash +++ b/tests/cases/stable/storage/np.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDHJ8BAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IG51bXB5IGFzIG5wCgppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKZnJvbSBnZW5sYXllci5zdG9yYWdlLl9pbnRlcm5hbC5nZW5lcmF0ZSBpbXBvcnQgZ2VuZXJhdGVfc3RvcmFnZQoKCkBnZW5lcmF0ZV9zdG9yYWdlCmNsYXNzIFRlc3Q6Cglmb286IG5wLmZsb2F0MzIKCglkZWYgYWJjKHNlbGYpOgoJCXJldHVybiBzZWxmLmZvbwoKCnRzdCA9IFRlc3QoKQp0c3QuZm9vID0gbnAuZmxvYXQzMigwLjUpCgphc3NlcnQgdHN0LmZvbyA9PSAwLjUsIGYne3RzdC5mb299Jwphc3NlcnQgdHlwZSh0c3QuZm9vKSBpcyBucC5mbG9hdDMyLCBmJ3t0eXBlKHRzdC5mb28pfScKcHJpbnQodHN0LmZvbykKCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxyfAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBudW1weSBhcyBucAoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmZyb20gZ2VubGF5ZXIuc3RvcmFnZS5faW50ZXJuYWwuZ2VuZXJhdGUgaW1wb3J0IGdlbmVyYXRlX3N0b3JhZ2UKCgpAZ2VuZXJhdGVfc3RvcmFnZQpjbGFzcyBUZXN0OgoJZm9vOiBucC5mbG9hdDMyCgoJZGVmIGFiYyhzZWxmKToKCQlyZXR1cm4gc2VsZi5mb28KCgp0c3QgPSBUZXN0KCkKdHN0LmZvbyA9IG5wLmZsb2F0MzIoMC41KQoKYXNzZXJ0IHRzdC5mb28gPT0gMC41LCBmJ3t0c3QuZm9vfScKYXNzZXJ0IHR5cGUodHN0LmZvbykgaXMgbnAuZmxvYXQzMiwgZid7dHlwZSh0c3QuZm9vKX0nCnByaW50KHRzdC5mb28pCgpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/storage/persists.0.hash b/tests/cases/stable/storage/persists.0.hash index adc75de2d..6f4106281 100644 --- a/tests/cases/stable/storage/persists.0.hash +++ b/tests/cases/stable/storage/persists.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/stable/storage/read_nondet.0.hash b/tests/cases/stable/storage/read_nondet.0.hash index 34d616dc8..74ede8fe9 100644 --- a/tests/cases/stable/storage/read_nondet.0.hash +++ b/tests/cases/stable/storage/read_nondet.0.hash @@ -1 +1 @@ -LQEAACUVowI3LUbDran4l8dNNJu/4ORQx5gWfJ9YD42vhd71fpbD6gAAAACDAgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF57oAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCv96pn90vMq46SFcdUOno3Af0EMen6CFMDp9zUiNNU5YAAAAAgwI0NTYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAuGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnAAAAAIMUHQEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjpsYXRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgU3RvcmFnZShnbC5jb250cmFjdC5Db250cmFjdCk6CglhOiBzdHIKCglkZWYgX19pbml0X18oc2VsZik6CgkJc2VsZi5hID0gJzEyMycKCgkJZGVmIGYoKToKCQkJcHJpbnQoc2VsZi5hKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGYpCgkJc2VsZi5hID0gJzQ1NicKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGYpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQEAAC0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCRqtO0me0YTFGMKUIKVN5qk+zOkFIIu6dcvDrLiymbsAAAAAAgwI0NTYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWjAroAVjB0Ws8wFKrxYumTMEAwLKC+8/Vv4tc8Cgj4LGELAAAAAIMUHQEAACMgeyAiRGVwZW5kcyI6ICJweS1nZW5sYXllcjpsYXRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCgoKY2xhc3MgU3RvcmFnZShnbC5jb250cmFjdC5Db250cmFjdCk6CglhOiBzdHIKCglkZWYgX19pbml0X18oc2VsZik6CgkJc2VsZi5hID0gJzEyMycKCgkJZGVmIGYoKToKCQkJcHJpbnQoc2VsZi5hKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGYpCgkJc2VsZi5hID0gJzQ1NicKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKGYpCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDAgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/storage/storage_tree_map.0.hash b/tests/cases/stable/storage/storage_tree_map.0.hash index 94947fa18..ed6376cc4 100644 --- a/tests/cases/stable/storage/storage_tree_map.0.hash +++ b/tests/cases/stable/storage/storage_tree_map.0.hash @@ -1 +1 @@ -LQEAAA0VowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFkgBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKZnJvbSBnZW5sYXllci5zdG9yYWdlLl9pbnRlcm5hbC5nZW5lcmF0ZSBpbXBvcnQgZ2VuZXJhdGVfc3RvcmFnZQoKCkBnZW5lcmF0ZV9zdG9yYWdlCmNsYXNzIFVzZXJTdG9yYWdlOgoJbTogZ2wuVHJlZU1hcFtzdHIsIHUzMl0KCgp0c3QgPSBVc2VyU3RvcmFnZSgpCgp0c3QubVsnMSddID0gMTIKdHN0Lm1bJzInXSA9IDEzCmRlbCB0c3QubVsnMSddCnByaW50KCcxJyBpbiB0c3QubSwgdHN0Lm1bJzInXSkKCmV4aXQoMCkKAAAAAAAAAAAAAAAAAAAAAAAAAAAF +LQEAABUVowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZIAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZS5faW50ZXJuYWwuZ2VuZXJhdGUgaW1wb3J0IGdlbmVyYXRlX3N0b3JhZ2UKCgpAZ2VuZXJhdGVfc3RvcmFnZQpjbGFzcyBVc2VyU3RvcmFnZToKCW06IGdsLlRyZWVNYXBbc3RyLCB1MzJdCgoKdHN0ID0gVXNlclN0b3JhZ2UoKQoKdHN0Lm1bJzEnXSA9IDEyCnRzdC5tWycyJ10gPSAxMwpkZWwgdHN0Lm1bJzEnXQpwcmludCgnMScgaW4gdHN0Lm0sIHRzdC5tWycyJ10pCgpleGl0KDApCgAAAAAAAAAAAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/stable/storage/to_str.0.hash b/tests/cases/stable/storage/to_str.0.hash index 8d7a3e77b..f66e46468 100644 --- a/tests/cases/stable/storage/to_str.0.hash +++ b/tests/cases/stable/storage/to_str.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFloBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQoKaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKZnJvbSBnZW5sYXllci5zdG9yYWdlIGltcG9ydCBhbGxvdwoKZnJvbSBkYXRhY2xhc3NlcyBpbXBvcnQgZGF0YWNsYXNzCmltcG9ydCBkYXRldGltZQoKCkBhbGxvdwpAZGF0YWNsYXNzCmNsYXNzIFVzZXI6CgluYW1lOiBzdHIKCWJpcnRoZGF5OiBkYXRldGltZS5kYXRldGltZQoKCmNsYXNzIExsbUVyYzIwKGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCXg6IFVzZXIKCglkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKCQlwcmludChzdHIoc2VsZi54KSkKAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZaAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KCmltcG9ydCBnZW5sYXllciBhcyBnbApmcm9tIGdlbmxheWVyLnR5cGVzIGltcG9ydCAqCmZyb20gZ2VubGF5ZXIuc3RvcmFnZSBpbXBvcnQgYWxsb3cKCmZyb20gZGF0YWNsYXNzZXMgaW1wb3J0IGRhdGFjbGFzcwppbXBvcnQgZGF0ZXRpbWUKCgpAYWxsb3cKQGRhdGFjbGFzcwpjbGFzcyBVc2VyOgoJbmFtZTogc3RyCgliaXJ0aGRheTogZGF0ZXRpbWUuZGF0ZXRpbWUKCgpjbGFzcyBMbG1FcmMyMChnbC5jb250cmFjdC5Db250cmFjdCk6Cgl4OiBVc2VyCgoJZGVmIF9faW5pdF9fKHNlbGYpIC0+IE5vbmU6CgkJcHJpbnQoc3RyKHNlbGYueCkpCgAABQ== diff --git a/tests/cases/stable/storage/tree_map_nested.0.hash b/tests/cases/stable/storage/tree_map_nested.0.hash index f85f77c82..57761f016 100644 --- a/tests/cases/stable/storage/tree_map_nested.0.hash +++ b/tests/cases/stable/storage/tree_map_nested.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator.0.hash b/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator.0.hash index d5e09be16..6d1554edf 100644 --- a/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator.0.hash +++ b/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDLtsCAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgppbXBvcnQgc3lzCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCWRlZiBnZXRfaW5wdXQoKToKCQkJcmV0dXJuICJBcyBwZXRzLCByYXRzIGFyZSBhZmZlY3Rpb25hdGUsIHBsYXlmdWwsIGFuZCBmb3JtIHN0cm9uZyBib25kcyB3aXRoIHRoZWlyIGh1bWFuIGNvbXBhbmlvbnMuIFRoZXkncmUgY3VyaW91cywgZW5qb3kgaW50ZXJhY3RpdmUgdG95cywgYW5kIGNhbiBsZWFybiB0cmlja3MgbXVjaCBsaWtlIHNtYWxsIGRvZ3MuIFRoZWlyIGFkYXB0YWJpbGl0eSwgaW50ZWxsaWdlbmNlLCBhbmQgY2hhcm1pbmcgcGVyc29uYWxpdGllcyBtYWtlIHRoZW0gdHJ1bHkgY29vbCBhbmltYWxzIHRoYXQgZGVzZXJ2ZSBtdWNoIG1vcmUgYXBwcmVjaWF0aW9uIHRoYW4gdGhleSBjdXJyZW50bHkgZ2V0LiIKCgkJcHJpbnQoCgkJCWdsLmVxX3ByaW5jaXBsZS5wcm9tcHRfbm9uX2NvbXBhcmF0aXZlKAoJCQkJZ2V0X2lucHV0LAoJCQkJdGFzaz0nUHJvZHVjZSBhIHRleHQgc3VtbWFyeScsCgkJCQljcml0ZXJpYT0nSXQgbXVzdCBiZSBzaG9ydGVyIHRoYW4gdGhlIG9yaWdpbmFsIHRleHQgYW5kIGJlIGEgdmFsaWQgc3VtbWFyeScsCgkJCSksCgkJCWZpbGU9c3lzLnN0ZGVyciwKCQkpCgAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgy7bAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKaW1wb3J0IHN5cwoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlkZWYgZ2V0X2lucHV0KCk6CgkJCXJldHVybiAiQXMgcGV0cywgcmF0cyBhcmUgYWZmZWN0aW9uYXRlLCBwbGF5ZnVsLCBhbmQgZm9ybSBzdHJvbmcgYm9uZHMgd2l0aCB0aGVpciBodW1hbiBjb21wYW5pb25zLiBUaGV5J3JlIGN1cmlvdXMsIGVuam95IGludGVyYWN0aXZlIHRveXMsIGFuZCBjYW4gbGVhcm4gdHJpY2tzIG11Y2ggbGlrZSBzbWFsbCBkb2dzLiBUaGVpciBhZGFwdGFiaWxpdHksIGludGVsbGlnZW5jZSwgYW5kIGNoYXJtaW5nIHBlcnNvbmFsaXRpZXMgbWFrZSB0aGVtIHRydWx5IGNvb2wgYW5pbWFscyB0aGF0IGRlc2VydmUgbXVjaCBtb3JlIGFwcHJlY2lhdGlvbiB0aGFuIHRoZXkgY3VycmVudGx5IGdldC4iCgoJCXByaW50KAoJCQlnbC5lcV9wcmluY2lwbGUucHJvbXB0X25vbl9jb21wYXJhdGl2ZSgKCQkJCWdldF9pbnB1dCwKCQkJCXRhc2s9J1Byb2R1Y2UgYSB0ZXh0IHN1bW1hcnknLAoJCQkJY3JpdGVyaWE9J0l0IG11c3QgYmUgc2hvcnRlciB0aGFuIHRoZSBvcmlnaW5hbCB0ZXh0IGFuZCBiZSBhIHZhbGlkIHN1bW1hcnknLAoJCQkpLAoJCQlmaWxlPXN5cy5zdGRlcnIsCgkJKQoABQ== diff --git a/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator_bad.0.hash b/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator_bad.0.hash index d5e09be16..6d1554edf 100644 --- a/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator_bad.0.hash +++ b/tests/cases/unstable/nondet/eq/ncomp/eq_prompt_non_comparative_validator_bad.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDLtsCAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgppbXBvcnQgc3lzCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCWRlZiBnZXRfaW5wdXQoKToKCQkJcmV0dXJuICJBcyBwZXRzLCByYXRzIGFyZSBhZmZlY3Rpb25hdGUsIHBsYXlmdWwsIGFuZCBmb3JtIHN0cm9uZyBib25kcyB3aXRoIHRoZWlyIGh1bWFuIGNvbXBhbmlvbnMuIFRoZXkncmUgY3VyaW91cywgZW5qb3kgaW50ZXJhY3RpdmUgdG95cywgYW5kIGNhbiBsZWFybiB0cmlja3MgbXVjaCBsaWtlIHNtYWxsIGRvZ3MuIFRoZWlyIGFkYXB0YWJpbGl0eSwgaW50ZWxsaWdlbmNlLCBhbmQgY2hhcm1pbmcgcGVyc29uYWxpdGllcyBtYWtlIHRoZW0gdHJ1bHkgY29vbCBhbmltYWxzIHRoYXQgZGVzZXJ2ZSBtdWNoIG1vcmUgYXBwcmVjaWF0aW9uIHRoYW4gdGhleSBjdXJyZW50bHkgZ2V0LiIKCgkJcHJpbnQoCgkJCWdsLmVxX3ByaW5jaXBsZS5wcm9tcHRfbm9uX2NvbXBhcmF0aXZlKAoJCQkJZ2V0X2lucHV0LAoJCQkJdGFzaz0nUHJvZHVjZSBhIHRleHQgc3VtbWFyeScsCgkJCQljcml0ZXJpYT0nSXQgbXVzdCBiZSBzaG9ydGVyIHRoYW4gdGhlIG9yaWdpbmFsIHRleHQgYW5kIGJlIGEgdmFsaWQgc3VtbWFyeScsCgkJCSksCgkJCWZpbGU9c3lzLnN0ZGVyciwKCQkpCgAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgy7bAgAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKaW1wb3J0IHN5cwoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlkZWYgZ2V0X2lucHV0KCk6CgkJCXJldHVybiAiQXMgcGV0cywgcmF0cyBhcmUgYWZmZWN0aW9uYXRlLCBwbGF5ZnVsLCBhbmQgZm9ybSBzdHJvbmcgYm9uZHMgd2l0aCB0aGVpciBodW1hbiBjb21wYW5pb25zLiBUaGV5J3JlIGN1cmlvdXMsIGVuam95IGludGVyYWN0aXZlIHRveXMsIGFuZCBjYW4gbGVhcm4gdHJpY2tzIG11Y2ggbGlrZSBzbWFsbCBkb2dzLiBUaGVpciBhZGFwdGFiaWxpdHksIGludGVsbGlnZW5jZSwgYW5kIGNoYXJtaW5nIHBlcnNvbmFsaXRpZXMgbWFrZSB0aGVtIHRydWx5IGNvb2wgYW5pbWFscyB0aGF0IGRlc2VydmUgbXVjaCBtb3JlIGFwcHJlY2lhdGlvbiB0aGFuIHRoZXkgY3VycmVudGx5IGdldC4iCgoJCXByaW50KAoJCQlnbC5lcV9wcmluY2lwbGUucHJvbXB0X25vbl9jb21wYXJhdGl2ZSgKCQkJCWdldF9pbnB1dCwKCQkJCXRhc2s9J1Byb2R1Y2UgYSB0ZXh0IHN1bW1hcnknLAoJCQkJY3JpdGVyaWE9J0l0IG11c3QgYmUgc2hvcnRlciB0aGFuIHRoZSBvcmlnaW5hbCB0ZXh0IGFuZCBiZSBhIHZhbGlkIHN1bW1hcnknLAoJCQkpLAoJCQlmaWxlPXN5cy5zdGRlcnIsCgkJKQoABQ== diff --git a/tests/cases/unstable/nondet/validator/agree.0.hash b/tests/cases/unstable/nondet/validator/agree.0.hash index 9a6782d42..b3bf463c3 100644 --- a/tests/cases/unstable/nondet/validator/agree.0.hash +++ b/tests/cases/unstable/nondet/validator/agree.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDRlAEAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGh0bWwKZnJvbSBodG1sLnBhcnNlciBpbXBvcnQgSFRNTFBhcnNlcgoKZmNmID0gc2V0KFsnc2NyaXB0JywgJ2lmcmFtZSddKQoKCmNsYXNzIFNjcmlwdFJlbW92ZXIoSFRNTFBhcnNlcik6CglyZXN1bHQ6IGxpc3Rbc3RyXQoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlzdXBlcigpLl9faW5pdF9fKCkKCQlzZWxmLnJlc3VsdCA9IFtdCgkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoKCWRlZiBoYW5kbGVfc3RhcnR0YWcoc2VsZiwgdGFnLCBhdHRycyk6CgkJaWYgdGFnLmxvd2VyKCkgaW4gZmNmOgoJCQlzZWxmLmluX3NjcmlwdCA9IFRydWUKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKHNlbGYuZ2V0X3N0YXJ0dGFnX3RleHQoKSkKCglkZWYgaGFuZGxlX2VuZHRhZyhzZWxmLCB0YWcpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoJCWVsaWYgbm90IHNlbGYuaW5fc2NyaXB0OgoJCQlzZWxmLnJlc3VsdC5hcHBlbmQoZic8L3t0YWd9PicpCgoJZGVmIGhhbmRsZV9kYXRhKHNlbGYsIGRhdGEpOgoJCWlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGRhdGEpCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgbW9kZTogc3RyKToKCQlkZWYgcnVuKCkgLT4gc3RyOgoJCQlyZXMgPSBnbC5ub25kZXQud2ViLnJlbmRlcigKCQkJCSdodHRwczovL3Rlc3Qtc2VydmVyLmdlbmxheWVyLmNvbS9zdGF0aWMvZ2Vudm0vaGVsbG8uaHRtbCcsIG1vZGU9bW9kZQoJCQkpICAjIHR5cGU6IGlnbm9yZQoJCQlpZiBtb2RlID09ICdodG1sJzoKCQkJCXBhcnNlciA9IFNjcmlwdFJlbW92ZXIoKQoJCQkJcGFyc2VyLmZlZWQocmVzKQoJCQkJcmVzID0gJycuam9pbihwYXJzZXIucmVzdWx0KQoJCQlyZXR1cm4gcmVzCgoJCXByaW50KGdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEocnVuKS5zdHJpcCgpKQoAAAAAAAAAAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAg0ZQBAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBodG1sCmZyb20gaHRtbC5wYXJzZXIgaW1wb3J0IEhUTUxQYXJzZXIKCmZjZiA9IHNldChbJ3NjcmlwdCcsICdpZnJhbWUnXSkKCgpjbGFzcyBTY3JpcHRSZW1vdmVyKEhUTUxQYXJzZXIpOgoJcmVzdWx0OiBsaXN0W3N0cl0KCglkZWYgX19pbml0X18oc2VsZik6CgkJc3VwZXIoKS5fX2luaXRfXygpCgkJc2VsZi5yZXN1bHQgPSBbXQoJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCglkZWYgaGFuZGxlX3N0YXJ0dGFnKHNlbGYsIHRhZywgYXR0cnMpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBUcnVlCgkJZWxpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChzZWxmLmdldF9zdGFydHRhZ190ZXh0KCkpCgoJZGVmIGhhbmRsZV9lbmR0YWcoc2VsZiwgdGFnKToKCQlpZiB0YWcubG93ZXIoKSBpbiBmY2Y6CgkJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGYnPC97dGFnfT4nKQoKCWRlZiBoYW5kbGVfZGF0YShzZWxmLCBkYXRhKToKCQlpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChkYXRhKQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIG1vZGU6IHN0cik6CgkJZGVmIHJ1bigpIC0+IHN0cjoKCQkJcmVzID0gZ2wubm9uZGV0LndlYi5yZW5kZXIoCgkJCQknaHR0cHM6Ly90ZXN0LXNlcnZlci5nZW5sYXllci5jb20vc3RhdGljL2dlbnZtL2hlbGxvLmh0bWwnLCBtb2RlPW1vZGUKCQkJKSAgIyB0eXBlOiBpZ25vcmUKCQkJaWYgbW9kZSA9PSAnaHRtbCc6CgkJCQlwYXJzZXIgPSBTY3JpcHRSZW1vdmVyKCkKCQkJCXBhcnNlci5mZWVkKHJlcykKCQkJCXJlcyA9ICcnLmpvaW4ocGFyc2VyLnJlc3VsdCkKCQkJcmV0dXJuIHJlcwoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikuc3RyaXAoKSkKAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/unstable/nondet/validator/disagree.0.hash b/tests/cases/unstable/nondet/validator/disagree.0.hash index 9a6782d42..b3bf463c3 100644 --- a/tests/cases/unstable/nondet/validator/disagree.0.hash +++ b/tests/cases/unstable/nondet/validator/disagree.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDRlAEAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGh0bWwKZnJvbSBodG1sLnBhcnNlciBpbXBvcnQgSFRNTFBhcnNlcgoKZmNmID0gc2V0KFsnc2NyaXB0JywgJ2lmcmFtZSddKQoKCmNsYXNzIFNjcmlwdFJlbW92ZXIoSFRNTFBhcnNlcik6CglyZXN1bHQ6IGxpc3Rbc3RyXQoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlzdXBlcigpLl9faW5pdF9fKCkKCQlzZWxmLnJlc3VsdCA9IFtdCgkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoKCWRlZiBoYW5kbGVfc3RhcnR0YWcoc2VsZiwgdGFnLCBhdHRycyk6CgkJaWYgdGFnLmxvd2VyKCkgaW4gZmNmOgoJCQlzZWxmLmluX3NjcmlwdCA9IFRydWUKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKHNlbGYuZ2V0X3N0YXJ0dGFnX3RleHQoKSkKCglkZWYgaGFuZGxlX2VuZHRhZyhzZWxmLCB0YWcpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoJCWVsaWYgbm90IHNlbGYuaW5fc2NyaXB0OgoJCQlzZWxmLnJlc3VsdC5hcHBlbmQoZic8L3t0YWd9PicpCgoJZGVmIGhhbmRsZV9kYXRhKHNlbGYsIGRhdGEpOgoJCWlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGRhdGEpCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgbW9kZTogc3RyKToKCQlkZWYgcnVuKCkgLT4gc3RyOgoJCQlyZXMgPSBnbC5ub25kZXQud2ViLnJlbmRlcigKCQkJCSdodHRwczovL3Rlc3Qtc2VydmVyLmdlbmxheWVyLmNvbS9zdGF0aWMvZ2Vudm0vaGVsbG8uaHRtbCcsIG1vZGU9bW9kZQoJCQkpICAjIHR5cGU6IGlnbm9yZQoJCQlpZiBtb2RlID09ICdodG1sJzoKCQkJCXBhcnNlciA9IFNjcmlwdFJlbW92ZXIoKQoJCQkJcGFyc2VyLmZlZWQocmVzKQoJCQkJcmVzID0gJycuam9pbihwYXJzZXIucmVzdWx0KQoJCQlyZXR1cm4gcmVzCgoJCXByaW50KGdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEocnVuKS5zdHJpcCgpKQoAAAAAAAAAAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAg0ZQBAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBodG1sCmZyb20gaHRtbC5wYXJzZXIgaW1wb3J0IEhUTUxQYXJzZXIKCmZjZiA9IHNldChbJ3NjcmlwdCcsICdpZnJhbWUnXSkKCgpjbGFzcyBTY3JpcHRSZW1vdmVyKEhUTUxQYXJzZXIpOgoJcmVzdWx0OiBsaXN0W3N0cl0KCglkZWYgX19pbml0X18oc2VsZik6CgkJc3VwZXIoKS5fX2luaXRfXygpCgkJc2VsZi5yZXN1bHQgPSBbXQoJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCglkZWYgaGFuZGxlX3N0YXJ0dGFnKHNlbGYsIHRhZywgYXR0cnMpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBUcnVlCgkJZWxpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChzZWxmLmdldF9zdGFydHRhZ190ZXh0KCkpCgoJZGVmIGhhbmRsZV9lbmR0YWcoc2VsZiwgdGFnKToKCQlpZiB0YWcubG93ZXIoKSBpbiBmY2Y6CgkJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGYnPC97dGFnfT4nKQoKCWRlZiBoYW5kbGVfZGF0YShzZWxmLCBkYXRhKToKCQlpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChkYXRhKQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIG1vZGU6IHN0cik6CgkJZGVmIHJ1bigpIC0+IHN0cjoKCQkJcmVzID0gZ2wubm9uZGV0LndlYi5yZW5kZXIoCgkJCQknaHR0cHM6Ly90ZXN0LXNlcnZlci5nZW5sYXllci5jb20vc3RhdGljL2dlbnZtL2hlbGxvLmh0bWwnLCBtb2RlPW1vZGUKCQkJKSAgIyB0eXBlOiBpZ25vcmUKCQkJaWYgbW9kZSA9PSAnaHRtbCc6CgkJCQlwYXJzZXIgPSBTY3JpcHRSZW1vdmVyKCkKCQkJCXBhcnNlci5mZWVkKHJlcykKCQkJCXJlcyA9ICcnLmpvaW4ocGFyc2VyLnJlc3VsdCkKCQkJcmV0dXJuIHJlcwoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikuc3RyaXAoKSkKAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/unstable/nondet/web/get_webpage_html.0.hash b/tests/cases/unstable/nondet/web/get_webpage_html.0.hash index 9a6782d42..b3bf463c3 100644 --- a/tests/cases/unstable/nondet/web/get_webpage_html.0.hash +++ b/tests/cases/unstable/nondet/web/get_webpage_html.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDRlAEAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGh0bWwKZnJvbSBodG1sLnBhcnNlciBpbXBvcnQgSFRNTFBhcnNlcgoKZmNmID0gc2V0KFsnc2NyaXB0JywgJ2lmcmFtZSddKQoKCmNsYXNzIFNjcmlwdFJlbW92ZXIoSFRNTFBhcnNlcik6CglyZXN1bHQ6IGxpc3Rbc3RyXQoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlzdXBlcigpLl9faW5pdF9fKCkKCQlzZWxmLnJlc3VsdCA9IFtdCgkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoKCWRlZiBoYW5kbGVfc3RhcnR0YWcoc2VsZiwgdGFnLCBhdHRycyk6CgkJaWYgdGFnLmxvd2VyKCkgaW4gZmNmOgoJCQlzZWxmLmluX3NjcmlwdCA9IFRydWUKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKHNlbGYuZ2V0X3N0YXJ0dGFnX3RleHQoKSkKCglkZWYgaGFuZGxlX2VuZHRhZyhzZWxmLCB0YWcpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoJCWVsaWYgbm90IHNlbGYuaW5fc2NyaXB0OgoJCQlzZWxmLnJlc3VsdC5hcHBlbmQoZic8L3t0YWd9PicpCgoJZGVmIGhhbmRsZV9kYXRhKHNlbGYsIGRhdGEpOgoJCWlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGRhdGEpCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgbW9kZTogc3RyKToKCQlkZWYgcnVuKCkgLT4gc3RyOgoJCQlyZXMgPSBnbC5ub25kZXQud2ViLnJlbmRlcigKCQkJCSdodHRwczovL3Rlc3Qtc2VydmVyLmdlbmxheWVyLmNvbS9zdGF0aWMvZ2Vudm0vaGVsbG8uaHRtbCcsIG1vZGU9bW9kZQoJCQkpICAjIHR5cGU6IGlnbm9yZQoJCQlpZiBtb2RlID09ICdodG1sJzoKCQkJCXBhcnNlciA9IFNjcmlwdFJlbW92ZXIoKQoJCQkJcGFyc2VyLmZlZWQocmVzKQoJCQkJcmVzID0gJycuam9pbihwYXJzZXIucmVzdWx0KQoJCQlyZXR1cm4gcmVzCgoJCXByaW50KGdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEocnVuKS5zdHJpcCgpKQoAAAAAAAAAAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAg0ZQBAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBodG1sCmZyb20gaHRtbC5wYXJzZXIgaW1wb3J0IEhUTUxQYXJzZXIKCmZjZiA9IHNldChbJ3NjcmlwdCcsICdpZnJhbWUnXSkKCgpjbGFzcyBTY3JpcHRSZW1vdmVyKEhUTUxQYXJzZXIpOgoJcmVzdWx0OiBsaXN0W3N0cl0KCglkZWYgX19pbml0X18oc2VsZik6CgkJc3VwZXIoKS5fX2luaXRfXygpCgkJc2VsZi5yZXN1bHQgPSBbXQoJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCglkZWYgaGFuZGxlX3N0YXJ0dGFnKHNlbGYsIHRhZywgYXR0cnMpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBUcnVlCgkJZWxpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChzZWxmLmdldF9zdGFydHRhZ190ZXh0KCkpCgoJZGVmIGhhbmRsZV9lbmR0YWcoc2VsZiwgdGFnKToKCQlpZiB0YWcubG93ZXIoKSBpbiBmY2Y6CgkJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGYnPC97dGFnfT4nKQoKCWRlZiBoYW5kbGVfZGF0YShzZWxmLCBkYXRhKToKCQlpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChkYXRhKQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIG1vZGU6IHN0cik6CgkJZGVmIHJ1bigpIC0+IHN0cjoKCQkJcmVzID0gZ2wubm9uZGV0LndlYi5yZW5kZXIoCgkJCQknaHR0cHM6Ly90ZXN0LXNlcnZlci5nZW5sYXllci5jb20vc3RhdGljL2dlbnZtL2hlbGxvLmh0bWwnLCBtb2RlPW1vZGUKCQkJKSAgIyB0eXBlOiBpZ25vcmUKCQkJaWYgbW9kZSA9PSAnaHRtbCc6CgkJCQlwYXJzZXIgPSBTY3JpcHRSZW1vdmVyKCkKCQkJCXBhcnNlci5mZWVkKHJlcykKCQkJCXJlcyA9ICcnLmpvaW4ocGFyc2VyLnJlc3VsdCkKCQkJcmV0dXJuIHJlcwoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikuc3RyaXAoKSkKAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/unstable/nondet/web/get_webpage_screenshot.0.hash b/tests/cases/unstable/nondet/web/get_webpage_screenshot.0.hash index 19976456e..eeba6163b 100644 --- a/tests/cases/unstable/nondet/web/get_webpage_screenshot.0.hash +++ b/tests/cases/unstable/nondet/web/get_webpage_screenshot.0.hash @@ -1 +1 @@ -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 diff --git a/tests/cases/unstable/nondet/web/get_webpage_text.0.hash b/tests/cases/unstable/nondet/web/get_webpage_text.0.hash index 9a6782d42..b3bf463c3 100644 --- a/tests/cases/unstable/nondet/web/get_webpage_text.0.hash +++ b/tests/cases/unstable/nondet/web/get_webpage_text.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDRlAEAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGh0bWwKZnJvbSBodG1sLnBhcnNlciBpbXBvcnQgSFRNTFBhcnNlcgoKZmNmID0gc2V0KFsnc2NyaXB0JywgJ2lmcmFtZSddKQoKCmNsYXNzIFNjcmlwdFJlbW92ZXIoSFRNTFBhcnNlcik6CglyZXN1bHQ6IGxpc3Rbc3RyXQoKCWRlZiBfX2luaXRfXyhzZWxmKToKCQlzdXBlcigpLl9faW5pdF9fKCkKCQlzZWxmLnJlc3VsdCA9IFtdCgkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoKCWRlZiBoYW5kbGVfc3RhcnR0YWcoc2VsZiwgdGFnLCBhdHRycyk6CgkJaWYgdGFnLmxvd2VyKCkgaW4gZmNmOgoJCQlzZWxmLmluX3NjcmlwdCA9IFRydWUKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKHNlbGYuZ2V0X3N0YXJ0dGFnX3RleHQoKSkKCglkZWYgaGFuZGxlX2VuZHRhZyhzZWxmLCB0YWcpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBGYWxzZQoJCWVsaWYgbm90IHNlbGYuaW5fc2NyaXB0OgoJCQlzZWxmLnJlc3VsdC5hcHBlbmQoZic8L3t0YWd9PicpCgoJZGVmIGhhbmRsZV9kYXRhKHNlbGYsIGRhdGEpOgoJCWlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGRhdGEpCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgbW9kZTogc3RyKToKCQlkZWYgcnVuKCkgLT4gc3RyOgoJCQlyZXMgPSBnbC5ub25kZXQud2ViLnJlbmRlcigKCQkJCSdodHRwczovL3Rlc3Qtc2VydmVyLmdlbmxheWVyLmNvbS9zdGF0aWMvZ2Vudm0vaGVsbG8uaHRtbCcsIG1vZGU9bW9kZQoJCQkpICAjIHR5cGU6IGlnbm9yZQoJCQlpZiBtb2RlID09ICdodG1sJzoKCQkJCXBhcnNlciA9IFNjcmlwdFJlbW92ZXIoKQoJCQkJcGFyc2VyLmZlZWQocmVzKQoJCQkJcmVzID0gJycuam9pbihwYXJzZXIucmVzdWx0KQoJCQlyZXR1cm4gcmVzCgoJCXByaW50KGdsLmVxX3ByaW5jaXBsZS5zdHJpY3RfZXEocnVuKS5zdHJpcCgpKQoAAAAAAAAAAAAAAAAF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAg0ZQBAAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBodG1sCmZyb20gaHRtbC5wYXJzZXIgaW1wb3J0IEhUTUxQYXJzZXIKCmZjZiA9IHNldChbJ3NjcmlwdCcsICdpZnJhbWUnXSkKCgpjbGFzcyBTY3JpcHRSZW1vdmVyKEhUTUxQYXJzZXIpOgoJcmVzdWx0OiBsaXN0W3N0cl0KCglkZWYgX19pbml0X18oc2VsZik6CgkJc3VwZXIoKS5fX2luaXRfXygpCgkJc2VsZi5yZXN1bHQgPSBbXQoJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCglkZWYgaGFuZGxlX3N0YXJ0dGFnKHNlbGYsIHRhZywgYXR0cnMpOgoJCWlmIHRhZy5sb3dlcigpIGluIGZjZjoKCQkJc2VsZi5pbl9zY3JpcHQgPSBUcnVlCgkJZWxpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChzZWxmLmdldF9zdGFydHRhZ190ZXh0KCkpCgoJZGVmIGhhbmRsZV9lbmR0YWcoc2VsZiwgdGFnKToKCQlpZiB0YWcubG93ZXIoKSBpbiBmY2Y6CgkJCXNlbGYuaW5fc2NyaXB0ID0gRmFsc2UKCQllbGlmIG5vdCBzZWxmLmluX3NjcmlwdDoKCQkJc2VsZi5yZXN1bHQuYXBwZW5kKGYnPC97dGFnfT4nKQoKCWRlZiBoYW5kbGVfZGF0YShzZWxmLCBkYXRhKToKCQlpZiBub3Qgc2VsZi5pbl9zY3JpcHQ6CgkJCXNlbGYucmVzdWx0LmFwcGVuZChkYXRhKQoKCmNsYXNzIENvbnRyYWN0KGdsLmNvbnRyYWN0LkNvbnRyYWN0KToKCUBnbC5wdWJsaWMud3JpdGUKCWRlZiBtYWluKHNlbGYsIG1vZGU6IHN0cik6CgkJZGVmIHJ1bigpIC0+IHN0cjoKCQkJcmVzID0gZ2wubm9uZGV0LndlYi5yZW5kZXIoCgkJCQknaHR0cHM6Ly90ZXN0LXNlcnZlci5nZW5sYXllci5jb20vc3RhdGljL2dlbnZtL2hlbGxvLmh0bWwnLCBtb2RlPW1vZGUKCQkJKSAgIyB0eXBlOiBpZ25vcmUKCQkJaWYgbW9kZSA9PSAnaHRtbCc6CgkJCQlwYXJzZXIgPSBTY3JpcHRSZW1vdmVyKCkKCQkJCXBhcnNlci5mZWVkKHJlcykKCQkJCXJlcyA9ICcnLmpvaW4ocGFyc2VyLnJlc3VsdCkKCQkJcmV0dXJuIHJlcwoKCQlwcmludChnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bikuc3RyaXAoKSkKAAAAAAAAAAAAAAAABQ== diff --git a/tests/cases/unstable/nondet/web/sandbox.0.hash b/tests/cases/unstable/nondet/web/sandbox.0.hash index 27195b0fe..c0d168136 100644 --- a/tests/cases/unstable/nondet/web/sandbox.0.hash +++ b/tests/cases/unstable/nondet/web/sandbox.0.hash @@ -1 +1 @@ -LQEAABUVowK6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCwAAAACDCgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOGuI0Enkt9rapj7fJg5cB+4sCtvx+0CKBD3g0ZJRoXnugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQshueAT90YIuSlHhhKHs952wsB2/oObeZR2G9lQzC51ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVowLhriNBJ5Lfa2qY+3yYOXAfuLArb8ftAigQ94NGSUaF5wAAAACDFlwBAAAjIHsgIkRlcGVuZHMiOiAicHktZ2VubGF5ZXI6dGVzdCIgfQppbXBvcnQgZ2VubGF5ZXIgYXMgZ2wKZnJvbSBnZW5sYXllci50eXBlcyBpbXBvcnQgKgoKaW1wb3J0IGpzb24KCgpjbGFzcyBDb250cmFjdChnbC5jb250cmFjdC5Db250cmFjdCk6CglAZ2wucHVibGljLndyaXRlCglkZWYgbWFpbihzZWxmLCBldjogc3RyKToKCQlkZWYgcnVuX25kZXQoKToKCQkJZ2xiID0gZ2xvYmFscygpCgkJCXByaW50KGYne2dsLnZtLnNwYXduX3NhbmRib3gobGFtYmRhOiBldmFsKGV2LCBnbGIpKX0nKQoJCQlwcmludChqc29uLmxvYWRzLl9fbmFtZV9fKQoKCQlnbC5lcV9wcmluY2lwbGUuc3RyaWN0X2VxKHJ1bl9uZGV0KQoF +LQEAAB0VowIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCIbngE/dGCLkpR4YSh7PedsLAdv6Dm3mUdhvZUMwudWYAAAAAgwoEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6AFYwdFrPMBSq8WLpkzBAMCygvvP1b+LXPAoI+CxhCyG54BP3Rgi5KUeGEoez3nbCwHb+g5t5lHYb2VDMLnVmJ6FedFDZ8E6cPY0thWqOnHjfoAgeosEo/ck84t8169YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaMCugBWMHRazzAUqvFi6ZMwQDAsoL7z9W/i1zwKCPgsYQsAAAAAgxZcAQAAIyB7ICJEZXBlbmRzIjogInB5LWdlbmxheWVyOnRlc3QiIH0KaW1wb3J0IGdlbmxheWVyIGFzIGdsCmZyb20gZ2VubGF5ZXIudHlwZXMgaW1wb3J0ICoKCmltcG9ydCBqc29uCgoKY2xhc3MgQ29udHJhY3QoZ2wuY29udHJhY3QuQ29udHJhY3QpOgoJQGdsLnB1YmxpYy53cml0ZQoJZGVmIG1haW4oc2VsZiwgZXY6IHN0cik6CgkJZGVmIHJ1bl9uZGV0KCk6CgkJCWdsYiA9IGdsb2JhbHMoKQoJCQlwcmludChmJ3tnbC52bS5zcGF3bl9zYW5kYm94KGxhbWJkYTogZXZhbChldiwgZ2xiKSl9JykKCQkJcHJpbnQoanNvbi5sb2Fkcy5fX25hbWVfXykKCgkJZ2wuZXFfcHJpbmNpcGxlLnN0cmljdF9lcShydW5fbmRldCkKBQ== diff --git a/tests/runner/origin/base_host.py b/tests/runner/origin/base_host.py index cfc35f24a..3e0c4f5ce 100644 --- a/tests/runner/origin/base_host.py +++ b/tests/runner/origin/base_host.py @@ -448,7 +448,7 @@ async def run_genvm( manager_uri: str = 'http://127.0.0.1:3999', ctx: Context, is_sync: bool, - capture_output: bool = True, + debug_mode: str = 'disabled', message: Message, host_data: str = '', gas_data: dict[str, str] | None = None, @@ -493,7 +493,7 @@ async def wrap_proc_body(attempt: int): 'major': 0, # FIXME 'message': message, 'is_sync': is_sync, - 'capture_output': capture_output, + 'debug_mode': debug_mode, 'host_data': host_data, 'max_execution_minutes': max_exec_mins, # this parameter is needed to prevent zombie genvms 'timestamp': timestamp, diff --git a/tests/runner/origin/public_abi.py b/tests/runner/origin/public_abi.py index 6baf5a15b..6c29cc2ce 100644 --- a/tests/runner/origin/public_abi.py +++ b/tests/runner/origin/public_abi.py @@ -34,11 +34,12 @@ class _MemoryLimiterConsts(typing.NamedTuple): class _RootOffsets(typing.NamedTuple): - CONTRACT: int = 0 - CODE: int = 1 - LOCKED_SLOTS: int = 2 - UPGRADERS: int = 3 - MAJOR: int = 4 + MAJOR: int = 0 + CONTRACT: int = 1 + CODE: int = 2 + LOCKED_SLOTS: int = 3 + UPGRADERS: int = 4 + CODE_SLOT: int = 5 root_offsets: typing.Final = _RootOffsets() @@ -136,6 +137,9 @@ def not_utf8_text() -> 'VmError': def malformed_runner() -> 'VmError': return VmError('invalid_contract malformed_runner') @staticmethod + def major_mismatch() -> 'VmError': + return VmError('invalid_contract major_mismatch') + @staticmethod def wasm() -> '_VmErrorInvalidContractWasm': return _VmErrorInvalidContractWasm() diff --git a/tests/runner/ya_test_runner_plugins/integration.py b/tests/runner/ya_test_runner_plugins/integration.py index a83cb0df0..df0204539 100644 --- a/tests/runner/ya_test_runner_plugins/integration.py +++ b/tests/runner/ya_test_runner_plugins/integration.py @@ -524,16 +524,10 @@ async def _run_single_step( bytes([public_abi.ResultCode.RETURN]) + gvm_calldata.encode(res['value']) ) elif res['kind'] == 'user_error': - if isinstance(res['value'], str): - encoded_nondet.append( - bytes([public_abi.ResultCode.USER_ERROR]) + res['value'].encode('utf-8') - ) - else: - encoded_nondet.append( - bytes([public_abi.ResultCode.USER_ERROR]) - + b'\x00\x00\x00\x00' - + gvm_calldata.encode(res['value']) - ) + encoded_nondet.append( + bytes([public_abi.ResultCode.USER_ERROR]) + + gvm_calldata.encode(res['value']) + ) elif res['kind'] == 'vm_error': encoded_nondet.append( bytes([public_abi.ResultCode.VM_ERROR]) + res['value'].encode('utf-8') @@ -575,6 +569,9 @@ async def _run_single_step( request_extra = {} if 'stable' in self._test_case.description.tags: request_extra['no_modules'] = True + case_permissions = single_conf.get('permissions') + if case_permissions is not None: + request_extra['permissions'] = case_permissions dflt_bucket = 2**200 bucket_totals: list[int] = single_conf.get( 'bucket_totals', [dflt_bucket, dflt_bucket] @@ -599,12 +596,11 @@ async def _run_single_step( manager_uri=manager_uri, message=single_conf['message'], timeout=single_conf.get('deadline', 10 * 60), - capture_output=True, is_sync=(mode == 's'), host_data=host_data, ctx=ctx, host='unix://' + mock_host.path, - extra_args=['--debug-mode'], + debug_mode='unsafe', code=code, calldata=calldata_bytes, bucket_totals=bucket_totals, diff --git a/tests/runner/ya_test_runner_plugins/permits.py b/tests/runner/ya_test_runner_plugins/permits.py index 3a411ab9e..afd818887 100644 --- a/tests/runner/ya_test_runner_plugins/permits.py +++ b/tests/runner/ya_test_runner_plugins/permits.py @@ -190,14 +190,13 @@ async def _run_background_genvm( manager_uri=manager_uri, ctx=ctx, is_sync=True, - capture_output=True, message=FAKE_MESSAGE, host_data='{"node_address":"test","tx_id":"test"}', host='unix://' + sock_path, code=code, calldata=gvm_calldata.encode({}), timeout=300, - extra_args=['--debug-mode'], + debug_mode='unsafe', request_extra={'no_modules': True}, shutdown_early=shut_downer, ) @@ -211,7 +210,6 @@ async def _assert_blocks(self, manager_uri: str, code: bytes) -> bool: 'major': 0, 'message': FAKE_MESSAGE, 'is_sync': True, - 'capture_output': True, 'host_data': '{"node_address":"test","tx_id":"test"}', 'max_execution_minutes': 20, 'timestamp': '2024-11-26T06:42:42.424242Z',