diff --git a/tig-protocol/src/add_block.rs b/tig-protocol/src/add_block.rs index 1ddc9915..1ec24b69 100644 --- a/tig-protocol/src/add_block.rs +++ b/tig-protocol/src/add_block.rs @@ -15,9 +15,9 @@ pub(crate) async fn execute(ctx: &mut T) -> String { confirm_mempool_wasms(ctx, &block).await; update_deposits(ctx, &block).await; update_cutoffs(ctx, &block).await; - update_solution_signature_thresholds(ctx, &block).await; update_qualifiers(ctx, &block).await; update_frontiers(ctx, &block).await; + update_solution_signature_thresholds(ctx, &block).await; update_influence(ctx, &block).await; update_adoption(ctx, &block).await; update_innovator_rewards(ctx, &block).await; @@ -441,15 +441,56 @@ async fn update_cutoffs(ctx: &mut T, block: &Block) { #[time] async fn update_solution_signature_thresholds(ctx: &mut T, block: &Block) { let config = block.config(); + let num_challenges = block.data().active_challenge_ids.len() as f64; - let mut num_new_solutions_by_challenge = HashMap::::new(); + let mut solutions_rate_multiplier_by_player = HashMap::>::new(); + for player_id in block.data().active_player_ids.iter() { + let player = get_player_by_id(ctx, player_id, Some(&block.id)) + .await + .unwrap_or_else(|e| panic!("get_player_by_id error: {:?}", e)); + let player_avg_qualifiers = player + .block_data() + .num_qualifiers_by_challenge() + .values() + .fold(0, |acc, v| acc + *v) as f64 + / num_challenges; + solutions_rate_multiplier_by_player.insert( + player.id.clone(), + player + .block_data() + .num_qualifiers_by_challenge() + .iter() + .map(|(k, v)| { + ( + k.clone(), + if *v == 0 { + 1.0 + } else { + (player_avg_qualifiers / *v as f64).max(1.0) + }, + ) + }) + .collect(), + ); + } + + let mut solutions_rate_by_challenge = HashMap::::new(); for benchmark_id in block.data().mempool_proof_ids.iter() { let benchmark = get_benchmark_by_id(ctx, benchmark_id, false) .await .unwrap_or_else(|e| panic!("get_benchmark_by_id error: {:?}", e)); - *num_new_solutions_by_challenge + let scale = match solutions_rate_multiplier_by_player.get(&benchmark.settings.player_id) { + Some(fraction_qualifiers) => { + match fraction_qualifiers.get(&benchmark.settings.challenge_id) { + Some(fraction) => fraction.clone(), + None => 1.0, + } + } + None => 1.0, + }; + *solutions_rate_by_challenge .entry(benchmark.settings.challenge_id.clone()) - .or_default() += benchmark.details.num_solutions; + .or_default() += scale * benchmark.details.num_solutions as f64; } for challenge_id in block.data().active_challenge_ids.iter() { @@ -463,9 +504,9 @@ async fn update_solution_signature_thresholds(ctx: &mut T, block: &B Some(data) => *data.solution_signature_threshold() as f64, None => max_threshold, }; - let current_rate = *num_new_solutions_by_challenge + let current_rate = *solutions_rate_by_challenge .get(challenge_id) - .unwrap_or(&0) as f64; + .unwrap_or(&0.0); let equilibrium_rate = config.qualifiers.total_qualifiers_threshold as f64 / config.benchmark_submissions.lifespan_period as f64;