Skip to content

Support contract executables when working with snapshots #2703

Description

@fnando

Summary

The snapshot code path does not fully support contract executables. Recent work flattened contract executable spec lookup on the RPC path (39b3683) to handle all three ContractExecutable variants — StellarAsset, Wasm, and CAP-85 ExternalRef — but the snapshot path was not updated in parallel. As a result, snapshots can silently omit a contract's executable/Wasm, and there is no offline path to resolve a contract's spec/executable from a snapshot.

Gaps

1. snapshot create silently drops ExternalRef executables

In cmd/soroban-cli/src/commands/snapshot/create.rs (~line 382-417), the match over ScContractInstance.executable handles:

  • ContractExecutable::Wasm(hash) → adds the Wasm hash to the next-pass filter
  • ContractExecutable::StellarAsset → adds the asset issuer
  • _ => {}silently ignores ContractExecutable::ExternalRef

When a snapshotted contract instance uses a CAP-85 externally-managed executable, snapshot create:

  • does not add the executable-reference entry (owner's ContractData keyed by ScVal::ExecutableTag(tag)) to the filter, and
  • never discovers the underlying Wasm hash,

so the resulting snapshot is missing the executable/Wasm for that contract.

Work: add an ExternalRef match arm that filters on contract == external_ref.executable_owner with key == ScVal::ExecutableTag(external_ref.tag). That reference entry's value is the Wasm hash, so an extra expansion hop is needed: when the reference entry is later matched, decode its ScVal::Bytes value into a Hash and add it to next.wasm_hashes so the ContractCode is included. This likely requires extending SearchInputs (~line 260) with a per-key ContractData filter, since the current filter matches ContractData only by whole-contract id (~line 350), not by a specific key.

2. No offline spec/executable resolution from a snapshot

Every executable-resolution helper is hardwired to network.rpc_client():

  • get_remote_contract_speccmd/soroban-cli/src/get_spec.rs:35
  • fetch_from_contract / fetch_wasm_hash_from_contractcmd/soroban-cli/src/wasm.rs:125,154
  • resolve_external_ref_wasm_hash / get_remote_wasm_from_hashcmd/soroban-cli/src/utils.rs (rpc module) :381,421

To read executables from a snapshot rather than over RPC, a snapshot-backed analogue of these helpers is needed that looks entries up in the LedgerSnapshot instead of via rpc::Client.

3. Consistent three-variant handling

Mirror the flattened three-variant handling already present in get_spec.rs:63, wasm.rs:136, and wasm.rs:165 so that StellarAsset, Wasm, and ExternalRef are all handled consistently in the snapshot path, replacing the silent _ => {}.

Acceptance criteria

  • snapshot create captures the executable-reference entry and underlying Wasm for contracts using a CAP-85 ExternalRef executable.
  • Contract spec/executable can be resolved offline from a snapshot for all three ContractExecutable variants.
  • Snapshot executable handling matches the RPC path (no silent drop of ExternalRef).
  • Tests covering ExternalRef executables in snapshots.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Backlog (Not Ready)

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions