added basic key rotation information to mixnet contract
This commit is contained in:
+16
-6
@@ -28,12 +28,12 @@ use nym_mixnet_contract_common::{
|
||||
ContractBuildInformation, ContractState, ContractStateParams, CurrentIntervalResponse,
|
||||
CurrentNymNodeVersionResponse, Delegation, EpochEventId, EpochRewardedSet, EpochStatus,
|
||||
GatewayBond, GatewayBondResponse, GatewayOwnershipResponse, HistoricalNymNodeVersionEntry,
|
||||
IdentityKey, IdentityKeyRef, IntervalEventId, MixNodeBond, MixNodeDetails,
|
||||
MixOwnershipResponse, MixnodeDetailsByIdentityResponse, MixnodeDetailsResponse, NodeId,
|
||||
NumberOfPendingEventsResponse, NymNodeBond, NymNodeDetails, NymNodeVersionHistoryResponse,
|
||||
PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, PagedGatewayResponse,
|
||||
PagedMixnodeBondsResponse, PagedNodeDelegationsResponse, PendingEpochEvent,
|
||||
PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEvent,
|
||||
IdentityKey, IdentityKeyRef, IntervalEventId, KeyRotationIdResponse, KeyRotationState,
|
||||
MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsByIdentityResponse,
|
||||
MixnodeDetailsResponse, NodeId, NumberOfPendingEventsResponse, NymNodeBond, NymNodeDetails,
|
||||
NymNodeVersionHistoryResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse,
|
||||
PagedGatewayResponse, PagedMixnodeBondsResponse, PagedNodeDelegationsResponse,
|
||||
PendingEpochEvent, PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEvent,
|
||||
PendingIntervalEventResponse, PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg,
|
||||
RewardedSet, UnbondedMixnode,
|
||||
};
|
||||
@@ -546,6 +546,16 @@ pub trait MixnetQueryClient {
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_key_rotation_state(&self) -> Result<KeyRotationState, NyxdError> {
|
||||
self.query_mixnet_contract(MixnetQueryMsg::GetKeyRotationState {})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_key_rotation_id(&self) -> Result<KeyRotationIdResponse, NyxdError> {
|
||||
self.query_mixnet_contract(MixnetQueryMsg::GetKeyRotationId {})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
// extension trait to the query client to deal with the paged queries
|
||||
|
||||
@@ -40,3 +40,6 @@ contract-testing = []
|
||||
utoipa = ["dep:utoipa"]
|
||||
schema = ["cw2"]
|
||||
generate-ts = ['ts-rs']
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::EpochId;
|
||||
use cosmwasm_schema::cw_serde;
|
||||
|
||||
pub type KeyRotationId = u32;
|
||||
|
||||
#[cw_serde]
|
||||
pub struct KeyRotationState {
|
||||
/// Defines how long each key rotation is valid for (in terms of epochs)
|
||||
pub validity_epochs: u32,
|
||||
|
||||
/// Records the initial epoch_id when the key rotation has been introduced (0 for fresh contracts).
|
||||
/// It is used for determining when rotation is meant to advance.
|
||||
pub initial_epoch_id: EpochId,
|
||||
}
|
||||
|
||||
impl KeyRotationState {
|
||||
pub fn key_rotation_id(&self, current_epoch_id: EpochId) -> KeyRotationId {
|
||||
let diff = current_epoch_id.saturating_sub(self.initial_epoch_id);
|
||||
let full_rots = diff / self.validity_epochs;
|
||||
full_rots
|
||||
}
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
pub struct KeyRotationIdResponse {
|
||||
pub rotation_id: KeyRotationId,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn key_rotation_id() {
|
||||
let state = KeyRotationState {
|
||||
validity_epochs: 24,
|
||||
initial_epoch_id: 0,
|
||||
};
|
||||
assert_eq!(0, state.key_rotation_id(0));
|
||||
assert_eq!(0, state.key_rotation_id(23));
|
||||
assert_eq!(1, state.key_rotation_id(24));
|
||||
assert_eq!(1, state.key_rotation_id(47));
|
||||
assert_eq!(2, state.key_rotation_id(48));
|
||||
|
||||
let state = KeyRotationState {
|
||||
validity_epochs: 12,
|
||||
initial_epoch_id: 0,
|
||||
};
|
||||
assert_eq!(0, state.key_rotation_id(0));
|
||||
assert_eq!(0, state.key_rotation_id(11));
|
||||
assert_eq!(1, state.key_rotation_id(12));
|
||||
assert_eq!(1, state.key_rotation_id(23));
|
||||
assert_eq!(2, state.key_rotation_id(24));
|
||||
|
||||
let state = KeyRotationState {
|
||||
validity_epochs: 24,
|
||||
initial_epoch_id: 10000,
|
||||
};
|
||||
assert_eq!(0, state.key_rotation_id(123));
|
||||
assert_eq!(0, state.key_rotation_id(10000));
|
||||
assert_eq!(0, state.key_rotation_id(10001));
|
||||
assert_eq!(0, state.key_rotation_id(10023));
|
||||
assert_eq!(1, state.key_rotation_id(10024));
|
||||
assert_eq!(1, state.key_rotation_id(10047));
|
||||
assert_eq!(2, state.key_rotation_id(10048));
|
||||
assert_eq!(2, state.key_rotation_id(10060));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#![warn(clippy::expect_used)]
|
||||
#![warn(clippy::unwrap_used)]
|
||||
#![warn(clippy::todo)]
|
||||
|
||||
mod config_score;
|
||||
pub mod constants;
|
||||
pub mod delegation;
|
||||
@@ -13,6 +9,7 @@ pub mod events;
|
||||
pub mod gateway;
|
||||
pub mod helpers;
|
||||
pub mod interval;
|
||||
pub mod key_rotation;
|
||||
pub mod mixnode;
|
||||
pub mod msg;
|
||||
pub mod nym_node;
|
||||
@@ -37,6 +34,7 @@ pub use gateway::{
|
||||
pub use interval::{
|
||||
CurrentIntervalResponse, EpochId, EpochState, EpochStatus, Interval, IntervalId,
|
||||
};
|
||||
pub use key_rotation::*;
|
||||
pub use mixnode::{
|
||||
LegacyMixLayer, MixNode, MixNodeBond, MixNodeConfigUpdate, MixNodeDetails,
|
||||
MixOwnershipResponse, MixnodeDetailsByIdentityResponse, MixnodeDetailsResponse, NodeCostParams,
|
||||
|
||||
@@ -170,6 +170,11 @@ impl NodeRewarding {
|
||||
}
|
||||
}
|
||||
|
||||
// we panic here as opposed to returning an error as this is undefined behaviour,
|
||||
// because the pledge amount has decreased (i.e. slashing has occurred) which
|
||||
// should not be possible under any situation. at this point we don't know how many other things
|
||||
// might have failed so we have to bail
|
||||
#[allow(clippy::panic)]
|
||||
pub fn pending_detailed_operator_reward(&self, original_pledge: &Coin) -> StdResult<Decimal> {
|
||||
let initial_dec = original_pledge.amount.into_base_decimal()?;
|
||||
if initial_dec > self.operator {
|
||||
@@ -189,6 +194,11 @@ impl NodeRewarding {
|
||||
Ok(truncate_reward(delegator_reward, &delegation.amount.denom))
|
||||
}
|
||||
|
||||
// we panic here as opposed to returning an error as this is undefined behaviour,
|
||||
// because the pledge amount has decreased (i.e. slashing has occurred) which
|
||||
// should not be possible under any situation. at this point we don't know how many other things
|
||||
// might have failed so we have to bail
|
||||
#[allow(clippy::panic)]
|
||||
pub fn withdraw_operator_reward(
|
||||
&mut self,
|
||||
original_pledge: &Coin,
|
||||
|
||||
@@ -35,6 +35,7 @@ use crate::{
|
||||
PreassignedGatewayIdsResponse,
|
||||
},
|
||||
interval::{CurrentIntervalResponse, EpochStatus},
|
||||
key_rotation::{KeyRotationIdResponse, KeyRotationState},
|
||||
mixnode::{
|
||||
MixOwnershipResponse, MixStakeSaturationResponse, MixnodeDetailsByIdentityResponse,
|
||||
MixnodeDetailsResponse, MixnodeRewardingDetailsResponse, PagedMixnodeBondsResponse,
|
||||
@@ -857,6 +858,15 @@ pub enum QueryMsg {
|
||||
/// Cosmos address used for the query of the signing nonce.
|
||||
address: String,
|
||||
},
|
||||
|
||||
// sphinx key rotation-related
|
||||
#[cfg_attr(feature = "schema", returns(KeyRotationState))]
|
||||
/// Gets the current state config of the key rotation (i.e. starting epoch id and validity duration)
|
||||
GetKeyRotationState {},
|
||||
|
||||
/// Gets the current key rotation id
|
||||
#[cfg_attr(feature = "schema", returns(KeyRotationIdResponse))]
|
||||
GetKeyRotationId {},
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
|
||||
@@ -151,6 +151,9 @@ impl Simulator {
|
||||
}
|
||||
}
|
||||
|
||||
// this code is not meant to be used in production systems, only in tests
|
||||
// so a panic due to inconsistent arguments is fine
|
||||
#[allow(clippy::panic)]
|
||||
pub fn simulate_epoch(
|
||||
&mut self,
|
||||
node_params: &BTreeMap<NodeId, NodeRewardingParameters>,
|
||||
|
||||
@@ -21,7 +21,7 @@ nym-sphinx-types = { path = "../types" }
|
||||
nym-topology = { path = "../../topology" }
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
|
||||
version = "0.2.95"
|
||||
workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
rand_chacha = { workspace = true }
|
||||
|
||||
Generated
-3
@@ -1193,7 +1193,6 @@ version = "1.5.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58",
|
||||
"cosmwasm-derive",
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-controllers",
|
||||
@@ -1208,8 +1207,6 @@ dependencies = [
|
||||
"rand_chacha",
|
||||
"semver",
|
||||
"serde",
|
||||
"thiserror 2.0.12",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -55,3 +55,13 @@ sylvia = "1.3.3"
|
||||
schemars = "0.8.16"
|
||||
|
||||
thiserror = "2.0.11"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
unwrap_used = "deny"
|
||||
expect_used = "deny"
|
||||
todo = "deny"
|
||||
dbg_macro = "deny"
|
||||
exit = "deny"
|
||||
panic = "deny"
|
||||
unimplemented = "deny"
|
||||
unreachable = "deny"
|
||||
@@ -33,7 +33,6 @@ nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts
|
||||
cosmwasm-schema = { workspace = true, optional = true }
|
||||
cosmwasm-std = { workspace = true }
|
||||
|
||||
cosmwasm-derive = { workspace = true }
|
||||
cw-controllers = { workspace = true }
|
||||
cw2 = { workspace = true }
|
||||
cw-storage-plus = { workspace = true }
|
||||
@@ -41,8 +40,6 @@ cw-storage-plus = { workspace = true }
|
||||
bs58 = { workspace = true }
|
||||
serde = { workspace = true, default-features = false, features = ["derive"] }
|
||||
semver = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
time = { version = "0.3", features = ["macros"] }
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow.workspace = true
|
||||
@@ -55,3 +52,6 @@ easy-addr = { path = "../../common/cosmwasm-smart-contracts/easy_addr" }
|
||||
default = []
|
||||
contract-testing = ["mixnet-contract-common/contract-testing"]
|
||||
schema-gen = ["mixnet-contract-common/schema", "cosmwasm-schema"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -78,6 +78,7 @@ pub const NYMNODE_ROLES_ASSIGNMENT_NAMESPACE: &str = "roles";
|
||||
pub const NYMNODE_REWARDED_SET_METADATA_NAMESPACE: &str = "roles_metadata";
|
||||
pub const NYMNODE_ACTIVE_ROLE_ASSIGNMENT_KEY: &str = "active_roles";
|
||||
|
||||
pub const KEY_ROTATION_STATE_KEY: &str = "key_rot_state";
|
||||
pub const NODE_ID_COUNTER_KEY: &str = "nic";
|
||||
pub const PENDING_MIXNODE_CHANGES_NAMESPACE: &str = "pmc";
|
||||
pub const MIXNODES_PK_NAMESPACE: &str = "mnn";
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::constants::INITIAL_PLEDGE_AMOUNT;
|
||||
use crate::interval::storage as interval_storage;
|
||||
use crate::mixnet_contract_settings::storage as mixnet_params_storage;
|
||||
use crate::nodes::storage as nymnodes_storage;
|
||||
use crate::queued_migrations::introduce_key_rotation_id;
|
||||
use crate::rewards::storage::RewardingStorage;
|
||||
use cosmwasm_std::{
|
||||
entry_point, to_json_binary, Addr, Coin, Deps, DepsMut, Env, MessageInfo, QueryResponse,
|
||||
@@ -598,6 +599,14 @@ pub fn query(
|
||||
QueryMsg::GetSigningNonce { address } => to_json_binary(
|
||||
&crate::signing::queries::query_current_signing_nonce(deps, address)?,
|
||||
),
|
||||
|
||||
// sphinx key rotation-related
|
||||
QueryMsg::GetKeyRotationState {} => {
|
||||
to_json_binary(&crate::nodes::queries::query_key_rotation_state(deps)?)
|
||||
}
|
||||
QueryMsg::GetKeyRotationId {} => {
|
||||
to_json_binary(&crate::nodes::queries::query_key_rotation_id(deps)?)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(query_res?)
|
||||
@@ -605,18 +614,18 @@ pub fn query(
|
||||
|
||||
#[entry_point]
|
||||
pub fn migrate(
|
||||
deps: DepsMut<'_>,
|
||||
mut deps: DepsMut<'_>,
|
||||
_env: Env,
|
||||
msg: MigrateMsg,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
set_build_information!(deps.storage)?;
|
||||
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
|
||||
|
||||
// let skip_state_updates = msg.unsafe_skip_state_updates.unwrap_or(false);
|
||||
//
|
||||
// if !skip_state_updates {
|
||||
//
|
||||
// }
|
||||
let skip_state_updates = msg.unsafe_skip_state_updates.unwrap_or(false);
|
||||
|
||||
if !skip_state_updates {
|
||||
introduce_key_rotation_id(deps.branch())?;
|
||||
}
|
||||
|
||||
// due to circular dependency on contract addresses (i.e. mixnet contract requiring vesting contract address
|
||||
// and vesting contract requiring the mixnet contract address), if we ever want to deploy any new fresh
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::constants::{
|
||||
NYM_NODE_DETAILS_DEFAULT_RETRIEVAL_LIMIT, NYM_NODE_DETAILS_MAX_RETRIEVAL_LIMIT,
|
||||
UNBONDED_NYM_NODES_DEFAULT_RETRIEVAL_LIMIT, UNBONDED_NYM_NODES_MAX_RETRIEVAL_LIMIT,
|
||||
};
|
||||
use crate::interval::storage as interval_storage;
|
||||
use crate::nodes::helpers::{
|
||||
attach_nym_node_details, get_node_details_by_id, get_node_details_by_identity,
|
||||
get_node_details_by_owner,
|
||||
@@ -21,7 +22,9 @@ use mixnet_contract_common::nym_node::{
|
||||
PagedNymNodeDetailsResponse, PagedUnbondedNymNodesResponse, Role, RolesMetadataResponse,
|
||||
StakeSaturationResponse, UnbondedNodeResponse,
|
||||
};
|
||||
use mixnet_contract_common::{NodeId, NymNodeBond, NymNodeDetails};
|
||||
use mixnet_contract_common::{
|
||||
KeyRotationIdResponse, KeyRotationState, NodeId, NymNodeBond, NymNodeDetails,
|
||||
};
|
||||
use nym_contracts_common::IdentityKey;
|
||||
|
||||
pub(crate) fn query_nymnode_bonds_paged(
|
||||
@@ -257,3 +260,14 @@ pub fn query_stake_saturation(
|
||||
uncapped_saturation: Some(node_rewarding.uncapped_bond_saturation(&rewarding_params)),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn query_key_rotation_state(deps: Deps<'_>) -> StdResult<KeyRotationState> {
|
||||
storage::KEY_ROTATION_STATE.load(deps.storage)
|
||||
}
|
||||
|
||||
pub fn query_key_rotation_id(deps: Deps<'_>) -> StdResult<KeyRotationIdResponse> {
|
||||
let interval = interval_storage::current_interval(deps.storage)?;
|
||||
let rotation_state = storage::KEY_ROTATION_STATE.load(deps.storage)?;
|
||||
let rotation_id = rotation_state.key_rotation_id(interval.current_epoch_absolute_id());
|
||||
Ok(KeyRotationIdResponse { rotation_id })
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::nodes::storage::rewarded_set::{ACTIVE_ROLES_BUCKET, ROLES, ROLES_METADATA};
|
||||
use crate::nodes::storage::{nym_nodes, NYMNODE_ID_COUNTER};
|
||||
use crate::nodes::storage::{nym_nodes, KEY_ROTATION_STATE, NYMNODE_ID_COUNTER};
|
||||
use cosmwasm_std::{StdResult, Storage};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::nym_node::{RewardedSetMetadata, Role};
|
||||
use mixnet_contract_common::{EpochId, NodeId, NymNodeBond, RoleAssignment};
|
||||
use mixnet_contract_common::{EpochId, KeyRotationState, NodeId, NymNodeBond, RoleAssignment};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||
@@ -124,6 +124,15 @@ pub(crate) fn initialise_storage(storage: &mut dyn Storage) -> Result<(), Mixnet
|
||||
ROLES_METADATA.save(storage, active_bucket as u8, &Default::default())?;
|
||||
ROLES_METADATA.save(storage, inactive_bucket as u8, &Default::default())?;
|
||||
|
||||
// since we're initialising fresh storage, the current epoch_id is 0
|
||||
KEY_ROTATION_STATE.save(
|
||||
storage,
|
||||
&KeyRotationState {
|
||||
validity_epochs: 24,
|
||||
initial_epoch_id: 0,
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -2,23 +2,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::{
|
||||
NODE_ID_COUNTER_KEY, NYMNODE_ACTIVE_ROLE_ASSIGNMENT_KEY, NYMNODE_IDENTITY_IDX_NAMESPACE,
|
||||
NYMNODE_OWNER_IDX_NAMESPACE, NYMNODE_PK_NAMESPACE, NYMNODE_REWARDED_SET_METADATA_NAMESPACE,
|
||||
NYMNODE_ROLES_ASSIGNMENT_NAMESPACE, PENDING_NYMNODE_CHANGES_NAMESPACE,
|
||||
UNBONDED_NYMNODE_IDENTITY_IDX_NAMESPACE, UNBONDED_NYMNODE_OWNER_IDX_NAMESPACE,
|
||||
UNBONDED_NYMNODE_PK_NAMESPACE,
|
||||
KEY_ROTATION_STATE_KEY, NODE_ID_COUNTER_KEY, NYMNODE_ACTIVE_ROLE_ASSIGNMENT_KEY,
|
||||
NYMNODE_IDENTITY_IDX_NAMESPACE, NYMNODE_OWNER_IDX_NAMESPACE, NYMNODE_PK_NAMESPACE,
|
||||
NYMNODE_REWARDED_SET_METADATA_NAMESPACE, NYMNODE_ROLES_ASSIGNMENT_NAMESPACE,
|
||||
PENDING_NYMNODE_CHANGES_NAMESPACE, UNBONDED_NYMNODE_IDENTITY_IDX_NAMESPACE,
|
||||
UNBONDED_NYMNODE_OWNER_IDX_NAMESPACE, UNBONDED_NYMNODE_PK_NAMESPACE,
|
||||
};
|
||||
use crate::nodes::storage::helpers::RoleStorageBucket;
|
||||
use cosmwasm_std::Addr;
|
||||
use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex, UniqueIndex};
|
||||
use mixnet_contract_common::nym_node::{NymNodeBond, RewardedSetMetadata, Role, UnbondedNymNode};
|
||||
use mixnet_contract_common::{NodeId, PendingNodeChanges};
|
||||
use mixnet_contract_common::{KeyRotationState, NodeId, PendingNodeChanges};
|
||||
use nym_contracts_common::IdentityKey;
|
||||
|
||||
pub(crate) mod helpers;
|
||||
|
||||
pub(crate) use helpers::*;
|
||||
|
||||
/// Item recording the current state of the key rotation setup
|
||||
pub const KEY_ROTATION_STATE: Item<KeyRotationState> = Item::new(KEY_ROTATION_STATE_KEY);
|
||||
|
||||
// IMPORTANT NOTE: we're using the same storage key as we had for MIXNODE_ID_COUNTER,
|
||||
// so that we could start from the old values
|
||||
pub const NYMNODE_ID_COUNTER: Item<NodeId> = Item::new(NODE_ID_COUNTER_KEY);
|
||||
|
||||
@@ -1,2 +1,21 @@
|
||||
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2022-2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::interval::storage as interval_storage;
|
||||
use crate::nodes::storage as nymnodes_storage;
|
||||
use cosmwasm_std::DepsMut;
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::KeyRotationState;
|
||||
|
||||
pub fn introduce_key_rotation_id(deps: DepsMut) -> Result<(), MixnetContractError> {
|
||||
let current_epoch_id =
|
||||
interval_storage::current_interval(deps.storage)?.current_epoch_absolute_id();
|
||||
nymnodes_storage::KEY_ROTATION_STATE.save(
|
||||
deps.storage,
|
||||
&KeyRotationState {
|
||||
validity_epochs: 24,
|
||||
initial_epoch_id: current_epoch_id,
|
||||
},
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -56,14 +56,6 @@ impl AsRef<x25519::PrivateKey> for SphinxPrivateKey {
|
||||
}
|
||||
}
|
||||
|
||||
// impl Deref for SphinxPrivateKey {
|
||||
// type Target = x25519::PrivateKey;
|
||||
//
|
||||
// fn deref(&self) -> &Self::Target {
|
||||
// &self.inner
|
||||
// }
|
||||
// }
|
||||
|
||||
pub(crate) struct SphinxPublicKey {
|
||||
pub(crate) rotation_id: u32,
|
||||
pub(crate) inner: x25519::PublicKey,
|
||||
|
||||
Reference in New Issue
Block a user