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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions