Compare commits

..

4 Commits

Author SHA1 Message Date
Jędrzej Stuczyński 2cc99b486e being VERY explicit about loading coconut keys 2023-12-14 10:09:52 +00:00
Jędrzej Stuczyński 556d980c01 fixed node indexing 2023-12-14 09:27:39 +00:00
Jędrzej Stuczyński b86ae7520e hardcoded migration data 2023-12-14 09:05:47 +00:00
Jędrzej Stuczyński 43da0e3aa7 ignore dkg 2023-12-14 08:30:49 +00:00
32 changed files with 209 additions and 264 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release --features wireguard
args: --workspace --release
- name: Upload Artifact
uses: actions/upload-artifact@v3
@@ -51,7 +51,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release --features wireguard
args: --workspace --release
- name: Prepare build output
shell: bash
Generated
-1
View File
@@ -7572,7 +7572,6 @@ dependencies = [
"nym-network-defaults",
"nym-task",
"nym-wireguard-types",
"serde",
"tokio",
"x25519-dalek 2.0.0",
]
@@ -275,10 +275,6 @@ impl NymApiClient {
Ok(self.nym_api.get_gateways().await?)
}
pub async fn get_all_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError> {
Ok(self.nym_api.get_all_gateways().await?)
}
pub async fn get_cached_described_gateways(
&self,
) -> Result<Vec<DescribedGateway>, ValidatorClientError> {
@@ -79,11 +79,6 @@ pub trait NymApiClientExt: ApiClient {
.await
}
async fn get_all_gateways(&self) -> Result<Vec<GatewayBond>, NymAPIError> {
self.get_json(&[routes::API_VERSION, routes::GATEWAYS_ALL], NO_PARAMS)
.await
}
async fn get_gateways_described(&self) -> Result<Vec<DescribedGateway>, NymAPIError> {
self.get_json(
&[routes::API_VERSION, routes::GATEWAYS, routes::DESCRIBED],
@@ -6,7 +6,6 @@ use nym_network_defaults::NYM_API_VERSION;
pub const API_VERSION: &str = NYM_API_VERSION;
pub const MIXNODES: &str = "mixnodes";
pub const GATEWAYS: &str = "gateways";
pub const GATEWAYS_ALL: &str = "gateways/all";
pub const DESCRIBED: &str = "described";
pub const DETAILED: &str = "detailed";
-63
View File
@@ -81,15 +81,6 @@ ExitPolicy accept6 *6:119
ExitPolicy accept *4:120
ExitPolicy reject6 [FC00::]/7:*
# Portless
ExitPolicy accept *:0
ExitPolicy accept *4:0
ExitPolicy accept *6:0
ExitPolicy reject *:0
ExitPolicy reject *4:0
ExitPolicy reject *6:0
#ExitPolicy accept *:8080 #and another comment here
ExitPolicy reject FE80:0000:0000:0000:0202:B3FF:FE1E:8329:*
@@ -193,60 +184,6 @@ ExitPolicy reject *:*
},
);
// ExitPolicy accept *:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy accept *4:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::V4Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy accept *6:0
expected.push(
Accept,
AddressPortPattern {
ip_pattern: IpPattern::V6Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *4:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::V4Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy reject *6:0
expected.push(
Reject,
AddressPortPattern {
ip_pattern: IpPattern::V6Star,
ports: PortRange::new_zero(),
},
);
// ExitPolicy FE80:0000:0000:0000:0202:B3FF:FE1E:8329:*
expected.push(
Reject,
+14 -37
View File
@@ -264,13 +264,7 @@ mod stringified_ip_pattern {
impl AddressPortPattern {
/// Return true iff this pattern matches a given address and port.
pub fn matches(&self, addr: &IpAddr, port: u16) -> bool {
// For backward compatibility, we treat port 0 as a wildcard until all gateways have
// upgraded, at which point we can add *:0 to the policy list.
if port == 0 {
self.ip_pattern.matches(addr)
} else {
self.ip_pattern.matches(addr) && self.ports.contains(port)
}
self.ip_pattern.matches(addr) && self.ports.contains(port)
}
/// As matches, but accept a SocketAddr.
@@ -401,9 +395,19 @@ fn parse_addr(s: &str) -> Result<IpAddr, PolicyError> {
})
}
/// Helper: try to parse a port making sure it's non-zero
fn parse_port(s: &str) -> Result<u16, PolicyError> {
s.parse::<u16>()
.map_err(|_| PolicyError::InvalidPort { raw: s.to_string() })
let port = s
.parse::<u16>()
.map_err(|_| PolicyError::InvalidPort { raw: s.to_string() })?;
if port == 0 {
Err(PolicyError::InvalidPort {
raw: port.to_string(),
})
} else {
Ok(port)
}
}
impl FromStr for IpPattern {
@@ -490,10 +494,6 @@ impl PortRange {
PortRange::new_unchecked(1, 65535)
}
pub fn new_zero() -> Self {
PortRange { start: 0, end: 0 }
}
/// Create a new PortRange.
///
/// The Portrange contains all ports between `start` and `end` inclusive.
@@ -574,7 +574,6 @@ mod test {
check("marzipan:80");
check("1.2.3.4:90-80");
check("1.2.3.4:0-80");
check("1.2.3.4/100:8888");
check("[1.2.3.4]/16:80");
check("[::1]/130:8888");
@@ -613,22 +612,6 @@ mod test {
check("0.0.0.0/0:*", &["127.0.0.1:80"], &["[f00b::]:80"]);
check("[::]/0:*", &["[f00b::]:80"], &["127.0.0.1:80"]);
check(
"*:0",
&["1.2.3.4:0", "[::1]:0", "9.0.0.0:0"],
&["1.2.3.4:443", "[::1]:500", "9.0.0.0:80", "[::1]:80"],
);
check(
"*4:0",
&["1.2.3.4:0", "9.0.0.0:0"],
&["1.2.3.4:443", "9.0.0.0:80", "[::1]:0", "[::1]:80"],
);
check(
"*6:0",
&["[::1]:0"],
&["[::1]:80", "1.2.3.4:0", "1.2.3.4:443"],
);
}
#[test]
@@ -637,7 +620,6 @@ mod test {
policy.push(AddressPolicyAction::Accept, "*:443".parse()?);
policy.push(AddressPolicyAction::Accept, "[::1]:80".parse()?);
policy.push(AddressPolicyAction::Reject, "*:80".parse()?);
policy.push(AddressPolicyAction::Accept, "*:0".parse()?);
let policy = policy; // drop mut
assert!(policy
@@ -658,9 +640,6 @@ mod test {
assert!(policy
.allows_sockaddr(&"127.0.0.1:66".parse().unwrap())
.is_none());
assert!(policy
.allows_sockaddr(&"127.0.0.1:0".parse().unwrap())
.unwrap());
Ok(())
}
@@ -693,6 +672,7 @@ mod test {
assert_eq!("*".parse::<PortRange>().unwrap(), PortRange::new_all());
assert!("hello".parse::<PortRange>().is_err());
assert!("0".parse::<PortRange>().is_err());
assert!("65536".parse::<PortRange>().is_err());
assert!("65537".parse::<PortRange>().is_err());
assert!("1-2-3".parse::<PortRange>().is_err());
@@ -700,9 +680,6 @@ mod test {
assert!("1-".parse::<PortRange>().is_err());
assert!("-2".parse::<PortRange>().is_err());
assert!("-".parse::<PortRange>().is_err());
assert_eq!("0".parse::<PortRange>().unwrap(), PortRange::new_zero(),);
assert!("0-1".parse::<PortRange>().is_err());
}
#[test]
-1
View File
@@ -22,5 +22,4 @@ log.workspace = true
nym-network-defaults = { path = "../network-defaults" }
nym-task = { path = "../task" }
nym-wireguard-types = { path = "../wireguard-types" }
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util"] }
+11 -10
View File
@@ -9,12 +9,13 @@ use nym_wireguard_types::registration::GatewayClientRegistry;
use std::sync::Arc;
// Currently the module related to setting up the virtual network device is platform specific.
use crate::setup::PeerPair;
#[cfg(target_os = "linux")]
use crate::setup::{peer_static_pairs, PRIVATE_KEY};
use crate::setup::{peer_allowed_ips, peer_static_public_key, PRIVATE_KEY};
use defguard_wireguard_rs::WGApi;
#[cfg(target_os = "linux")]
use defguard_wireguard_rs::{InterfaceConfiguration, WireguardInterfaceApi};
use defguard_wireguard_rs::{
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WireguardInterfaceApi,
};
#[cfg(target_os = "linux")]
use nym_network_defaults::{WG_PORT, WG_TUN_DEVICE_ADDRESS};
@@ -23,7 +24,6 @@ use nym_network_defaults::{WG_PORT, WG_TUN_DEVICE_ADDRESS};
pub async fn start_wireguard(
mut task_client: nym_task::TaskClient,
_gateway_client_registry: Arc<GatewayClientRegistry>,
peer_pairs: Vec<PeerPair>,
) -> Result<WGApi, Box<dyn std::error::Error + Send + Sync + 'static>> {
let ifname = String::from("wg0");
let wgapi = WGApi::new(ifname.clone(), false)?;
@@ -36,11 +36,13 @@ pub async fn start_wireguard(
peers: vec![],
};
wgapi.configure_interface(&interface_config)?;
let peers = peer_static_pairs(peer_pairs);
for peer in peers.iter() {
wgapi.configure_peer(peer)?;
}
wgapi.configure_peer_routing(&peers)?;
let peer = peer_static_public_key();
let mut peer = Peer::new(Key::new(peer.to_bytes()));
let peer_ip = peer_allowed_ips();
let peer_ip_mask = IpAddrMask::new(peer_ip.network_address(), peer_ip.netmask());
peer.set_allowed_ips(vec![peer_ip_mask]);
wgapi.configure_peer(&peer)?;
wgapi.configure_peer_routing(&[peer.clone()])?;
tokio::spawn(async move { task_client.recv().await });
@@ -50,7 +52,6 @@ pub async fn start_wireguard(
pub async fn start_wireguard(
_task_client: nym_task::TaskClient,
_gateway_client_registry: Arc<GatewayClientRegistry>,
_peer_pairs: Vec<PeerPair>,
) -> Result<WGApi, Box<dyn std::error::Error + Send + Sync + 'static>> {
todo!("WireGuard is currently only supported on Linux")
}
+26 -38
View File
@@ -1,11 +1,7 @@
use std::net::IpAddr;
use base64::{engine::general_purpose, Engine as _};
use defguard_wireguard_rs::host::Peer;
use defguard_wireguard_rs::key::Key;
use defguard_wireguard_rs::net::IpAddrMask;
use log::{info, warn};
use serde::Deserialize;
use log::info;
// The wireguard UDP listener
pub const WG_ADDRESS: &str = "0.0.0.0";
@@ -14,23 +10,21 @@ pub const WG_ADDRESS: &str = "0.0.0.0";
// Corresponding public key: "WM8s8bYegwMa0TJ+xIwhk+dImk2IpDUKslDBCZPizlE="
pub(crate) const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg=";
#[derive(Deserialize, Debug)]
pub struct PeerPair {
pub addr: String,
pub public_key: String,
}
// The AllowedIPs for the connected peer, which is one a single IP and the same as the IP that the
// peer has configured on their side.
const ALLOWED_IPS: &str = "10.1.0.2";
fn decode_base64_key(base64_key: &str) -> Result<[u8; 32], String> {
fn decode_base64_key(base64_key: &str) -> [u8; 32] {
general_purpose::STANDARD
.decode(base64_key)
.map_err(|_| String::from("Could not decode"))?
.unwrap()
.try_into()
.map_err(|_| String::from("Not enough bytes"))
.unwrap()
}
pub fn server_static_private_key() -> x25519_dalek::StaticSecret {
// TODO: this is a temporary solution for development
let static_private_bytes: [u8; 32] = decode_base64_key(PRIVATE_KEY).unwrap();
let static_private_bytes: [u8; 32] = decode_base64_key(PRIVATE_KEY);
let static_private = x25519_dalek::StaticSecret::from(static_private_bytes);
let static_public = x25519_dalek::PublicKey::from(&static_private);
info!(
@@ -40,29 +34,23 @@ pub fn server_static_private_key() -> x25519_dalek::StaticSecret {
static_private
}
pub fn peer_static_pairs(raw_pairs: Vec<PeerPair>) -> Vec<Peer> {
raw_pairs
.into_iter()
.filter_map(|pair| {
if let Ok(peer_static_public_bytes) = decode_base64_key(&pair.public_key) {
let peer_static_public = x25519_dalek::PublicKey::from(peer_static_public_bytes);
let mut peer = Peer::new(Key::new(peer_static_public.to_bytes()));
pub fn peer_static_public_key() -> x25519_dalek::PublicKey {
// A single static public key is used during development
if let Ok(key) = pair.addr.parse::<IpAddr>() {
let peer_ip = ip_network::IpNetwork::new_truncate(key, 32u8)
.expect("Netmask should be correct");
let peer_ip_mask =
IpAddrMask::new(peer_ip.network_address(), peer_ip.netmask());
peer.set_allowed_ips(vec![peer_ip_mask]);
Some(peer)
} else {
warn!("Not adding {:?} as IP doesn't parse", pair);
None
}
} else {
warn!("Not adding {:?} as public key doesn't decode", pair);
None
}
})
.collect()
// Read from NYM_PEER_PUBLIC_KEY env variable
let peer = std::env::var("NYM_PEER_PUBLIC_KEY").expect("NYM_PEER_PUBLIC_KEY must be set");
let peer_static_public_bytes: [u8; 32] = decode_base64_key(&peer);
let peer_static_public = x25519_dalek::PublicKey::from(peer_static_public_bytes);
info!(
"Adding wg peer public key: {}",
general_purpose::STANDARD.encode(peer_static_public)
);
peer_static_public
}
pub fn peer_allowed_ips() -> ip_network::IpNetwork {
let key: IpAddr = ALLOWED_IPS.parse().unwrap();
let cidr = 32u8;
ip_network::IpNetwork::new_truncate(key, cidr).unwrap()
}
+85 -4
View File
@@ -10,19 +10,22 @@ use crate::dealings::transactions::try_commit_dealings;
use crate::epoch_state::queries::{
query_current_epoch, query_current_epoch_threshold, query_initial_dealers,
};
use crate::epoch_state::storage::CURRENT_EPOCH;
use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD};
use crate::epoch_state::transactions::{advance_epoch_state, try_surpassed_threshold};
use crate::error::ContractError;
use crate::state::{State, MULTISIG, STATE};
use crate::verification_key_shares::queries::query_vk_shares_paged;
use crate::verification_key_shares::storage::vk_shares;
use crate::verification_key_shares::transactions::try_commit_verification_key_share;
use crate::verification_key_shares::transactions::try_verify_verification_key_share;
use cosmwasm_std::{
entry_point, to_binary, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response,
entry_point, to_binary, Addr, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response,
Timestamp,
};
use cw4::Cw4Contract;
use nym_coconut_dkg_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use nym_coconut_dkg_common::types::{Epoch, EpochState};
use nym_coconut_dkg_common::types::{Epoch, EpochId, EpochState, TimeConfiguration};
use nym_coconut_dkg_common::verification_key::ContractVKShare;
/// Instantiate the contract.
///
@@ -127,7 +130,85 @@ pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result<QueryResponse,
}
#[entry_point]
pub fn migrate(_deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
pub fn migrate(deps: DepsMut<'_>, env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
CURRENT_EPOCH.save(
deps.storage,
&Epoch {
state: EpochState::InProgress,
epoch_id: 0,
time_configuration: TimeConfiguration {
public_key_submission_time_secs: 999999,
dealing_exchange_time_secs: 999999,
verification_key_submission_time_secs: 999999,
verification_key_validation_time_secs: 999999,
verification_key_finalization_time_secs: 999999,
in_progress_time_secs: 999999,
},
finish_timestamp: env.block.time.plus_days(10000),
},
)?;
let apis = [
"https://qa-nym-api-coconut1.qa.nymte.ch/api",
"https://qa-nym-api-coconut2.qa.nymte.ch/api",
"https://qa-nym-api-coconut3.qa.nymte.ch/api",
"https://qa-nym-api-coconut-6.qa.nymte.ch/api",
"https://qa-nym-api-coconut-7.qa.nymte.ch/api",
"https://qa-nym-api-coconut-8.qa.nymte.ch/api",
"https://qa-nym-api-coconut-9.qa.nymte.ch/api",
"https://qa-nym-api-coconut-10.qa.nymte.ch/api",
"https://qa-nym-api-coconut-11.qa.nymte.ch/api",
"https://qa-nym-api-coconut-12.qa.nymte.ch/api",
];
let addresses = [
Addr::unchecked("n1e6wkf0x2l4qt45uwkft9t7fs3ka02rsmft5jjn"),
Addr::unchecked("n190f6rwtcpfgx3y84af6eapg54suehd4nzq4sh3"),
Addr::unchecked("n1c7nu7wncuru09eg2m8429d5ff6umytet993xmf"),
Addr::unchecked("n144fypmxc9jrdk28qrjlptpqn7h077f30vvvdjf"),
Addr::unchecked("n15rmhp3psrnlcgp8tsa9y528ppwt0vvwuazfa4a"),
Addr::unchecked("n18dy35dtsg7ycyp7g9pvlj29ksmjpu9h6tznxdl"),
Addr::unchecked("n17usrtqe6ypvn3r4v05sspu3ufs30uykc7euwne"),
Addr::unchecked("n1efpvtu5x7x4v293pc42a2fwkf265lnh05r023z"),
Addr::unchecked("n15k2zadxm7m3wyfyx7g2uk2tctmmp43syxuqmdf"),
Addr::unchecked("n1k4w8pp62htn0tdmrsv3gh9kzrap4tpalw8eqd7"),
];
let keys = [
"ANFuTGQ2AVgbgaUCuYW7QZS8heTZjvJgPY8Xw3ekYRFsAq9uWJmSPctB7Qp5XCHsVk4yLF9CHr5YypWMy47kiMR8nrwVjS6Du2Ek2kCpjZTYEqMFfQqgS3YgYKrN2BYwgko2T9tx3SgCgeN7w7aWpypYPRNVDcVJ17GetAor4NGiKBSBboT4Y2WPLoDhqAmjwpeoSHTip2T3Wt9mQAcUv88my4cM8UwSEcF7P69h5nRaFxZ5ZGdofrcju9CrM2yjher5av25idSwFrfHWaqqP1dJcK4XbuSLczVvYYMaUkBsMD4w9fcdCkLeDu3sd3yv8doBiYXzWSve5QKvYKTqELbebuqimVnL7YkXPuksb482hUh5HVMsfW2Mw4jigSG1p42XsYpuLVEpKB7479Dn4pG4yL9iATkycg6myA6yQKVA42ztbtoqg3cbkLDZG1LFm4rLpWoc6BqkucRKPNRZx4xn8ZzXfuQqso11h1DLurDuWSrCVcxmSYQ5zCMGmEeeKpBLvVsmopptHr4dVrQLeG5RZqWhXEviGjHMLBYwRS6ffZVeB4yPATXroPtXTCgiYj9PpXhfTkeDkQLiEAWBXb7xPioXhcGBBfCs7JSSRGKdQFQHwCQpCFdTsmsAmurwqrmu8TnrSh6simDfUDSukWhxY5R5Q8oN2x9w8QoGiUgdiAuP68LvvdXPEuSMzdVXGZKGv5p9k5LsqRiU4MnmjGdGQjfThZzZz9zZKZJC8GEHVmRapz2StkFTFGqk3MxEZmw9G2PYKyQiMkkGcSx27opRJuKgrVY5u7yKcUnaW7u5AKXNoEYSUQwhzsHzuxL3GpCEqT7WpbBfT1NBuL2nshV69wCCGXdB4Jc7d3sa7vRfNRGtcP3guRwtkJyRehJkUYXApG1HKwNkLnVXYCbey9MqyckB3ZVG3",
"ARAqwgaJv5nqGVjHymhMM1UUZj8YdWYDjUTNepBJefRfTyaHAsHs2yyazEGV4r4cYt5cXQgFVPQxFYAodPLfWcjXYZ72QVdrNrwQWju2kpeManXUrTQpNouyvc5XNhPN7ZiV4cTfPqowj7QtZC83AJhwVX7FkdQD5YzyZijB5FuvP96hG8CttidBq19ChUEDpVxN6zas3yBAs2R1kFcXBnK2mpXRYUj6Tx3LfV6FgDi8KU6upaggwyqmCsN4KYW3DPZsXy33kDx6T15fc3SfM7HWcyz3WS4c6uuCZtBYPZHz1TbJJQhxx22iS581oqj1yUVQqyKYyeRFh88XXS7oeMejBCnmqj99HuBQquwCRbViDbQoR74sPCWviFREQjLPHQK4jrKUsJNCyedSfo9es5ANA7pNDFokEfbg4RwoibZtk1nSMy9PwLjVsGMnBSzdNDTSzMVKtmdGgFEWQHLa8vhMpJvEW2tAbYq1inJwYYGTT1zgZGiMCNrcHh93j1YvXMdRKeScaWBKqMZ6TB24349CcdU34Uh4grYMnHchfzm66fYqC4FrzdPs8KuyQ2qrpCE3aGkFPrngzMbtkPJTAAsujeRnGm5U88PTEP9e9axa8zus2ab9RArhXA6jVHYo7b8rBACfYFfQwQRVeZd6NnPHbzdRh5KpM6YjKV9jx6LmsRQtWUbfokFUbPhHDsftuYxB7p3GJdnPABqkTZPLuuEBgs62dK2BD4r1PSQsSiLeSeR6CPdEPJ8hibRU5FV9qmvnivVjZdbnfEb8DuAnPADxUvfstsp4NFwjPj6DpGo7TASzYNitSuoXffwpTKNcQYDLygPFbzoymrzBLjKrMNj7cY9Y8DGBAXQ8CHNcrbzsZi56KXYyk4LBBEeGKuL9s6bU9K6UpXgSbFQMDHAodVPdHaXGi6aUv",
"9kCmPfjfAXZyES7T8m4PQ1RXEowa7raooGcyPUCYxCCMo798ZdRvj9mdmX9PVgZWttbsWUDgywDA5uC1WqJLPVDmbuwowZ8pP3QTkM4bBwThBvY4Ureoq3Zw5QZhJCwsH7oRpYU1TXd8eAuv4a8oALZCiNPLPB1CYpxFxxB2Hxs4DxKVaSfMqvKLu8n11K1GRFpAYjFAEuDrgTQA63n8QwDdKuYrxcbQcbuiYsnsocheVLUcmZdKdXPACZXd8yufq4qcwdGqokVmQSxUMwEFVCu49skYnrvuTckSefTHFApTT7RqpzczcCADtyPAfYu3FBgxCNMUJ9EgZGLMp24LiLBPY4BNSb98Cu7frhWueefhFicLVBbUnLuBQ9oDh9dRqit944NLg1Vfj53yBEkoqZxH5NTd6sUJztS14ieJzLhkfpbJ7a6C4EaXA2hx4ziHipPFENNPg9vvq1q1rDSN336CwYrsKQhoPaSJs7apPWJfRLHw3vqJLhkHExDBGgGzh5vfCw7qvxxcC8f7FjpWNiQxcNzcqSCgNrsbiRBhqxiYjJixN1C5uMkYm2JcfyufgnRA8MzXPfPTNQMMY2dYAw5WfVhAc4VNRiSdPF5dCcP8H4ejg5q9KZgChgrTSHVWxNa7HfRSFSXoFeh1VJVAMyL1p1tNmW2ax2Cjhiq5r1wWXAaCYTgtrLxuTyZCUuNtzz5ZXjgynJsRyuLmRypTV1ior1AeLQsvU4DqfD8dLW3QeurZfxSzEkoKPknQeM4BAyDnA3iDsVsAUh2KCq3UZJanaJB8EWvirxK7K4E1CWTWNR4966gsCgoexvRaT7SFZTy6vVn3joCkpm7NUFgSW3dN8CV4iijpkMehhP822btLPXV21chUT8mStc6gbrnF2kzJJeGkcWFpAUqtpUBFTM7EKZSuzdddf",
"AVmJTFnQNqiMV8Fe3WNvUdRK6E285aKrhD2VjvH3SzRr8oQyzZsuZCAdeQXiiZAp8rcjWCQqDZoevVcP1V68Y2TFC61bCkJoVTvRzK26ij9GhX43sNLx1gdGvPUPVgNfnF1A9z94m2WevRm8wkq7tPyVtx2izhrSKyoc7sPSh57rX5oSwYRBALnmBjZVUjESTV32nEgFgDUH1UX3sh2LB2fAh91DDqcWC8oGJzwURfuU2jSkXmVr1BfXgRxeu6AX8W7GJKJ6qwQQ5XhtT5Hpk6fjNHUHC42qLLc8LWiFEZKULrkEY42tuEquBJrJgMT73tt73MN7L7LDzx6BW8xYQoMiC3TogPTqpJbFGCpKy9A9GM2xzYVGQMA7q8Y5jvjHLHGYcq4o3unGTLkpQAfrYZaxMUPmXWL4vEgRxDTjuwDAD3dTx46pX8iytwzGmWR2e2J1Qa6nqPsipGskuroMxmvfxcdTnf2Fu5wpEnRhFB1Tb65sN6PivKTXDyjD8iiPA5PgdvoNxJ1hR2sJYbaQxKFM3kLxSLRT42DrWJ3oqPpit3aHNoL4uDpBS8fMeB3xNkdz1K66QCPhPZHt1QQq7WjXjFL9N4DYULrEeN9TQHuEV2dEZ5RjyypRVzcXtuGqJAZAtFbLYxdNiiafmxJd5LZWbp13ZDoNV4z5FcsGcMKxMhUvVUtpEirQi58R3dZ4fhkbkdcy8yUmSmNMQxnRViPoiSfxWhKn5anvvbWScAQdefy56JgMP8JYn74iR3T2WdBFCdKAuSnKJfoWRhkHJLQemYeAHERgJBAYQsrv1HatRfa9qs1eMtn5fbWzBqgkAFQHBvSdVjzmY4SAzoucmB6scvSbCh48PAgDr1sBWCHFpGJQUvoELAEV6nTtVs85aMRJZbU7S4muv6xwNWm2RyL5Y9hDyuY8n",
"8KsXTBGHT8Hq2TShNFqpXC9h5Z2gduvGhybDD4n8K8zGEgNwkHgQtCYyVEWwghGjHifyCdEBgb8tsoTN3ppWd7o3H7bnz1Rm7pFhgW8nAWJi2vH67XNEzi9hRvqFWNUpTAkUF2CLvVZN181i6iXaHezQmzm3xk6kndCfzpepCdmSW1EQkAL3pPE4dDTXzig1jECLp1T9dcmutTsXzcACqJwcQVeiUgfffrYm3BUTg1BjXV5QCM5ndfHYcjdK7dDLB6Pfbiy6CZLh2yPiaxGAzB1KAn6eN9WBg58eWmZ4s1L85JwArSvBk7G7mjfQiwww8qDzyF7TJEanaK7tL24hhkv3WmrCSs1TBGh1YmBWYhwMNJrj5q7T4UnLAjaTL7yYuaJSa1kasagLniDDBYkmCUJs6wuQdxqoxdxn6dEo1jaaNZnsc8XtPcNGMEaoje5j5ARCDGk1B9477HvNzandhzrSBiBZhE2i89FgaUQdFBLH34UAWFo9szuZNRT9Tna8F86WEHCYbU1HAQShDsVYMkL3yYnc9m1CehB1TC3CMgMEj7p3Ma7PqtYQWjGZqRPo6s3xyUYQFKhM1QjUnr68k64KX6ejTkbNaDgNLisQwK2eJKjBwxDZFQQoqTeLH18QhVg4ju5VMYegjbzw8F8btyu6Er3UpnSqT1R8BWZvBkbqmadGCRXHM4t51GFf824LRZvGMtdrvRNQNjq6oTLeJ4PwvagCWxpxcdhtbfWRr9f3mr8xyJH2jYnxgbFecgZh2y2DeCATsm7kLfF6LvYFioUHWHitYUTAe4pNKgUT6pghY1hq5cP8h1cPrCdLykutBEMPQCGRpJPbKqd8fZBTSebSH4vSTzHQQZwfZCPRqg3FSS7XbK7YukUBT1JLjX9VSuU7MZ84ka6yr8u5ivQmUCnYgyjU1q9CC",
"8iy5uKH1444RXi1meR3DziSXhPYU9DKowBc42qbNCcenRvxNvivEdPTxuzjPa37ruwShBP7dyyGHxdtPL23PhAcx4k5azP2RQBezpURFkVtaYZeZc9Ww4tgSRwcz1Em7sWmY7NsuaNT7WHf7SKaSCitzuzs1FJX26kynJa86CeiripRBZHNDNmCRb5GkpNTvQ6XPsrioMhqzq1BQkS58h76qo7bVm9GrQg3ZbnXmnWaFfUruUfQBGBRx6JFuDvJNCpQGddhTk4uhYj48WG2uvSPqwVMXfQjwpUuoQcengL6ZXR5t7bkAi3jNsiKP3kewVWsJabBYqGtvtHtk6mikYwq2MMSfeu82HthzGQohawutLuicottsyC7xHRqRr622QhGNrra7xv4fh6EeAgJkrH2FGfknpuo7LbygGjDdhvy9L3JswAGz1xZGqstpxKDjonMvDB3jbbF2PhcZ1YCwFgmVHEKKpdPSpgxudo3swSfWYMNURmUPEZ7aEsV11t7a4ueLTBYTsAW7WwrB7YwCdB2EuiBJwMWiBioTov9LTyeF57Eoznse8xcpG4Teyy5QHDYVzvgUG5uAtzsGRqHE9xRjXDmBgasD6d6zxPNbZah11UzKqHF4D1SYudDbcztHD7RPir9mXR8mvrM6odRrcmnRQ16J3w6UShsemRaNqfYoU2dgLhbrXEMgsjzST4xcTJ4ChVfMNpH837cDoyHwZ8NUVAvmTgTipyNNnxNCti3JfCGLyy5gW5vo5BGM7BfPbtQCranuQRVH6AWUPWxe4DhhRwcCNJtsPFsTn44E7KHqt773Frd9u3NX6s4558azbf7r3QeJ2ub1B555iLSx4i6v1hpMmz5TPtbhD8fafvbRbSJBHhKF3yt2fsGTedoYovbWsMe6hEmZmEdN4AxnFGvF2qg4mtvcA",
"8tiA2WBGaqsosaL1e2Ukus5YDiddfuqnKSdDTasdhB7yrjthdwfHCvLHiZX5HeMz7ZQWvQHhZzqimPVQkABJVWRH4wMtv1FXAjnyQ48CwWbXYZNPEXJpC35RXaixQBa8F4bYsusHNyyDAtdEveKV3trq5bjthdNsbYwCoYYnDDSMRMPggg64PTrBUVeS8pNWTarWe8uDc9ABN9wnhN7fsMBNyza6WKHkN7dvU3Zaytd4EZXcaPyRL1rRpMP2k8KC3gBtz3CZNQEgjZd4j2sA5DM2KYLi7aGJSG5LWrxRF8Ze9AzvJbLeTELTQYbHtr3RSqQkEQGANoJf8cqZZ6Ngdq5cCxj5PWixDQjcYey8jsTRzXcRo4gQZwjhmVBvqb1w7qnnY2kpxx95iAGGzfs2ivbbPo1EfVCrFGhdmMbXwLwrbCqcqHUweTk7x4ucC3XjP2XqCf6xu7M52YQXbKnst5i5aN4MgpNBogCVd7Q15dr2rJt1juJhp65LozSQrPfXWo3AX2p95eJe4mxaS1XcgN9cZVsMvxLFRpsFxBxx2NaWqrU5jFCo56AeBLP2qsEJgxmv9BG7hZLnZ7xshYjgM5uyt9xkBiUycL5huLjVCDrW2qnX9TZwYjqXum9pyTkhrLJPugsf8DHjmjvvJJxtssqZjoQwPU2j6DoZREjyyp5dNNFiL8L2rkoXNbT9KwdStbmKjBWXEKazMPdYJgs5Gi5wnwNvywo9UbPKbomkdZBF9edRwBWRHpfFo1jo1EQMRhrPgj54Cg8sqWebcaWBBifFDAcRkXxGJhQd2DVeHRWgXXQyWgcftW44CCQV5qD7FX5GbBjvsLWoPjcs3qYPQC8NVuRNaAitB4SwuCHQriLxYmBRTktoSeJ5M5n82N8h6o3ChoYxKbB8jpX2xxgo36j7BjKztDTZy",
"AVv8vjCkXVsQNLkDCxMNYib7kgisTajfQE55NENySPUH2qgFq3mN43dww86rcgHgAhs87gjYjJbebZeGWn6JcUgdY2KCuNofmF38qf56rV9ax8xiy28jNrtqxZFXhZgqAzN9X7ncDThwEVCiHiPmHEcbVcXw3if7ozbNVqEZyc7kF2kSKF4xwtK1GpQ1av7WTPwyByM5Ti24DdBrgKu7iiTMRDtbExiyjJjVvK84yXkhEZui4VvM9aMTocNJByuku5TkM2kjnu1r1Fb8ByRiu6nPe9nWbz5CVfcLNURtTQD4o65dopDzip5KcJuGVeAgjQYQP3Y2iEht3Gk3m5SsEkbrfe1nhCtYschcQxEv4fwqCeqSmUJbaRqqzXMfQSHJcSCYg98rMJ72CKRjeNN6vdY4xx8LSDJz5MDVvwaF6er5DR3jfQw5iYXiV8a6PY2ipm7kf9qGE8dMAXfopH3QqC9hQh3jNXiSr76QjGft2NZLNcm6xS51wwM12w9eGWwbDRxD7nvm6ANFf9jtH3Ctp8T34NbqzDK6hkeUmmSCvu3kqM8RcdLTBw2f4BKZ3S5ffR8Dz5ZnxsT9i72XgbKykdyfBBGEkdvutyzXmjEGTHEgp859zd14LKpsNChwqwwjmRttEn6HMgVuQU7p3vDvmkHpMVMH7Ae1oPwFSivVAi6w4a9jDV7oPns8ffMK2v4kK8rbpYApFDm2dBGZXwVQMmcRoSXBzX3yHCBCbWFbahH6a9edxopxsBmk5fkAiPw9TK3bCtSs53d2GpArb2vixzGufLxX5gWTQ4iRd9c9sLaSVgHsYAY2oSUqBmKczhKdBnacZUN7Eidqmgay8e8Ty96crFf2iNeTnYhgqLKZw8kdM2KQNyXXdpU1QtmL9S5noC2ibhDqvE7PSDe6K6z16jFfUroRtRyB9",
"9vS4jyKJ9XKi5NuaDfysRWPjiJNLMhtsWicNkd3jFmMJUT2E3oUhqZkKd3zQaAoJEsT5QkreQE49SiQmbYKgWx5KHpbRv36AEs9abDtJD3Vzie9aKGMnrxVBMsu8E4H8FbHY91cNHZ64JAt8hKcAR131CBZMGnG4JctHNnz9yk9ynkeakx9TWvsRJpPWzxnowy1aUGnBGALxvjNsee4SPcY2TvmUKtkkjrgEGxZRfqyM3YnNPZVr2RLWQ4oeMMCPojFqzgNfdtGjg3Mns82sokNwMN8ZGpX1cxKWCp92gg8cmuPruythtu4j1MWQR2AsnT963Pp4H2CdsHBbv8KFPBSaS9SWnGwyG9xibbfK8RtdoGK4xxrhM2DdJP5Qpxu8e3nYwknVMYNHKfJjhupAtDHbrJscJQm2NqHJDw9kLjfGCwYYLVDxx7NLnqUNSKn13Lc4BJmwSyYUP9YdMYgkMwfscGRrtZGRwUAPY5rPcd6Tde7X43GCib87bFx1UpypafBdbQjfthRmZthggL84hZapNbfHwFZu5ttZAV6FUy1jYJ2ByMkFF45QPRz4BJZRzZVWLDzdP6QCrf7S1TifYEtcGdMN2mHZDfkc8NGFy6jGgg8ULRd1vPTco6fzXjqZJf5gXY6xGfTimBuZBwTqS43qyLGtahCq2Ue51hcWqi8x6mSS9pZukDVthQEAbWmNs3U3NSErpYd25iQtGwbJVrYr4XY1TbPGHN1L3HftQJcUerSWughCzp85PY1yBzM8E2t9DAo4cEK8vvwCmbbHLnwrhXfNLYHvrdpsziVprEz3yRBcRqcYaSaaNkd5DYwzp8UqnE6eS11grHhUgd2VVuaTgpmgcbCjBUhqET25aJ5w7Lwy7xMhNdF4HePwbEiqnAWqKk6bQhFqndmB7UKVnRwSi55iVN5KK",
"8vi5eKGVaSjNKx27tf4ncS7WiZNeeXeBvwHWVbiAW1gDjtbtT8tnFaGBUiNz9bDB4Shr1YcGz8gGeFCsv7GZgbP9rEM96dQnPPXH3draEqyVw8ZwzwvosZai3UXBYqBaWQQFEvk48XKJbowwPzNtERR3G2qNdViag1k8Pp841Nw7Dz6cLNsenQ3uH67d52tVNsqqvSwsPMBbd2xjRbCEbXWUc8UFqK3V2cU2koLFRc79fJPACys3ymKYqCsoKDL1xDBarpXumKVV4H8WKPC3coSG4RbaT9eMYeaYqp3Kct2nLzWP3xrFJpZRKNR2Y5fXSsbqZLS7XdfAV624p9YRA2TWsZfdQekoQADzMnoZyVjp7pHapmh2aY4xg853GrCfsCq7JXiFprxTruWqKy3xkcmv6yTAvC7vVkyczVpqyBbZ9atQtn34QELzYWXmq9tojcWgg2m5687z6mRBAjboxmYVJ7YskM1i7vrgHes2bsy4WM76zST2wiHMGiBcDvJsWj1f6VefjZm93BWqyTEJwpEBWKUFjqAEB3XmK8xeKCvQPFkVc8WBLjDosGoAXE584SfbWYdrQi2Bwb4aWGgSmmYUmAUkvnhmWA2RFqm6jjZKJsSHwn9qegcknPAnRVAGi3eLLtNpTZ3W7GehSjWse5KKBPWJyDtDR9qtLvkiwd7upQvYy5qyMeJhS3WbpVxcPQc1qPSJs4nVpDJMY2Qm1SCNVETPn5jAb4gQA81MuRsmdy9LmX3RwLYGLPznvCuHNTB8zis72cj2SKX2RygAR9cMjFutQkuGhsqMyiPx69UWAsnqhgSU5xcn2X1ex4gaA3vwaWJSSsJ17SpDAsxiJKKYUFSXNArwJ7w17dDGuQwikev8x2LeDqgvFvepyeqn1Hz3bR2JdP41A2MEoQDEM7WjwsJdTZKLJ",
"9sokmCXUBroQ161SoMrPJPpU6B1jQjCfzx6aVfUKZqutCzBCZX1D6S3AMjzPKJo3dGcNN9jYVTSHR8K1qzsuq7B7T9FDuqjHSu4mSptNNo7a4mRiE7xc1C3k5PH48z86j8DYedJS7khM21mrPrAShBNG8yVM8reRWKuVjrNJBT3aUFD7psjNXhRVSL74YJx8ECf8sNAL2i8jGDC5mgZkKWx5tTXADLgZZSRPTTcjztWEFXTgWUcjr8UnedKgNa3C8NNRLyxmPXVEjh3LQEDPsFejHARJPRi1TgG8yTo9jXoe7wsWoptQpQjeDBZC3DthzJ8RBNcYNY5DhdC3aUpPEVRs3DE4XsEWNTkJYHcFAMGbFYckjMaAtrCSCm9ePGg8ywYSANutHb9cCyboSqhsPXxbe6cf2g8obTkJVqWtrykQhY2YajBPs6bpXj8pmay2DwKTKtREyNyspzufXH5VPypsmJg8Zicy5Jy57YJgfanJaEgCEhor5F6k5CN54ZSmKWnap6Pks7KmTpJdoJxqpLxTGXfMd6FJxdqQ5rXB9S4Fb9xtQQAiZ9STeXvGQaMxpCdwVgBw9oXYLpq8DT9VEgYNWoTuTtLLHQZrKj7ToUYpPvKvrXAzifBjETMvvsogoUnXKCQA33WGv2wASXPpoynvWzbr9W96hkeJucrofXBdYDVowzQCCQACwdFzTFz2on37iCx95McgEZg2B2wwE49RQ7bTSXC9L1zj3LetZu9eEiZ2UgZsc7JCV1E8E4k6rdC8euz1cRZHvQ1RgF4cyB3MgHwSCHKyukoUk1humpB7ftLpYaq6y7qRBuPnWqCxGcjGo6rfpRmJt8aNSNDVXZGAhpFWUVsnvWqpVSSwrZuK26n18rMPkufYkXpAQ1yptszkb1yodZU6e9aQaLB9uNAoiQJiE8mR2",
"9ft11E8rkGmYbFYppZrFpjh2akPDTgcexV5RiMnGsU1ekr7GJvicVSBniEmAKHzAvbpbQhgSpydrFwE8sxpVvH3cqqbWx6htPmtv3GxDWHVp4J9o32egWPgmNGBmtH1SxRJiKhCdNmW7gKCEAqymDQhM2YDvFVdtXoSrpyM5kBxqkjQhvRGUVkeerxEmuFHB1QGjzV1k1zc77wRoKoWeN4ZpdUBQ4PCDdJ5jgtTefj4DLbvLxJAioSQf9Ef38sjrerfEhoh5N3upgMVJuBEwUxyk7B8TZ41SMUtva45cR7hDfLJUCbem6QTPxs1ADxDRSjrvYuzJE4RxWow8Hrp6hz42B13YgAkZ9cqMp1S9JMzEuzBCdzm8vPyjbZkfNAQqiGVA21o6m4BUTCseanAziDsakrsDZZAMpC4X8Tjm3AaUNQP2rBz4nb6ZkQVPUUQB5AvXqh5zupKfzYNV5WUK4EvzN8YknwVh11ckdw3JKCo5Kk1rhguz4gaCqg2mYZNoJdf4zjSwsRaHrWRXJdEhXQKZQxaWwNPEQbK2amfPoC7ungEXMiwQei1wSC1p1TY6FZTnekYwuYBtDRCyiNqXJwvv4WRfuJCykLjBHomrhKhR3hoYPD3DcynQWWdanHiFVE9rQQQKYv7UJQ8gELu9CCSrUgt5LDmPGhSMvYbfUzCofWvMSjhsRPiwheqLp3sEr2fNfssNZ382ZpKDdQPCaDnQhi7naLfuAp5gyo7rZC3QYUhhM2bbEaPRYGixhWf7uv6q8j6RR2u7sQnqemjdSsJnRfe6r5DwAuWxNkTm2sPUJ8pmvjfT6WLHkq8PmcrD4vNGQK8SGBRbaTweTckig1ri8WMN5JY8UbGkMkCtJxZWPqAq8rvyZf1agvEDHeKHf2u5ZTBEqGtLFyNrgziM2YCURQLLTW87b",
];
for (i, ((address, api), key)) in addresses
.iter()
.zip(apis.iter())
.zip(keys.iter())
.enumerate()
{
let share = ContractVKShare {
share: key.to_string(),
announce_address: api.to_string(),
node_index: (i + 1) as u64,
owner: address.clone(),
epoch_id: 0,
verified: true,
};
vk_shares().save(deps.storage, (address, 0), &share)?;
}
THRESHOLD.save(deps.storage, &7)?;
Ok(Default::default())
}
+6 -7
View File
@@ -51,7 +51,7 @@
- [Querying the Chain](tutorials/cosmos-service/querying.md)
- [Typescript](tutorials/typescript.md)
- [Simple Service Provider](tutorials/simple-service-provider/simple-service-provider.md)
- [[DEPRECATED] Simple Service Provider](tutorials/simple-service-provider/simple-service-provider.md)
- [Tutorial Overview](tutorials/simple-service-provider/overview.md)
- [Preparing Your User Client Environment](tutorials/simple-service-provider/preparating-env.md)
- [Building Your User Client](tutorials/simple-service-provider/user-client.md)
@@ -59,12 +59,11 @@
- [Building Your Service Provider](tutorials/simple-service-provider/service-provider.md)
- [Sending a Message Through the Mixnet](tutorials/simple-service-provider/sending-message.md)
[//]: # (TODO make generic )
[//]: # (# Shipyard Builders Hackathon 2023 )
[//]: # (- [General Info & Resources]&#40;shipyard/general.md&#41;)
[//]: # (- [Hackathon Challenges]&#40;shipyard/challenges-overview.md&#41;)
[//]: # (- [A Note on Infrastructure]&#40;shipyard/infra.md&#41;)
[//]: # (- [Submission Guidelines]&#40;shipyard/guidelines.md&#41;)
# Shipyard Builders Hackathon 2023
- [General Info & Resources](shipyard/general.md)
- [Hackathon Challenges](shipyard/challenges-overview.md)
- [A Note on Infrastructure](shipyard/infra.md)
- [Submission Guidelines](shipyard/guidelines.md)
# Events
@@ -61,8 +61,7 @@ Quite a bit of stuff gets built. The key working parts are:
* [network requester](../nodes/network-requester.md): `nym-network-requester`
* [nym-cli tool](../tools/nym-cli.md): `nym-cli`
* [nym-api](https://nymtech.net/operators/nodes/nym-api.html): `nym-api`
[//]: # (* [nymvisor]&#40;https://nymtech.net/operators/nodes/nymvisor-upgrade.html&#41;: `nymvisor`)
* [nymvisor](https://nymtech.net/operators/nodes/nymvisor-upgrade.html): `nymvisor`
The repository also contains Typescript applications which aren't built in this process. These can be built by following the instructions on their respective docs pages.
* [Nym Wallet](../wallet/desktop-wallet.md)
+2 -2
View File
@@ -4,9 +4,9 @@ This is Nym's technical documentation, containing information and setup guides a
If you are new to Nym and want to learn about the Mixnet, explore kickstart options and demos, learn how to integrate with the network, and follow developer tutorials check out the [Developer Portal](https://nymtech.net/developers/) where you can find also our [FAQ section](https://nymtech.net/developers/faq/general-faq.html).
If you are looking for information and setup guides for the various pieces of Nym Mixnet infrastructure (Mix Nodes, Gateways and Network Requesters) and Nyx blockchain validators see the [Operators Guides](https://nymtech.net/operators) book.
If you are looking for information and setup guides for the various pieces of Nym Mixnet infrastructure (Mix Nodes, Gateways and Network Requesters) and Nyx blockchain validators see the **new [Operators Guides](https://nymtech.net/operators)** book.
If you're specifically looking for TypeScript/JavaScript related information such as SDKs to build your own tools, step-by-step tutorials, live playgrounds and more - check out the [TS SDK Handbook](https://sdk.nymtech.net/).
If you're specifically looking for TypeScript/JavaScript related information such as SDKs to build your own tools, step-by-step tutorials, live playgrounds and more - make sure to check out the **new [TS SDK Handbook](https://sdk.nymtech.net/)** !
## Popular pages
**Network Architecture:**
+1 -2
View File
@@ -20,8 +20,7 @@
- [Nym API Setup](nodes/nym-api.md)
- [Maintenance](nodes/maintenance.md)
- [Manual Node Upgrade](nodes/manual-upgrade.md)
[//]: # ( - [Automatic Node Upgrade: Nymvisor Setup and Usage]&#40;nodes/nymvisor-upgrade.md&#41;)
- [Automatic Node Upgrade: Nymvisor Setup and Usage](nodes/nymvisor-upgrade.md)
- [Troubleshooting](nodes/troubleshooting.md)
# FAQ
@@ -62,8 +62,7 @@ Quite a bit of stuff gets built. The key working parts are:
* [network requester](../nodes/network-requester-setup.md): `nym-network-requester`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
* [nym-api](../nodes/nym-api.md): `nym-api`
[//]: # (* [nymvisor]&#40;../nodes/nymvisor-upgrade.md&#41;: `nymvisor`)
* [nymvisor](../nodes/nymvisor-upgrade.md): `nymvisor`
The repository also contains Typescript applications which aren't built in this process. These can be built by following the instructions on their respective docs pages.
* [Nym Wallet](https://nymtech.net/docs/wallet/desktop-wallet.html)
-5
View File
@@ -242,11 +242,6 @@ impl Config {
self
}
pub fn with_client_keys_path(mut self, client_keys: PathBuf) -> Self {
self.wireguard.storage_paths.client_keys = client_keys;
self
}
pub fn with_listening_address(mut self, listening_address: IpAddr) -> Self {
self.gateway.listening_address = listening_address;
+1 -1
View File
@@ -130,7 +130,7 @@ impl From<ConfigV1_1_31> for Config {
announced_port: value.wireguard.announced_port,
private_network_prefix: Default::default(),
storage_paths: nym_node::config::persistence::WireguardPaths {
client_keys: Default::default(),
// no fields (yet)
},
},
storage_paths: GatewayPaths {
+1 -4
View File
@@ -207,10 +207,7 @@ impl<St> Gateway<St> {
&self,
shutdown: TaskClient,
) -> Result<WGApi, Box<dyn Error + Send + Sync>> {
let file = std::fs::File::open(&self.config.wireguard.storage_paths.client_keys)?;
let reader = std::io::BufReader::new(file);
let peers = serde_json::from_reader(reader)?;
nym_wireguard::start_wireguard(shutdown, Arc::clone(&self.client_registry), peers).await
nym_wireguard::start_wireguard(shutdown, Arc::clone(&self.client_registry)).await
}
fn start_client_websocket_listener(
+19 -17
View File
@@ -57,14 +57,14 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
&config.storage_paths.decryption_key_path,
&config.storage_paths.public_key_with_proof_path,
))?;
if let Ok(coconut_keypair_value) =
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
&config.storage_paths.secret_key_path,
&config.storage_paths.verification_key_path,
))
{
coconut_keypair.set(Some(coconut_keypair_value)).await;
}
// if let Ok(coconut_keypair_value) =
// nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
// &config.storage_paths.secret_key_path,
// &config.storage_paths.verification_key_path,
// ))
// {
// coconut_keypair.set(Some(coconut_keypair_value)).await;
// }
let persistent_state =
PersistentState::load_from_file(&config.storage_paths.dkg_persistent_state_path)
.unwrap_or_default();
@@ -186,15 +186,17 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
}
pub(crate) async fn run(mut self, mut shutdown: TaskClient) {
let mut interval = interval(self.polling_rate);
while !shutdown.is_shutdown() {
tokio::select! {
_ = interval.tick() => self.handle_epoch_state().await,
_ = shutdown.recv() => {
trace!("DkgController: Received shutdown");
}
}
}
warn!("ignoring the dkg epochs!");
shutdown.mark_as_success();
// let mut interval = interval(self.polling_rate);
// while !shutdown.is_shutdown() {
// tokio::select! {
// _ = interval.tick() => self.handle_epoch_state().await,
// _ = shutdown.recv() => {
// trace!("DkgController: Received shutdown");
// }
// }
// }
}
// TODO: can we make it non-async? it seems we'd have to modify `coconut_keypair.set(coconut_keypair_value)` in new
+8
View File
@@ -80,6 +80,14 @@ async fn start_nym_api_tasks(
let network_details = NetworkDetails::new(connected_nyxd.to_string(), nym_network_details);
let coconut_keypair = coconut::keypair::KeyPair::new();
let keys = nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
&config.coconut_signer.storage_paths.secret_key_path,
&config.coconut_signer.storage_paths.verification_key_path,
))
.expect("failed to load coconut keys");
coconut_keypair.set(Some(keys)).await;
info!("set coconut keys");
// let's build our rocket!
let rocket = http::setup_rocket(
@@ -146,7 +146,7 @@ impl PacketPreparer {
let initialisation_backoff = Duration::from_secs(30);
loop {
let gateways = self.validator_cache.gateways_all().await;
let mixnodes = self.validator_cache.mixnodes_all_basic().await;
let mixnodes = self.validator_cache.mixnodes_basic().await;
if gateways.len() < minimum_full_routes {
self.topology_wait_backoff(initialisation_backoff).await;
@@ -179,21 +179,12 @@ impl PacketPreparer {
async fn all_mixnodes_and_gateways(&self) -> (Vec<MixNodeBond>, Vec<GatewayBond>) {
info!("Obtaining network topology...");
let mixnodes = self.validator_cache.mixnodes_all_basic().await;
let mixnodes = self.validator_cache.mixnodes_basic().await;
let gateways = self.validator_cache.gateways_all().await;
(mixnodes, gateways)
}
async fn filtered_mixnodes_and_gateways(&self) -> (Vec<MixNodeBond>, Vec<GatewayBond>) {
info!("Obtaining network topology...");
let mixnodes = self.validator_cache.mixnodes_filtered_basic().await;
let gateways = self.validator_cache.gateways_filtered().await;
(mixnodes, gateways)
}
pub(crate) fn try_parse_mix_bond(&self, mix: &MixNodeBond) -> Result<mix::Node, String> {
let identity = mix.mix_node.identity_key.clone();
mix.try_into().map_err(|_| identity)
@@ -217,7 +208,7 @@ impl PacketPreparer {
n: usize,
blacklist: &mut HashSet<String>,
) -> Option<Vec<TestRoute>> {
let (mixnodes, gateways) = self.filtered_mixnodes_and_gateways().await;
let (mixnodes, gateways) = self.all_mixnodes_and_gateways().await;
// separate mixes into layers for easier selection
let mut layered_mixes = HashMap::new();
for mix in mixnodes {
+13 -14
View File
@@ -182,20 +182,19 @@ impl NymContractCache {
}
}
pub async fn mixnodes_filtered_basic(&self) -> Vec<MixNodeBond> {
self.mixnodes_filtered()
.await
.into_iter()
.map(|bond| bond.bond_information)
.collect()
}
pub async fn mixnodes_all_basic(&self) -> Vec<MixNodeBond> {
self.mixnodes_all()
.await
.into_iter()
.map(|bond| bond.bond_information)
.collect()
pub async fn mixnodes_basic(&self) -> Vec<MixNodeBond> {
match time::timeout(Duration::from_millis(100), self.inner.read()).await {
Ok(cache) => cache
.mixnodes
.clone()
.into_iter()
.map(|bond| bond.bond_information)
.collect(),
Err(err) => {
error!("{err}");
Vec::new()
}
}
}
pub async fn gateways_filtered(&self) -> Vec<GatewayBond> {
-1
View File
@@ -19,7 +19,6 @@ pub(crate) fn nym_contract_cache_routes(settings: &OpenApiSettings) -> (Vec<Rout
settings: routes::get_mixnodes,
routes::get_mixnodes_detailed,
routes::get_gateways,
routes::get_all_gateways,
routes::get_active_set,
routes::get_active_set_detailed,
routes::get_rewarded_set,
-6
View File
@@ -114,12 +114,6 @@ pub async fn get_blacklisted_gateways(
}
}
#[openapi(tag = "contract-cache")]
#[get("/gateways/all")]
pub async fn get_all_gateways(cache: &State<NymContractCache>) -> Json<Vec<GatewayBond>> {
Json(cache.gateways_all().await.clone())
}
#[openapi(tag = "contract-cache")]
#[get("/epoch/reward_params")]
pub async fn get_interval_reward_params(
+1 -1
View File
@@ -119,7 +119,7 @@ impl StorageManager {
r#"
SELECT
d.identity as "identity: String",
CASE WHEN count(*) > 3 THEN AVG(reliability) ELSE 100 END as "value: f32"
AVG(reliability) as "value: f32"
FROM
gateway_details d
JOIN
+1 -3
View File
@@ -93,9 +93,7 @@ impl Default for Wireguard {
),
announced_port: DEFAULT_WIREGUARD_PORT,
private_network_prefix: DEFAULT_WIREGUARD_PREFIX,
storage_paths: persistence::WireguardPaths {
client_keys: PathBuf::from("/root/keys_pub.json"),
},
storage_paths: persistence::WireguardPaths {},
}
}
}
+1 -2
View File
@@ -2,10 +2,9 @@
// SPDX-License-Identifier: GPL-3.0-only
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct WireguardPaths {
pub client_keys: PathBuf,
// pub keys:
}
@@ -35,7 +35,7 @@ impl MyTopologyProvider {
})
.collect::<Vec<_>>();
let gateways = self.validator_client.get_all_gateways().await.unwrap();
let gateways = self.validator_client.get_cached_gateways().await.unwrap();
nym_topology_from_detailed(filtered_mixnodes, gateways)
}
@@ -1,4 +1,4 @@
use std::net::{IpAddr, SocketAddr};
use std::net::SocketAddr;
pub use nym_client_core::error::ClientCoreError;
use nym_exit_policy::PolicyError;
@@ -57,15 +57,9 @@ pub enum IpPacketRouterError {
#[error("the provided socket address, '{addr}' is not covered by the exit policy!")]
AddressNotCoveredByExitPolicy { addr: SocketAddr },
#[error("the provided ip address, '{ip}' is not covered by the exit policy!")]
IpNotCoveredByExitPolicy { ip: IpAddr },
#[error("failed filter check: '{addr}'")]
AddressFailedFilterCheck { addr: SocketAddr },
#[error("failed filter check: '{ip}'")]
IpFailedFilterCheck { ip: IpAddr },
#[error("failed to apply the exit policy: {source}")]
ExitPolicyFailure {
#[from]
@@ -1,7 +1,4 @@
use std::{
collections::HashMap,
net::{IpAddr, SocketAddr},
};
use std::{collections::HashMap, net::IpAddr};
use futures::StreamExt;
use nym_ip_packet_requests::{
@@ -323,11 +320,15 @@ impl MixnetListener {
}
// Filter check
let dst = dst.unwrap_or_else(|| SocketAddr::new(dst_addr, 0));
if !self.request_filter.check_address(&dst).await {
log::info!("Denied filter check: {dst}");
// TODO: we could consider sending back a response here
return Err(IpPacketRouterError::AddressFailedFilterCheck { addr: dst });
if let Some(dst) = dst {
if !self.request_filter.check_address(&dst).await {
log::warn!("Failed filter check: {dst}");
// TODO: we could consider sending back a response here
return Err(IpPacketRouterError::AddressFailedFilterCheck { addr: dst });
}
} else {
// TODO: we should also filter packets without port number
log::warn!("Ignoring filter check for packet without port number! TODO!");
}
// TODO: consider changing from Vec<u8> to bytes::Bytes?