Skip to content

Oracle auth check is O(n) linear scan on every proof submission — degrades with multi-oracle deployments #75

Description

@cybermax4200

Why this matters now:
The engine supports a multi-oracle roster (added as a feature). Every call to submit_proof, approve_proof, reject_proof, dispute_proof, and resolve_dispute calls require_oracleis_registered_oracleread_oracles → iterates the full Vec<Address>. With even 10 oracles this is a 10-entry Vec scan on every proof operation. This is a compute cost and CPU-instruction budget problem that grows linearly with oracle count, directly threatening the test_approve_proof_budget budget assertion that must stay under 50% of the Soroban CPU limit.

Problem / What:
storage::is_registered_oracle calls read_oracles (a full Vec read from instance storage) then calls .iter().any(|o| o == *addr). This is O(n) in oracle count for every auth check. The fix is to mirror the Sponsor pattern already used in task-registry: store oracle membership as DataKey::OracleFlag(Address) -> bool in instance storage (O(1) lookup), maintaining the DataKey::Oracles Vec only for the get_oracles() enumeration endpoint. Both structures must be kept in sync on add_oracle, remove_oracle, and set_oracle.

Key Challenges:

  • add_oracle, remove_oracle, and set_oracle must maintain both the OracleFlag map and the Oracles Vec atomically (Soroban has no transactions, but both writes happen in the same contract invocation).
  • set_oracle replaces the entire roster — must clear all existing OracleFlag entries before setting the new one; requires iterating the old Vec exactly once during the replacement.
  • Budget test test_approve_proof_budget must still pass (and should improve).

Acceptance Criteria:

  • is_registered_oracle(addr) performs exactly 1 instance storage read regardless of oracle count.
  • add_oracle, remove_oracle, set_oracle keep OracleFlag(Address) and Oracles Vec consistent.
  • get_oracles() still returns the full list.
  • All existing oracle tests pass.
  • test_approve_proof_budget CPU budget assertion still passes.

Relevant files/functions:

  • contracts/reward-engine/src/storage.rsis_registered_oracle, push_oracle, remove_oracle_from_list, write_oracles, read_oracles, DataKey
  • contracts/reward-engine/src/verification.rsrequire_oracle, add_oracle, remove_oracle, set_oracle

Out of scope: Changing oracle authorization semantics, TTL management.

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions