Skip to content

Commit

Permalink
fix: rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
Supremesource committed Nov 22, 2024
1 parent c7a8a8a commit f1e6806
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 46 deletions.
38 changes: 24 additions & 14 deletions pallets/offworker/src/dispatches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub mod dispatches {
#[pallet::weight((Weight::zero(), DispatchClass::Normal, Pays::No))]
pub fn send_decrypted_weights(
origin: OriginFor<T>,
payload: DecryptedWeightsPayload<T::Public, BlockNumberFor<T>>, /* make payload accept zk proofs of wrong encryption */
payload: DecryptedWeightsPayload<T::Public, BlockNumberFor<T>>,
_signature: T::Signature,
) -> DispatchResultWithPostInfo {
// Signature valiadation is performed by the validate unsigned function
Expand All @@ -31,35 +31,45 @@ pub mod dispatches {
let DecryptedWeightsPayload {
subnet_id,
decrypted_weights,
delta,
delta: _,
block_number,
public,
forced_send_by_rotation,
} = payload;

let decryption_data = SubnetDecryptionData::<T>::get(subnet_id);
if let Some(decryption_data) = decryption_data {
let acc_id = public.into_account();

// Modify this section to handle the forced rotation case
SubnetDecryptionData::<T>::try_mutate(subnet_id, |maybe_data| -> DispatchResult {
let decryption_data = maybe_data.as_mut().ok_or(Error::<T>::InvalidSubnetId)?;

ensure!(
decryption_data.node_id == public.into_account(),
decryption_data.node_id == acc_id,
Error::<T>::InvalidDecryptionKey
);
} else {
return Err(Error::<T>::InvalidSubnetId.into());
}

// Get all epochs for this subnet
// If this was a forced rotation send, clear the rotating_from field
if forced_send_by_rotation {
decryption_data.rotating_from = None;
}

Ok(())
})?;

// Rest of the function remains the same
let epoch_count = ConsensusParameters::<T>::iter_prefix(subnet_id).count();

// dbg!("lenght check", decrypted_weights.len(), epoch_count);
// Check if the length matches
ensure!(
decrypted_weights.len() == epoch_count,
Error::<T>::DecryptedWeightsLengthMismatch
);

// TODO: make a periodical irrationality delta reseter that subnet owner can control
IrrationalityDelta::<T>::mutate(subnet_id, |current| {
*current = current.saturating_add(delta)
});
// IrrationalityDelta::<T>::mutate(subnet_id, |current| {
// *current = current.saturating_add(delta)
// });
IrrationalityDelta::<T>::set(subnet_id, I64F64::from_num(0));

pallet_subnet_emission::Pallet::<T>::handle_decrypted_weights(
subnet_id,
decrypted_weights,
Expand Down
7 changes: 6 additions & 1 deletion pallets/offworker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,11 @@ impl<T: Config> Pallet<T> {
.collect()
}

fn do_send_weights(subnet_id: u16, delta: I64F64) -> Result<(), &'static str> {
fn do_send_weights(
subnet_id: u16,
delta: I64F64,
forced_send_by_rotation: bool,
) -> Result<(), &'static str> {
let signer = Signer::<T, T::AuthorityId>::all_accounts();
if !signer.can_sign() {
return Err(
Expand All @@ -359,6 +363,7 @@ impl<T: Config> Pallet<T> {
delta,
block_number: <system::Pallet<T>>::block_number(),
public: account.public.clone(),
forced_send_by_rotation,
},
|payload, signature| Call::send_decrypted_weights { payload, signature },
);
Expand Down
4 changes: 2 additions & 2 deletions pallets/offworker/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<T: Config> Pallet<T> {
.filter(|(block, _)| *block > last_processed_block)
.collect::<Vec<_>>();

let (send_weights, result) = process_consensus_params::<T>(
let (send_weights, result, forced_send) = process_consensus_params::<T>(
subnet_id,
acc_id.clone(),
new_params,
Expand All @@ -61,7 +61,7 @@ impl<T: Config> Pallet<T> {

if !send_weights {
Self::save_subnet_state(subnet_id, max_block, result.simulation_result);
} else if let Err(err) = Self::do_send_weights(subnet_id, result.delta) {
} else if let Err(err) = Self::do_send_weights(subnet_id, result.delta, forced_send) {
log::error!(
"Couldn't send weights to runtime for subnet {}: {}",
subnet_id,
Expand Down
1 change: 1 addition & 0 deletions pallets/offworker/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub struct DecryptedWeightsPayload<Public, BlockNumber> {
pub delta: I64F64,
pub block_number: BlockNumber,
pub public: Public,
pub forced_send_by_rotation: bool,
}

#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, scale_info::TypeInfo)]
Expand Down
34 changes: 9 additions & 25 deletions pallets/offworker/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,12 @@ use super::*;
use crate::profitability::{get_copier_stake, is_copying_irrational};
use types::SimulationYumaParams;

fn should_send_rotation_weights<T>(subnet_id: u16, acc_id: &T::AccountId) -> bool
where
T: pallet_subspace::Config + pallet_subnet_emission::Config + pallet::Config,
{
// Get subnet decryption data and return early if None
let decryption_info = match SubnetDecryptionData::<T>::get(subnet_id) {
Some(data) => data,
None => return false,
};

// If there's rotation info and we're the one rotating from, return true
if let Some((rotating_from_id, _block)) = decryption_info.rotating_from {
if &rotating_from_id == acc_id {
return true;
}
}

false
}

pub fn process_consensus_params<T>(
subnet_id: u16,
acc_id: T::AccountId,
consensus_params: Vec<(u64, ConsensusParams<T>)>,
simulation_result: ConsensusSimulationResult<T>,
) -> (bool, ShouldDecryptResult<T>)
) -> (bool, ShouldDecryptResult<T>, bool)
where
T: pallet_subspace::Config + pallet_subnet_emission::Config + pallet::Config,
{
Expand All @@ -38,6 +18,7 @@ where
};

let mut final_should_send = false;
let mut forced_send = false;

log::info!("Processing consensus params for subnet {}", subnet_id);
log::info!(
Expand Down Expand Up @@ -149,8 +130,12 @@ where
);

let current_should_send = if !should_decrypt_result.should_decrypt {
let rotation_should_send = should_send_rotation_weights::<T>(subnet_id, &acc_id);
let rotation_should_send =
pallet_subnet_emission::Pallet::<T>::should_send_rotation_weights(
subnet_id, &acc_id,
);
if rotation_should_send {
forced_send = true;
should_decrypt_result.delta = I64F64::from_num(0);
}
rotation_should_send
Expand All @@ -169,7 +154,7 @@ where
final_should_send = current_should_send;
}
log::info!("should_decrypt: {}", result.should_decrypt);
(final_should_send, result)
(final_should_send, result, forced_send)
}

/// Returns
Expand Down Expand Up @@ -281,8 +266,7 @@ pub fn compute_simulation_yuma_params<T: Config>(
decrypted_weights
.iter()
.cloned()
.chain(sp_std::iter::once((copier_uid, copier_weights))), /* HONZA TODO figure out
* this validator key */
.chain(sp_std::iter::once((copier_uid, copier_weights))),
);

Some(SimulationYumaParams {
Expand Down
23 changes: 22 additions & 1 deletion pallets/subnet_emission/src/decryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ impl<T: Config> Pallet<T> {
node_public_key: new_node.node_public_key,
activation_block: None, /* This will get updated based on the first encrypted
* weights */
rotating_from: Some((previous_node_id, block_number)),
rotating_from: Some(previous_node_id),
last_keep_alive: block_number,
}),
);
Expand All @@ -616,4 +616,25 @@ impl<T: Config> Pallet<T> {
Self::cleanup_weight_encryption_data(subnet_id);
}
}

pub fn should_send_rotation_weights(subnet_id: u16, acc_id: &T::AccountId) -> bool {
// Iterate through all subnet decryption data
let rotated_subnets: Vec<u16> = SubnetDecryptionData::<T>::iter()
.filter_map(|(subnet, decryption_info)| {
// Check if there's rotation information and the rotating_from matches acc_id
if let Some(rotating_from_id) = decryption_info.rotating_from {
if &rotating_from_id == acc_id {
Some(subnet)
} else {
None
}
} else {
None
}
})
.collect();

// Check if the input subnet_id is in the collected rotated subnets
rotated_subnets.contains(&subnet_id)
}
}
2 changes: 1 addition & 1 deletion pallets/subnet_emission/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ where
// gets assigned when first encrypted weights appear on the subnet
pub activation_block: Option<u64>,
pub last_keep_alive: u64,
pub rotating_from: Option<(T::AccountId, u64)>, // rotating from at block
pub rotating_from: Option<T::AccountId>,
}
6 changes: 4 additions & 2 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node-subspace"),
impl_name: create_runtime_str!("node-subspace"),
authoring_version: 1,
spec_version: 494,
spec_version: 497,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
Expand Down Expand Up @@ -468,7 +468,9 @@ impl pallet_subnet_emission::Config for Runtime {
type Decimals = ConstU8<9>;
type HalvingInterval = ConstU64<250_000_000>;
type MaxSupply = ConstU64<1_000_000_000>;
type DecryptionNodeRotationInterval = ConstU64<5_000>;
// type DecryptionNodeRotationInterval = ConstU64<5_000>;
type DecryptionNodeRotationInterval = ConstU64<5_0>;

type MaxAuthorities = ConstU32<100>;
// Represented in number of blocks, defines how long decryption node will be banned for.
// Ban presists even if ping are being sent.
Expand Down

0 comments on commit f1e6806

Please sign in to comment.