Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a4cffece5 | |||
| e9144fb1bd |
@@ -14,6 +14,7 @@ use cosmwasm_std::Decimal;
|
|||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use cosmwasm_std::Addr;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
@@ -510,4 +511,5 @@ pub enum QueryMsg {
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct MigrateMsg {
|
pub struct MigrateMsg {
|
||||||
pub vesting_contract_address: Option<String>,
|
pub vesting_contract_address: Option<String>,
|
||||||
|
pub gateway_address: Addr,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use mixnet_contract_common::error::MixnetContractError;
|
|||||||
use mixnet_contract_common::{
|
use mixnet_contract_common::{
|
||||||
ContractState, ContractStateParams, ExecuteMsg, InstantiateMsg, Interval, MigrateMsg, QueryMsg,
|
ContractState, ContractStateParams, ExecuteMsg, InstantiateMsg, Interval, MigrateMsg, QueryMsg,
|
||||||
};
|
};
|
||||||
|
use crate::gateways::storage;
|
||||||
|
|
||||||
fn default_initial_state(
|
fn default_initial_state(
|
||||||
owner: Addr,
|
owner: Addr,
|
||||||
@@ -568,6 +569,17 @@ pub fn migrate(
|
|||||||
mixnet_params_storage::CONTRACT_STATE.save(deps.storage, ¤t_state)?;
|
mixnet_params_storage::CONTRACT_STATE.save(deps.storage, ¤t_state)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let gateway_bond = match storage::gateways()
|
||||||
|
.idx
|
||||||
|
.owner
|
||||||
|
.item(deps.storage, msg.gateway_address.clone())?
|
||||||
|
{
|
||||||
|
Some(record) => record.1,
|
||||||
|
None => return Err(MixnetContractError::NoAssociatedGatewayBond { owner: msg.gateway_address.clone() }),
|
||||||
|
};
|
||||||
|
|
||||||
|
storage::gateways().remove(deps.storage, gateway_bond.identity())?;
|
||||||
|
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,16 +59,6 @@ pub struct RewardedSetUpdater {
|
|||||||
storage: NymApiStorage,
|
storage: NymApiStorage,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weight of a layer being chose is reciprocal to current count in layer
|
|
||||||
fn layer_weight(l: &Layer, layer_assignments: &HashMap<Layer, f32>) -> f32 {
|
|
||||||
let total = layer_assignments.values().fold(0., |acc, i| acc + i);
|
|
||||||
if total == 0. {
|
|
||||||
1.
|
|
||||||
} else {
|
|
||||||
1. - (layer_assignments.get(l).unwrap_or(&0.) / total)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RewardedSetUpdater {
|
impl RewardedSetUpdater {
|
||||||
pub(crate) async fn current_interval_details(
|
pub(crate) async fn current_interval_details(
|
||||||
&self,
|
&self,
|
||||||
@@ -88,15 +78,13 @@ impl RewardedSetUpdater {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Needs to run for active and reserve sets separatley, as it does not preserve order
|
||||||
async fn determine_layers(
|
async fn determine_layers(
|
||||||
&self,
|
&self,
|
||||||
rewarded_set: &[MixNodeDetails],
|
set: &[MixNodeDetails],
|
||||||
) -> Result<(Vec<LayerAssignment>, HashMap<String, Layer>), RewardingError> {
|
) -> Result<Vec<LayerAssignment>, RewardingError> {
|
||||||
let mut families_in_layer: HashMap<String, Layer> = HashMap::new();
|
let mut assignments = Vec::with_capacity(set.len());
|
||||||
let mut assignments = vec![];
|
let target_layer_count = set.len() / 3;
|
||||||
let mut layer_assignments: HashMap<Layer, f32> = HashMap::new();
|
|
||||||
let mut rng = OsRng;
|
|
||||||
let layers = vec![Layer::One, Layer::Two, Layer::Three];
|
|
||||||
|
|
||||||
let mix_to_family = self.validator_cache.mix_to_family().await.to_vec();
|
let mix_to_family = self.validator_cache.mix_to_family().await.to_vec();
|
||||||
|
|
||||||
@@ -104,31 +92,60 @@ impl RewardedSetUpdater {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<HashMap<IdentityKey, FamilyHead>>();
|
.collect::<HashMap<IdentityKey, FamilyHead>>();
|
||||||
|
|
||||||
for mix in rewarded_set {
|
let mut regular_nodes = Vec::with_capacity(set.len());
|
||||||
let family = mix_to_family.get(&mix.bond_information.identity().to_owned());
|
|
||||||
// Get layer already assigned to nodes family, if any
|
|
||||||
let family_layer = family.and_then(|h| families_in_layer.get(h.identity()));
|
|
||||||
|
|
||||||
// Same node families are always assigned to the same layer, otherwise layer selected by a random weighted choice
|
let mut families = HashMap::new();
|
||||||
let layer = if let Some(layer) = family_layer {
|
|
||||||
layer.to_owned()
|
for node in set.iter() {
|
||||||
|
if let Some(fh) = mix_to_family.get(node.bond_information.identity()) {
|
||||||
|
let family: &mut Vec<u32> = families.entry(fh.identity()).or_default();
|
||||||
|
family.push(node.mix_id())
|
||||||
} else {
|
} else {
|
||||||
layers
|
regular_nodes.push(node.mix_id())
|
||||||
.choose_weighted(&mut rng, |l| layer_weight(l, &layer_assignments))?
|
|
||||||
.to_owned()
|
|
||||||
};
|
|
||||||
|
|
||||||
assignments.push(LayerAssignment::new(mix.mix_id(), layer));
|
|
||||||
|
|
||||||
// layer accounting
|
|
||||||
let layer_entry = layer_assignments.entry(layer).or_insert(0.);
|
|
||||||
*layer_entry += 1.;
|
|
||||||
if let Some(family) = family {
|
|
||||||
families_in_layer.insert(family.identity().to_string(), layer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((assignments, families_in_layer))
|
let mut layers = HashMap::new();
|
||||||
|
layers.insert(Layer::One, Vec::with_capacity(target_layer_count));
|
||||||
|
layers.insert(Layer::Two, Vec::with_capacity(target_layer_count));
|
||||||
|
layers.insert(Layer::Three, Vec::with_capacity(target_layer_count));
|
||||||
|
|
||||||
|
// Assign all members of a family to same layer
|
||||||
|
for (_head, members) in families.iter_mut() {
|
||||||
|
let smallest_layer = layers
|
||||||
|
.iter()
|
||||||
|
.min_by_key(|(_layer, members)| members.len())
|
||||||
|
.map(|(layer, _members)| *layer)
|
||||||
|
.unwrap_or(Layer::One);
|
||||||
|
|
||||||
|
let entry = layers.entry(smallest_layer).or_default();
|
||||||
|
if entry.len() + members.len() <= target_layer_count {
|
||||||
|
entry.extend_from_slice(members)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign nodes with no families into layers
|
||||||
|
for mix_id in regular_nodes.drain(..) {
|
||||||
|
let smallest_layer = layers
|
||||||
|
.iter()
|
||||||
|
.min_by_key(|(_layer, members)| members.len())
|
||||||
|
.map(|(layer, _members)| *layer)
|
||||||
|
.unwrap_or(Layer::One);
|
||||||
|
|
||||||
|
let entry = layers.entry(smallest_layer).or_default();
|
||||||
|
if entry.len() < target_layer_count {
|
||||||
|
entry.push(mix_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (layer, members) in layers {
|
||||||
|
let layer_assignments = members
|
||||||
|
.into_iter()
|
||||||
|
.map(|mix_id| LayerAssignment::new(mix_id, layer));
|
||||||
|
assignments.extend(layer_assignments);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(assignments)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn determine_rewarded_set(
|
fn determine_rewarded_set(
|
||||||
@@ -248,11 +265,19 @@ impl RewardedSetUpdater {
|
|||||||
let new_rewarded_set =
|
let new_rewarded_set =
|
||||||
self.determine_rewarded_set(all_mixnodes, rewarding_parameters.rewarded_set_size)?;
|
self.determine_rewarded_set(all_mixnodes, rewarding_parameters.rewarded_set_size)?;
|
||||||
|
|
||||||
let (layer_assignments, _families_in_layer) =
|
let (active_set, reserve_set) =
|
||||||
self.determine_layers(&new_rewarded_set).await?;
|
new_rewarded_set.split_at(rewarding_parameters.active_set_size as usize);
|
||||||
|
|
||||||
|
let mut active_set_layer_assignments = self.determine_layers(active_set).await?;
|
||||||
|
let reserve_set_layer_assignments = self.determine_layers(reserve_set).await?;
|
||||||
|
|
||||||
|
active_set_layer_assignments.extend(reserve_set_layer_assignments);
|
||||||
|
|
||||||
self.nyxd_client
|
self.nyxd_client
|
||||||
.advance_current_epoch(layer_assignments, rewarding_parameters.active_set_size)
|
.advance_current_epoch(
|
||||||
|
active_set_layer_assignments,
|
||||||
|
rewarding_parameters.active_set_size,
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user