Skip to content

Add Rust ABI support for WASM subgraphs#6462

Draft
cargopete wants to merge 5 commits intographprotocol:masterfrom
cargopete:rust-abi-support
Draft

Add Rust ABI support for WASM subgraphs#6462
cargopete wants to merge 5 commits intographprotocol:masterfrom
cargopete:rust-abi-support

Conversation

@cargopete
Copy link
Copy Markdown
Contributor

Summary

Adds support for Rust-compiled WASM subgraphs as an alternative to AssemblyScript. This introduces a new rust_abi/ module parallel to the existing asc_abi/, with a clean ptr+len FFI protocol and TLV entity serialization.

  • rust_abi/ module (~1,450 LOC) — ToRustWasm/FromRustWasm traits, TLV entity serialization, trigger serialization (RustLogTrigger/RustCallTrigger/RustBlockTrigger), and all host function linker wrappers (store, crypto, logging, data sources, IPFS, ethereum calls) with async + gas metering
  • Language detectionis_rust_module() detects "graphite" namespace imports; MappingLanguage enum stored on ValidModule
  • Dispatchbuild_linker() branches on language; handle_trigger_rust() uses Rust calling convention (allocate → write bytes → call handler(ptr, len) → reset_arena)
  • Compatibility — skips parity_wasm gas injection for Rust modules (parity_wasm can't parse modern WASM features like bulk-memory); skips AS-specific exports (id_of_type, _start)
  • Ethereum triggersToRustBytes impl for all 3 trigger types (Log, Call, Block)
  • 14 unit tests passing for entity roundtrips, trigger serialization, type roundtrips

Live-tested

Deployed an ERC20 subgraph (compiled with Graphite SDK) to this fork, indexing real USDC Transfer events from Ethereum mainnet. Full pipeline verified: block ingestion → event scanning → Rust WASM handler → entity storage → correct GraphQL query results.

Architecture

                    ┌─────────────────────────┐
                    │    HostExports<C>       │  ← Language-agnostic (unchanged)
                    │  (store, crypto, ipfs)  │
                    └────────────┬────────────┘
                                 │
              ┌──────────────────┼──────────────────┐
              │                                     │
    ┌─────────┴─────────┐             ┌─────────────┴────────────┐
    │  AscAbiHost       │             │  RustAbiHost             │
    │  (existing code)  │             │  (new, this PR)          │
    │  AscPtr<T>        │             │  ptr+len, TLV serde      │
    └───────────────────┘             └──────────────────────────┘

Known gaps (not blocking review)

  • Gas metering — parity_wasm gas injection is bypassed for Rust modules. Needs wasmtime fuel metering or a WASM-2.0-compatible alternative.
  • NEAR triggers — stubbed as unimplemented! (Ethereum-only for now)
  • Offchain/subgraph triggers — stubbed as empty bytes

Test plan

  • Existing graph-node tests pass (14 rust_abi + 17 NEAR chain tests confirmed locally)
  • WASM integration test: load Rust WASM, serialize trigger, call handler, verify entity
  • Live test: deploy Rust subgraph to running fork, index mainnet events, query via GraphQL
  • Verify AS subgraphs are completely unaffected (no changes to AS code paths)

- Add Ethereum ToRustBytes impl for Log/Call/Block triggers
- Add NEAR ToRustBytes stub (unimplemented, Ethereum-only for now)
- Propagate ToRustBytes trait bounds through instance_manager
- Skip parity_wasm gas injection for Rust modules (can't parse bulk-memory opcodes)
- Skip AS-specific exports (id_of_type, _start) for Rust modules
- Add handle_trigger_rust and invoke_handler_rust calling convention
- Add Rust host function wrappers in module/context.rs
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