Skip to content

Wire native NFT (SRC-721/1155) apply path before activating NFT_TOKENOP_HEIGHT #773

Description

@satyakwok

Summary

NFT_TOKENOP_HEIGHT must stay dormant (u64::MAX) until the apply/storage layer ships. The wire format and fork gates are in, but no handler turns a parsed NFT TokenOp into state. Activating the fork now would halt the chain.

Verified state (not assumed — checked against code)

Shipped:

  • Wire format: TokenOp::{DeployNft, MintNft, TransferNft, BurnNft, ApproveNft, SetApprovalForAll} + SRC-1155 variants in crates/sentrix-primitives/src/transaction.rs. Nodes can parse these txs.
  • Three gate sites, all reject pre-fork:
    • crates/sentrix-core/src/block_executor/validate.rs:247 (Pass-1 validate)
    • crates/sentrix-core/src/block_executor.rs:531 (Pass-1 dispatch)
    • crates/sentrix-core/src/block_executor.rs:909 (Pass-2 apply) — also rejects post-fork with "NFT TokenOp dispatch handlers not yet wired (Phase B follow-up PR)".

NOT shipped (the gap):

  • ContractRegistry / SRC20Contract in crates/sentrix-core/src/vm.rs is purely fungible: amount: u64, balance_of, mint/burn/transfer/approve. No token_id, no owner_of, no per-token owner map, no token_type.
  • No NFT storage tables in sentrix-storage.
  • No apply handler functions anywhere.

Why activating now halts the chain

Post-fork the two passes disagree:

Pass-1 (validate): gate opens → NFT tx accepted as VALID
Pass-2 (apply):    still returns Err("handlers not yet wired")
⇒ a valid-looking NFT tx enters the mempool, a proposer includes it in a block,
  every validator then fails to apply that block → block cannot finalize
  → chain STUCK at that height

Note: the validator process does not panic/abort (Audit L3 replaced the old unreachable!() with a graceful InvalidTransaction). The halt is via an unappliable block, not a crash — same operational outcome (chain stops), subtler mechanism.

What "wire the apply path" requires

  • NFT contract storage model — token_id → owner mapping, collection metadata, approvals/operator-approval set. Either a new contract type or an extension to ContractRegistry (currently SRC-20-only).
  • Apply handlers for every variant: DeployNft / MintNft / TransferNft / BurnNft / ApproveNft / SetApprovalForAll and the SRC-1155 batch ops.
  • Remove the post-fork "handlers not yet wired" reject at block_executor.rs:909 once handlers land.
  • Converge Pass-1 ⇔ Pass-2 — both must accept/reject identically post-fork. The current divergence is the halt hazard.
  • RPC read surface for NFT ownership / metadata.
  • Determinism: per-token iteration sorted, no HashMap-order dependence in state_root inputs (same class as the SIP-6 epoch-set fix).
  • Regression tests (fail-before/pass-after) + testnet bake before any NFT_TOKENOP_HEIGHT is pinned.

Activation discipline

Same as every consensus fork on Sentrix: implement → testnet bake → mainnet halt-all + simultaneous-start with NFT_TOKENOP_HEIGHT=<height> on all validators. Do not flip the gate before the apply path is merged and baked.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityconsensusBFT / PoA / consensus layer

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions