Skip to content

Commit

Permalink
Make challenge difficulty configurable.
Browse files Browse the repository at this point in the history
  • Loading branch information
FiveMovesAhead committed May 13, 2024
1 parent e334bb8 commit d20df0b
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 105 deletions.
11 changes: 6 additions & 5 deletions tig-benchmarker/src/benchmarker/setup_job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rand::{
};
use rand_distr::Distribution;
use std::collections::HashMap;
use tig_structs::core::*;
use tig_structs::{config::*, core::*};
use tig_utils::{FrontierOps, PointOps};

pub async fn execute() -> Result<()> {
Expand Down Expand Up @@ -100,7 +100,7 @@ async fn pick_settings_to_benchmark() -> Result<Job> {
let mut rng = StdRng::seed_from_u64(time() as u64);
let challenge = pick_challenge(&mut rng, player_data, challenges, selected_algorithms)?;
let selected_algorithm_id = selected_algorithms[&challenge.id].clone();
let difficulty = pick_difficulty(&mut rng, challenge)?;
let difficulty = pick_difficulty(&mut rng, latest_block, challenge)?;
Ok(Job {
benchmark_id: Alphanumeric.sample_string(&mut rng, 32),
download_url: get_download_url(&selected_algorithm_id, download_urls)?,
Expand Down Expand Up @@ -168,9 +168,10 @@ fn pick_challenge<'a>(
Ok(challenge)
}

fn pick_difficulty(rng: &mut StdRng, challenge: &Challenge) -> Result<Vec<i32>> {
let min_difficulty = challenge.details.min_difficulty();
let max_difficulty = challenge.details.max_difficulty();
fn pick_difficulty(rng: &mut StdRng, block: &Block, challenge: &Challenge) -> Result<Vec<i32>> {
let difficulty_parameters = &block.config().difficulty.parameters[&challenge.id];
let min_difficulty = difficulty_parameters.min_difficulty();
let max_difficulty = difficulty_parameters.max_difficulty();
let block_data = challenge.block_data();
let random_difficulty = block_data.base_frontier().sample(rng).scale(
&min_difficulty,
Expand Down
66 changes: 17 additions & 49 deletions tig-protocol/src/add_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ use std::{
collections::{HashMap, HashSet},
ops::Mul,
};
use tig_structs::core::*;
use tig_structs::{config::*, core::*};
use tig_utils::*;

pub(crate) async fn execute<T: Context>(ctx: &mut T) -> String {
let block = create_block(ctx).await;
confirm_mempool_challenges(ctx, &block).await;
confirm_mempool_algorithms(ctx, &block).await;
confirm_mempool_benchmarks(ctx, &block).await;
confirm_mempool_proofs(ctx, &block).await;
Expand Down Expand Up @@ -47,7 +46,6 @@ async fn create_block<T: Context>(ctx: &mut T) -> Block {
.height
.saturating_sub(config.benchmark_submissions.lifespan_period);
let mut data = BlockData {
mempool_challenge_ids: HashSet::<String>::new(),
mempool_algorithm_ids: HashSet::<String>::new(),
mempool_benchmark_ids: HashSet::<String>::new(),
mempool_fraud_ids: HashSet::<String>::new(),
Expand All @@ -58,14 +56,6 @@ async fn create_block<T: Context>(ctx: &mut T) -> Block {
active_benchmark_ids: HashSet::<String>::new(),
active_player_ids: HashSet::<String>::new(),
};
for challenge in ctx
.get_challenges(ChallengesFilter::Mempool, None)
.await
.unwrap_or_else(|e| panic!("get_challenges error: {:?}", e))
.iter()
{
data.mempool_challenge_ids.insert(challenge.id.clone());
}
for algorithm in ctx
.get_algorithms(AlgorithmsFilter::Mempool, None, false)
.await
Expand Down Expand Up @@ -107,16 +97,8 @@ async fn create_block<T: Context>(ctx: &mut T) -> Block {
data.mempool_wasm_ids.insert(wasm.algorithm_id.clone());
}

for challenge in ctx
.get_challenges(ChallengesFilter::Confirmed, None)
.await
.unwrap_or_else(|e| panic!("get_challenges error: {:?}", e))
{
let round_active = challenge.state.unwrap().round_active;
if round_active.is_some_and(|x| details.round >= x) {
data.active_challenge_ids.insert(challenge.id);
}
}
data.active_challenge_ids
.extend(config.difficulty.parameters.keys().cloned());
let wasms: HashMap<String, Wasm> = ctx
.get_wasms(WasmsFilter::Confirmed, false)
.await
Expand Down Expand Up @@ -196,17 +178,6 @@ async fn create_block<T: Context>(ctx: &mut T) -> Block {
.add_block(&details, &data, &config)
.await
.unwrap_or_else(|e| panic!("add_block error: {:?}", e));
for challenge_id in data.mempool_challenge_ids.iter() {
let state = ChallengeState {
block_confirmed: None,
round_submitted: None,
round_active: None,
round_inactive: None,
};
ctx.update_challenge_state(challenge_id, &state)
.await
.unwrap_or_else(|e| panic!("update_challenge_state error: {:?}", e));
}
for algorithm_id in data.mempool_algorithm_ids.iter() {
let state = AlgorithmState {
block_confirmed: None,
Expand Down Expand Up @@ -294,20 +265,6 @@ async fn create_block<T: Context>(ctx: &mut T) -> Block {
}
}

async fn confirm_mempool_challenges<T: Context>(ctx: &mut T, block: &Block) {
for challenge_id in block.data().mempool_challenge_ids.iter() {
let challenge = get_challenge_by_id(ctx, challenge_id, None)
.await
.unwrap_or_else(|e| panic!("get_challenge_by_id error: {:?}", e));
let mut state = challenge.state().clone();
state.block_confirmed = Some(block.details.height);
state.round_submitted = Some(block.details.round);
ctx.update_challenge_state(challenge_id, &state)
.await
.unwrap_or_else(|e| panic!("update_challenge_state error: {:?}", e));
}
}

async fn confirm_mempool_algorithms<T: Context>(ctx: &mut T, block: &Block) {
for algorithm_id in block.data().mempool_algorithm_ids.iter() {
let algorithm = get_algorithm_by_id(ctx, algorithm_id, None)
Expand Down Expand Up @@ -565,6 +522,7 @@ async fn update_qualifiers<T: Context>(ctx: &mut T, block: &Block) {
let BenchmarkSettings {
player_id,
algorithm_id,
challenge_id,
difficulty,
..
} = &benchmark.settings;
Expand All @@ -574,6 +532,15 @@ async fn update_qualifiers<T: Context>(ctx: &mut T, block: &Block) {
{
break;
}
let difficulty_parameters = &config.difficulty.parameters[challenge_id];
let min_difficulty = difficulty_parameters.min_difficulty();
let max_difficulty = difficulty_parameters.max_difficulty();
if (0..difficulty.len())
.into_iter()
.any(|i| difficulty[i] < min_difficulty[i] || difficulty[i] > max_difficulty[i])
{
continue;
}
curr_frontier_index = frontier_indexes[difficulty];
let player_data = data_by_player.get_mut(player_id).unwrap();
let algorithm_data = data_by_algorithm.get_mut(algorithm_id).unwrap();
Expand Down Expand Up @@ -629,8 +596,9 @@ async fn update_frontiers<T: Context>(ctx: &mut T, block: &Block) {
.unwrap_or_else(|e| panic!("get_challenge_by_id error: {:?}", e));
let mut block_data = challenge.block_data().clone();

let min_difficulty = challenge.details.min_difficulty();
let max_difficulty = challenge.details.max_difficulty();
let difficulty_parameters = &config.difficulty.parameters[&challenge.id];
let min_difficulty = difficulty_parameters.min_difficulty();
let max_difficulty = difficulty_parameters.max_difficulty();

let base_frontier = block_data
.qualifier_difficulties()
Expand All @@ -645,7 +613,7 @@ async fn update_frontiers<T: Context>(ctx: &mut T, block: &Block) {

let multiplier = (*block_data.num_qualifiers() as f64
/ config.qualifiers.total_qualifiers_threshold as f64)
.clamp(0.0, config.difficulty_bounds.max_multiplier);
.clamp(0.0, config.difficulty.max_scaling_factor);
let scaled_frontier = base_frontier
.scale(&min_difficulty, &max_difficulty, multiplier)
.extend(&min_difficulty, &max_difficulty);
Expand Down
11 changes: 0 additions & 11 deletions tig-protocol/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ pub enum BlockFilter {
pub enum ChallengesFilter {
Id(String),
Name(String),
Mempool,
Confirmed,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FraudsFilter {
Expand Down Expand Up @@ -128,10 +126,6 @@ pub trait Context {
data: &BlockData,
config: &ProtocolConfig,
) -> ContextResult<String>;
async fn add_challenge_to_mempool(
&mut self,
details: &ChallengeDetails,
) -> ContextResult<String>;
async fn add_algorithm_to_mempool(
&mut self,
details: &AlgorithmDetails,
Expand Down Expand Up @@ -162,11 +156,6 @@ pub trait Context {
) -> ContextResult<()>;

// Updates
async fn update_challenge_state(
&mut self,
challenge_id: &String,
state: &ChallengeState,
) -> ContextResult<()>;
async fn update_challenge_block_data(
&mut self,
challenge_id: &String,
Expand Down
2 changes: 1 addition & 1 deletion tig-protocol/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use tig_structs::core::{BenchmarkSettings, DifficultyParameter};
use tig_structs::{config::DifficultyParameter, core::BenchmarkSettings};

#[derive(Debug, PartialEq)]
pub enum ProtocolError {
Expand Down
13 changes: 9 additions & 4 deletions tig-protocol/src/submit_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub(crate) async fn execute<T: Context>(
verify_benchmark_settings_are_unique(ctx, settings).await?;
verify_nonces_are_unique(solutions_meta_data)?;
verify_solutions_signatures(solutions_meta_data, &challenge)?;
verify_benchmark_difficulty(&settings.difficulty, &challenge)?;
verify_benchmark_difficulty(&settings.difficulty, &challenge, &block)?;
let benchmark_id = ctx
.add_benchmark_to_mempool(
&settings,
Expand Down Expand Up @@ -199,10 +199,14 @@ fn verify_solutions_signatures(
Ok(())
}

fn verify_benchmark_difficulty(difficulty: &Vec<i32>, challenge: &Challenge) -> ProtocolResult<()> {
let challenge_data = challenge.block_data();
fn verify_benchmark_difficulty(
difficulty: &Vec<i32>,
challenge: &Challenge,
block: &Block,
) -> ProtocolResult<()> {
let config = block.config();
let difficulty_parameters = &config.difficulty.parameters[&challenge.id];

let difficulty_parameters = &challenge.details.difficulty_parameters;
if difficulty.len() != difficulty_parameters.len()
|| difficulty
.iter()
Expand All @@ -215,6 +219,7 @@ fn verify_benchmark_difficulty(difficulty: &Vec<i32>, challenge: &Challenge) ->
});
}

let challenge_data = challenge.block_data();
let (lower_frontier, upper_frontier) = if *challenge_data.scaling_factor() > 1f64 {
(
challenge_data.base_frontier(),
Expand Down
28 changes: 25 additions & 3 deletions tig-structs/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::serializable_struct_with_getters;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub use tig_utils::Point;
use tig_utils::PreciseNumber;

serializable_struct_with_getters! {
Expand All @@ -9,7 +11,7 @@ serializable_struct_with_getters! {
wasm_vm: WasmVMConfig,
solution_signature: SolutionSignatureConfig,
qualifiers: QualifiersConfig,
difficulty_bounds: DifficultyBoundsConfig,
difficulty: DifficultyConfig,
multi_factor_proof_of_work: MultiFactorProofOfWorkConfig,
rounds: RoundsConfig,
algorithm_submissions: AlgorithmSubmissionsConfig,
Expand Down Expand Up @@ -52,8 +54,28 @@ serializable_struct_with_getters! {
}
}
serializable_struct_with_getters! {
DifficultyBoundsConfig {
max_multiplier: f64,
DifficultyParameter {
name: String,
min_value: i32,
max_value: i32,
}
}
pub trait MinMaxDifficulty {
fn min_difficulty(&self) -> Point;
fn max_difficulty(&self) -> Point;
}
impl MinMaxDifficulty for Vec<DifficultyParameter> {
fn min_difficulty(&self) -> Point {
self.iter().map(|p| p.min_value).collect()
}
fn max_difficulty(&self) -> Point {
self.iter().map(|p| p.max_value).collect()
}
}
serializable_struct_with_getters! {
DifficultyConfig {
max_scaling_factor: f64,
parameters: HashMap<String, Vec<DifficultyParameter>>,
}
}
serializable_struct_with_getters! {
Expand Down
32 changes: 0 additions & 32 deletions tig-structs/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ serializable_struct_with_getters! {
Challenge {
id: String,
details: ChallengeDetails,
state: Option<ChallengeState>,
block_data: Option<ChallengeBlockData>,
}
}
Expand Down Expand Up @@ -150,7 +149,6 @@ serializable_struct_with_getters! {
}
serializable_struct_with_getters! {
BlockData {
mempool_challenge_ids: HashSet<String>,
mempool_algorithm_ids: HashSet<String>,
mempool_benchmark_ids: HashSet<String>,
mempool_proof_ids: HashSet<String>,
Expand All @@ -167,36 +165,6 @@ serializable_struct_with_getters! {
serializable_struct_with_getters! {
ChallengeDetails {
name: String,
difficulty_parameters: Vec<DifficultyParameter>,
}
}
impl ChallengeDetails {
pub fn min_difficulty(&self) -> Point {
self.difficulty_parameters
.iter()
.map(|p| p.min_value)
.collect()
}
pub fn max_difficulty(&self) -> Point {
self.difficulty_parameters
.iter()
.map(|p| p.max_value)
.collect()
}
}
serializable_struct_with_getters! {
ChallengeState {
block_confirmed: Option<u32>,
round_submitted: Option<u32>,
round_active: Option<u32>,
round_inactive: Option<u32>,
}
}
serializable_struct_with_getters! {
DifficultyParameter {
name: String,
min_value: i32,
max_value: i32,
}
}
serializable_struct_with_getters! {
Expand Down

0 comments on commit d20df0b

Please sign in to comment.