Skip to content

feat: implement end-to-end oracle consensus engine (#219) - #223

Merged
rohan911438 merged 5 commits into
Stellar-Prex:mainfrom
Dannyswiss1:feature/oracle-consensus-engine
Jul 20, 2026
Merged

feat: implement end-to-end oracle consensus engine (#219)#223
rohan911438 merged 5 commits into
Stellar-Prex:mainfrom
Dannyswiss1:feature/oracle-consensus-engine

Conversation

@Dannyswiss1

Copy link
Copy Markdown
Contributor

Closes #219

Previously, oracle layer aggregated provider responses but had no configurable consensus — no outlier rejection, no weighting, no stale detection, and no auditable resolution path.

This PR implements a full E2E consensus engine that validates, weights, filters, and resolves markets deterministically.

What's Changed

Core Engine — crates/oracle-consensus / services/oracle/consensus/

New module ConsensusEngine with configurable rules:

struct ConsensusConfig {
  min_providers: u32, // e.g. 3
  consensus_threshold_bps: u16, // e.g. 66% must agree
  outlier_method: OutlierMethod::Mad | ZScore | Iqr,
  outlier_threshold: f64,
  max_staleness_secs: u64,
  provider_weights: Map<ProviderId, u16>,
}

Add a configurable OracleConsensusEngine that validates provider responses,
rejects stale and statistically outlying readings (robust MAD z-score),
assigns provider weights, and checks results against a configurable
consensus threshold. Wire it into oracleService.aggregateResults so real
market resolution flows (resolveWithFallback, retry queue) go through the
engine, with per-market overrides via market.oracleConfig (maxStalenessMs,
consensusThreshold, minConsensusResponses, outlierThreshold).

Extend the AuditLog model/auditService with an 'oracle' category so every
consensus decision (reached or rejected) is persisted with full weight and
rejection breakdown for compliance/debugging.

Add unit tests for the engine (including a fast-check property test) and
integration tests exercising the full oracleService flow.

it('resolves a market end-to-end via resolveWithFallback honoring market-level oracleConfig thresholds', async () => {
const now = Date.now();
const ts = new Date(now).toISOString();
The workspace failed to compile under CI's RUSTFLAGS=-D warnings because
none of the 12 contract crates declared `testutils` as a known Cargo
feature, so soroban-sdk macro-generated cfg(feature = "testutils") code
tripped rustc's unexpected_cfgs lint. Declare the feature on every crate
(matching the existing soroban-sdk testutils dev-dependency) to fix it.

Also fix the genuine issues that were hiding behind that failure and
would have broken the next CI step:
- unused imports/variables and one dead private fn (access-control,
  shared, prediction-market, market-factory, treasury, zk-verifier)
- clippy lints: too_many_arguments on contract entry points with
  inherently many independent params (amm-pool::initialize,
  market-factory::create_market, x402-integration::submit_private_order),
  len_zero, useless_conversion, redundant_closure, and a
  mismatched_lifetime_syntaxes lint in two test helpers

Verified clean end-to-end locally with CI's exact RUSTFLAGS: cargo
check/clippy/build/test all pass, 44 tests green.

Also un-ignore and commit real package-lock.json files for backend and
frontend — actions/setup-node's cache-dependency-path pointed at these
paths but they were gitignored and never committed, which is the root
cause of the Backend/Frontend/Backend Stress Tests/Preview deployment
job failures ("unable to cache dependencies").
The previous fix (feature declarations, unused-var/clippy cleanup) turned
out to be necessary but not sufficient: cargo check still fails on the
real CI runner with error[E0512] in ethnum 1.5.0's error.rs, which builds
a TryFromIntError via mem::transmute(()) assuming it's zero-sized — an
assumption current stable rustc no longer holds. This didn't reproduce in
local testing because of a rustc version difference, but it's confirmed
reproducing on the actual GitHub Actions runner.

ethnum 1.5.0 is pinned by an exact `=1.5.0` requirement in
soroban-env-common 20.3.0 (itself pulled in by soroban-sdk 20.x), so
neither a Cargo.lock bump nor a normal semver-range override can move it
to a fixed release. Vendor ethnum 1.5.3's source (upstream fix, no other
API changes) under contracts/vendor/ethnum-1.5.0-patched, keeping its
declared version at 1.5.0 so it satisfies the exact pin, and point
[patch.crates-io] at it.

Verified end-to-end offline (check/clippy/build/test all green, 44 tests
passing) using the same vendored source.
@rohan911438
rohan911438 merged commit 002fc2c into Stellar-Prex:main Jul 20, 2026
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement End-to-End Oracle Consensus Engine

3 participants