sway icon indicating copy to clipboard operation
sway copied to clipboard

feat: forc-node local contract state forking

Open zees-dev opened this issue 2 months ago • 3 comments

Description

Addresses #7448

This pull request introduces state forking support to the local node in forc-node, allowing developers to run a local node that mirrors the contract state from a remote node at latest block height (currently only latest is supported).

The contract bytecode and state is fetched dynamically (at runtime - from specified forked url) as the state is requested.

State Forking Feature

  • Added fork_url and fork_block_number to forc-node local, enabling users to specify a remote node and block height for state forking (it must support historical execution).
  • Refactored local/mod.rs to support state forking by integrating a new fork module, which handles fetching state from the remote node and merging it with local storage. The node now conditionally initializes with forking logic based on user input.

Dependency and Build Updates

  • Updated Cargo.toml and forc-node/Cargo.toml to use patched versions of fuel-core crates from a specific branch
    • This was required as we need to override the datasource in the combined database; the datasource attributes are private; the fuel-core v0.46.0 patch simply updates the visibility of the relevant attributes so that they can be overriden to provide fork functionality
  • Made the block_on_any_runtime function in forc-pkg/src/source/reg/mod.rs public, allowing it to be used outside its original module
    • This is necessary for async operations in the new forking logic since the overriden trait function impls are not async

Testing and Examples

  • Added new test contracts and supporting files (fork and fork-caller) to demonstrate and validate the state forking capability.
    • These include contract sources, ABI files, and storage slot definitions. [1] [2] [3] [4] [5] [6] [7] [8]

These updates collectively enable local development nodes to fork contract state from a remote node, greatly enhancing testing flexibility and realism for smart contract developers.

Related PR: https://github.com/FuelLabs/fuel-core/pull/3134

Checklist

  • [x] I have linked to any relevant issues.
  • [x] I have commented my code, particularly in hard-to-understand areas.
  • [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • [x] I have added tests that prove my fix is effective or that my feature works.
  • [x] I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • [x] I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • [x] I have requested a review from the relevant team or maintainers.

[!NOTE] Adds state forking to forc-node local via --fork-url/--fork-block-number, fetching contract bytecode/state on demand and persisting locally, with tests, docs, and dependency updates.

  • forc-node:
    • Local forking: New flags --fork-url and --fork-block-number enable mirroring contract state from a remote node; lazily fetches contract bytecode/storage and caches in local DB.
    • Storage plumbing: Introduces ForkingOnChainStorage/ForkClient and reconstructs CombinedDatabase to overlay remote state; supports non-interactive mode for config updates.
  • Chain config & utils:
    • check_and_update_chain_config supports non-interactive flows; block_on_any_runtime made public for blocking async calls from sync contexts.
  • Tests:
    • Adds integration tests and example contracts (fork, fork-caller) validating bytecode/state forking and transitive calls; updates EVM tests to newer revm API.
  • Docs:
    • New "Testing with Forc Node" guide and SUMMARY entry; spelling list updated (e.g., AMM, RocksDB).
  • Dependencies:
    • Patches fuel-core* crates to git master; bumps revm and enables features; aligns Cargo.toml/dev-deps accordingly.

Written by Cursor Bugbot for commit d6c6bd980d157bf73133c72139421fff19060d86. This will update automatically on new commits. Configure here.

zees-dev avatar Oct 31 '25 03:10 zees-dev

CodSpeed Performance Report

Merging #7478 will not alter performance

Comparing feat/forc-node-local-state-forking (740c8a6) with master (c73137d)

Summary

✅ 25 untouched

codspeed-hq[bot] avatar Oct 31 '25 03:10 codspeed-hq[bot]

Nice, this is looking really promising. It'd be great to also write up some documentation to include with this PR, stepping through an example use case of when and how to use this feature. Maybe in the same sort of vein as what we have written up for forc debug.

JoshuaBatty avatar Nov 03 '25 01:11 JoshuaBatty

PR Summary

Adds state forking to forc-node local (via --fork-url and optional --fork-block-number) that lazily hydrates contract bytecode/state from a remote node, with tests, docs, and dependency updates.

  • forc-node (Local):
    • Add contract state forking: new --fork-url and optional --fork-block-number to mirror state from a remote node.
    • Implement forked storage layer (local/fork.rs) that lazily fetches contract bytecode and ContractsState at a requested block height and caches it locally.
    • Wire forking into node startup by reconstructing CombinedDatabase with fork-aware on/off-chain storage; support dry-run output and non-interactive mode.
  • CLI/UX:
    • Add hidden --non-interactive to local, testnet, and ignition to skip prompts.
  • Docs:
    • New guide: "Testing with Forc Node" showing how to fork Testnet and query via forc-call.
    • Add spellcheck entries (e.g., AMM, RocksDB).
  • Tests:
    • Add example contracts and integration tests validating bytecode fetch, state reads/writes on fork, transitive calls, and historical height forking with caching.
  • Dependencies/Build:
    • Patch fuel-core crates to master and expose data source internals for forking.
    • Bump and rework revm usage; adjust EVM test harness accordingly.
    • Make forc-pkg::block_on_any_runtime public for sync calls inside storage.

Written by Cursor Bugbot for commit 740c8a6ed5543c8550757b8f2a69c11c272976be. This will update automatically on new commits. Configure here.

cursor[bot] avatar Nov 26 '25 10:11 cursor[bot]