diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 6f58a14..823d74f 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -118,11 +118,18 @@ impl ContractParameters { for (outcome, payout_map) in self.outcome_payouts.iter() { // Check for unknown outcomes. - if let &Outcome::Attestation(outcome_index) = outcome { - if outcome_index >= self.event.outcome_messages.len() { - return Err(Error); + match outcome { + &Outcome::Attestation(outcome_index) => { + if outcome_index >= self.event.outcome_messages.len() { + return Err(Error); + } } - } + Outcome::Expiry => { + if self.event.expiry.is_none() { + return Err(Error); + } + } + }; // Check for empty payout map. if payout_map.len() == 0 { diff --git a/src/contract/outcome.rs b/src/contract/outcome.rs index dd91326..bd83bfb 100644 --- a/src/contract/outcome.rs +++ b/src/contract/outcome.rs @@ -80,7 +80,7 @@ pub(crate) fn build_outcome_txs( }; let lock_time = match outcome { - Outcome::Expiry => LockTime::from_consensus(params.event.expiry), + Outcome::Expiry => LockTime::from_consensus(params.event.expiry.ok_or(Error)?), Outcome::Attestation(_) => LockTime::ZERO, // Normal outcome transaction }; @@ -91,9 +91,9 @@ pub(crate) fn build_outcome_txs( output: vec![outcome_output], }; - (outcome, outcome_tx) + Ok((outcome, outcome_tx)) }) - .collect(); + .collect::>()?; let funding_spend_info = FundingSpendInfo::new(¶ms.market_maker, ¶ms.players, params.funding_value)?; diff --git a/src/oracles.rs b/src/oracles.rs index 3dfab8f..e0efb72 100644 --- a/src/oracles.rs +++ b/src/oracles.rs @@ -1,7 +1,7 @@ use secp::{MaybePoint, MaybeScalar, Point, Scalar}; use serde::{Deserialize, Serialize}; -use crate::{serialization, OutcomeIndex}; +use crate::{serialization, Outcome, OutcomeIndex}; /// An oracle's announcement of a future event. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -17,7 +17,8 @@ pub struct EventAnnouncement { pub outcome_messages: Vec>, /// The unix timestamp beyond which the oracle is considered to have gone AWOL. - pub expiry: u32, + /// If set to `None`, the event has no expected expiry. + pub expiry: Option, } impl EventAnnouncement { @@ -63,4 +64,11 @@ impl EventAnnouncement { ); Some(k + e * d) } + + /// Returns an iterator over all possible outcomes in the event. + pub fn all_outcomes(&self) -> impl IntoIterator { + (0..self.outcome_messages.len()) + .map(|i| Outcome::Attestation(i)) + .chain(self.expiry.map(|_| Outcome::Expiry)) + } }