wip internal-dev

This commit is contained in:
Gala
2023-10-09 12:02:58 +02:00
committed by Jędrzej Stuczyński
parent 30294062af
commit d445a26999
10 changed files with 4876 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
build:
wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/credentials
wasm-opt -Oz -o ../../dist/wasm/credentials/nym_node_tester_wasm_bg.wasm ../../dist/wasm/credentials/nym_node_tester_wasm_bg.wasm
+2
View File
@@ -0,0 +1,2 @@
node_modules
dist
+5
View File
@@ -0,0 +1,5 @@
// A dependency graph that contains any wasm must all be imported
// asynchronously. This `bootstrap.js` file does the single async import, so
// that no one else needs to worry about it again.
import('./index.js')
.catch(e => console.error('Error importing `index.js`:', e));
+18
View File
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nym Credentials WebAssembly Demo</title>
<script src="bootstrap.js"></script>
</head>
<body>
<p>
Create here the demo
</p>
</body>
</html>
+173
View File
@@ -0,0 +1,173 @@
// Copyright 2020-2023 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.
class WebWorkerClient {
worker = null;
constructor() {
this.worker = new Worker('./worker.js');
this.worker.onmessage = (ev) => {
if (ev.data && ev.data.kind) {
switch (ev.data.kind) {
case 'Ready':
const {selfAddress} = ev.data.args;
displaySenderAddress(selfAddress);
break;
case 'ReceiveMessage':
const {message, senderTag, isTestPacket } = ev.data.args;
displayReceived(message, senderTag, isTestPacket);
break;
case 'DisplayString':
const { rawString } = ev.data.args;
displayReceivedRawString(rawString)
break;
case 'DisableMagicTestButton':
const magicButton = document.querySelector('#magic-button');
magicButton.setAttribute('disabled', "true")
break;
case 'DisplayTesterResults':
const {score, sentPackets, receivedPackets, receivedAcks, duplicatePackets, duplicateAcks} = ev.data.args;
const resultText = `Test score: ${score}. Sent ${sentPackets} packets. Received ${receivedPackets} packets and ${receivedAcks} acks back. We also got ${duplicatePackets} duplicate packets and ${duplicateAcks} duplicate acks.`
displayReceivedRawString(resultText)
break;
}
}
};
}
sendMessage = (message, recipient) => {
if (!this.worker) {
console.error('Could not send message because worker does not exist');
return;
}
this.worker.postMessage({
kind: 'SendMessage',
args: {
message, recipient,
},
});
};
sendMagicPayload = (mixnodeIdentity) => {
if (!this.worker) {
console.error('Could not send message because worker does not exist');
return;
}
this.worker.postMessage({
kind: 'MagicPayload',
args: {
mixnodeIdentity,
},
});
}
}
let client = null;
async function main() {
client = new WebWorkerClient();
const sendButton = document.querySelector('#send-button');
sendButton.onclick = function () {
sendMessageTo();
};
const magicButton = document.querySelector('#magic-button');
magicButton.onclick = function () {
sendMagicPayload();
}
}
/**
* Create a Sphinx packet and send it to the mixnet through the gateway node.
*
* Message and recipient are taken from the values in the user interface.
*
*/
async function sendMessageTo() {
const message = document.getElementById('message').value;
const recipient = document.getElementById('recipient').value;
await client.sendMessage(message, recipient);
displaySend(message);
}
async function sendMagicPayload() {
const payload = document.getElementById('magic_payload').value;
await client.sendMagicPayload(payload)
displaySend(`clicked the button and the payload is: ${payload}...`);
}
/**
* Display messages that have been sent up the websocket. Colours them blue.
*
* @param {string} message
*/
function displaySend(message) {
let timestamp = new Date().toISOString().substr(11, 12);
let sendDiv = document.createElement('div');
let paragraph = document.createElement('p');
paragraph.setAttribute('style', 'color: blue');
let paragraphContent = document.createTextNode(timestamp + ' sent >>> ' + message);
paragraph.appendChild(paragraphContent);
sendDiv.appendChild(paragraph);
document.getElementById('output').appendChild(sendDiv);
}
/**
* Display received text messages in the browser. Colour them green.
*
* @param {Uint8Array} raw
*/
function displayReceived(raw, sender_tag, isTestPacket) {
let content = new TextDecoder().decode(raw);
if (sender_tag !== undefined) {
console.log("this message also contained some surbs from", sender_tag)
}
if (isTestPacket) {
const decoded = JSON.parse(content)
content = `Received packet ${decoded.msg_id} / ${decoded.total_msgs} for node ${decoded.encoded_node_identity} (test: ${decoded.test_id})`
}
displayReceivedRawString(content)
}
function displayReceivedRawString(raw) {
let timestamp = new Date().toISOString().substr(11, 12);
let receivedDiv = document.createElement('div');
let paragraph = document.createElement('p');
paragraph.setAttribute('style', 'color: green');
let paragraphContent = document.createTextNode(timestamp + ' received >>> ' + raw);
paragraph.appendChild(paragraphContent);
receivedDiv.appendChild(paragraph);
document.getElementById('output').appendChild(receivedDiv);
}
/**
* Display the nymClient's sender address in the user interface
*
* @param {String} address
*/
function displaySenderAddress(address) {
document.getElementById('sender').value = address;
}
main();
@@ -0,0 +1,40 @@
{
"name": "create-wasm-app",
"version": "0.1.0",
"description": "create an app to consume rust-generated wasm packages",
"main": "index.js",
"bin": {
"create-wasm-app": ".bin/create-wasm-app.js"
},
"scripts": {
"build": "webpack --config webpack.config.js",
"build:wasm": "cd ../ && make wasm-build",
"start": "webpack-dev-server --port 8001"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rustwasm/create-wasm-app.git"
},
"keywords": [
"webassembly",
"wasm",
"rust",
"webpack"
],
"author": "Gala Calero <https://github.com/gala1234>",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/nymtech/nym/issues"
},
"homepage": "https://nymtech.net/docs",
"devDependencies": {
"copy-webpack-plugin": "^11.0.0",
"hello-wasm-pack": "^0.1.0",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
},
"dependencies": {
"@nymproject/nym_node_tester_wasm": "file:../../../dist/wasm/credentials"
}
}
@@ -0,0 +1,33 @@
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
module.exports = {
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
},
entry: {
bootstrap: './bootstrap.js',
worker: './worker.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
mode: 'development',
// mode: 'production',
plugins: [
new CopyWebpackPlugin({
patterns: [
'index.html',
{
from: '../../../dist/wasm/credentials/*.(js|wasm)',
to: '[name][ext]',
},
],
}),
],
experiments: { syncWebAssembly: true },
};
+152
View File
@@ -0,0 +1,152 @@
// Copyright 2020-2023 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.
const RUST_WASM_URL = "nym_credentials_wasm_bg.wasm"
importScripts('nym_credentials_wasm_bg.js');
console.log('Initializing worker');
// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts`
const {
default_debug,
no_cover_debug,
NymNodeTester,
set_panic_hook,
currentNetworkTopology,
} = wasm_bindgen;
let client = null;
function dummyTopology() {
const l1Mixnode = {
mixId: 1,
owner: 'n1lftjhnl35cjsfd533zhgrwrspx6qmumd8vjgp9',
host: '80.85.86.75',
mixPort: 1789,
identityKey: '91mNjhJSBkJ9Lb6f1iuYMDQPLiX3kAv6paSUCWjGRwQz',
sphinxKey: 'DmfN1mL1T95nPXvLK44AQKCpW1pStHNQCi6Fgpz5dxDV',
layer: 1,
version: '1.1.20',
};
const l2Mixnode = {
mixId: 2,
owner: 'n18ztkyh20gwzrel0e5m4sahd358fq9p4skwa7d3',
host: '139.162.199.75',
mixPort: 1789,
identityKey: 'BkLhuKQNyPS19sHZ3HHKCTKwK7hCU6XiFLndyZZHiB7s',
sphinxKey: '7KGC97tJRhJZKhDqFcsp4Vu715VVxizuD7BktnzuSmZC',
layer: 2,
version: '1.1.20',
};
const l3Mixnode = {
mixId: 3,
owner: 'n1njq8h4nndp7ngays5el2rdp22hq67lwqcaq3ph',
host: '139.162.244.139',
identityKey: 'EPja9Kv8JtPHsFbzPdBQierMu5GmQy5roE5njyD6dmND',
sphinxKey: 'HWpsZChDrtEH8XNscW3qJMRzdCfUD8N8DmMcKqFv7tcf',
layer: 3,
};
const gateway = {
owner: 'n1d9lclqnfddgg57xe5p0fw4ng54m9f95hal5tlq',
host: '85.159.211.99',
mixPort: 1789,
clientsPort: 9000,
identityKey: '6pXQcG1Jt9hxBzMgTbQL5Y58z6mu4KXVRbA1idmibwsw',
sphinxKey: 'GSdqV7GFSwHWQrVV13pNLMeafTLDVFKBKVPxuhdGrpR3',
version: '1.1.19',
};
const mixnodes = new Map();
mixnodes.set(1, [l1Mixnode]);
mixnodes.set(2, [l2Mixnode]);
mixnodes.set(3, [l3Mixnode]);
const gateways = [gateway];
return {
mixnodes, gateways
}
}
function printAndDisplayTestResult(result) {
result.log_details();
self.postMessage({
kind: 'DisplayTesterResults',
args: {
score: result.score(),
sentPackets: result.sent_packets,
receivedPackets: result.received_packets,
receivedAcks: result.received_acks,
duplicatePackets: result.duplicate_packets,
duplicateAcks: result.duplicate_acks,
},
});
}
async function testWithNymCredentials() {
const preferredGateway = "6pXQcG1Jt9hxBzMgTbQL5Y58z6mu4KXVRbA1idmibwsw";
const nymApi = 'https://qa-nym-api.qa.nymte.ch/api';
// A) construct with hardcoded topology
const topology = dummyTopology()
// optional arguments: id, gateway
// mandatory (one of) arguments: topology, nymApi
const nodeTester = await new NymNodeTester({ id: "foomp", topology: topology });
// B) first get topology directly from nym-api
// const topology = await currentNetworkTopology(nymApi)
// const nodeTester = await new NymNodeTester({topology});
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
// const validator = 'https://qa-nym-api.qa.nymte.ch/api';
// const nodeTester = await new NymNodeTester({nymApi});
self.onmessage = async event => {
if (event.data && event.data.kind) {
switch (event.data.kind) {
case 'MagicPayload': {
const {mixnodeIdentity} = event.data.args;
console.log("starting node test...");
let result = await nodeTester.test_node(mixnodeIdentity);
printAndDisplayTestResult(result)
}
}
}
};
}
async function main() {
console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN START");
// load rust WASM package
await wasm_bindgen(RUST_WASM_URL);
console.log('Loaded RUST WASM');
// sets up better stack traces in case of in-rust panics
set_panic_hook();
//
// run test on simplified and dedicated tester:
await testWithTester();
//
console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN END")
}
// Let's get started!
main();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff