Skip to content

[BUG] Three competing #[contract] entry points collide on WASM export, breaking the release build #161

Description

@N-thnI

Status: ✅ Resolved on main — fixed by PR #157, commit 7073d25. Verified against a freshly-fetched origin/main before editing this issue.

Description

engine-core defined three separate #[contract] structs — EngineCore (core/mod.rs), CoreEngine (core/engine.rs), and ControlPlane (core/control_plane.rs) — each with its own initialize method. On the WASM target, contract methods are exported by name into a flat symbol namespace, so three initialize exports in one crate is a hard link error. This only reproduced on the exact build CI runs; a plain native cargo build/cargo test never touches WASM codegen and passed silently, which is why it shipped undetected.

Affected Component

engine-core/src/core/mod.rs, engine-core/src/core/engine.rs (removed), engine-core/src/core/control_plane.rs

Original Behavior (Bug)

$ cargo build --target wasm32-unknown-unknown --release
error: symbol `initialize` is already defined
  --> engine-core\src\core\control_plane.rs:66:1
   |
66 | #[contractimpl]
   | ^^^^^^^^^^^^^^^

Expected Behavior

The crate exports exactly one contract ABI. cargo build --target wasm32-unknown-unknown --release — the exact command .github/workflows/ci.yml runs — succeeds.

Root Cause

EngineCore and CoreEngine were early, unfinished draft contracts (no reentrancy guard, no circuit-breaker integration, raw panic! instead of typed errors) superseded by ControlPlane, the fully integrated, tested entry point (audit/circuit-breaker/governance/version/zk_hooks all wired through it, covered by core/tests.rs). Neither EngineCore nor CoreEngine was referenced anywhere else in the repo — confirmed via a full-repo grep for both type names before removal.

Resolution

  • Removed the EngineCore struct/impl and its now-unused CoreState/IntegrityProof types from core/mod.rs.
  • Deleted core/engine.rs (CoreEngine, EngineRole, CoreError) entirely, along with its pub mod engine; declaration.
  • ControlPlane (core/control_plane.rs) remains the sole #[contract] entry point and is unchanged in its public ABI.

Verification

$ git cat-file -e origin/main:engine-core/src/core/engine.rs
fatal: path 'engine-core/src/core/engine.rs' does not exist in 'origin/main'   # confirmed removed

$ git show origin/main:engine-core/src/core/mod.rs | grep -c EngineCore
0                                                                              # confirmed removed

$ cargo build --target wasm32-unknown-unknown --release
    Finished `release` profile [optimized] target(s) in 18.01s

$ cargo test --workspace
test result: ok. 78 passed; 0 failed; 0 ignored
  • AC-1: cargo build --target wasm32-unknown-unknown --release exits 0.
  • AC-2: cargo test --workspace passes (78/78).
  • AC-3: No remaining references to EngineCore or CoreEngine in the repo.

Definition of Done

  • Fix merged to main (PR Fix merge-corrupted engine-core, jest/eslint setup, repo cruft #157, 7073d25).
  • No new cargo clippy warnings introduced by this change (4 pre-existing warnings on main predate this fix — unrelated, minor: empty lines after doc comments, a slow zero-fill loop, a matches! suggestion).
  • .github/workflows/ci.yml's very first step is cargo build --target wasm32-unknown-unknown --release, run on every push to main/feat/** and every PR into main — this fix is exercised by CI on every change going forward, no CI update needed for this specifically.

Metadata

Metadata

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26bugSomething isn't workingengine-coreRust/Soroban engine-core crate

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions