mirror of
https://github.com/tig-foundation/tig-monorepo.git
synced 2026-02-21 10:27:49 +08:00
Make challenge difficulty configurable.
This commit is contained in:
parent
e334bb8f0c
commit
d20df0b824
@ -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<()> {
|
||||
@ -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)?,
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
@ -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(),
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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,
|
||||
@ -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)
|
||||
@ -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;
|
||||
@ -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();
|
||||
@ -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()
|
||||
@ -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);
|
||||
|
||||
@ -34,8 +34,6 @@ pub enum BlockFilter {
|
||||
pub enum ChallengesFilter {
|
||||
Id(String),
|
||||
Name(String),
|
||||
Mempool,
|
||||
Confirmed,
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum FraudsFilter {
|
||||
@ -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,
|
||||
@ -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,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use tig_structs::core::{BenchmarkSettings, DifficultyParameter};
|
||||
use tig_structs::{config::DifficultyParameter, core::BenchmarkSettings};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ProtocolError {
|
||||
|
||||
@ -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,
|
||||
@ -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()
|
||||
@ -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(),
|
||||
|
||||
@ -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! {
|
||||
@ -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,
|
||||
@ -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! {
|
||||
|
||||
@ -36,7 +36,6 @@ serializable_struct_with_getters! {
|
||||
Challenge {
|
||||
id: String,
|
||||
details: ChallengeDetails,
|
||||
state: Option<ChallengeState>,
|
||||
block_data: Option<ChallengeBlockData>,
|
||||
}
|
||||
}
|
||||
@ -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>,
|
||||
@ -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! {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user