Implement hash_threshold update logic.

This commit is contained in:
FiveMovesAhead 2025-03-31 18:39:49 +08:00
parent 8eac6014c3
commit cbc8454609
4 changed files with 36 additions and 9 deletions

View File

@ -38,11 +38,6 @@ pub trait Context {
challenge_id: &String,
block_id: &String,
) -> Option<ChallengeBlockData>;
async fn get_hash_threshold(
&self,
block_id: &String,
challenge_id: &String,
) -> Option<MerkleHash>;
async fn get_config(&self) -> ProtocolConfig;
async fn add_deposit_to_mempool(&self, details: DepositDetails) -> Result<String>;
async fn get_player_details(&self, player_id: &String) -> Option<PlayerDetails>;
@ -108,4 +103,5 @@ pub struct AddBlockCache {
pub active_breakthroughs_details: HashMap<String, BreakthroughDetails>,
pub active_breakthroughs_block_data: HashMap<String, BreakthroughBlockData>,
pub active_solutions: Vec<(BenchmarkSettings, u32, u32)>,
pub confirmed_num_solutions: HashMap<String, u32>,
}

View File

@ -214,12 +214,13 @@ pub async fn submit_proof<T: Context>(
}
// verify merkle_proofs
let hash_threshold = ctx
.get_challenge_block_data(&settings.challenge_id, &settings.block_id)
.await
.ok_or_else(|| anyhow!("Block too old"))?
.hash_threshold;
let mut verification_result = Ok(());
let max_branch_len = (64 - (num_nonces - 1).leading_zeros()) as usize;
let hash_threshold = ctx
.get_hash_threshold(&settings.block_id, &settings.challenge_id)
.await
.unwrap();
for merkle_proof in merkle_proofs.iter() {
if merkle_proof.branch.0.len() > max_branch_len
|| merkle_proof

View File

@ -19,6 +19,7 @@ pub(crate) async fn update(cache: &mut AddBlockCache) {
active_players_state,
active_players_block_data,
active_opow_block_data,
confirmed_num_solutions,
..
} = cache;
@ -93,6 +94,33 @@ pub(crate) async fn update(cache: &mut AddBlockCache) {
opow_data.cutoff = cutoff;
}
// update hash threshold
let max_threshold = U256::MAX;
let denominator: u64 = 1_000_000_000;
for challenge_id in active_challenge_ids.iter() {
let prev_hash_threshold = active_challenges_prev_block_data
.get(challenge_id)
.map(|x| U256::from(x.hash_threshold.clone().0))
.unwrap_or(max_threshold.clone());
let percentage_error = 1.0
- *confirmed_num_solutions.get(challenge_id).unwrap_or(&0) as f64
/ config.benchmarks.target_solution_rate;
let percent_delta = percentage_error
.abs()
.min(config.benchmarks.hash_threshold_max_percent_delta);
let numerator = (percent_delta * denominator as f64) as u64;
let delta = max_threshold / U256::from(denominator) * U256::from(numerator);
let challenge_data = active_challenges_block_data.get_mut(challenge_id).unwrap();
let hash_threshold = if percentage_error >= 0.0 {
prev_hash_threshold.saturating_add(delta)
} else {
prev_hash_threshold.saturating_sub(delta)
};
hash_threshold.to_big_endian(&mut challenge_data.hash_threshold.0);
}
// update qualifiers
let mut solutions_by_challenge =
HashMap::<String, Vec<(&BenchmarkSettings, &u32, &u32)>>::new();

View File

@ -68,6 +68,8 @@ serializable_struct_with_getters! {
min_per_nonce_fee: PreciseNumber,
min_base_fee: PreciseNumber,
runtime_configs: HashMap<AlgorithmType, RuntimeConfig>,
target_solution_rate: f64,
hash_threshold_max_percent_delta: f64,
}
}
serializable_struct_with_getters! {