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/wasm js demo #191

Merged
merged 10 commits into from
Apr 21, 2020
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
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ opt-level = "s"
[workspace]

members = [
"common/clients/directory-client",
"common/clients/mix-client",
"common/clients/multi-tcp-client",
"common/clients/provider-client",
"common/clients/validator-client",
"clients/desktop",
"clients/webassembly",
"common/client-libs/directory-client",
"common/client-libs/mix-client",
"common/client-libs/multi-tcp-client",
"common/client-libs/provider-client",
"common/client-libs/validator-client",
"common/config",
"common/crypto",
"common/healthcheck",
Expand All @@ -18,8 +20,6 @@ members = [
"common/topology",
"gateway",
"mixnode",
"nym-client",
"nym-sphinx-wasm",
"sfw-provider",
"sfw-provider/sfw-provider-requests",
"validator",
Expand Down
File renamed without changes.
22 changes: 11 additions & 11 deletions nym-client/Cargo.toml → clients/desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ tokio = { version = "0.2", features = ["full"] }
tokio-tungstenite = "0.10.1"

## internal
config = {path = "../common/config"}
crypto = {path = "../common/crypto"}
directory-client = { path = "../common/clients/directory-client" }
healthcheck = { path = "../common/healthcheck" }
mix-client = { path = "../common/clients/mix-client" }
multi-tcp-client = { path = "../common/clients/multi-tcp-client" }
nymsphinx = { path = "../common/nymsphinx" }
pemstore = {path = "../common/pemstore"}
provider-client = { path = "../common/clients/provider-client" }
sfw-provider-requests = { path = "../sfw-provider/sfw-provider-requests" }
topology = {path = "../common/topology" }
config = {path = "../../common/config"}
crypto = {path = "../../common/crypto"}
directory-client = { path = "../../common/client-libs/directory-client" }
healthcheck = { path = "../../common/healthcheck" }
mix-client = { path = "../../common/client-libs/mix-client" }
multi-tcp-client = { path = "../../common/client-libs/multi-tcp-client" }
nymsphinx = { path = "../../common/nymsphinx" }
pemstore = {path = "../../common/pemstore"}
provider-client = { path = "../../common/client-libs/provider-client" }
sfw-provider-requests = { path = "../../sfw-provider/sfw-provider-requests" }
topology = {path = "../../common/topology" }

[build-dependencies]
built = "0.3.2"
Expand Down
3 changes: 3 additions & 0 deletions clients/desktop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Nym Desktop Client

The Nym Desktop Client communicates with the remote, decentralised nodes which make up the Nym system as a whole.
File renamed without changes.
69 changes: 69 additions & 0 deletions clients/desktop/examples/chunking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2020 Nym Technologies SA
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use config::NymConfig;
use std::time;
use tokio::runtime::Runtime;

fn setup_logging() {
let mut log_builder = pretty_env_logger::formatted_timed_builder();
if let Ok(s) = ::std::env::var("RUST_LOG") {
log_builder.parse_filters(&s);
} else {
// default to 'Info'
log_builder.filter(None, log::LevelFilter::Info);
}

log_builder
.filter_module("hyper", log::LevelFilter::Warn)
.filter_module("tokio_reactor", log::LevelFilter::Warn)
.filter_module("reqwest", log::LevelFilter::Warn)
.filter_module("mio", log::LevelFilter::Warn)
.filter_module("want", log::LevelFilter::Warn)
.init();
}

fn main() {
// totally optional
setup_logging();

let mut rt = Runtime::new().unwrap();

// note: I have manually initialised the client with this config (because the keys weren't
// saved, etc - a really dodgy setup but good enough for a quick test)
// so to run it, you need to do the usual `nym-client init --id native-local`
// then optionally modify config.toml to increase rates, etc. if you want
let config = nym_client::config::Config::load_from_file(None, Some("native-local")).unwrap();
let mut client = nym_client::client::NymClient::new(config);

let input_data = std::fs::read("trailer.mp4").unwrap();

client.start();
let address = client.as_mix_destination();
client.send_message(address, input_data);

loop {
let mut messages = rt.block_on(async {
tokio::time::delay_for(time::Duration::from_secs(2)).await;
client.check_for_messages_async().await
});

if !messages.is_empty() {
assert_eq!(messages.len(), 1);
std::fs::write("downloaded.mp4", messages.pop().unwrap()).unwrap();
println!("done!");
std::process::exit(0);
}
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions nym-sphinx-wasm/Cargo.toml → clients/webassembly/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ slice_as_array = "1.1.0"
wasm-bindgen = "0.2"

# internal
crypto = { path = "../common/crypto" }
nymsphinx = { path = "../common/nymsphinx" }
crypto = { path = "../../common/crypto" }
nymsphinx = { path = "../../common/nymsphinx" }


# The `console_error_panic_hook` crate provides better debugging of panics by
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This is a Rust crate which is set up to automatically cross-compile the contents of `lib.rs` to WebAssembly (aka wasm).

Wasm is pretty close to bare metal. Browser-based or server-side JavaScript (or other wasm-using environments) can use the wasm output from this crate to create Sphinx packets at much higher speeds than would be possible using (interpreted) JavaScript. This helps browser-based and mobile applications get stronger privacy, in a way that wasn't previously possible.
Wasm is pretty close to bare metal. Browser-based or server-side JavaScript (or other wasm-using environments) can use the wasm output from this crate to create Sphinx packets at much higher speeds than would be possible using (interpreted) JavaScript. This enables browser-based and mobile applications get stronger privacy, in a way that wasn't previously possible.

### Compiling

Expand Down
30 changes: 30 additions & 0 deletions clients/webassembly/js-examples/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nym WebAssembly Demo</title>
</head>

<body>
<p>
<label for="fname">Recipient address: </label><input type="text" id="recipient" name="recipient"
value="HNka47Wji3LF23wGtU5oAFwoaM3tfbp2fBLGBPLcwUZ5">
</p>
<label for="fname">Text to send: </label><input type="text" id="sendtext" name="sendtext" value="Hello mixnet!">
<button id="send-button">Send</button>

<p>Send messages to the mixnet using the "send" button.</p>
<p><span style='color: blue;'>Sent</span> messages show in blue, <span style='color: green;'>received</span>
messages show in green.</p>

<hr>
<p>
<span id="output"></div>
</p>
<script src="./bootstrap.js"></script>

</body>

</html>
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

import * as wasm from "nym-sphinx-wasm";

console.log("Retrieving topology...");

class Route {
constructor(nodes) {
this.nodes = nodes;
Expand All @@ -29,50 +27,72 @@ class NodeData {
}
}

async function getTopology() {
let topologyURL = 'http://127.0.0.1:8080/api/presence/topology'; // TODO change this DAVE!!!!
let response = await makeRequest('get', topologyURL);
async function main() {
var gatewayUrl = "ws://127.0.0.1:1793";
var directoryUrl = "http://127.0.0.1:8080/api/presence/topology";

// Get the topology, then the mixnode and provider data
const topology = await getTopology(directoryUrl);

// Set up a websocket connection to the gateway node
var connection = await connectWebsocket(gatewayUrl).then(function (c) {
return c
}).catch(function (err) {
console.log("Websocket ERROR: " + err);
})

// Set up the send button
const sendButton = document.querySelector('#send-button');
sendButton.onclick = function () {
sendMessageToMixnet(connection, topology);
}
}

// Create a Sphinx packet and send it to the mixnet through the Gateway node.
function sendMessageToMixnet(connection, topology) {
let route = constructRoute(topology);
var recipient = document.getElementById("recipient").value;
var sendText = document.getElementById("sendtext").value;
let packet = wasm.create_sphinx_packet(JSON.stringify(route), sendText, recipient);
connection.send(packet);
displaySend(packet);
display("Sent a Sphinx packet containing message: " + sendText);
}

async function getTopology(directoryUrl) {
let response = await http('get', directoryUrl);
let topology = JSON.parse(response);
return topology;
}

async function main() {
// Get the topology, then the mixnode and provider data
const topology = await getTopology();
// Construct a route from the current network topology so we can get wasm to build us a Sphinx packet
function constructRoute(topology) {
const mixnodes = topology.mixNodes;
const provider = topology.mixProviderNodes[0];

// Construct a route so we can get wasm to build us a Sphinx packet
let nodes = [];
mixnodes.forEach(node => {
let n = new NodeData(node.host, node.pubKey);
nodes.push(n);
});
let p = new NodeData(provider.mixnetListener, provider.pubKey)
nodes.push(p);
let route = new Route(nodes);

// Create the packet
let packet = wasm.create_sphinx_packet(JSON.stringify(route), "THIS IS THE MESSAGE", "C2fdNoUybRuGrVYUM6QRejiELPQCohGbxjhKpU4UZ4ci");

// Set up a websocket connection to the gateway node
var port = "1793" // gateway websocket listens on 1793 by default, change if yours is different
var url = "ws://127.0.0.1:" + port;

connectWebsocket(url).then(function (server) {
server.send("hello gateway");
console.log(packet);
server.send(packet);
}).catch(function (err) {
console.log("Websocket ERROR: " + err);
})
return new Route(nodes);
}

// Let's get started!
main();

// utility functions below here, nothing too interesting...

function makeRequest(method, url) {
function display(message) {
document.getElementById("output").innerHTML = "<p>" + message + "</p >" + document.getElementById("output").innerHTML;
}

function displaySend(message) {
document.getElementById("output").innerHTML = "<p style='color: blue; word-break: break-all;'>sent >>> " + message + "</p >" + document.getElementById("output").innerHTML;
}

function http(method, url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
Expand All @@ -96,12 +116,6 @@ function makeRequest(method, url) {
});
}


function print(name, obj) {
console.log(name + ": " + JSON.stringify(obj));
}


function connectWebsocket(url) {
return new Promise(function (resolve, reject) {
var server = new WebSocket(url);
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions common/healthcheck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ tokio = { version = "0.2", features = ["full"] }

## internal
crypto = { path = "../crypto" }
directory-client = { path = "../clients/directory-client" }
multi-tcp-client = { path = "../clients/multi-tcp-client" }
directory-client = { path = "../client-libs/directory-client" }
multi-tcp-client = { path = "../client-libs/multi-tcp-client" }
nymsphinx = {path = "../nymsphinx" }
provider-client = { path = "../clients/provider-client" }
provider-client = { path = "../client-libs/provider-client" }
sfw-provider-requests = { path = "../../sfw-provider/sfw-provider-requests" }
topology = {path = "../topology" }

Expand Down
2 changes: 1 addition & 1 deletion gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ futures = "0.3"
futures-channel = "0.3"
futures-util = { version = "0.3", default-features = false, features = ["async-await", "sink", "std"] }
log = "0.4"
multi-tcp-client = { path = "../common/clients/multi-tcp-client" }
multi-tcp-client = { path = "../common/client-libs/multi-tcp-client" }
pretty_env_logger = "0.3"
tokio = { version = "0.2", features = ["full"] }
tokio-tungstenite = "0.10.1"
Expand Down
4 changes: 2 additions & 2 deletions mixnode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ tokio = { version = "0.2", features = ["full"] }
## internal
config = {path = "../common/config"}
crypto = {path = "../common/crypto"}
directory-client = { path = "../common/clients/directory-client" }
multi-tcp-client = { path = "../common/clients/multi-tcp-client" }
directory-client = { path = "../common/client-libs/directory-client" }
multi-tcp-client = { path = "../common/client-libs/multi-tcp-client" }
nymsphinx = {path = "../common/nymsphinx" }
pemstore = {path = "../common/pemstore"}
topology = {path = "../common/topology"}
Expand Down
2 changes: 1 addition & 1 deletion mixnode/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl MixNode {

if let Some(duplicate_node_key) = self.check_if_same_ip_node_exists() {
error!(
"Our announce-host is identical to one of existing nodes! (its key is {:?}",
"Our announce-host is identical to an existing node's announce-host! (its key is {:?}",
duplicate_node_key
);
return;
Expand Down
10 changes: 0 additions & 10 deletions nym-client/README.md

This file was deleted.

11 changes: 0 additions & 11 deletions nym-sphinx-wasm/www/index.html

This file was deleted.

4 changes: 2 additions & 2 deletions sfw-provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ hmac = "0.7.1"
## internal
crypto = { path = "../common/crypto" }
config = { path = "../common/config" }
directory-client = { path = "../common/clients/directory-client" }
directory-client = { path = "../common/client-libs/directory-client" }
nymsphinx = { path = "../common/nymsphinx" }
pemstore = { path = "../common/pemstore" }
sfw-provider-requests = { path = "./sfw-provider-requests" }
Expand All @@ -36,7 +36,7 @@ topology = { path = "../common/topology"}
# this dependency is due to requiring to know content of loop message. however, mix-client module itself
# is going to be removed or renamed at some point as it no longer servers its purpose of sending traffic to mix network
# and only provides utility functions
mix-client = { path = "../common/clients/mix-client" }
mix-client = { path = "../common/client-libs/mix-client" }


[build-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion sfw-provider/src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl ServiceProvider {

if let Some(duplicate_provider_key) = self.check_if_same_ip_provider_exists() {
error!(
"Our announce-host is identical to one of existing nodes! (its key is {:?}",
"Our announce-host is identical to an existing node's announce-host! (its key is {:?}",
duplicate_provider_key
);
return;
Expand Down
Loading