Skip to content

Comments

Feature/smart pointer hell#634

Open
kpob wants to merge 3 commits intorelease/2.5.0from
feature/smart-pointer-hell
Open

Feature/smart pointer hell#634
kpob wants to merge 3 commits intorelease/2.5.0from
feature/smart-pointer-hell

Conversation

@kpob
Copy link
Contributor

@kpob kpob commented Feb 10, 2026

No description provided.

kpob added 3 commits February 10, 2026 10:43
…irectly, improve error handling in `External` and `Module` components, and add a `casper-client` guide.
@github-actions
Copy link

Benchmark report

Action Details Gas diff
Wasm Deploy Filename: Benchmark.wasm 🟢 -1.182622888 CSPR (0.38%)
Contract Call Entry point: set_variable 🔴 +0.000903215 CSPR (0.64%)
Contract Call Entry point: get_variable 🔴 +0.00093011 CSPR (0.18%)
Contract Call Entry point: set_struct_variable 🔴 +0.00092645 CSPR (0.55%)
Contract Call Entry point: get_struct_variable 🔴 +0.00094463 CSPR (0.25%)
Contract Call Entry point: set_mapping 🔴 +0.000970025 CSPR (0.68%)
Contract Call Entry point: get_mapping 🔴 +0.00098615 CSPR (0.28%)
Contract Call Entry point: push_list 🟢 -0.00168658 CSPR (0.58%)
Contract Call Entry point: get_list 🔴 +0.001002785 CSPR (0.29%)
Contract Call Entry point: init_submodule 🔴 +0.00304469 CSPR (0.34%)
Contract Call Entry point: call_submodule 🔴 +0.003114785 CSPR (0.90%)
Contract Call Entry point: call_payable 🔴 +0.000936545 CSPR (0.02%)
Contract Call Entry point: transfer_back 🔴 +0.00093344 CSPR (0.04%)
Contract Call Entry point: emit_event 🔴 +0.00094421 CSPR (0.76%)
Contract Call Entry point: set_named_key 🔴 +0.000930305 CSPR (0.48%)
Contract Call Entry point: get_named_key 🔴 +0.00095057 CSPR (0.26%)
Contract Call Entry point: set_dictionary 🔴 +0.00089129 CSPR (0.31%)
Contract Call Entry point: get_dictionary 🔴 +0.000909095 CSPR (0.26%)

Copy link

@llamapreview llamapreview bot left a comment

Choose a reason for hiding this comment

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

AI Code Review by LlamaPReview

🎯 TL;DR & Recommendation

Recommendation: Request Changes

This PR removes unnecessary RefCell wrappers from core interfaces but introduces breaking API changes in ContractEnv and HostEnv constructors, which could silently fail external integrations not updated accordingly.

📄 Documentation Diagram

This diagram documents the updated ContractEnv creation flow after removing RefCell wrappers.

sequenceDiagram
    participant User as External Code
    participant CE as ContractEnv::new
    participant Backend as Rc<dyn ContractContext>
    note over CE: PR #35;634 changed backend type<br/>from Rc<RefCell<dyn ContractContext>><br/>to Rc<dyn ContractContext>
    User->>CE: Call new(index, backend)
    CE->>Backend: Store backend
    CE-->>User: Return ContractEnv instance
Loading

🌟 Strengths

  • Solid internal refactoring moving towards a cleaner architecture with interior mutability managed at the appropriate level.
  • Improved error handling in External and Module components with revertible unwraps, enhancing robustness.
Priority File Category Impact Summary (≤12 words) Anchors
P1 core/src/contract_env.rs Architecture Breaking API change in ContractEnv constructor. symbol:ContractContext, path:odra-vm/src/odra_vm_contract_env.rs
P1 core/src/host.rs Architecture Breaking API change in HostEnv constructor. path:odra-test/src/lib.rs
P2 core/src/var.rs Architecture Ownership shift to owned ContractEnv; internal optimization.
P2 core/src/external.rs Maintainability Enhanced error handling with revertible unwraps.
P2 odra-wasm-client/src/client.rs Performance Optimized static gas variable with AtomicU64.
P2 odra-casper/test-vm/src/vm/casper_vm.rs Architecture Internal mutability refactored to fields; complexity increased. path:odra-casper/test-vm/src/casper_host.rs

🔍 Notable Themes

  • The PR systematically removes outer RefCell wrappers from core structs (ContractEnv, HostEnv) and moves interior mutability inward, aligning with Rust best practices but introducing breaking changes.
  • Multiple tangential improvements (error handling, performance optimizations) are included alongside the main refactoring.

📈 Risk Diagram

This diagram illustrates the breaking API changes in ContractEnv and HostEnv constructors and their impact on external integrations.

sequenceDiagram
    participant Ext as External Integration
    participant CE as ContractEnv
    participant HE as HostEnv
    note over CE: R1(P1): Breaking API change<br/>ContractEnv::new now requires Rc<dyn ContractContext>
    Ext->>CE: Attempt to call new with old signature
    CE--x Ext: Compilation error
    note over HE: R2(P1): Breaking API change<br/>HostEnv::new now requires Rc<dyn HostContext>
    Ext->>HE: Attempt to call new with old signature
    HE--x Ext: Compilation error
Loading
⚠️ **Unanchored Suggestions (Manual Review Recommended)**

The following suggestions could not be precisely anchored to a specific line in the diff. This can happen if the code is outside the changed lines, has been significantly refactored, or if the suggestion is a general observation. Please review them carefully in the context of the full file.


📁 File: core/src/contract_env.rs

This is a breaking public API change. The ContractEnv::new signature changes from Rc<RefCell<dyn ContractContext>> to Rc<dyn ContractContext>. This affects all downstream constructors that pass a ContractContext implementation. The related_context shows ContractEnv::new is called in multiple locations (core tests, VM environments). All these call sites have been updated in the PR, but any external code using this API will break. Additionally, the ContractContext trait methods only require &self (immutable), so the removal of RefCell is semantically sound. The impact is constrained to construction sites, not usage, because the trait methods remain the same.

Related Code:

pub struct ContractEnv {
      index: u32,
      mapping_data: Vec<u8>,
      backend: Rc<dyn ContractContext>
  }

  impl ContractEnv {
      pub const fn new(index: u32, backend: Rc<dyn ContractContext>) -> Self {
          Self {
              index,
              mapping_data: Vec::new(),
              backend
          }
      }
  }


💡 Have feedback? We'd love to hear it in our GitHub Discussions.
✨ This review was generated by LlamaPReview Advanced, which is free for all open-source projects. Learn more.

#[derive(Clone)]
pub struct HostEnv {
backend: Rc<RefCell<dyn HostContext>>,
backend: Rc<dyn HostContext>,
Copy link

Choose a reason for hiding this comment

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

P1 | Confidence: High

This is a breaking public API change. HostEnv::new now accepts Rc<dyn HostContext> instead of Rc<RefCell<dyn HostContext>>. This impacts all code that instantiates HostEnv. The related_context shows an external usage in odra-test where CasperHost::new(vm) now returns Rc<CasperHost> (updated in the PR). The HostContext trait methods only require &self, so removing RefCell is safe. The internal field captures_events is changed to Cell<bool> for interior mutability, which is appropriate for a Copy type. This change aligns with the overall refactoring to remove unnecessary RefCell wrappers.

@@ -31,9 +35,9 @@ impl<T> ModuleComponent for Var<T> {
/// Creates a new instance of `Var` with the given environment and index.
fn instance(env: Rc<ContractEnv>, index: u8) -> Self {
Copy link

Choose a reason for hiding this comment

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

P2 | Confidence: High

The Var struct now stores a direct ContractEnv instead of Rc<ContractEnv>. This changes the ownership model: each Var now owns its own ContractEnv (a child environment) rather than sharing an Rc. This is a significant architectural shift but is internally consistent because ContractEnv is Clone. The performance and memory impact should be evaluated, as cloning ContractEnv is cheap (it's a small struct with an Rc for the backend). The key field uses OnceCell for lazy computation of the storage key, which is a good optimization. No breaking change is introduced because the public API of Var (get/set methods) remains unchanged.

pub const PROXY_CALLER: &[u8; 52814] = include_bytes!("../resources/proxy_caller_with_return.wasm");

static GAS: OnceLock<Arc<Mutex<u64>>> = OnceLock::new();
static GAS: AtomicU64 = AtomicU64::new(DEFAULT_GAS);
Copy link

Choose a reason for hiding this comment

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

P2 | Confidence: High

The GAS static variable is changed from OnceLock<Arc<Mutex<u64>>> to AtomicU64. This is a separate optimization not directly related to the smart pointer refactoring. It reduces overhead for concurrent access (although the framework is single-threaded in Wasm) and simplifies the code. This is a positive change but should be noted as a tangential improvement.

@@ -80,15 +80,15 @@ impl<T: ContractRef> External<T> {
if self.contract_ref.get().is_none() {
Copy link

Choose a reason for hiding this comment

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

[Contextual Comment]
This comment refers to code near real line 79. Anchored to nearest_changed(80) line 80.


P2 | Confidence: High

The PR improves error handling by replacing .unwrap() with .unwrap_or_revert(&self.env). This ensures that if the OnceCell is unexpectedly uninitialized, the contract will revert with a clear error instead of panicking. This is a defensive programming improvement that aligns with the framework's revertible error model. The same pattern is applied in core/src/module.rs. While not a bug fix, it enhances robustness.

@odradev odradev deleted a comment from llamapreview bot Feb 16, 2026
Copy link
Contributor

@zie1ony zie1ony left a comment

Choose a reason for hiding this comment

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

CasperVM requires different approach

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.

2 participants