feat: multi-oracle consensus for result verification (#956) - #1207
Merged
yahia008 merged 4 commits intoAug 3, 2026
Merged
Conversation
…uccess-callback test: add test_transaction_signer_success_callback (StellarCheckMate#837)
…arCheckMate#956) Add a multi-oracle consensus mechanism so that match results require agreement from multiple independent Oracles before the payout executes. ## Changes ### contracts/escrow/src/errors.rs - Add OracleAlreadyConfirmed (22): oracle already voted on this match - Add ConflictingResult (23): oracle vote conflicts with prior votes - Add NotEnoughConfirmations (24): threshold not yet reached - Add NotAnOracle (25): caller is not in the approved oracle list ### contracts/escrow/src/types.rs - Add DataKey::OracleConfirmations(u64): per-match confirmation count - Add DataKey::OracleVote(u64, Address): per-(match, oracle) vote record - Add DataKey::ApprovedOracles: instance-stored list of approved oracles - Add DataKey::RequiredOracleConfirmations: configurable threshold (default 2) ### contracts/escrow/src/lib.rs - Add add_approved_oracle(oracle): admin registers an oracle for consensus - Add remove_approved_oracle(oracle): admin deregisters an oracle - Add get_approved_oracles(): returns current approved oracle list - Add set_required_confirmations(count): admin sets the threshold (default 2) - Add get_required_confirmations(): returns current threshold - Add submit_result_consensus(match_id, winner, oracle_address): any approved oracle calls this; payout executes once threshold is reached; conflicting votes are rejected - Add get_oracle_confirmations(match_id): returns current confirmation count - Add is_allowlist_enforced(): exposes AllowlistEnforced state publicly - Extract execute_payout() private helper shared by submit_result and submit_result_consensus to eliminate duplication ### contracts/escrow/src/tests/consensus.rs (new) 26 new tests covering: happy-path 2-of-2 / 2-of-3 / 3-of-3 consensus, draw payout, partial votes, conflicting votes, duplicate votes, unapproved oracle, paused contract, invalid state (pending/completed/nonexistent), fund conservation, confirmation count accuracy, escrow balance zero after payout, and active-match list cleanup. ### Pre-existing test fixes - events.rs: add missing Ledger trait import; fix test_expire_match_emits_event to use set_match_timeout(17_280) instead of advancing to ledger 518_401 (which causes persistent storage TTL expiry in the test env) - token_allowlist.rs: remove spurious & from assert_eq comparisons - security.rs: update test_accept_admin_wrong_caller_rejected to expect auth-failure Abort rather than a contract Unauthorized return (Soroban panics on require_auth failure when the signer is not in mock_auths) All 232 tests pass.
Collaborator
|
hi fix conflict |
# Conflicts: # Cargo.lock # contracts/escrow/src/errors.rs # contracts/escrow/src/lib.rs # contracts/escrow/src/tests/events.rs # contracts/escrow/src/tests/mod.rs # contracts/escrow/src/types.rs
|
@Rayyanah0 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #956 — Implement Multi-Oracle Consensus for Result Verification
A single Oracle is a single point of failure. This PR adds a consensus mechanism so match results require agreement from N-of-M independent Oracles before the payout executes.
What was changed
New public API
add_approved_oracle(oracle)remove_approved_oracle(oracle)get_approved_oracles()set_required_confirmations(count)get_required_confirmations()submit_result_consensus(match_id, winner, oracle_address)get_oracle_confirmations(match_id)is_allowlist_enforced()New error codes
OracleAlreadyConfirmedConflictingResultNotEnoughConfirmationsNotAnOracleImplementation notes
MATCH_TTL_LEDGERSlifetime.submit_result_consensusstores the first vote'sWinnervia the existingDataKey::OracleRecordkey as the reference; all subsequent votes are checked against it.submit_resultpath is unchanged. A new privateexecute_payouthelper eliminates duplication.Tests
26 new tests in
contracts/escrow/src/tests/consensus.rs:ConflictingResultOracleAlreadyConfirmedNotAnOracleContractPausedget_oracle_confirmationsincrements correctly)set_required_confirmations(0)→InvalidAmountsubmit_resultstill works independentlyPre-existing test fixes included
These 3 issues existed on
mainand were blocking the test suite from compiling or passing:events.rs: MissingLedgertrait import;test_expire_match_emits_eventadvanced to ledger 518_401 which causes persistent storage TTL expiry — fixed to useset_match_timeout(17_280)+ advance to 17_281.token_allowlist.rs: Spurious&reference inassert_eqcomparisons (type mismatchAddressvs&Address).security.rs:test_accept_admin_wrong_caller_rejectedexpectedErr(Ok(Unauthorized))but Soroban panics withAbortonrequire_authfailure when the signer is absent frommock_auths.CI
All 232 tests pass (
cargo test -p escrow).