instantiate mixnet contract with custom key rotation validity

This commit is contained in:
Jędrzej Stuczyński
2025-05-19 14:54:45 +01:00
parent 93d2e9509f
commit 89a3480c2a
12 changed files with 69 additions and 5 deletions
@@ -193,6 +193,9 @@ pub enum MixnetContractError {
#[error("attempted to perform the operation with 0 coins. This is not allowed")]
ZeroCoinAmount,
#[error("key rotation validity below minimum value")]
TooShortRotationInterval,
#[error("this validator ({current_validator}) is not the one responsible for advancing this epoch. It's responsibility of {chosen_validator}.")]
RewardingValidatorMismatch {
current_validator: Addr,
@@ -82,6 +82,18 @@ pub struct InstantiateMsg {
#[serde(default)]
pub interval_operating_cost: OperatingCostRange,
#[serde(default)]
pub key_validity_in_epochs: Option<u32>,
}
impl InstantiateMsg {
// needs to give us enough time to pre-announce key for following epoch
// and have an overlap with the preceding epoch
pub const MIN_KEY_ROTATION_VALIDITY: u32 = 3;
pub fn key_validity_in_epochs(&self) -> u32 {
self.key_validity_in_epochs.unwrap_or(24)
}
}
#[cw_serde]
@@ -34,5 +34,6 @@ pub fn default_mixnet_init_msg() -> nym_mixnet_contract_common::InstantiateMsg {
version_score_params: Default::default(),
profit_margin: Default::default(),
interval_operating_cost: Default::default(),
key_validity_in_epochs: None,
}
}
@@ -41,6 +41,15 @@
}
]
},
"key_validity_in_epochs": {
"default": null,
"type": [
"integer",
"null"
],
"format": "uint32",
"minimum": 0.0
},
"profit_margin": {
"default": {
"maximum": "1",
@@ -37,6 +37,15 @@
}
]
},
"key_validity_in_epochs": {
"default": null,
"type": [
"integer",
"null"
],
"format": "uint32",
"minimum": 0.0
},
"profit_margin": {
"default": {
"maximum": "1",
+7 -1
View File
@@ -83,6 +83,11 @@ pub fn instantiate(
});
}
let key_rotation_validity = msg.key_validity_in_epochs();
if key_rotation_validity < InstantiateMsg::MIN_KEY_ROTATION_VALIDITY {
return Err(MixnetContractError::TooShortRotationInterval);
}
let rewarding_validator_address = deps.api.addr_validate(&msg.rewarding_validator_address)?;
let vesting_contract_address = deps.api.addr_validate(&msg.vesting_contract_address)?;
let state = default_initial_state(
@@ -110,7 +115,7 @@ pub fn instantiate(
msg.current_nym_node_version,
)?;
RewardingStorage::new().initialise(deps.storage, reward_params)?;
nymnodes_storage::initialise_storage(deps.storage)?;
nymnodes_storage::initialise_storage(deps.storage, key_rotation_validity)?;
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
set_build_information!(deps.storage)?;
@@ -690,6 +695,7 @@ mod tests {
minimum: "1000".parse().unwrap(),
maximum: "10000".parse().unwrap(),
},
key_validity_in_epochs: None,
};
let sender = message_info(&deps.api.addr_make("sender"), &[]);
@@ -103,7 +103,10 @@ pub(crate) fn next_nymnode_id_counter(store: &mut dyn Storage) -> StdResult<Node
Ok(id)
}
pub(crate) fn initialise_storage(storage: &mut dyn Storage) -> Result<(), MixnetContractError> {
pub(crate) fn initialise_storage(
storage: &mut dyn Storage,
key_rotation_validity: u32,
) -> Result<(), MixnetContractError> {
let active_bucket = RoleStorageBucket::default();
let inactive_bucket = active_bucket.other();
@@ -128,7 +131,7 @@ pub(crate) fn initialise_storage(storage: &mut dyn Storage) -> Result<(), Mixnet
KEY_ROTATION_STATE.save(
storage,
&KeyRotationState {
validity_epochs: 24,
validity_epochs: key_rotation_validity,
initial_epoch_id: 0,
},
)?;
@@ -1858,6 +1858,7 @@ pub mod test_helpers {
version_score_params: Default::default(),
profit_margin: Default::default(),
interval_operating_cost: Default::default(),
key_validity_in_epochs: None,
};
let env = mock_env();
let info = sender("creator");
@@ -25,6 +25,10 @@ pub(crate) struct Args {
#[clap(long)]
custom_epoch_duration_secs: Option<u64>,
/// Specifies custom number of epochs sphinx keys are going to be valid for
#[clap(long)]
key_validity_in_epochs: Option<u32>,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
@@ -38,6 +42,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), NetworkManagerError> {
args.built_contracts,
args.network_name,
args.custom_epoch_duration_secs.map(Duration::from_secs),
args.key_validity_in_epochs,
)
.await?
.into_loaded();
@@ -39,6 +39,10 @@ pub(crate) struct Args {
#[clap(long)]
custom_epoch_duration_secs: Option<u64>,
/// Specifies custom number of epochs sphinx keys are going to be valid for
#[clap(long)]
key_validity_in_epochs: Option<u32>,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
@@ -51,6 +55,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), NetworkManagerError> {
args.built_contracts,
args.network_name,
args.custom_epoch_duration_secs.map(Duration::from_secs),
args.key_validity_in_epochs,
)
.await?
.into();
@@ -37,6 +37,10 @@ pub(crate) struct Args {
#[clap(long)]
custom_epoch_duration_secs: Option<u64>,
/// Specifies custom number of epochs sphinx keys are going to be valid for
#[clap(long)]
key_validity_in_epochs: Option<u32>,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
@@ -53,6 +57,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), NetworkManagerError> {
args.built_contracts,
args.network_name,
args.custom_epoch_duration_secs.map(Duration::from_secs),
args.key_validity_in_epochs,
)
.await?
.into();
@@ -127,6 +127,7 @@ impl NetworkManager {
&self,
ctx: &InitCtx,
custom_epoch_duration: Option<Duration>,
key_validity_in_epochs: Option<u32>,
) -> Result<nym_mixnet_contract_common::InstantiateMsg, NetworkManagerError> {
Ok(nym_mixnet_contract_common::InstantiateMsg {
rewarding_validator_address: ctx
@@ -165,6 +166,7 @@ impl NetworkManager {
version_score_params: Default::default(),
profit_margin: Default::default(),
interval_operating_cost: Default::default(),
key_validity_in_epochs,
})
}
@@ -408,6 +410,7 @@ impl NetworkManager {
&self,
ctx: &mut InitCtx,
custom_epoch_duration: Option<Duration>,
key_validity_in_epochs: Option<u32>,
) -> Result<(), NetworkManagerError> {
ctx.println(format!(
"💽 {}Instantiating all the contracts...",
@@ -422,7 +425,8 @@ impl NetworkManager {
let code_id = ctx.network.contracts.mixnet.upload_info()?.code_id;
let admin = ctx.network.contracts.mixnet.admin()?.address.clone();
ctx.set_pb_message(format!("attempting to instantiate {name} contract..."));
let init_msg = self.mixnet_init_message(ctx, custom_epoch_duration)?;
let init_msg =
self.mixnet_init_message(ctx, custom_epoch_duration, key_validity_in_epochs)?;
let init_fut = ctx.admin.instantiate(
code_id,
&init_msg,
@@ -694,6 +698,7 @@ impl NetworkManager {
contracts: P,
network_name: Option<String>,
custom_epoch_duration: Option<Duration>,
key_validity_in_epochs: Option<u32>,
) -> Result<Network, NetworkManagerError> {
let network_name = self.get_network_name(network_name);
let mut ctx = InitCtx::new(network_name, self.admin.deref().clone(), &self.rpc_endpoint)?;
@@ -702,7 +707,7 @@ impl NetworkManager {
self.upload_contracts(&mut ctx).await?;
self.create_contract_admins_mnemonics(&mut ctx)?;
self.transfer_admin_tokens(&ctx).await?;
self.instantiate_contracts(&mut ctx, custom_epoch_duration)
self.instantiate_contracts(&mut ctx, custom_epoch_duration, key_validity_in_epochs)
.await?;
self.perform_final_migrations(&mut ctx).await?;
self.get_build_info(&mut ctx).await?;