Account for binary quality.

This commit is contained in:
FiveMovesAhead 2025-11-25 13:37:03 +00:00
parent 5fbd9f812b
commit ddef2300de
4 changed files with 58 additions and 28 deletions

View File

@ -61,10 +61,11 @@ pub async fn submit_precommit<T: Context>(
}
let track_config = &challenge_config.active_tracks[&settings.track_id];
if num_bundles == 0 {
if num_bundles < track_config.min_num_bundles {
return Err(anyhow!(
"Invalid num_bundles '{}'. Must at least 1",
"Invalid num_bundles '{}'. Must be at least {}",
num_bundles,
track_config.min_num_bundles,
));
}
@ -173,6 +174,8 @@ pub async fn submit_benchmark<T: Context>(
}
// random sample nonces
let challenge_config = &ctx.get_config().await.challenges[&settings.challenge_id];
let track_config = &challenge_config.active_tracks[&settings.track_id];
let mut rng = StdRng::seed_from_u64(seed);
let mut nonce_quality = solution_quality
.iter()
@ -200,19 +203,42 @@ pub async fn submit_benchmark<T: Context>(
let group = &mut nonce_quality[start_idx..end_idx];
group.sort_unstable_by_key(|&(_, quality)| quality);
average_quality_by_group.push(group[num_nonces_per_group / 2].1);
sampled_nonces.extend(
group
.iter()
.skip(num_nonces_per_group / 2)
.map(|&(idx, _)| idx as u64),
);
match challenge_config.quality_type {
QualityType::Continuous => {
let median = group[num_nonces_per_group / 2].1;
average_quality_by_group.push(median);
if median >= track_config.min_active_quality {
sampled_nonces.extend(
group
.iter()
.skip(num_nonces_per_group / 2)
.map(|&(idx, _)| idx as u64),
);
}
}
QualityType::Binary => {
let mean =
(group.iter().map(|&(_, q)| q as i64).sum::<i64>() / group.len() as i64) as i32;
average_quality_by_group.push(mean);
if mean >= track_config.min_active_quality {
sampled_nonces.extend(
group
.iter()
.filter(|&(_, quality)| *quality != 0)
.map(|&(idx, _)| idx as u64),
);
}
}
}
}
let max_samples = ctx.get_config().await.challenges[&settings.challenge_id].max_samples;
for i in 0..sampled_nonces.len().min(challenge_config.max_samples) {
let j = rng.gen_range(i..sampled_nonces.len());
sampled_nonces.swap(i, j);
}
let sampled_nonces = sampled_nonces
.into_iter()
.take(max_samples)
.take(challenge_config.max_samples)
.collect::<HashSet<u64>>();
ctx.add_benchmark_to_mempool(

View File

@ -55,7 +55,7 @@ pub(crate) async fn update(cache: &mut AddBlockCache) {
.entry(settings.challenge_id.clone())
.or_default() += average_quality_by_bundle
.iter()
.filter(|&&x| x >= track_config.min_quality_threshold)
.filter(|&&x| x >= track_config.min_active_quality)
.count() as u64;
}
}
@ -142,7 +142,7 @@ pub(crate) async fn update(cache: &mut AddBlockCache) {
.enumerate()
.flat_map(|(i, x)| {
x.1.iter()
.filter(|&&quality| quality >= track_config.min_quality_threshold)
.filter(|&&quality| quality >= track_config.min_active_quality)
.map(move |&quality| (i, quality))
})
.collect::<Vec<_>>();

View File

@ -63,15 +63,31 @@ serializable_struct_with_getters! {
min_topup_amount: PreciseNumber,
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename_all = "lowercase")]
pub enum ChallengeType {
CPU,
GPU,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename_all = "snake_case")]
pub enum QualityType {
Continuous,
Binary,
}
serializable_struct_with_getters! {
TrackConfig {
num_nonces_per_bundle: u64,
min_num_bundles: u64,
runtime_config_limits: RuntimeConfig,
min_quality_threshold: i32,
min_active_quality: i32,
}
}
serializable_struct_with_getters! {
ChallengeConfig {
name: String,
r#type: ChallengeType,
quality_type: QualityType,
submission_delay_multiplier: f64,
max_samples: usize,
lifespan_period: u32,

View File

@ -1,5 +1,5 @@
use crate::{
config::{ProtocolConfig, RuntimeConfig},
config::{ChallengeConfig, ProtocolConfig, RuntimeConfig},
serializable_struct_with_getters,
};
use serde::{Deserialize, Serialize};
@ -42,7 +42,7 @@ serializable_struct_with_getters! {
serializable_struct_with_getters! {
Challenge {
id: String,
details: ChallengeDetails,
config: ChallengeConfig,
state: ChallengeState,
block_data: Option<ChallengeBlockData>,
}
@ -271,18 +271,6 @@ serializable_struct_with_getters! {
}
// Challenge child structs
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename_all = "lowercase")]
pub enum ChallengeType {
CPU,
GPU,
}
serializable_struct_with_getters! {
ChallengeDetails {
name: String,
r#type: ChallengeType,
}
}
serializable_struct_with_getters! {
ChallengeState {
round_active: u32,