most of nym-node changes
This commit is contained in:
@@ -933,7 +933,7 @@ impl From<nym_node_requests::api::v1::node::models::HostKeys> for HostKeys {
|
||||
fn from(value: nym_node_requests::api::v1::node::models::HostKeys) -> Self {
|
||||
HostKeysDeHelper {
|
||||
ed25519: value.ed25519_identity,
|
||||
current_x25519_sphinx_key: value.current_x25519_sphinx_key.into(),
|
||||
current_x25519_sphinx_key: value.primary_x25519_sphinx_key.into(),
|
||||
pre_announced_x25519_sphinx_key: value.pre_announced_x25519_sphinx_key.map(Into::into),
|
||||
x25519_noise: value.x25519_noise,
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ mod tests {
|
||||
hostname: Some("foomp.com".to_string()),
|
||||
keys: crate::api::v1::node::models::HostKeys {
|
||||
ed25519_identity: *ed22519.public_key(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: current_rotation_id,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
@@ -154,7 +154,7 @@ mod tests {
|
||||
hostname: Some("foomp.com".to_string()),
|
||||
keys: crate::api::v1::node::models::HostKeys {
|
||||
ed25519_identity: *ed22519.public_key(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: current_rotation_id,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
@@ -174,7 +174,7 @@ mod tests {
|
||||
hostname: Some("foomp.com".to_string()),
|
||||
keys: crate::api::v1::node::models::HostKeys {
|
||||
ed25519_identity: *ed22519.public_key(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: current_rotation_id,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
@@ -195,7 +195,7 @@ mod tests {
|
||||
hostname: Some("foomp.com".to_string()),
|
||||
keys: crate::api::v1::node::models::HostKeys {
|
||||
ed25519_identity: *ed22519.public_key(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: current_rotation_id,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
@@ -236,7 +236,7 @@ mod tests {
|
||||
hostname: Some("foomp.com".to_string()),
|
||||
keys: HostKeys {
|
||||
ed25519_identity: *ed22519.public_key(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: u32::MAX,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
@@ -293,7 +293,7 @@ mod tests {
|
||||
hostname: legacy_info_no_noise.hostname.clone(),
|
||||
keys: crate::api::v1::node::models::HostKeys {
|
||||
ed25519_identity: legacy_info_no_noise.keys.ed25519_identity.parse().unwrap(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: u32::MAX,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
@@ -308,7 +308,7 @@ mod tests {
|
||||
hostname: legacy_info_noise.hostname.clone(),
|
||||
keys: crate::api::v1::node::models::HostKeys {
|
||||
ed25519_identity: legacy_info_noise.keys.ed25519_identity.parse().unwrap(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: u32::MAX,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
@@ -365,7 +365,7 @@ mod tests {
|
||||
hostname: legacy_info.hostname.clone(),
|
||||
keys: crate::api::v1::node::models::HostKeys {
|
||||
ed25519_identity: legacy_info.keys.ed25519.parse().unwrap(),
|
||||
current_x25519_sphinx_key: SphinxKey {
|
||||
primary_x25519_sphinx_key: SphinxKey {
|
||||
rotation_id: u32::MAX,
|
||||
public_key: *x25519_sphinx.public_key(),
|
||||
},
|
||||
|
||||
@@ -131,12 +131,17 @@ pub struct HostKeys {
|
||||
#[cfg_attr(feature = "openapi", schema(value_type = String))]
|
||||
pub ed25519_identity: ed25519::PublicKey,
|
||||
|
||||
#[deprecated(note = "use explicit primary_x25519_sphinx_key instead")]
|
||||
#[serde(alias = "x25519")]
|
||||
#[serde(with = "bs58_x25519_pubkey")]
|
||||
#[schemars(with = "String")]
|
||||
#[cfg_attr(feature = "openapi", schema(value_type = String))]
|
||||
pub x25519_sphinx: x25519::PublicKey,
|
||||
|
||||
/// Current, active, x25519 sphinx key clients are expected to use when constructing packets
|
||||
/// with this node in the route.
|
||||
#[serde(alias = "x25519")]
|
||||
#[serde(alias = "x25519_sphinx")]
|
||||
#[serde(deserialize_with = "de_sphinx_key")]
|
||||
pub current_x25519_sphinx_key: SphinxKey,
|
||||
pub primary_x25519_sphinx_key: SphinxKey,
|
||||
|
||||
/// Pre-announced x25519 sphinx key clients will use during the following key rotation
|
||||
#[serde(default)]
|
||||
@@ -223,7 +228,7 @@ impl From<HostKeys> for LegacyHostKeysV3 {
|
||||
fn from(value: HostKeys) -> Self {
|
||||
LegacyHostKeysV3 {
|
||||
ed25519_identity: value.ed25519_identity,
|
||||
x25519_sphinx: value.current_x25519_sphinx_key.public_key,
|
||||
x25519_sphinx: value.primary_x25519_sphinx_key.public_key,
|
||||
x25519_noise: value.x25519_noise,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,6 +529,9 @@ pub struct Mixnet {
|
||||
/// Settings for controlling replay detection
|
||||
pub replay_protection: ReplayProtection,
|
||||
|
||||
#[serde(default)]
|
||||
pub key_rotation: KeyRotation,
|
||||
|
||||
#[serde(default)]
|
||||
pub debug: MixnetDebug,
|
||||
}
|
||||
@@ -717,6 +720,32 @@ impl Default for ReplayProtectionDebug {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(default)]
|
||||
pub struct KeyRotation {
|
||||
pub debug: KeyRotationDebug,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(default)]
|
||||
pub struct KeyRotationDebug {
|
||||
/// Specifies how often the node should poll for any changes in the key rotation global state.
|
||||
#[serde(with = "humantime_serde")]
|
||||
pub rotation_state_poling_interval: Duration,
|
||||
}
|
||||
|
||||
impl KeyRotationDebug {
|
||||
pub const DEFAULT_ROTATION_STATE_POLLING_INTERVAL: Duration = Duration::from_secs(4 * 60 * 60);
|
||||
}
|
||||
|
||||
impl Default for KeyRotationDebug {
|
||||
fn default() -> Self {
|
||||
KeyRotationDebug {
|
||||
rotation_state_poling_interval: Self::DEFAULT_ROTATION_STATE_POLLING_INTERVAL,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MixnetDebug {
|
||||
// given that genuine clients are using mean delay of 50ms,
|
||||
// the probability of them delaying for over 10s is 10^-87
|
||||
@@ -767,6 +796,7 @@ impl Mixnet {
|
||||
nym_api_urls,
|
||||
nyxd_urls,
|
||||
replay_protection: ReplayProtection::new_default(data_dir),
|
||||
key_rotation: Default::default(),
|
||||
debug: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1403,6 +1403,7 @@ pub async fn try_upgrade_config_v9<P: AsRef<Path>>(
|
||||
.bloomfilter_disk_flushing_rate,
|
||||
},
|
||||
},
|
||||
key_rotation: Default::default(),
|
||||
debug: MixnetDebug {
|
||||
maximum_forward_packet_delay: old_cfg.mixnet.debug.maximum_forward_packet_delay,
|
||||
packet_forwarding_initial_backoff: old_cfg
|
||||
|
||||
@@ -31,18 +31,29 @@ pub(crate) async fn host_information(
|
||||
let pre_announced = match state.x25519_sphinx_keys.secondary() {
|
||||
None => None,
|
||||
Some(secondary_key) => {
|
||||
todo!()
|
||||
if secondary_key.rotation_id() == primary_key.rotation_id() + 1 {
|
||||
Some(api_requests::v1::node::models::SphinxKey {
|
||||
rotation_id: secondary_key.rotation_id(),
|
||||
public_key: secondary_key.x25519_pubkey(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let primary_pubkey = primary_key.x25519_pubkey();
|
||||
|
||||
#[allow(deprecated)]
|
||||
let host_info = api_requests::v1::node::models::HostInformation {
|
||||
ip_address: state.static_information.ip_addresses.clone(),
|
||||
hostname: state.static_information.hostname.clone(),
|
||||
keys: api_requests::v1::node::models::HostKeys {
|
||||
ed25519_identity: *state.static_information.ed25519_identity_keys.public_key(),
|
||||
current_x25519_sphinx_key: api_requests::v1::node::models::SphinxKey {
|
||||
x25519_sphinx: primary_pubkey,
|
||||
primary_x25519_sphinx_key: api_requests::v1::node::models::SphinxKey {
|
||||
rotation_id: primary_key.rotation_id(),
|
||||
public_key: primary_key.x25519_pubkey(),
|
||||
public_key: primary_pubkey,
|
||||
},
|
||||
x25519_noise: state.static_information.x25519_noise_key,
|
||||
pre_announced_x25519_sphinx_key: pre_announced,
|
||||
|
||||
@@ -35,13 +35,12 @@ impl ActiveSphinxKeys {
|
||||
primary: SphinxPrivateKey,
|
||||
secondary: Option<SphinxPrivateKey>,
|
||||
) -> Self {
|
||||
todo!()
|
||||
// ActiveSphinxKeys {
|
||||
// inner: Arc::new(ActiveSphinxKeysInner {
|
||||
// primary_key: ArcSwap::from_pointee(primary),
|
||||
// secondary_key: ArcSwapOption::from_pointee(secondary),
|
||||
// }),
|
||||
// }
|
||||
ActiveSphinxKeys {
|
||||
inner: Arc::new(ActiveSphinxKeysInner {
|
||||
primary_key: ArcSwap::from_pointee(primary),
|
||||
secondary_key: ArcSwapOption::from_pointee(secondary),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn even(&self) -> Option<SphinxKeyGuard> {
|
||||
|
||||
@@ -6,7 +6,6 @@ use crate::node::key_rotation::manager::SphinxKeyManager;
|
||||
use crate::node::nym_apis_client::NymApisClient;
|
||||
use crate::node::replay_protection::manager::ReplayProtectionBloomfiltersManager;
|
||||
use futures::pin_mut;
|
||||
use nym_node_metrics::NymNodeMetrics;
|
||||
use nym_task::ShutdownToken;
|
||||
use nym_validator_client::models::{KeyRotationInfoResponse, KeyRotationState};
|
||||
use std::time::Duration;
|
||||
@@ -14,7 +13,7 @@ use time::OffsetDateTime;
|
||||
use tokio::time::{interval, sleep, Instant};
|
||||
use tracing::{error, info, trace, warn};
|
||||
|
||||
struct RotationConfig {
|
||||
pub(crate) struct RotationConfig {
|
||||
epoch_duration: Duration,
|
||||
rotation_state: KeyRotationState,
|
||||
}
|
||||
@@ -78,20 +77,24 @@ enum KeyRotationActionState {
|
||||
impl KeyRotationController {
|
||||
pub(crate) fn new(
|
||||
config: &Config,
|
||||
rotation_config: RotationConfig,
|
||||
client: NymApisClient,
|
||||
replay_protection_manager: ReplayProtectionBloomfiltersManager,
|
||||
metrics: NymNodeMetrics,
|
||||
managed_keys: SphinxKeyManager,
|
||||
shutdown_token: ShutdownToken,
|
||||
) -> Self {
|
||||
todo!()
|
||||
// KeyRotationController {
|
||||
// regular_polling_interval,
|
||||
// replay_protection_manager,
|
||||
// client,
|
||||
// managed_keys,
|
||||
// shutdown_token,
|
||||
// }
|
||||
KeyRotationController {
|
||||
regular_polling_interval: config
|
||||
.mixnet
|
||||
.key_rotation
|
||||
.debug
|
||||
.rotation_state_poling_interval,
|
||||
rotation_config,
|
||||
replay_protection_manager,
|
||||
client,
|
||||
managed_keys,
|
||||
shutdown_token,
|
||||
}
|
||||
}
|
||||
|
||||
async fn determine_next_action(&self) -> NextAction {
|
||||
@@ -234,7 +237,7 @@ impl KeyRotationController {
|
||||
polling_interval.reset();
|
||||
|
||||
let mut next_action = self.determine_next_action().await;
|
||||
let mut state_update_future = sleep(next_action.until_deadline());
|
||||
let state_update_future = sleep(next_action.until_deadline());
|
||||
pin_mut!(state_update_future);
|
||||
|
||||
while !self.shutdown_token.is_cancelled() {
|
||||
|
||||
@@ -180,7 +180,7 @@ impl SphinxKeyManager {
|
||||
// immediately rotate keys (but leave 1h grace period for current primary, i.e. set it as secondary)
|
||||
if primary.rotation_id() != current_rotation_id {
|
||||
warn!("this node has been inactive for more than a key rotation duration. the current primary key was generated for rotation {} while the current rotation is {current_rotation_id}. new key will be generated now.", primary.rotation_id());
|
||||
let mut this = SphinxKeyManager {
|
||||
let this = SphinxKeyManager {
|
||||
keys: ActiveSphinxKeys::new_loaded(primary, None),
|
||||
primary_key_path: primary_key_path.as_ref().to_path_buf(),
|
||||
secondary_key_path: secondary_key_path.as_ref().to_path_buf(),
|
||||
|
||||
@@ -1003,11 +1003,13 @@ impl NymNode {
|
||||
replay_protection_manager: ReplayProtectionBloomfiltersManager,
|
||||
) -> Result<(), NymNodeError> {
|
||||
let managed_keys = self.take_managed_sphinx_keys()?;
|
||||
let rotation_state = nym_apis_client.get_key_rotation_info().await?;
|
||||
|
||||
let rotation_controller = KeyRotationController::new(
|
||||
&self.config,
|
||||
rotation_state.into(),
|
||||
nym_apis_client,
|
||||
replay_protection_manager,
|
||||
self.metrics.clone(),
|
||||
managed_keys,
|
||||
self.shutdown_manager.clone_token("key-rotation-controller"),
|
||||
);
|
||||
|
||||
@@ -210,7 +210,7 @@ impl ReplayProtectionBloomfilters {
|
||||
})?;
|
||||
|
||||
let id = guard.primary.metadata.rotation_id;
|
||||
let bytes = guard.primary.data.to_bytes();
|
||||
let bytes = guard.primary.bytes();
|
||||
Ok((bytes, id))
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ impl ReplayProtectionBloomfilters {
|
||||
};
|
||||
|
||||
let id = secondary.metadata.rotation_id;
|
||||
let bytes = secondary.data.to_bytes();
|
||||
let bytes = secondary.bytes();
|
||||
Ok(Some((bytes, id)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use nym_crypto::asymmetric::x25519;
|
||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
|
||||
use nym_sphinx_framing::codec::{NymCodec, NymCodecError};
|
||||
use nym_sphinx_framing::packet::FramedNymPacket;
|
||||
use nym_sphinx_params::PacketSize;
|
||||
use nym_sphinx_params::{PacketSize, SphinxKeyRotation};
|
||||
use nym_sphinx_routing::generate_hop_delays;
|
||||
use nym_sphinx_types::constants::{
|
||||
EXPANDED_SHARED_SECRET_HKDF_INFO, EXPANDED_SHARED_SECRET_HKDF_SALT,
|
||||
@@ -101,6 +101,7 @@ pub(crate) struct ThroughputTestingClient {
|
||||
listener: TcpListener,
|
||||
forward_connection: Framed<TcpStream, NymCodec>,
|
||||
payload_key: PayloadKey,
|
||||
key_rotation: SphinxKeyRotation,
|
||||
}
|
||||
|
||||
fn rederive_lioness_payload_key(shared_secret: &[u8; 32]) -> PayloadKey {
|
||||
@@ -195,6 +196,12 @@ impl ThroughputTestingClient {
|
||||
}
|
||||
};
|
||||
|
||||
let key_rotation = if loaded_private.is_even_rotation() {
|
||||
SphinxKeyRotation::EvenRotation
|
||||
} else {
|
||||
SphinxKeyRotation::OddRotation
|
||||
};
|
||||
|
||||
Ok(ThroughputTestingClient {
|
||||
stats,
|
||||
last_received_update: Instant::now(),
|
||||
@@ -210,6 +217,7 @@ impl ThroughputTestingClient {
|
||||
listener,
|
||||
forward_connection: Framed::new(forward_connection, NymCodec),
|
||||
payload_key,
|
||||
key_rotation,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -256,8 +264,13 @@ impl ThroughputTestingClient {
|
||||
packet_bytes.append(&mut payload_bytes);
|
||||
|
||||
let forward_packet = NymPacket::sphinx_from_bytes(&packet_bytes)?;
|
||||
todo!()
|
||||
// Ok(FramedNymPacket::new(forward_packet, Default::default()))
|
||||
// let key_rotation = if self.s
|
||||
|
||||
Ok(FramedNymPacket::new(
|
||||
forward_packet,
|
||||
Default::default(),
|
||||
self.key_rotation,
|
||||
))
|
||||
}
|
||||
|
||||
async fn send_packets(&mut self) -> anyhow::Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user