Skip to content

[Architecture] Refactor Soroban OwnerTokenList Vector Indexing to Constant-Time Map Storage with Page Slotted Keys #23

Description

@Darkvader-ship-it

Estimated Effort: 3 weeks / 6 days

Impacted Subsystems / Files:

  • contracts/phase-protocol/src/lib.rs
  • contracts/phase-protocol/Cargo.toml

Context & Problem Statement:
In contracts/phase-protocol/src/lib.rs, owner_tokens_remove performs a linear $O(N)$ scan over a Vec<u64> to find and remove a token ID when an NFT is transferred. As user portfolio sizes scale, transferring tokens consumes exponentially higher WASM CPU instructions and ledger read/write fees, risking transaction failure due to exceeding Soroban gas budget limits.

Technical Requirements & Scope:

  1. Replace DataKey::OwnerTokenList(Address) vector storage with a dynamic mapping structure using DataKey::OwnerTokenIndex(Address, u64) and DataKey::OwnerTokenAt(Address, u32).
  2. Implement constant-time $O(1)$ swap-and-pop logic during token transfers.
  3. Maintain backwards compatibility for simulateTokenOfOwnerByIndex RPC queries.
  4. Add Rust unit tests in contracts/phase-protocol/src/lib.rs verifying gas costs remain constant for wallets owning >1,000 tokens.

Multi-File Change Surface:
Modifies core storage structures in contracts/phase-protocol/src/lib.rs and requires updating simulateListedTokenIdsForOwner in lib/phase-protocol.ts to consume the updated index scheme.

Acceptance Criteria:

  • Token transfer gas cost remains static regardless of recipient token balance.
  • All existing unit tests in contracts/phase-protocol pass cleanly.
  • Zero linear vector iterations in owner_tokens_remove.

Suggested Approach / Investigation Steps:

  1. Benchmark gas usage of owner_tokens_remove for vector lengths N=10 to N=1000.
  2. Implement swap-and-pop index key pattern in Rust.
  3. Update SDK helper simulation functions to test new storage key layout.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions