From c439b93216d9ab7e4ff105b3fdc51d0ab24003de Mon Sep 17 00:00:00 2001 From: Luiz Carvalho Date: Thu, 30 May 2024 23:05:32 -0300 Subject: [PATCH] fix: out of bounds error on yuma calc (#60) --- pallets/subspace/src/math.rs | 6 +++--- pallets/subspace/src/step.rs | 2 +- pallets/subspace/src/step/yuma.rs | 23 +++++++++++++---------- pallets/subspace/tests/registration.rs | 3 +-- pallets/subspace/tests/step_linear.rs | 4 ++-- pallets/subspace/tests/subnet.rs | 3 +-- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/pallets/subspace/src/math.rs b/pallets/subspace/src/math.rs index d01896931..38f53ad65 100644 --- a/pallets/subspace/src/math.rs +++ b/pallets/subspace/src/math.rs @@ -253,19 +253,19 @@ pub fn vec_mask_sparse_matrix( first_vector: &[u64], second_vector: &[u64], mask_fn: impl Fn(u64, u64) -> bool, -) -> Vec> { +) -> Option>> { let n: usize = sparse_matrix.len(); let mut result: Vec> = vec![vec![]; n]; for (i, sparse_row) in sparse_matrix.iter().enumerate() { for (j, value) in sparse_row.iter() { - if !mask_fn(first_vector[i], second_vector[*j as usize]) { + if !mask_fn(*first_vector.get(i)?, *second_vector.get(*j as usize)?) { result[i].push((*j, *value)); } } } - result + Some(result) } pub fn inplace_mask_vector(mask: &[bool], vector: &mut [I32F32]) { diff --git a/pallets/subspace/src/step.rs b/pallets/subspace/src/step.rs index b88ac66fc..efae4d98a 100644 --- a/pallets/subspace/src/step.rs +++ b/pallets/subspace/src/step.rs @@ -86,7 +86,7 @@ failed to run yuma consensus algorithm: {err:?}, skipping this block. \ }); if res.is_err() { - return; + continue; } } diff --git a/pallets/subspace/src/step/yuma.rs b/pallets/subspace/src/step/yuma.rs index 176667232..9f7910bf7 100644 --- a/pallets/subspace/src/step/yuma.rs +++ b/pallets/subspace/src/step/yuma.rs @@ -88,7 +88,8 @@ impl YumaCalc { }) .unzip(); - let mut weights = self.compute_weights(); + let mut weights = + self.compute_weights().ok_or(YumaError::Other("weights storage is broken"))?; log::trace!("final weights: {weights:?}"); let stake = self.compute_stake()?; @@ -119,7 +120,9 @@ impl YumaCalc { let BondsAndDividends { ema_bonds, dividends, - } = self.compute_bonds_and_dividends(&weights, &active_stake, &incentives); + } = self + .compute_bonds_and_dividends(&weights, &active_stake, &incentives) + .ok_or(YumaError::Other("bonds storage is broken"))?; let Emissions { pruning_scores, @@ -288,7 +291,7 @@ impl YumaCalc { Ok(emissions) } - fn compute_weights(&self) -> WeightsVal { + fn compute_weights(&self) -> Option { // Access network weights row unnormalized. let mut weights = Pallet::::get_weights_sparse(self.netuid); log::trace!(" original weights: {weights:?}"); @@ -309,14 +312,14 @@ impl YumaCalc { &self.last_update, &self.block_at_registration, |updated, registered| updated <= registered, - ); + )?; log::trace!(" no deregistered modules weights: {weights:?}"); // Normalize remaining weights. inplace_row_normalize_sparse(&mut weights); log::trace!(" normalized weights: {weights:?}"); - WeightsVal::unchecked_from_inner(weights) + Some(WeightsVal::unchecked_from_inner(weights)) } fn compute_stake(&self) -> Result { @@ -424,7 +427,7 @@ impl YumaCalc { weights: &WeightsVal, active_stake: &ActiveStake, incentives: &IncentivesVal, - ) -> BondsAndDividends { + ) -> Option { // Access network bonds. let mut bonds = Pallet::::get_bonds_sparse(self.netuid); log::trace!(" original bonds: {bonds:?}"); @@ -439,7 +442,7 @@ impl YumaCalc { &self.last_update, &self.block_at_registration, |updated, registered| updated <= registered, - ); + )?; log::trace!(" no deregistered modules bonds: {bonds:?}"); // Normalize remaining bonds: sum_i b_ij = 1. @@ -478,10 +481,10 @@ impl YumaCalc { inplace_col_max_upscale_sparse(&mut ema_bonds, self.module_count); log::trace!(" upscaled ema bonds: {ema_bonds:?}"); - BondsAndDividends { + Some(BondsAndDividends { ema_bonds, dividends: DividendsVal::unchecked_from_inner(dividends), - } + }) } fn compute_emissions<'a>( @@ -679,7 +682,7 @@ impl Pallet { fn get_bonds_sparse(netuid: u16) -> Vec> { let n: usize = Self::get_subnet_n(netuid) as usize; let mut bonds: Vec> = vec![vec![]; n]; - for (uid_i, bonds_i) in Bonds::::iter_prefix(netuid) { + for (uid_i, bonds_i) in Bonds::::iter_prefix(netuid).filter(|(uid, _)| *uid < n as u16) { for (uid_j, bonds_ij) in bonds_i { bonds[uid_i as usize].push((uid_j, I32F32::from_num(bonds_ij))); } diff --git a/pallets/subspace/tests/registration.rs b/pallets/subspace/tests/registration.rs index fee8c8cc8..302ea8ed4 100644 --- a/pallets/subspace/tests/registration.rs +++ b/pallets/subspace/tests/registration.rs @@ -9,8 +9,7 @@ use sp_core::U256; use log::info; use pallet_subspace::{ voting::ApplicationStatus, CuratorApplications, Emission, Error, MaxAllowedModules, - MaxAllowedUids, MinStake, RemovedSubnets, Stake, SubnetNames, - TotalSubnets, N, + MaxAllowedUids, MinStake, RemovedSubnets, Stake, SubnetNames, TotalSubnets, N, }; use sp_runtime::{DispatchResult, Percent}; diff --git a/pallets/subspace/tests/step_linear.rs b/pallets/subspace/tests/step_linear.rs index 2024a5cdf..57795d2b0 100644 --- a/pallets/subspace/tests/step_linear.rs +++ b/pallets/subspace/tests/step_linear.rs @@ -4,8 +4,8 @@ use frame_support::assert_ok; use log::info; use mock::*; use pallet_subspace::{ - DaoTreasuryDistribution, GlobalDaoTreasury, MaxAllowedWeights, - MinAllowedWeights, MinBurn, SubnetStakeThreshold, Tempo, + DaoTreasuryDistribution, GlobalDaoTreasury, MaxAllowedWeights, MinAllowedWeights, MinBurn, + SubnetStakeThreshold, Tempo, }; use sp_core::U256; use sp_runtime::Percent; diff --git a/pallets/subspace/tests/subnet.rs b/pallets/subspace/tests/subnet.rs index a9ea02eb3..d9c9e38c0 100644 --- a/pallets/subspace/tests/subnet.rs +++ b/pallets/subspace/tests/subnet.rs @@ -4,8 +4,7 @@ use frame_support::{assert_err, assert_ok}; use log::info; use mock::*; use pallet_subspace::{ - Dividends, Error, FounderShare, MaximumSetWeightCallsPerEpoch, - SubnetNames, Tempo, N, + Dividends, Error, FounderShare, MaximumSetWeightCallsPerEpoch, SubnetNames, Tempo, N, }; use sp_core::U256; use sp_runtime::Percent;