Skip to content

Latest commit

 

History

History
126 lines (85 loc) · 9.5 KB

File metadata and controls

126 lines (85 loc) · 9.5 KB

Graphite Roadmap — April 2026

Goal: full feature parity with AssemblyScript graph-ts so any production subgraph can be written in Rust.

Current state: feature parity achieved. All graph-ts host functions are implemented. ERC20 and ERC721 subgraphs are live on The Graph Studio (Arbitrum One). Five example subgraphs cover every handler type. Native cargo test covers the entire SDK without Docker.


Week 1 — Quick Wins (Apr 9–13)

1.1 BigDecimal arithmetic

Status: ✅ done. Add, Sub, Mul, Div impls in graphite/src/primitives.rs, backed by num-bigint.

1.2 BigInt modulo

Status: ✅ done. Rem impl added to BigInt.

1.3 entity.remove() codegen

Status: ✅ done. pub fn remove(id: &str) emitted for every generated entity; calls ffi::store_remove on WASM and the native store on non-WASM builds.

1.4 @entity(immutable: true) support

Status: ✅ done. Immutable entities detected in schema.rs; save() is suppressed and only the initial write path is emitted.

1.5 Address type utilities

Status: ✅ done. Address::from_hex_str(s: &str) added via AddressExt trait in graphite/src/primitives.rs.

1.6 Field nullability in codegen

Status: ✅ done. Non-nullable fields (! in schema) are emitted as T instead of Option<T>, giving a compile error rather than a silent None.


Week 2 — Tuple and Array Event Decoding (Apr 14–20)

2.1 Runtime decoder for array types

Status: ✅ done. Fixed arrays (T[N]), dynamic arrays (T[]), and nested arrays (T[][]) fully decoded in graph-as-runtime/src/ethereum.rs via read_ethereum_value_array.

2.2 Runtime decoder for tuple types

Status: ✅ done. KIND_TUPLE decoded recursively into EthereumValue::Tuple(Vec<EthereumValue>). Covers Uniswap V3 Swap, Aave Borrow, and similar modern DeFi events.

2.3 Codegen for complex event param types

Status: ✅ done. abi.rs emits correct field types and find_array / find_tuple accessors for array and tuple params.

2.4 ethereum.decode host function

Status: ✅ done. ethereum_decode(types, data) wrapper in graph-as-runtime/src/ethereum.rs; calls the host FFI on WASM, returns None on native (mock directly with EthereumValue).


Week 3 — Contract Calls and Dynamic Data Sources (Apr 21–25)

3.1 ethereum.call SDK wrapper

Status: ✅ done. ContractCall::new(address, signature).with_args(encoded).call(host) builder in graphite/src/call.rs. Selector computed via crypto::selector.

3.2 ethereum.call native mock

Status: ✅ done. mock::set_call_result, mock::assert_called, mock::call_count on the thread-local mock; MockHost::assert_called and MockHost::call_count on the struct-based mock.

3.3 Dynamic data sources

Status: ✅ done. data_source::create, data_source::address, and data_source::network wrappers in graphite/src/data_source.rs. mock::assert_data_source_created and MockHost::assert_data_source_created for testing. Manifest templates: section parsing is still manual (deploy tool does not yet auto-generate it).

3.4 crypto.keccak256 native implementation

Status: ✅ done. graphite/src/crypto.rs uses alloy_primitives::keccak256 on both WASM and native — works in cargo test with no mock setup. crypto::selector strips return types and returns the 4-byte function selector.


Week 4 — Schema Completeness and Handler Coverage (Apr 26–30)

4.1 @derivedFrom in schema codegen

Status: ✅ done. Fields with @derivedFrom are detected and excluded from the generated struct, new(), setters, save(), and load(). Graph-node handles the reverse lookup at query time.

4.2 Call handlers

Status: ✅ done. #[handler(call)] generates WASM entry points that call read_ethereum_call and decode via FromRawCall. {Contract}{Fn}Call structs are generated by graphite codegen for every ABI function. Manifest callHandlers section parsing is still manual (not auto-generated by the deploy tool).

4.3 Multiple data sources — validated example

Status: ✅ done. examples/multi-source/ — ERC20 + ERC721 data sources in one subgraph.yaml, sharing a single WASM file. Codegen handles multiple [[contracts]] entries. Four native tests cover both handlers, namespace isolation, and mixed event counts.

4.4 Receipt handlers

Status: ✅ done. EthereumTransactionReceipt (status, gas_used, log_count) decoded from AS memory at offset 28 of EthereumEvent. receipt: Option<TransactionReceipt> threaded through RawEthereumEventEventContext. Re-exported from graphite as graphite::TransactionReceipt.

4.5 Non-fatal errors

Status: ✅ done. nonfatal_error!(host, "msg") macro logs at CRITICAL level. With features: [nonFatalErrors] in the manifest, graph-node records the error and continues indexing.

4.6 ipfs.cat native mock

Status: ✅ done. mock::set_ipfs_result(cid, bytes) registers content in a thread-local; MockHost::ipfs_cat checks both instance content and the thread-local.


May candidates → all done

Feature Effort Status
JSON module Medium ✅ done. graphite::json::from_bytes / from_strJsonValue. On WASM calls json.fromBytes host and decodes AS JSONValue from memory. On native uses serde_json. Re-exported via prelude.
Dynamic data source manifest codegen Low ✅ done. [[templates]] section in graphite.toml generates the same ABI bindings as [[contracts]]. Deploy tool already walks templates: in the manifest via collect_file_refs.
ENS (ens.nameByAddress) Low-medium ✅ done. graphite::ens::name_by_address(address) calls ens.nameByAddress FFI on WASM; checks mock::set_ens_name thread-local on native. MockHost::mock_ens_name for struct-based tests.
File data sources (IPFS indexing) High ✅ done. #[handler(file)] macro variant generates a WASM export that reads IPFS content bytes and calls the _impl with (content: &Vec<u8>, ctx: &FileContext). Schema codegen skips no changes needed — file handlers use standard entities.
Timeseries / aggregations High ✅ done. Timestamp and Int8 scalars map to i64 in codegen. set_i64/FieldValue::Int8 added throughout the stack. @aggregation entities skipped in codegen (graph-node auto-computes them). _Schema_ (fulltext directives) also skipped.
Subgraph composition High ✅ done (no-op). Composition is a query-layer concern — graph-node handles it at deploy time. No handler SDK changes needed.
Fulltext search (@fulltext) Low ✅ done. _Schema_ object skipped in codegen; @fulltext directives are PostgreSQL-specific and handled entirely by graph-node.
Subgraph grafting Low ✅ done. graft: commented block added to graphite init scaffold's subgraph.yaml. Grafting is a deployment-time manifest option — no handler SDK changes needed.

Post-April Completions

Feature Status
dataSource.createWithContext ✅ done. WASM path uses new new_asc_string_array + data_source_create_with_context FFI. Hostless create_file_with_context available for #[handler] code. Context retrievable via context_current() / context_string(key).
File data source example ✅ done. examples/file-ds/ — ERC721 transfer handler spawns IPFS file data source; #[handler(file)] metadata handler parses JSON and updates entity. Four native tests.
Log capture fix (testing::MockHost) ✅ done. logs field changed to RefCell<Vec<(LogLevel, String)>> so log() can write through &self. get_logs(), logs_at() helpers added.
receipt: true manifest generation ✅ done. receipt = true in graphite.toml [[contracts]] section emits receipt: true in the mapping.
Hostless data source API ✅ done. data_source::create_file, create_file_with_context, create_contract, context_current, context_string, id_current, address_current, network_current — all cfg-dispatch (FFI on WASM, thread-local on native).
CI: all examples in WASM build ✅ done. CI builds ERC20, ERC721, ERC1155, multi-source, file-ds, and uniswap-v2.
examples/file-ds in workspace ✅ done. Added to Cargo.toml workspace members; all tests run in cargo test --workspace.
Uniswap V2 factory example ✅ done. examples/uniswap-v2/ — Factory + Pair template pattern. handle_pair_created creates Pool entity and calls data_source::create_contract("Pair", addr). handle_swap records Swap entity and increments Pool.swapCount (LE-byte arithmetic). mock::set_current_address and mock::assert_contract_data_source_created added. Four native tests.
graphite init scaffold fix ✅ done. Generated lib.rs now uses correct #[handler] pattern (no host param, builder-style entity, _impl convention, no_std boilerplate) matching the real examples. Includes a native test.

Success Criteria

By end of April, a developer should be able to:

  1. Index any ERC20/ERC721/ERC1155 event with no manual workarounds —
  2. Index a factory-pattern contract (Uniswap V2 pairs, etc.) via dynamic data sources —
  3. Call contract view functions from inside a handler —
  4. Write entities with relationships using @derivedFrom
  5. Run cargo test and cover all handler logic — including contract calls and keccak — without Docker —

All criteria met. Covers ~100% of production subgraph patterns on The Graph today.