Skip to content

feat: rework manager api for cross-major calls - #7

Open
kp2pml30 wants to merge 1 commit into
v0.2-devfrom
pr/v0.2/feat/rework-manager-api
Open

feat: rework manager api for cross-major calls#7
kp2pml30 wants to merge 1 commit into
v0.2-devfrom
pr/v0.2/feat/rework-manager-api

Conversation

@kp2pml30

@kp2pml30 kp2pml30 commented Jul 28, 2026

Copy link
Copy Markdown
Member

Auto-opened executor mirror of genlayerlabs/genvm-manager#9.

Carries the executor-side work for that manager PR. Auto-closed as merged when the manager PR lands (its pr/v0.2/feat/rework-manager-api branch is moved onto v0.2-dev).

Summary by CodeRabbit

  • New Features

    • Added support for nested contract execution, including permission checks, state propagation, recursion limits, and fuel budgeting.
    • Added cross-version contract executor resolution and nested execution communication.
    • Added configurable memory limits and improved storage-write handling.
    • Added consistent result hashing and host connection initialization.
  • Bug Fixes

    • Improved host finalization by reliably flushing all active connections.
    • Corrected recursion-limit enforcement and state selection for nested calls.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The executor replaces local host-function declarations with shared interfaces. It adds host handshake and nested-run RPCs, propagates nested permissions and execution limits, supports cross-executor CallContract, and uses shared deterministic-fuel and result-hashing logic.

Changes

Nested execution and host integration

Layer / File(s) Summary
Shared interfaces and result hashing
executor/crates/common/Cargo.toml, executor/crates/common/src/lib.rs, executor/crates/modules-interfaces/Cargo.toml, executor/src/host/mod.rs, executor/src/rt/vm/mod.rs, executor/codegen/data/host-fns.json, executor/crates/common/src/host_fns.rs
The common crate re-exports host interfaces from genvm_modules_interfaces. The local host-function declarations and generated definitions are removed. Result hashing uses the shared small_hash helper.
Host handshake and nested RPC
executor/src/host/mod.rs, executor/src/exe/run.rs, executor/src/lib.rs
Hosts receive and flush hello data during connection. New RPCs resolve call-contract executors and run nested executions. Finalization flushes all hosts instead of sending notify_finished.
Nested runtime limits and permissions
executor/src/exe/run.rs, executor/src/lib.rs, executor/src/rt/memlimiter.rs, executor/src/rt/mod.rs, executor/src/rt/supervisor/mod.rs
Nested permissions, storage writes, fee buckets, memory limits, recursion, signer data, and deterministic fuel budgets are propagated into runtime setup.
Cross-executor CallContract flow
executor/src/wasi/genlayer_sdk.rs
CallContract routes nested execution across executors, propagates execution metadata, validates replies, updates sub-VM hashes, and charges LLM operations through shared deterministic-fuel accounting.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CallContract
  participant Host
  participant NestedExecutor
  participant ReplyDecoder
  CallContract->>Host: resolve_callcontract_executor
  CallContract->>Host: run_nested envelope
  Host->>NestedExecutor: execute nested envelope
  NestedExecutor-->>Host: nested reply
  Host-->>CallContract: NestedRunReply
  CallContract->>ReplyDecoder: validate and decode reply
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.48% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: reworking the manager API to support cross-major contract calls.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr/v0.2/feat/rework-manager-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kp2pml30
kp2pml30 force-pushed the pr/v0.2/feat/rework-manager-api branch 3 times, most recently from 2c26539 to 4bfbdcb Compare August 3, 2026 09:08
* feat(sdk): call contracts of another major through the host ✨
* refactor(rt): bound recursion with a budget minted by the chain root ♻️
* refactor(exe): carry nested execution state as one explicit group ♻️
* fix(exe): fold the callee's small hash on the nested route 🐛🔒️
* feat(exe): refuse a crossing call while custom runners are loaded ✨
* feat(host): write caller-supplied hello bytes and drop notify_finished ✨
* fix(supervisor): load precompiled modules only for registry runners 🔒️
* fix(sdk): stop exporting nondet permission across the boundary 🐛
@kp2pml30
kp2pml30 force-pushed the pr/v0.2/feat/rework-manager-api branch from 4bfbdcb to e3e1ffa Compare August 3, 2026 11:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
executor/src/exe/run.rs (1)

125-133: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The nested WRITE_STORAGE check can never be true.

check_nested_permissions at Line 127 rejects WRITE_STORAGE. So the contains(WRITE_STORAGE) test at Lines 128-130 always yields false. The two statements state opposite intents, which makes the nested storage-write rule hard to read.

Replace the lookup with the explicit constant, or drop WRITE_STORAGE from check_nested_permissions if a nested run may ever write.

♻️ Proposed clarification
     let can_write_storage = match &execution_data.nested {
         Some(nested) => {
             check_nested_permissions(nested.permissions)?;
-            nested
-                .permissions
-                .contains(genvm_modules_interfaces::NestedPermissions::WRITE_STORAGE)
+            // `check_nested_permissions` rejects WRITE_STORAGE, so a nested run
+            // never writes storage.
+            false
         }
         None => args.permissions.contains('w'),
     };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@executor/src/exe/run.rs` around lines 125 - 133, Resolve the contradiction in
the nested permission flow around can_write_storage and
check_nested_permissions: use an explicit false result for nested WRITE_STORAGE
access if nested writes remain disallowed, removing the unreachable
permissions.contains(WRITE_STORAGE) lookup; otherwise update
check_nested_permissions to permit it only if nested runs are intended to write.
Preserve the existing top-level args.permissions behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@executor/src/host/mod.rs`:
- Around line 768-774: Update HostManager::flush_all to attempt flush() on every
host even when one fails, recording the first error while continuing through the
remaining hosts; return that recorded error only after the loop completes, or
Ok(()) when all flushes succeed.

---

Nitpick comments:
In `@executor/src/exe/run.rs`:
- Around line 125-133: Resolve the contradiction in the nested permission flow
around can_write_storage and check_nested_permissions: use an explicit false
result for nested WRITE_STORAGE access if nested writes remain disallowed,
removing the unreachable permissions.contains(WRITE_STORAGE) lookup; otherwise
update check_nested_permissions to permit it only if nested runs are intended to
write. Preserve the existing top-level args.permissions behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e1d02bf-d3b2-46af-88d5-3ab6a7ff553b

📥 Commits

Reviewing files that changed from the base of the PR and between 1c8126d and e3e1ffa.

⛔ Files ignored due to path filters (210)
  • executor/Cargo.lock is excluded by !**/*.lock, !**/*.lock
  • executor/crates/common/Cargo.lock is excluded by !**/*.lock, !**/*.lock
  • executor/crates/modules-interfaces/Cargo.lock is excluded by !**/*.lock, !**/*.lock
  • tests/integration/stable/agentic/wasi/environ_args/environ_args.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/agentic/wasi/hash_random/hash_random.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/agentic/wasi/id_repr/id_repr.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/agentic/wasi/set_order/set_order.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/agentic/wasi/wasi_clock/wasi_clock.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/agentic/wasi/wasi_random/wasi_random.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/bench/read_tree_map.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/bench/read_tree_map.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/call_wasi_extra.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/disagree_in_sandbox.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/flt.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/fork_bomb.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/method_init.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/method_init.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/method_private.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/method_private.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/oom.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/rec.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/rec_1023.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/rec_1024.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/storage_rw_long.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/storage_rw_long.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/exploits/unreachable.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/leader_no_nondet.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/leader_no_nondet.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_leader.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_leader.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_err.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_err.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_exit.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_exit.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_exit_wrong_err.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_exit_wrong_err.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_nerr.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/leader_errors/simple_valid_err_nerr.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/metod_det_get_webpage.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/metod_det_get_webpage.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/trivial.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/trivial.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_agree.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_agree.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_disagree.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_disagree.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_imm.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_imm.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_imm.1.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/rollback_imm.1_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/sync.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/sync.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/sync_err.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/nondet/validator/sync_err.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/balance.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/balance_eth.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/sandbox_overspend.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/sandbox_overspend_2.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_all.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_all.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_all.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_all.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/balances/undefined_method.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_method.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_method.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_method.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/balances/undefined_method_payable.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_method_payable.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_method_payable.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_method_payable.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/balances/undefined_receive.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_receive.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_receive.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/balances/undefined_receive.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/embeddings/simple.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/embeddings/simple.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/embeddings/simple_det.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/embeddings/simple_det.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/embeddings/simple_tokenizer.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/embeddings/simple_tokenizer.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/embeddings/vecdb.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/events/post_event.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/call_view.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/call_view.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/call_view.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/call_view.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/intercontract/call_view_iface.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/call_view_iface.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/call_view_iface.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/call_view_iface.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/intercontract/deploy.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/deploy_salt.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/send_message.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/send_message_eth.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/send_message_on.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/send_message_on.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/send_message_on.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/intercontract/send_message_on.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/other/meth/method_init.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_init_wrong_name.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_init_wrong_name.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/other/meth/method_public.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_public.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_retn.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_retn.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_retn_view.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_retn_view.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_rollback.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/meth/method_rollback.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.1.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.1_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.2.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.2_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.3.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.3_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.4.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.4_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.5.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.5_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.6.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.6_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.7.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.7_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.8.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.8_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.9.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/other/ret/returns.9_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/pitfalls/error_msg.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/pitfalls/error_msg.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/pitfalls/error_msg_overridden.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/pitfalls/error_msg_overridden.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/pitfalls/multi_contract.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/pitfalls/pub_ctor.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/pitfalls/store_proxy.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/rollbacks/call_view.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/rollbacks/call_view.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/rollbacks/call_view.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/rollbacks/call_view.jsonnet is excluded by !tests/**
  • tests/integration/stable/py/rollbacks/nondet.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/rollbacks/simple.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/assign-json.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/assign-json.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/exit.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/exit.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/print.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/print.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/rollback.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/rollback.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/sandbox.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/s/sandbox.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/det/sandbox_write.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/assign-json.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/assign-json.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/exit.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/exit.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/print.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/print.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/rollback.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/sandbox/non-det/s/rollback.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/complex_types.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/complex_types.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/prim_types.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/prim_types.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/ret-float.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/ret-float.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/ret-tuple.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/ret-tuple.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/ret.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/ret.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/trivial.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/py/schemas/trivial.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/runners/dup-dependency.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/runners/env-template.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/runners/malformed_runner.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/runners/no_runner.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/runners/zip/no-zip.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/datetime.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/floats.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/formats.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/issue_163.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/module/np.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/module/pil.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/re.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/self-run/typing_is_ok.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/alloc_generic.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/alloc_generic_err.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/base.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/floats.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/gvm-89.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/gvm-89.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/default-frozen.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/default-frozen.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/default-frozen.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/default-frozen.jsonnet is excluded by !tests/**
  • tests/integration/stable/storage/locking/modify_ctor.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/modify_ctor.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/modify_ctor.jsonnet is excluded by !tests/**
  • tests/integration/stable/storage/locking/modify_later.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/modify_later.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/modify_later.0_0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/locking/modify_later.jsonnet is excluded by !tests/**
  • tests/integration/stable/storage/np.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/persists.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/persists.0_0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/read_nondet.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/storage_tree_map.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/to_str.0.hash is excluded by !**/*.hash, !tests/**
  • tests/integration/stable/storage/tree_map_nested.0.hash is excluded by !**/*.hash, !tests/**
📒 Files selected for processing (13)
  • executor/codegen/data/host-fns.json
  • executor/crates/common/Cargo.toml
  • executor/crates/common/src/host_fns.rs
  • executor/crates/common/src/lib.rs
  • executor/crates/modules-interfaces/Cargo.toml
  • executor/src/exe/run.rs
  • executor/src/host/mod.rs
  • executor/src/lib.rs
  • executor/src/rt/memlimiter.rs
  • executor/src/rt/mod.rs
  • executor/src/rt/supervisor/mod.rs
  • executor/src/rt/vm/mod.rs
  • executor/src/wasi/genlayer_sdk.rs
💤 Files with no reviewable changes (2)
  • executor/codegen/data/host-fns.json
  • executor/crates/common/src/host_fns.rs

Comment thread executor/src/host/mod.rs
Comment on lines +768 to +774

pub async fn flush_all(&self) -> Result<()> {
for host in &self.hosts {
host.lock().await.flush()?;
}
Ok(())
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Flush every host before returning the first error.

flush_all returns as soon as one host's flush fails. Hosts later in self.hosts are never flushed after that point. If a host after the failing one still holds buffered writes, that data does not reach its destination before the process exits.

Iterate every host, collect any error, and continue. Return the first error only after every host has had a chance to flush.

🔧 Proposed fix to flush every host and report the first error
     pub async fn flush_all(&self) -> Result<()> {
-        for host in &self.hosts {
-            host.lock().await.flush()?;
-        }
-        Ok(())
+        let mut first_err = None;
+        for host in &self.hosts {
+            if let Err(e) = host.lock().await.flush() {
+                if first_err.is_none() {
+                    first_err = Some(e);
+                }
+            }
+        }
+        match first_err {
+            Some(e) => Err(e),
+            None => Ok(()),
+        }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub async fn flush_all(&self) -> Result<()> {
for host in &self.hosts {
host.lock().await.flush()?;
}
Ok(())
}
pub async fn flush_all(&self) -> Result<()> {
let mut first_err = None;
for host in &self.hosts {
if let Err(e) = host.lock().await.flush() {
if first_err.is_none() {
first_err = Some(e);
}
}
}
match first_err {
Some(e) => Err(e),
None => Ok(()),
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@executor/src/host/mod.rs` around lines 768 - 774, Update
HostManager::flush_all to attempt flush() on every host even when one fails,
recording the first error while continuing through the remaining hosts; return
that recorded error only after the loop completes, or Ok(()) when all flushes
succeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant