Browse Source

Cleanup oracle id and url handling

compile-for-aarch64
Daniel Karzel 3 years ago
parent
commit
cc79cb1d2b
No known key found for this signature in database GPG Key ID: 30C3FC2E438ADB6E
  1. 27
      daemon/src/model.rs
  2. 47
      daemon/src/oracle.rs

27
daemon/src/model.rs

@ -6,7 +6,9 @@ use rust_decimal::Decimal;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use bdk::bitcoin::{Address, Amount}; use bdk::bitcoin::{Address, Amount};
use reqwest::Url;
use std::fmt; use std::fmt;
use std::str::FromStr;
use std::time::SystemTime; use std::time::SystemTime;
use uuid::Uuid; use uuid::Uuid;
@ -110,8 +112,33 @@ pub struct WalletInfo {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct OracleEventId(pub String); pub struct OracleEventId(pub String);
impl OracleEventId {
pub fn to_olivia_url(&self) -> Url {
Url::from_str("https://h00.ooo")
.expect("valid URL from constant")
.join(self.0.as_str())
.expect("Event id can be joined")
}
}
impl Display for OracleEventId { impl Display for OracleEventId {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.0.fmt(f) self.0.fmt(f)
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn to_olivia_url() {
let url = OracleEventId("/x/BitMEX/BXBT/2021-09-23T10:00:00.price[n:20]".to_string())
.to_olivia_url();
assert_eq!(
url,
Url::from_str("https://h00.ooo/x/BitMEX/BXBT/2021-09-23T10:00:00.price[n:20]").unwrap()
);
}
}

47
daemon/src/oracle.rs

@ -13,9 +13,6 @@ use rocket::time::{Duration, OffsetDateTime, Time};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
/// Where `olivia` is located.
const OLIVIA_URL: &str = "https://h00.ooo";
const OLIVIA_EVENT_TIME_FORMAT: &[FormatItem] = const OLIVIA_EVENT_TIME_FORMAT: &[FormatItem] =
format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]"); format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]");
@ -87,22 +84,23 @@ where
} }
async fn update_latest_announcements(&mut self) -> Result<()> { async fn update_latest_announcements(&mut self) -> Result<()> {
let new_announcements = next_urls() let new_announcements = next_ids()
.into_iter() .into_iter()
.map(|event_url| async move { .map(|event_id| async move {
let response = reqwest::get(event_url.clone()) let url = event_id.to_olivia_url();
let response = reqwest::get(url.clone())
.await .await
.with_context(|| format!("Failed to GET {}", event_url))?; .with_context(|| format!("Failed to GET {}", url))?;
if !response.status().is_success() { if !response.status().is_success() {
anyhow::bail!("GET {} responded with {}", event_url, response.status()); anyhow::bail!("GET {} responded with {}", url, response.status());
} }
let announcement = response let announcement = response
.json::<Announcement>() .json::<Announcement>()
.await .await
.context("Failed to deserialize as Announcement")?; .context("Failed to deserialize as Announcement")?;
Result::<_, anyhow::Error>::Ok((OracleEventId(event_url), announcement)) Result::<_, anyhow::Error>::Ok((event_id, announcement))
}) })
.collect::<FuturesOrdered<_>>() .collect::<FuturesOrdered<_>>()
.try_collect::<HashMap<OracleEventId, Announcement>>() .try_collect::<HashMap<OracleEventId, Announcement>>()
@ -117,7 +115,7 @@ where
let pending_attestations = self.pending_attestations.clone(); let pending_attestations = self.pending_attestations.clone();
for event_id in pending_attestations.into_iter() { for event_id in pending_attestations.into_iter() {
{ {
let res = match reqwest::get(format!("{}{}", OLIVIA_URL, event_id)).await { let res = match reqwest::get(event_id.to_olivia_url()).await {
Ok(res) if res.status().is_success() => res, Ok(res) if res.status().is_success() => res,
Ok(res) if res.status() == StatusCode::NOT_FOUND => { Ok(res) if res.status() == StatusCode::NOT_FOUND => {
tracing::trace!("Attestation not ready yet"); tracing::trace!("Attestation not ready yet");
@ -225,10 +223,10 @@ where
/// Construct the URL of the next 24 `BitMEX/BXBT` hourly events /// Construct the URL of the next 24 `BitMEX/BXBT` hourly events
/// `olivia` will attest to. /// `olivia` will attest to.
fn next_urls() -> Vec<String> { fn next_ids() -> Vec<OracleEventId> {
next_24_hours(OffsetDateTime::now_utc()) next_24_hours(OffsetDateTime::now_utc())
.into_iter() .into_iter()
.map(event_url) .map(event_id)
.collect() .collect()
} }
@ -242,19 +240,18 @@ pub fn next_announcement_after(timestamp: OffsetDateTime) -> OracleEventId {
// always ceil to next hour // always ceil to next hour
let adjusted = let adjusted =
timestamp.replace_time(Time::from_hms(timestamp.hour() + 1, 0, 0).expect("in_range")); timestamp.replace_time(Time::from_hms(timestamp.hour() + 1, 0, 0).expect("in_range"));
let event_id = event_url(adjusted);
OracleEventId(event_id) event_id(adjusted)
} }
/// Construct the URL of `olivia`'s `BitMEX/BXBT` event to be attested /// Construct the URL of `olivia`'s `BitMEX/BXBT` event to be attested
/// for at the time indicated by the argument `datetime`. /// for at the time indicated by the argument `datetime`.
fn event_url(datetime: OffsetDateTime) -> String { fn event_id(datetime: OffsetDateTime) -> OracleEventId {
let datetime = datetime let datetime = datetime
.format(&OLIVIA_EVENT_TIME_FORMAT) .format(&OLIVIA_EVENT_TIME_FORMAT)
.expect("valid formatter for datetime"); .expect("valid formatter for datetime");
format!("{}/x/BitMEX/BXBT/{}.price[n:20]", OLIVIA_URL, datetime) OracleEventId(format!("/x/BitMEX/BXBT/{}.price[n:20]", datetime))
} }
#[derive(Debug, Clone, serde::Deserialize, PartialEq)] #[derive(Debug, Clone, serde::Deserialize, PartialEq)]
@ -570,23 +567,17 @@ mod tests {
use time::macros::datetime; use time::macros::datetime;
#[test] #[test]
fn next_event_url_is_correct() { fn next_event_id_is_correct() {
let url = event_url(datetime!(2021-09-23 10:00:00).assume_utc()); let event_id = event_id(datetime!(2021-09-23 10:00:00).assume_utc());
assert_eq!( assert_eq!(event_id.0, "/x/BitMEX/BXBT/2021-09-23T10:00:00.price[n:20]");
url,
"https://h00.ooo/x/BitMEX/BXBT/2021-09-23T10:00:00.price[n:20]"
);
} }
#[test] #[test]
fn next_event_url_after_timestamp() { fn next_event_id_after_timestamp() {
let url = next_announcement_after(datetime!(2021-09-23 10:40:00).assume_utc()); let event_id = next_announcement_after(datetime!(2021-09-23 10:40:00).assume_utc());
assert_eq!( assert_eq!(event_id.0, "/x/BitMEX/BXBT/2021-09-23T11:00:00.price[n:20]");
url.0,
"https://h00.ooo/x/BitMEX/BXBT/2021-09-23T11:00:00.price[n:20]"
);
} }
#[test] #[test]

Loading…
Cancel
Save