Skip to content

Commit

Permalink
Remove ability for entries to tie (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
tee8z authored Dec 27, 2024
1 parent 9b2b18e commit 81a3807
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 112 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion daemon/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "daemon"
version = "1.2.0"
version = "1.3.0"
edition = "2021"
repository = "https://github.com/tee8z/noaa-data-pipeline"

Expand Down
2 changes: 1 addition & 1 deletion oracle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "oracle"
version = "1.2.0"
version = "1.3.0"
edition = "2021"
repository = "https://github.com/tee8z/noaa-data-pipeline"

Expand Down
10 changes: 5 additions & 5 deletions oracle/src/db/event_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl EventData {
let observation_date = OffsetDateTime::format(event.observation_date, &Rfc3339)
.map_err(|e| duckdb::Error::ToSqlConversionFailure(Box::new(e)))?;
let nonce = to_vec(&event.nonce).unwrap();
let annoucement_bytes = to_vec(&event.event_annoucement).unwrap();
let announcement_bytes = to_vec(&event.event_announcement).unwrap();
let conn = self.new_write_connection_retry().await?;
let mut stmt = conn.prepare(
"INSERT INTO events (
Expand All @@ -247,7 +247,7 @@ impl EventData {
signing_date,
observation_date,
locations,
event_annoucement,
event_announcement,
coordinator_pubkey) VALUES(?,?,?,?,?,?,?,?,?,?)",
)?;
stmt.execute(params![
Expand All @@ -259,7 +259,7 @@ impl EventData {
signing_date,
observation_date,
locations_sql,
annoucement_bytes,
announcement_bytes,
event.coordinator_pubkey
])?;

Expand Down Expand Up @@ -679,7 +679,7 @@ impl EventData {
"id",
"signing_date::TEXT",
"observation_date::TEXT",
"event_annoucement",
"event_announcement",
"locations",
"total_allowed_entries",
"number_of_places_win",
Expand Down Expand Up @@ -764,7 +764,7 @@ impl EventData {
"number_of_values_per_entry",
"attestation_signature",
"nonce",
"event_annoucement",
"event_announcement",
))
.from("events")
.where_(where_clause);
Expand Down
2 changes: 1 addition & 1 deletion oracle/src/db/event_db_migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn create_initial_schema(conn: &mut Connection) -> Result<(), duckdb::Error>
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
nonce BLOB NOT NULL,
event_annoucement BLOB NOT NULL,
event_announcement BLOB NOT NULL,
locations TEXT[] NOT NULL,
coordinator_pubkey TEXT,
attestation_signature BLOB
Expand Down
25 changes: 13 additions & 12 deletions oracle/src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub struct CreateEventData {
/// Used to sign the result of the event being watched
pub nonce: Scalar,
/// Used in constructing the dlctix transactions
pub event_annoucement: EventAnnouncement,
pub event_announcement: EventAnnouncement,
/// The pubkey of the coordinator
pub coordinator_pubkey: Option<String>,
}
Expand All @@ -131,23 +131,24 @@ impl CreateEventData {
event.observation_date.format(&Rfc3339).unwrap()
));
}
let allowed_scored_ranks = 3;
let possible_user_outcomes: Vec<Vec<usize>> =
generate_winner_permutations(event.total_allowed_entries);
generate_ranking_permutations(event.total_allowed_entries, allowed_scored_ranks);
info!("user outcomes: {:?}", possible_user_outcomes);

let outcome_messages: Vec<Vec<u8>> = generate_outcome_messages(possible_user_outcomes);

let mut rng = rand::thread_rng();
let nonce = Scalar::random(&mut rng);
let nonce_point = nonce.base_point_mul();
// Manually set expiry to 7 days after the signature should have been proveded so users can get their funds back
// Manually set expiry to 7 days after the signature should have been provided so users can get their funds back
let expiry = event
.signing_date
.saturating_add(Duration::DAY * 7)
.unix_timestamp() as u32;

// The actual accounement the oracle is going to attest the outcome
let event_annoucement = EventAnnouncement {
// The actual announcement the oracle is going to attest the outcome
let event_announcement = EventAnnouncement {
oracle_pubkey: oracle_pubkey.into(),
nonce_point,
outcome_messages,
Expand All @@ -163,7 +164,7 @@ impl CreateEventData {
number_of_places_win: 1_i64, // Default to 1 winning score to simplify possible outcomes
number_of_values_per_entry: event.number_of_values_per_entry as i64,
locations: event.clone().locations,
event_annoucement,
event_announcement,
coordinator_pubkey: event
.coordinator
.map(|v| Some(v.pubkey))
Expand Down Expand Up @@ -202,7 +203,7 @@ impl From<CreateEventData> for Event {
total_allowed_entries: value.total_allowed_entries,
number_of_places_win: value.number_of_places_win,
number_of_values_per_entry: value.number_of_values_per_entry,
event_annoucement: value.event_annoucement,
event_announcement: value.event_announcement,
nonce: value.nonce,
status: EventStatus::default(),
entry_ids: vec![],
Expand Down Expand Up @@ -238,7 +239,7 @@ pub struct SignEvent {
pub observation_date: OffsetDateTime,
pub status: EventStatus,
pub nonce: Scalar,
pub event_annoucement: EventAnnouncement,
pub event_announcement: EventAnnouncement,
pub number_of_places_win: i64,
pub number_of_values_per_entry: i64,
pub attestation: Option<MaybeScalar>,
Expand Down Expand Up @@ -299,7 +300,7 @@ impl<'a> TryFrom<&Row<'a>> for SignEvent {
serde_json::from_slice(&blob)
})?
.map_err(|e| duckdb::Error::FromSqlConversionFailure(6, Type::Any, Box::new(e)))?,
event_annoucement: row
event_announcement: row
.get::<usize, Value>(7)
.map(|raw| {
let blob = match raw {
Expand Down Expand Up @@ -614,8 +615,8 @@ pub struct Event {
pub weather: Vec<Weather>,
/// Nonce the oracle committed to use as part of signing final results
pub nonce: Scalar,
/// Holds the predefined outcomes the oracle will attest to at event complet
pub event_annoucement: EventAnnouncement,
/// Holds the predefined outcomes the oracle will attest to at event complete
pub event_announcement: EventAnnouncement,
/// When added it means the oracle has signed that the current data is the final result
pub attestation: Option<MaybeScalar>,
}
Expand Down Expand Up @@ -658,7 +659,7 @@ impl<'a> TryFrom<&Row<'a>> for Event {
.map(|val| OffsetDateTime::parse(&val, &sql_time_format))?
.map(|val| val.to_offset(UtcOffset::UTC))
.map_err(|e| duckdb::Error::FromSqlConversionFailure(2, Type::Any, Box::new(e)))?,
event_annoucement: row
event_announcement: row
.get::<usize, Value>(3)
.map(|raw| {
let blob = match raw {
Expand Down
60 changes: 37 additions & 23 deletions oracle/src/db/outcome_generator.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
use itertools::Itertools;
use rayon::prelude::*;

pub fn generate_winner_permutations(num_players: usize) -> Vec<Vec<usize>> {
(0..=num_players)
.into_par_iter()
.flat_map(|r| {
(0..num_players)
.combinations(r)
.map(|v| v.into_iter().collect::<Vec<_>>())
.collect::<Vec<_>>()
})
.collect()

/// We are assuming the scoring mechanism does not allow for ties and every user has a unique score
/// (most likely using time as an element of the scoring)
pub fn generate_ranking_permutations(num_players: usize, rankings: usize) -> Vec<Vec<usize>> {
(0..num_players).permutations(rankings).collect()
}

pub fn generate_outcome_messages(possible_user_outcomes: Vec<Vec<usize>>) -> Vec<Vec<u8>> {
Expand All @@ -28,27 +21,48 @@ pub fn generate_outcome_messages(possible_user_outcomes: Vec<Vec<usize>>) -> Vec
#[cfg(test)]
mod test {

use super::generate_winner_permutations;
use super::generate_ranking_permutations;

#[test]
fn can_generate_list_of_winners_small() {
fn can_generate_list_of_winners_n5() {
let num_players = 5;
let permutations: Vec<Vec<usize>> = generate_winner_permutations(num_players);
println!("permutations: {:?}", permutations);
assert_eq!(permutations.len(), 32);
let permutations: Vec<Vec<usize>> = generate_ranking_permutations(num_players, 3);
assert_eq!(permutations.len(), 60);
}

#[test]
fn can_generate_list_of_winners_default_size() {
fn can_generate_list_of_winners_n20() {
let num_players = 20;
let permutations: Vec<Vec<usize>> = generate_winner_permutations(num_players);
assert_eq!(permutations.len(), 1_048_576);
let permutations: Vec<Vec<usize>> = generate_ranking_permutations(num_players, 3);
assert_eq!(permutations.len(), 6_840);
}

#[test]
fn can_generate_list_of_winners_large() {
fn can_generate_list_of_winners_n25() {
let num_players = 25;
let permutations: Vec<Vec<usize>> = generate_winner_permutations(num_players);
assert_eq!(permutations.len(), 33_554_432);
let permutations: Vec<Vec<usize>> = generate_ranking_permutations(num_players, 3);
assert_eq!(permutations.len(), 13_800);
}

#[test]
fn can_generate_list_of_winners_n100() {
let num_players = 100;
let permutations: Vec<Vec<usize>> = generate_ranking_permutations(num_players, 3);
assert_eq!(permutations.len(), 970_200);
}

#[test]
fn can_generate_list_of_winners_n200() {
let num_players = 200;
let permutations: Vec<Vec<usize>> = generate_ranking_permutations(num_players, 3);
assert_eq!(permutations.len(), 7_880_400);
}

#[test]
//note: beyond 500 players the time to create the permutations is over 60 seconds
fn can_generate_list_of_winners_n400() {
let num_players = 400;
let permutations: Vec<Vec<usize>> = generate_ranking_permutations(num_players, 3);
assert_eq!(permutations.len(), 63_520_800);
}
}
Loading

0 comments on commit 81a3807

Please sign in to comment.