Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/localnet #3951

Merged
merged 4 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion clients/socks5/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ pub(crate) struct Init {
nyxd_urls: Option<Vec<url::Url>>,

/// Comma separated list of rest endpoints of the API validators
#[clap(long, alias = "api_validators", value_delimiter = ',')]
#[clap(
long,
alias = "api_validators",
value_delimiter = ',',
group = "network"
)]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,

Expand Down
54 changes: 54 additions & 0 deletions scripts/build_topology.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import json
import os.path
import sys


def add_mixnode(base_network, base_dir, mix_id):
with open(os.path.join(base_dir, "mix" + str(mix_id) + ".json"), "r") as json_blob:
mix_data = json.load(json_blob)
base_network["mixnodes"][str(mix_id)][0]["identity_key"] = mix_data["identity_key"]
base_network["mixnodes"][str(mix_id)][0]["sphinx_key"] = mix_data["sphinx_key"]
base_network["mixnodes"][str(mix_id)][0]["mix_port"] = mix_data["mix_port"]
base_network["mixnodes"][str(mix_id)][0]["version"] = mix_data["version"]
base_network["mixnodes"][str(mix_id)][0]["host"] = mix_data["bind_address"]
base_network["mixnodes"][str(mix_id)][0]["layer"] = mix_id
base_network["mixnodes"][str(mix_id)][0]["mix_id"] = mix_id
base_network["mixnodes"][str(mix_id)][0]["owner"] = "whatever"
return base_network


def add_gateway(base_network, base_dir):
with open(os.path.join(base_dir, "gateway.json"), "r") as json_blob:
gateway_data = json.load(json_blob)
base_network["gateways"][0]["identity_key"] = gateway_data["identity_key"]
base_network["gateways"][0]["sphinx_key"] = gateway_data["sphinx_key"]
base_network["gateways"][0]["mix_port"] = gateway_data["mix_port"]
base_network["gateways"][0]["clients_port"] = gateway_data["clients_port"]
# base_network["gateways"][0]["version"] = gateway_data["version"]
base_network["gateways"][0]["host"] = gateway_data["bind_address"]
base_network["gateways"][0]["owner"] = "whatever"
return base_network


def main(args):
base_network = {
"mixnodes": {
"1": [{}],
"2": [{}],
"3": [{}],
},
"gateways": [{}]
}

base_dir = args[0]
base_network = add_mixnode(base_network, base_dir, 1)
base_network = add_mixnode(base_network, base_dir, 2)
base_network = add_mixnode(base_network, base_dir, 3)
base_network = add_gateway(base_network, base_dir)

with open(os.path.join(base_dir, "network.json"), "w") as out:
json.dump(base_network, out, indent=2)


if __name__ == '__main__':
main(sys.argv[1:])
68 changes: 68 additions & 0 deletions scripts/localnet_start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash

set -o errexit

# can't just use `mktemp` since syntax differs between linux and macos (thx apple)
suffix=$(openssl rand -base64 10 | tr -dc 'a-zA-Z0-9')
localnetdir="$HOME/.nym/localnets/localnet.$suffix"
mkdir -p "$localnetdir"

echo "Using $localnetdir for the localnet"

# initialise mixnet
echo "initialising mixnode1..."
cargo run --release --bin nym-mixnode -- init --id "mix1-$suffix" --host 127.0.0.1 --mix-port 10001 --verloc-port 20001 --http-api-port 30001 --output=json >> "$localnetdir/mix1.json"

echo "initialising mixnode2..."
cargo run --release --bin nym-mixnode -- init --id "mix2-$suffix" --host 127.0.0.1 --mix-port 10002 --verloc-port 20002 --http-api-port 30002 --output=json >> "$localnetdir/mix2.json"

echo "initialising mixnode3..."
cargo run --release --bin nym-mixnode -- init --id "mix3-$suffix" --host 127.0.0.1 --mix-port 10003 --verloc-port 20003 --http-api-port 30003 --output=json >> "$localnetdir/mix3.json"

echo "initialising gateway..."
cargo run --release --bin nym-gateway -- init --id "gateway-$suffix" --host 127.0.0.1 --mix-port 10004 --clients-port 9000 --output=json >> "$localnetdir/gateway.json"

# build the topology
echo "combining json files..."
python3 build_topology.py "$localnetdir"

networkfile=$localnetdir/network.json
echo "the full network file is located at $networkfile"

# start up the mixnet
echo "starting the mixnet..."
tmux start-server

tmux new-session -d -s localnet -n Mixnet -d "/usr/bin/env sh -c \" cargo run --release --bin nym-mixnode -- run --id mix1-$suffix \""
tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-mixnode -- run --id mix2-$suffix \""
tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-mixnode -- run --id mix3-$suffix \""
tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-gateway -- run --id gateway-$suffix \""

echo "waiting for nym-gateway to launch on port 9000..."

while ! nc -z localhost 9000; do
sleep 2
done

echo "nym-gateway launched"

# initialise the clients
echo "initialising network requester..."
cargo run --release --bin nym-network-requester -- init --id "network-requester-$suffix" --open-proxy=true --custom-mixnet "$networkfile" --output=json >> "$localnetdir/network_requester.json"
address=$(jq -r .client_address "$localnetdir/network_requester.json")

echo "initialising socks5 client..."
cargo run --release --bin nym-socks5-client -- init --id "socks5-client-$suffix" --provider "$address" --custom-mixnet "$networkfile" --no-cover

# startup the clients
tmux new-window -t 1 -n 'Clients' -d "/usr/bin/env sh -c \" cargo run --release --bin nym-network-requester -- run --id network-requester-$suffix --custom-mixnet $networkfile \"; /usr/bin/env sh -i"
tmux split-window -t localnet:1 "/usr/bin/env sh -c \" cargo run --release --bin nym-socks5-client -- run --id socks5-client-$suffix --custom-mixnet $networkfile \"; /usr/bin/env sh -i"
tmux split-window -t localnet:1

# prepare the command to test the socks5
tmux send-keys -t localnet:1 "time curl -x socks5h://127.0.0.1:1080 https://test-download-files-nym.s3.amazonaws.com/download-files/1MB.zip --output /dev/null 2>&1"

tmux select-layout -t localnet:0 tiled
tmux select-layout -t localnet:1 tiled

tmux attach -tlocalnet
23 changes: 21 additions & 2 deletions service-providers/network-requester/src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ use nym_client_core::init::helpers::current_gateways;
use nym_client_core::init::types::GatewaySetup;
use nym_client_core::init::types::{GatewayDetails, GatewaySelectionSpecification};
use nym_crypto::asymmetric::identity;
use nym_sdk::mixnet::NymTopology;
use nym_sphinx::addressing::clients::Recipient;
use serde::Serialize;
use std::fmt::Display;
use std::path::PathBuf;
use std::{fs, io};
use tap::TapFallible;

Expand Down Expand Up @@ -62,10 +64,19 @@ pub(crate) struct Init {
nyxd_urls: Option<Vec<url::Url>>,

/// Comma separated list of rest endpoints of the API validators
#[arg(long, alias = "api_validators", value_delimiter = ',')]
#[arg(
long,
alias = "api_validators",
value_delimiter = ',',
group = "network"
)]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,

/// Path to .json file containing custom network specification.
#[clap(long, group = "network", hide = true)]
custom_mixnet: Option<PathBuf>,

/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[arg(long)]
Expand Down Expand Up @@ -173,7 +184,15 @@ pub(crate) async fn execute(args: &Init) -> Result<(), NetworkRequesterError> {
let details_store =
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);

let available_gateways = {
let available_gateways = if let Some(hardcoded_topology) = args
.custom_mixnet
.as_ref()
.map(NymTopology::new_from_file)
.transpose()?
{
// hardcoded_topology
hardcoded_topology.get_gateways()
} else {
let mut rng = rand::thread_rng();
current_gateways(&mut rng, &config.base.client.nym_api_urls).await?
};
Expand Down
11 changes: 10 additions & 1 deletion service-providers/network-requester/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
};
use clap::Args;
use log::error;
use std::path::PathBuf;

const ENABLE_STATISTICS: &str = "enable-statistics";

Expand Down Expand Up @@ -36,6 +37,10 @@ pub(crate) struct Run {
#[arg(long)]
enabled_credentials_mode: Option<bool>,

/// Path to .json file containing custom network specification.
#[clap(long, group = "network", hide = true)]
custom_mixnet: Option<PathBuf>,

/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[arg(long, hide = true, conflicts_with = "medium_toggle")]
Expand Down Expand Up @@ -99,6 +104,10 @@ pub(crate) async fn execute(args: &Run) -> Result<(), NetworkRequesterError> {
}

log::info!("Starting socks5 service provider");
let server = crate::core::NRServiceProviderBuilder::new(config);
let mut server = crate::core::NRServiceProviderBuilder::new(config);
if let Some(custom_mixnet) = &args.custom_mixnet {
server = server.with_stored_topology(custom_mixnet)?
}

server.run_service_provider().await
}
Loading