Compare commits

...

1136 Commits

Author SHA1 Message Date
Dave Hrycyszyn 6aec202938 Merge pull request #259 from nymtech/hotfix/wasm_topology_version_filter
Filtering compatible node versions
2020-06-08 10:27:35 +01:00
jstuczyn 4e4187ad57 Filtering compatible node versions 2020-06-05 18:06:38 +01:00
Stefan Steinert c1e921db6a systemd service unit example (#257)
* systemd service unit example

* typo

* inconsistent use of sudo
2020-06-05 10:22:40 +01:00
jstuczyn 88eb1fce25 Using testnet directory in jsexample 2020-06-03 09:09:00 +01:00
Dave Hrycyszyn 65eb043c0b Update CHANGELOG.md 2020-06-02 14:20:23 +01:00
jstuczyn 5e78515216 Version bump 2020-06-02 12:21:42 +01:00
Dave Hrycyszyn 4c6181c09d Merge branch 'feature/rename-desktop-client' into develop 2020-06-02 12:06:10 +01:00
Dave Hrycyszyn 8cdc55b266 Changelog for 0.7.0 2020-06-02 12:05:28 +01:00
Dave Hrycyszyn 0c340a2cda renaming desktop to native client (#251) 2020-06-01 16:50:03 +01:00
Dave Hrycyszyn 496f7244ce renaming desktop to native client 2020-06-01 16:20:50 +01:00
Dave Hrycyszyn 2924551bff Cleaning up startup messages in native client (#249)
* Cleaning up startup messages in native client

* Fixed cargo fmt
2020-06-01 16:08:27 +01:00
Dave Hrycyszyn beacd21b46 Adding a pipenv dependencies file to the python client example (#250) 2020-06-01 16:08:01 +01:00
Dave Hrycyszyn 9d3500c0c5 fixing up readme, bumping version number (#246)
* fixing up readme, bumping version number

* Using the newest js
2020-06-01 11:54:03 +01:00
Jędrzej Stuczyński 860a69b246 Feature/sphinx socket packet encoder (#245)
* Ability to send sphinx packets of different sizes + more efficient decoding

* Closing connection on connection corruption

* Missing semicolons

* Missing license notices

* Default for packetsize
2020-05-27 10:08:08 +01:00
Dave Hrycyszyn aeb1a4b22e Merge branch 'feature/document-js-client' into develop 2020-05-26 18:34:22 +01:00
Dave Hrycyszyn dce22ba37c Last docs fixes 2020-05-26 18:32:48 +01:00
Dave Hrycyszyn 5ef2a22cc7 Adding some documentation to the webassembly client (#244)
* Adding some documentation to the webassembly client

* Noting that binary is unsupported for now
2020-05-21 16:57:38 +01:00
Dave Hrycyszyn 53cef63bdb Noting that binary is unsupported for now 2020-05-21 11:44:45 +01:00
Dave Hrycyszyn bfeb787e6f Adding some documentation to the webassembly client 2020-05-21 11:37:42 +01:00
Dave Hrycyszyn 1f749df59d Simplified some names and used the published npm package (#242) 2020-05-20 15:52:36 +01:00
Jędrzej Stuczyński c063cf83a6 Removed redundant console.log (#240) 2020-05-20 12:22:15 +01:00
Dave Hrycyszyn e83c4d3bea Feature/make andrew happy (#241)
* Fixing the path to nym client in node modules

* Updated package lock for latest npm
2020-05-19 13:17:16 +01:00
Jędrzej Stuczyński 54114f03b5 Feature/explicit gateway addressing (#239)
* validator: fixing a warning, untestify this when you need it for real code

* webassembly: minor readme changes.

* README changes in wasm

* Updated wasm version

* clients/webassembly: security vuln updates

* typo fix

* WIP commit

* Significantly simplified the API

* Changed switch to have default branch

* Managed to get rid of `this` bind

* Moved 'Recipient' definition

* Examples update

* Slightly more generalised 'try_from_string' for recipient

* Updated to use client@gateway addressing

* Updated tests

Co-authored-by: Dave Hrycyszyn <futurechimp@users.noreply.github.com>
2020-05-19 12:16:04 +01:00
Dave Hrycyszyn 8745fb4230 Feature/clean up (#238)
* validator: fixing a warning, untestify this when you need it for real code

* webassembly: minor readme changes.

* README changes in wasm

* Updated wasm version

* clients/webassembly: security vuln updates

* typo fix

* WIP commit

* Significantly simplified the API

* Changed switch to have default branch

* Managed to get rid of `this` bind

* Filled in a missing word

Co-authored-by: jstuczyn <jedrzej.stuczynski@gmail.com>
2020-05-19 10:32:52 +01:00
Jędrzej Stuczyński a38a9f604d Feature/addressing update (#237)
* Typo I've never noticed before

* Sphinx version update

* Updated 'address' to be 'recipient' (i.e. address + gateway)

* Updated websocket examples to use the updated structure
2020-05-18 13:01:51 +01:00
Jędrzej Stuczyński 7f99c2828b Added hidden init flag to increase default traffic volume (#234) 2020-05-15 10:09:27 +01:00
Jędrzej Stuczyński 2630629cdb Fixed unwrap on none value (#230) 2020-05-14 11:52:21 +01:00
Jędrzej Stuczyński 106267eb1a Bugfix/gateway crash on incomplete ws handshake (#229)
* Properly checking for errors during websocket handshake

* Unrelated typo

* Fixed similar bug in rust client
2020-05-14 11:51:04 +01:00
Jędrzej Stuczyński c8168adeb2 Bugfix/issue#231 (#233)
* Increasing reconnection attempt after actually computing delay

* Constructor mix-up....

* Replaced poll! macro with poll call (after macro expansion that's syntactically identical)
2020-05-14 11:49:36 +01:00
Jędrzej Stuczyński 3773800133 Feature/start local network improvements (#228)
* Moved directory_server from Debug section of configs

* Using correct variable path

* Updated start_local_network script

* Actually killing gateways on startup

* Removed redundant stop_local_network.sh

* The Canadian appeasement accord
2020-05-13 12:01:51 +01:00
Jędrzej Stuczyński ff2e24afbc Updated directory_client reqwest to 0.10 (#226)
* Updated directory_client reqwest to 0.10

* Using consistent syntax
2020-05-12 12:52:31 +01:00
Jędrzej Stuczyński f47b7cfb13 Updated js-example to get gateway from topology (#225) 2020-05-11 14:52:23 +01:00
Dave Hrycyszyn e2b9a9468a Feature/minor docs fixes (#223)
* webassembly: fixing example directory name in README

* rust client: fixing what I suspect is a typo in a type name

* Fixing wasm build instructions
2020-05-07 17:30:29 +01:00
Jędrzej Stuczyński 981f4de397 Requiring explicit timestamp when converting from rest to service mixnodes (#224) 2020-05-07 17:08:39 +01:00
Jędrzej Stuczyński a3192a190f Removed having to care about SURB_ID (#222) 2020-05-07 16:55:05 +01:00
Dave Hrycyszyn 37f5bfdf02 Simplified and corrected wasm-pack build instructions 2020-05-07 16:30:17 +01:00
Dave Hrycyszyn ccc516903c client: docs typos fix 2020-05-07 15:57:00 +01:00
Jędrzej Stuczyński 97a944a33e Updated wasm code to work with new gateway and updated the example (#219)
* Updated wasm code to work with new gateway and updated the example

* cargo fmt

* Fixed test by ensuring destination is present at a gateway

* Updated hardcoded default port

* ibid. to correct value
2020-05-06 16:20:43 +01:00
Jędrzej Stuczyński f9d3ee7fc4 Moved relevant parts of old mix-client to nymsphinx (#221) 2020-05-06 16:18:27 +01:00
Jędrzej Stuczyński c3e18cedd5 Feature/load keys on run (#220)
* Mixnode keys loaded in run command

* Client keys loaded in run command

* Removed unused imports
2020-05-06 16:17:02 +01:00
Dave Hrycyszyn fe17bdaf49 validator: removing health checker (#217) 2020-05-05 18:15:49 +01:00
Jędrzej Stuczyński 8249475fba Feature/healthchecker removal (#214)
* Some clippy and compiler warning fixes

* Removed healthchecker from the client

* Cargo fmt issue after 100 explicit saves.........

* Changes accidentally removed in previous PR
2020-05-05 14:19:39 +01:00
Jędrzej Stuczyński 65b9808662 The great sfw-provider purge of 2020 (#216)
* The great sfw-provider purge

* Cargo fmt...
2020-05-05 14:19:11 +01:00
Jędrzej Stuczyński fa1bcabe5a Fixed compilation warnings on unreachable code when compiling with features flag (#215) 2020-05-05 13:16:56 +01:00
Dave Hrycyszyn 20b25b1074 Update README.md 2020-05-05 13:00:57 +01:00
Jędrzej Stuczyński e6ec803818 Bugfix/send to correct gateway (#213)
* Initial multiple gateway support

* Hello random cargo fmt
2020-05-05 12:50:34 +01:00
Jędrzej Stuczyński 57c43a1f6b Feature/client socket adjustments (#212)
* Changed default listening port to something slightly more meaningful

* Removed TCP socket and made websocket the default option (as opposed to 'None')

* Updated template

* Updated ReceivedBuffer to allow direct message forwarding

* ignoring vscode directory

* Push messages mechanism for websocket client-clients

* Removed flawed chunking example

* ... but added bunch of websocket examples in return!

* Moves js example directory

* Cargo fmt

* Removed old listener code
2020-05-04 17:07:27 +01:00
Jędrzej Stuczyński e7b8ab8c10 Sending sphinx packet independent of the receiver task (#210) 2020-04-30 13:14:03 +01:00
Jędrzej Stuczyński abbf7041a4 Feature/gateway provider merge (#208)
* Initial draft for ClientsHandler

* Created listener struct

* typo

* Stateful websocket connection handler

* Exposing modules

* Depdendencies updates

* Moved listener to correct file + made start consume listener

* Main starting new listener

* Catching sigint

* Copied client storage from provider into gateway

* Exposed websocket listener type for nicer import path

* Defined websocket message receiver concrete type

* Client ledger struct without implementation

* ClientsHandler using more concrete types

* Mixnet sender + receiver and exposed listener type

* Handling mix packets

* Ability to forward mix packets

* "starting" both listeners at main

* Depedencies updates

* Initial type definitions for client messages

* Initial "gateway-requests" with AuthToken

* ibid.

* Restored most of ledger's functionalities

* Ability to retrieve all messages regardless of rate limit

* ClientsHandler request handling logic

* Required 'new' dependencies

* Main changes required for compilation

* PacketProcessor getting private key pointer

* "moved" types into gateway requests crate

* Moved and renamed types

* ibid.

* Added required serde_json dependency

* Skeleton for websocket request handling

* helper methods on ServerResponse

* WebSocket Handler pushing received mix messages directly to client

* PacketForwarder returning JoinHandle alongside the channel

* ClientsHandler following the same pattern

* Made websocket listener start method consistent with mix listener

* Syntax error + formatting

* Websocket handler having access to mix forwarder

* Minimal binary request parsing

* Implicitly derived std::error::Error on GatewayRequestsError

* Handling of all websocket requests

* Types import cleanup

* Updated placeholder fields

* Everything put into main

* Missing license notices

* Cleaned up unused code

* Copied and did initial minor changes to commands and config

* It's actually gateway

* Gateway sending its regular presence to directory server

* Re-organisation of gateway code + Gateway struct

* Updated provider argument description

* Restored duplicate ip check without importing NymTopology trait

* Moved hardcoded values into config

* Cargo fmt

* Compilation errors in other crates due to topology adjustments

* Test fixes

* Initial gateway-client

* Seemingly working version with bunch of hardcoded and temporary values

* cargo fmt

* Removed provider poller

* Updated config with gateway values instead of provider

* Gateway address including ws

* Removed hardcoded gateway address

* Properly skipping loop cover messages

* Updated log filter with tokio tungstenite related modules

* Updated sphinx version used

* Very minor cleanup

* unused import
2020-04-30 10:14:21 +01:00
Dave Hrycyszyn 903ef44328 Feature/route from topology (#201)
* directory-client: removing explicit type definitions

* clients/webassembly: ugly commit, removes dependency on HTTP crates

...at the cost of copying quite a bit of NymTopology-related stuff into
the WebAssembly client. I'll make an issue to refactor that later.

* A more helpful hint in the error message when websocket connection fails.

* Removing superfluous JavaScript, route checking now happens in Rust
2020-04-23 12:01:25 +01:00
Dave Hrycyszyn 44c48ef8ee FIXING DUE TO SOMEONE'S CHOICE OF EDITOR / OPERATING SYSTEM 2020-04-23 11:41:44 +01:00
Jędrzej Stuczyński a77881d284 Intermediate gateway-heart surgery checkpoint (#199)
* Initial draft for ClientsHandler

* Created listener struct

* typo

* Stateful websocket connection handler

* Exposing modules

* Depdendencies updates

* Moved listener to correct file + made start consume listener

* Main starting new listener

* Catching sigint

* Copied client storage from provider into gateway

* Exposed websocket listener type for nicer import path

* Defined websocket message receiver concrete type

* Client ledger struct without implementation

* ClientsHandler using more concrete types

* Mixnet sender + receiver and exposed listener type

* Handling mix packets

* Ability to forward mix packets

* "starting" both listeners at main

* Depedencies updates

* Initial type definitions for client messages
2020-04-23 10:36:13 +01:00
Dave Hrycyszyn 8baa236d81 Feature/wasm js demo (#191)
* Moved `nym-sphinx-wasm` into `wasm` folder and renamed its examples

* A proposal for some structural cleanup

* desktop client: beginning of a Rust example for chunking.

* Simplifying desktop client readme

* Tarting up webassembly README

* A more visual webassembly client example

* clients/webassembly: grouping a few things into named functions for clarity

* clients/webassembly: put URLs at top of file, prepping for drop-down action

* mixnode + provider run: changed startup error messages a bit

* clients/webassembly: scrolling from the bottom in the demo
2020-04-21 10:05:38 +01:00
Jędrzej Stuczyński 4af5788bba Feature/limit direct sphinx dependency + remove direct curve25519 dependency from wasm client (#189)
* Initial set of re-exported sphinx types and constants

* Removed direct sphinx dependency from healthchecker

* Crypto module

* nym-client no longer needing sphinx

* All common modules

* mix-client until removed

* Sfw-provider no longer depending on sphinx crate

* Mixnode no longe depending directly on sphinx crate

* Ibid. for sfw-provider-requests

* Corrected import inside nymsphinx itself

* wasm client no longer needing direct sphinx dependency

* Required gateway change due to re-exporting constants in one place

* Missing import path changes in tests

* Removed direct dependency on curve25519 from wasm client

* Lock file changes
2020-04-20 16:59:51 +01:00
Dave Hrycyszyn c5dd6bf93d Feature/improve js example (#190)
* nym-client: refactoring js example code a bit.

* nym-client: ignoring node modules in demo

* nym-client: adding webpack and a dev server

* nym-client: banging example into webpack format

* nym-client: webpack starting to work in the demo

* nym-client: more webpacking

* nym-client: ignoring bundle.js in dist

* Example code starting to breathe with webpack, not quite there yet

* nym-client: high point of attempted webpack business. Will revert to minimal, it's getting crazy.

* nym-client: removed lots of npm deps

* nym-client: added webpack html plugin to demo

* nym-client: removed app.scss from demo

* nym-client: removed lots of webpack config

* nym-client: ugly but working simple javascript demo

* nym-client: more demo simplification

* Simplifying a bit more

* nym-client: added some comments to js demo

* parameter rename
2020-04-20 15:48:26 +01:00
Jędrzej Stuczyński fda308694e Feature/very minor refactoring (#188)
* log statement for forwarding traffic

* Mixnode logging intent to forward packet

* Presence logging level decrease + making things less public

* Default adjustments + human readable equivalents in comments

* Do not immediately refresh topology on start
2020-04-17 18:59:22 +01:00
Jędrzej Stuczyński 8f4dff0074 Feature/persistent ledger (#187)
* Changed auth token storage to use sled instead of in memory hashmap

* Filtering sled related log messages

* Catching db error on trying to load sled

* Renamed default ledger name

* The actual dependency

* Changes due to ledger no longer being async

* Extra log statement

* Missing change to current_clients method

* Another uncommited change

* Cargo lock changes
2020-04-17 18:58:53 +01:00
Dave Hrycyszyn b8edb5c436 Optimising wasm build size, shaves about 10% size off our wasm output. (#186) 2020-04-17 18:21:22 +01:00
Dave Hrycyszyn 0bf74a0b36 Ran npm audit fix on the wasm demo directory. (#185) 2020-04-17 12:02:30 +01:00
Dave Hrycyszyn 1200a2f02d Feature/service persistence (#171)
* validator: adding Diesel ORM

* validator: making sure Iron::status is always avaialable

* ibid

* validator: presence-announcement REST API

* validator: adding Diesel setup

* Removing Diesel stuff from root of monorepo

* validator: adding Diesel migrations and setup

* validator: documenting how PresenceAnnouncement is different from presence.

* validator: added Chrono crate for datetime conversions into sql

* validator: restructured the presence module

* validator: removed presence announcements from persistence

* validator: commenting topology

* Adding staking to the mixmining service

* Start of mixmining + stake service

* validator: added a bit about mixmining to README

* validator: added Iron's params crate

* validator: reorganized mixmining service and db code

* validator: no need for this .env warning

* validator: removing params parser, it's now unused

* validator: adding json body parser library for Iron

* validator: adding spelling exceptions

* validator: adding bodyparser deps

* validator: ability to (de)serialize Mixnode struct

* validator: further announcement HTTP progress

* validator: simplified announcement route

* validator: injecting database and service into handler

* validator: renaming service and db variables

* validator: using camelCase json

* validator: using base Iron handler rather than middleware handler

* validator: better error message on unexpected json parsing

* validator: adding 'location' to  presence::Announcement

* comments on mixmining::Db

* validator: commenting out unused mixmining::Service methods for the moment

* validator: noting that we don't yet know how to measure capacity

* validator: comments

* validator: starting to add correct serializers in rest API

* validator: renaming a mixnode announcements

* validator: extracted route creation

* validator: going lower-case for node in "Mixnode"

* validator: removing the "announcement" model

* validator: renamed annoucements handlers

* validator: temporarily removed Chrono, remove it fully if it's not needed.

* validator: added all the needed Mixnode fields to the service model

* validator: moved models into their own file.

* validator: conversions to/from api vs service models

* validator: doing type conversions from rest to service models

* validator: unused import cleanup

* validator: rewrote mixmining service comments in light of recent thinking

* validator: some notes on type conversion tests

* wip

* validator: getting capacity from db works

* wip

* validator: eliminating borrows so we can have something pure to mutex out on

* validator: a working mutex on the mixmining service

* validator: renaming mixmining db get_capacity to capacity

* validator: making mixmining db capacity field private, using accessor

* validator: local capacity updates working

* validator: starting REST API for staking

* validator: fixing clippy warning

* validator: minor naming fixes on mixmining service

* validator: service mixnode and rest mixnode + topology conversions + tests

* validator: renaming mix_nodes to mixnodes for consistency

* validator: test fixtures for mixnode

* validator: moved service models into their own file

* validator: a properly-structured toplogy route

* validator: topology retrieval

* validator: killed test fixture warning

* validator: getting set for topology equality checks (testing purposes)

* validator: otherway conversions for topology and mixnode types

* validator: initial topology retrieval working

* validator: ditching go-ish variable name :)

* ibid

* validator: added a StakeUpdate struct to get around cargo fmt failing

* validator: commenting out struct so kill warning

* Ignoring validator vscode settings

* ibid

* ibid
2020-04-17 11:39:36 +01:00
Dave Hrycyszyn 9ab2517b87 Update README.md 2020-04-17 11:37:51 +01:00
Jędrzej Stuczyński 2b48e85554 Merge pull request #183 from nymtech/feature/nym-sphinx-wasm
Feature/nym sphinx wasm
2020-04-17 11:16:38 +01:00
Dave Hrycyszyn 00d31267fa nym-sphinx-wasm: taking advice from The Man Who Loved Iterators 2020-04-17 10:48:57 +01:00
Dave Hrycyszyn f8b2900698 Making Arc clones more explicit. 2020-04-17 10:33:54 +01:00
Dave Hrycyszyn bf2ff5cd78 Ditching comment that told me where to start work one morning. 2020-04-17 10:33:40 +01:00
Dave Hrycyszyn d3bb0b216d nym-sphinx-wasm: using the Try that was already available and reverting foolish change to public API of addressing/nodes 2020-04-17 10:28:10 +01:00
Dave Hrycyszyn 526d7fa27d Some README improvements 2020-04-17 09:52:17 +01:00
Dave Hrycyszyn befad123f6 Removing MIT license 2020-04-17 09:51:44 +01:00
Dave Hrycyszyn 7d49ac8d25 gateway: broke things apart a little bit 2020-04-16 21:11:25 +01:00
Dave Hrycyszyn d628e065f1 gateway: using named function for packet forwarding 2020-04-16 20:59:23 +01:00
Dave Hrycyszyn 1412fdb6a7 gateway: removing text messages 2020-04-16 20:59:03 +01:00
Dave Hrycyszyn 6654d72e78 gateway: shortening multi_tcp_client usages 2020-04-16 20:58:46 +01:00
Dave Hrycyszyn d7150cfa58 nymsphinx: re-exporting NODE_ADDRESS_LENGTH so gateway can use it 2020-04-16 20:57:53 +01:00
Dave Hrycyszyn 99e818952f gateway: grabbing some stuff out of nymsphinx 2020-04-16 20:57:18 +01:00
Dave Hrycyszyn a717a8aabf gateway: client cleanup 2020-04-16 19:47:06 +01:00
Dave Hrycyszyn 10520469dd typo fix 2020-04-16 18:34:18 +01:00
Dave Hrycyszyn ffd941169e nym-sphinx-wasm: documented sphinx_route_from(str) 2020-04-16 18:32:42 +01:00
Dave Hrycyszyn fd874845cd nym-sphinx-wasm: various cleanups on packet creation 2020-04-16 18:26:12 +01:00
Dave Hrycyszyn d7e4374054 nym-sphinx-wasm: noted that message chunking is not yet implemented 2020-04-16 17:12:59 +01:00
Dave Hrycyszyn 044b12cdf1 nym-sphinx-wasm: ditched old code 2020-04-16 17:12:41 +01:00
Dave Hrycyszyn 060d0b4f02 gateway: successful send using multi-tcp-client 2020-04-16 16:45:34 +01:00
Dave Hrycyszyn 4b2a6f20f3 scripts: building for local in debug mode 2020-04-16 13:43:25 +01:00
Dave Hrycyszyn 1eb211dbd4 nym-sphinx-wasm: including provider encoding in the packet 2020-04-16 13:43:04 +01:00
Dave Hrycyszyn 40e67e7809 nym-sphinx-wasm: chunking packet sends 2020-04-16 13:42:09 +01:00
Dave Hrycyszyn 146bbef3af nym-sphinx-wasm: loosening up serde-related dependencies 2020-04-16 13:40:41 +01:00
Dave Hrycyszyn ab61ef8680 Changing recipient 2020-04-15 20:56:17 +01:00
Dave Hrycyszyn dbd657646c Sending packet to the server 2020-04-15 20:56:02 +01:00
Dave Hrycyszyn beffc45cbe nym-client: typo fix 2020-04-15 20:54:59 +01:00
Dave Hrycyszyn 96bbf9c3f5 gateway: simplifying 2020-04-15 20:54:20 +01:00
Dave Hrycyszyn 85680b22d9 ibid 2020-04-15 20:54:08 +01:00
Dave Hrycyszyn e226001530 gateway: adding log related crates 2020-04-15 20:54:00 +01:00
Dave Hrycyszyn 2a6dd1d5a8 scripts: adding a stop script so I don't need to manually killall all the time 2020-04-15 20:53:29 +01:00
jstuczyn 62e61328a1 Updated email 2020-04-15 18:14:00 +01:00
Dave Hrycyszyn d8776d35ca Merge branch 'develop' into feature/nym-sphinx-wasm 2020-04-15 17:44:47 +01:00
Jędrzej Stuczyński dfefd2383e Improvements to sfw-provider - client communcation (#180)
* Moved auth_token to seperate file

* Extracted check_id as separate type

* Changes due to move of auth_token and making provider client mutable

* New way of serialization provider requests/responses

* Initial attempt of using new provider client

* Moved requests and responses to separate modules

* Moved serialization to separate  files

* Extracted readers and writers to io related modules

* Extra tests + bug fixes

* Updated tokio dependency to require correct features

* typo

* Easier conversion of requests/responses into enum variants

* Renamed 'read_be_u16' to better show its purpose

* Serialization related tests and fixes

* Tests for async_io + fixes

* Future considerations

* Configurable max request size

* Configurable max response size for client

* Removed debug drop implementations

* Removed debug print statement

* Changes to lock file

* Added license notifications

* Cargo fmt
2020-04-15 17:37:24 +01:00
Dave Hrycyszyn 53f29fd4a5 nym-sphinx-wasm: added a bit of documentation onto the www demo 2020-04-15 17:31:35 +01:00
Dave Hrycyszyn 3cbf1fa754 nym-sphinx-wasm: adding an example of wasm Sphinx in action 2020-04-15 17:24:43 +01:00
Dave Hrycyszyn a2e9590420 nym-sphinx-wasm: removing outdated Sphinx examples 2020-04-15 17:24:15 +01:00
Dave Hrycyszyn 9dc9ccd9d4 Removing submodule 2020-04-15 17:18:26 +01:00
Dave Hrycyszyn b662edc343 gateway: simplifying a bit. 2020-04-15 16:54:52 +01:00
Dave Hrycyszyn 279e46e045 nym-sphinx-wasm: appears to generate a Sphinx packet based on info sent from js.
Needs testing.
2020-04-15 16:54:28 +01:00
Dave Hrycyszyn 4fd07aef10 nym-sphinx-wasm: Adding serde to deal with json across wasm boundary 2020-04-15 16:49:18 +01:00
Dave Hrycyszyn d3227ab157 nym-sphinx-wasm: adding async dependency for js 2020-04-15 16:48:45 +01:00
Dave Hrycyszyn 353c8287db nym-sphinx-wasm: adding serde_json as a hack to get across the wasm boundary 2020-04-15 16:43:40 +01:00
Dave Hrycyszyn 16f466b795 Adding serde_json 2020-04-15 16:42:16 +01:00
Dave Hrycyszyn 65db7ef25d nym-sphinx-wasm: adding a JavaScript package 2020-04-15 13:09:01 +01:00
Dave Hrycyszyn 7088fb3ffc Upgraded all Sphinx commits to latest. 2020-04-15 13:08:31 +01:00
Dave Hrycyszyn 53c1aaa256 nymsphinx: adding wasm-bindgen feature to rand crate 2020-04-15 12:54:44 +01:00
Dave Hrycyszyn 306bbb1360 wasm: renamed js example folder 2020-04-14 15:59:54 +01:00
Dave Hrycyszyn c2e3582032 wasm: demo js starting to work 2020-04-14 15:58:34 +01:00
Dave Hrycyszyn dddac13496 gateway: adding a gateway node type which listens on a websocket 2020-04-14 15:50:59 +01:00
Dave Hrycyszyn f07966c3fc scripts: setting run_local_network.sh to be executable 2020-04-14 15:50:14 +01:00
Dave Hrycyszyn b468be83da wasm: noting that we will need to set release params in the root cargo file 2020-04-14 15:49:54 +01:00
Dave Hrycyszyn 25cfa26c56 nym-client: adding js example so I can see if sending is working at all. 2020-04-14 15:49:21 +01:00
Dave Hrycyszyn 3c8aad49fc Updated all uses of ed25519-dalek to 2.0.0 so that wasm-pack build works 2020-04-09 17:20:22 +01:00
Dave Hrycyszyn fd68994e64 A possibly-working wasm Sphinx packet. 2020-04-09 16:42:29 +01:00
Dave Hrycyszyn 61e0ec5ab5 ibid 2020-04-09 16:42:08 +01:00
Dave Hrycyszyn 0d33d35437 nym-sphinx-wasm: updating to latest Sphinx 2020-04-09 16:41:01 +01:00
Dave Hrycyszyn 213fd12ff7 nym-sphinx-wasm: broken WIP commit so the Stuczynski can be unleashed 2020-04-09 15:12:31 +01:00
Dave Hrycyszyn 2d323f180f Initial build of a Sphinx packet in WebAssembly 2020-04-09 14:07:16 +01:00
Dave Hrycyszyn 3f06ccc36b Adding Apache 2 license headers to all files (#178) 2020-04-09 11:24:24 +01:00
Dave Hrycyszyn cb82299f0e Bumped version numbers to 0.7.0-dev 2020-04-07 17:33:26 +01:00
Dave Hrycyszyn ad52e06546 Merge tag 'v0.6.0' into develop
Releasing v0.6.0
2020-04-07 17:30:12 +01:00
Dave Hrycyszyn f5a3d7eea3 Merge branch 'release/0.6.0' 2020-04-07 17:29:55 +01:00
Dave Hrycyszyn d47f0be2f2 Bumping version numbers 2020-04-07 17:29:46 +01:00
Dave Hrycyszyn 7cb78b2090 Add changelog for 0.6.0 2020-04-07 17:20:34 +01:00
Dave Hrycyszyn c4bc6d2799 Making changelog script executable 2020-04-07 17:20:09 +01:00
Jędrzej Stuczyński 3b6110a42e Feature/tcp client connection timeout (#176)
* Added timeout values to configs

* Fixed possible crash when using delay larger than 2 years

* Connection timeout with hardcoded value

* Using provided timeout value

* tcp client requiring timeout value at construction

* Client using updated tcp client

* Mixnode using updated tcp client

* Healthchecker having separate timeout + new client config field

* Updated validator with connection timeout field

* Added connection_timeout to validator config template
2020-04-07 15:50:23 +01:00
Jędrzej Stuczyński 7e1c957090 Feature/mixing stats logging (#175)
* Extra startup log messages

* Type alias for sent metrics map

* Initial metrics informer

* Separated report and running stats

* Decreases report logging level

* Added logging delay as a config value

* New metrics informer constructor

* Determining if running stats should be logged

* Separated running total and reports logging

* Missing changes
2020-04-07 11:21:12 +01:00
Jędrzej Stuczyński f03101cc0b Preventing multiplication overflow for reconnection backoff (#174)
* Preventing multiplication overflow for reconnection backoff

* Check for addition overflow + helpful-ish error message

* Not resetting delay twice

* Lowered healtcheck reconnection backoff to something way more reasonable but still impossible to reach
2020-04-07 11:02:00 +01:00
Jędrzej Stuczyński 6766cf3470 Feature/non mandatory debug config (#173)
* configs no longer need to have all debug fields set

* Removed debug section from config template of mixnode, provider and validator

* Significantly reduced debug section in client config template
2020-04-06 16:32:34 +01:00
Jędrzej Stuczyński b564cd935e Feature/addressing move (#169)
* Moved 'addressing' to nymsphinx + slightly better API + tests

* Replaced all usages of above in the project

* Removed 'split_and_encapsulate_message' from chunking API to get rid of circular dependency + to prefer usage of TopologyAccessor

* changes in Cargo.lock

* formatting
2020-04-03 15:07:02 +01:00
Jędrzej Stuczyński d859a98367 Checking if any other node is already announcing the same host (#168) 2020-04-02 15:39:14 +01:00
Jędrzej Stuczyński d02e248328 Bugfix/closing tcp client connections on drop (#167)
* Filtering out early eof errors

* Wrapping ConnectionManager in Abortable

* Decreased pathchecker logging level

* Client aborting all connection futures on drop

* Moved AbortHandle to connection_managers HashMap to couple them closer together
2020-04-02 15:38:21 +01:00
Jędrzej Stuczyński c401222a84 Yielding tokio task upon creating loop/real traffic message (#166) 2020-04-01 15:33:27 +01:00
Jędrzej Stuczyński 425746e215 Feature/minor healthchecker improvements (#165)
* Integrated new tcp client into healthchecker

* Printing detailed healtcheck score if in debug

* Decreased logging level for when establishing new connection

* Slightly better formatting for printing healthcheck scores
2020-04-01 12:19:39 +01:00
Jędrzej Stuczyński aee3286793 Feature/packet chunking (#158)
Basic support for message chunking and reconstruction. It's now possible to take arbitrarily-sized input and send it through the mixnet. The sending Nym client will automatically chunk the input into Sphinx packets, and the receiving Nym client will then reconstruct the message at the other end.
2020-03-31 16:00:41 +01:00
Dave Hrycyszyn 941bd6d846 Merge branch 'master' into develop 2020-03-30 20:11:01 +01:00
Dave Hrycyszyn 7228806eca monorepo: adding Apache V2.0 license 2020-03-30 20:10:32 +01:00
Dave Hrycyszyn 74e641b57c Adding developer chat to the README 2020-03-27 18:24:59 +00:00
Dave Hrycyszyn 37fd895d13 Update CHANGELOG.md 2020-03-24 11:33:00 +00:00
Dave Hrycyszyn ef062e15ac Documented changelog process a bit better 2020-03-23 11:33:35 +00:00
Dave Hrycyszyn b9143ebc9e Changelog updated 2020-03-23 11:31:36 +00:00
Dave Hrycyszyn 7083294b21 v0.5.0 changelog 2020-03-23 11:14:19 +00:00
Dave Hrycyszyn 9e068ef063 Merge tag 'vv0.5.0' into develop
Release v0.5.0.
2020-03-23 10:50:27 +00:00
Dave Hrycyszyn 1e99e6dc07 Merge branch 'release/v0.5.0' 2020-03-23 10:35:32 +00:00
Dave Hrycyszyn d576a17d33 New cargo versions for top-level binaries 2020-03-23 10:35:19 +00:00
Dave Hrycyszyn 40a14a10b1 Minor README simplification 2020-03-23 10:35:05 +00:00
Jędrzej Stuczyński 8a51503b34 Merge pull request #155 from nymtech/feature/remove-scary-message
removing spooky startup warning message
2020-03-20 13:35:18 +00:00
Dave Hrycyszyn 5109ef290c removing spooky startup warning message 2020-03-20 13:34:11 +00:00
Jędrzej Stuczyński 6e3b2b54df Merge pull request #154 from nymtech/feature/eliminate-double-banner
Some more startup fixes
2020-03-20 13:17:23 +00:00
Dave Hrycyszyn 0048f1a805 Consistenifying return type 2020-03-20 13:01:03 +00:00
Dave Hrycyszyn 5caf093dca Some more startup fixes 2020-03-20 12:56:26 +00:00
Dave Hrycyszyn 478084a5f1 Merge pull request #153 from nymtech/hotfix/client_startup_fix
Entering runtime context when creating mix traffic controller
2020-03-20 12:37:26 +00:00
jstuczyn db02e828a6 Removed outdated comment 2020-03-20 12:25:56 +00:00
jstuczyn 3a4bdc861a Entering runtime context when creating mix traffic controller 2020-03-20 12:23:04 +00:00
Jędrzej Stuczyński eae2fe675d Merge pull request #151 from nymtech/feature/remove-startup-warnings
Friendlification of startup messages
2020-03-19 11:55:30 +00:00
Dave Hrycyszyn df677362ed Merge pull request #150 from nymtech/hotfix/mixnode_startup_fix
Entering runtime context when creating packet forwarder
2020-03-19 11:54:33 +00:00
jstuczyn 776a857779 Entering runtime context when creating packet forwarder 2020-03-19 11:32:44 +00:00
Dave Hrycyszyn 3ccaf77249 mixnode, sfw-provider: no need to expose deep internals to users first thing 2020-03-19 11:18:43 +00:00
Jędrzej Stuczyński 6254169151 Merge pull request #149 from nymtech/feature/add-topology-to-validator
Feature/add topology to validator
2020-03-17 11:02:51 +00:00
Dave Hrycyszyn 684f7a1432 validator: removed unneeded serde_derive 2020-03-17 10:54:47 +00:00
Dave Hrycyszyn e6ac966757 validator: using fully-qualified struct names to eliminate a bit of noise 2020-03-17 09:42:52 +00:00
Dave Hrycyszyn bb235cb7f1 validator: noting async nature of spawn causes out of order messages 2020-03-16 18:11:36 +00:00
Dave Hrycyszyn 1b844292a9 validator: noted the need for some Tendermint startup tenderness and love 2020-03-16 18:09:15 +00:00
Dave Hrycyszyn 2bd837a1e4 validator: fixing unused variable and spelling warnings 2020-03-16 18:05:21 +00:00
Dave Hrycyszyn fced1159ce validator: returning empty topology json ready to be filled up from data 2020-03-16 18:02:20 +00:00
Dave Hrycyszyn 4095f33fca validator: adding json-handling functionality 2020-03-16 18:01:44 +00:00
Dave Hrycyszyn c4f15a3f97 Adding a better-structured route for topology 2020-03-16 17:32:02 +00:00
Dave Hrycyszyn 8a149570a9 validator: adding Iron router 2020-03-16 17:31:46 +00:00
Dave Hrycyszyn 73f07233ff Merge pull request #142 from nymtech/feature/concurrent_connection_managers
Feature/concurrent connection managers
2020-03-16 17:20:27 +00:00
jstuczyn 81ac2b97f4 Added a very important note : ) 2020-03-16 17:04:48 +00:00
jstuczyn a44272be60 Restored previously commented out tests 2020-03-16 17:04:37 +00:00
jstuczyn 3b2461080c Changed the multi-tcp client to have an option to wait for an error response 2020-03-16 17:04:26 +00:00
jstuczyn 270d7567df Merge branch 'develop' into feature/concurrent_connection_managers 2020-03-16 15:08:36 +00:00
Dave Hrycyszyn b2789bf2a1 Merge pull request #148 from nymtech/feature/windows_fix
Making code work on windows machines.
2020-03-16 15:06:21 +00:00
Jędrzej Stuczyński 6d1d8cc5dd Merge pull request #146 from nymtech/feature/add-http-interface
validator: adding HTTP interface
2020-03-16 14:47:57 +00:00
Jędrzej Stuczyński 560b01974f Merge pull request #145 from nymtech/feature/simplify-setup
Extracting the log setup
2020-03-16 14:22:28 +00:00
Dave Hrycyszyn c08ab00c57 validator: trying and temporarily failing to get nice startup messages 2020-03-16 14:15:36 +00:00
Dave Hrycyszyn aaee1bf49a validator: startup messages for REST API 2020-03-16 14:07:27 +00:00
Dave Hrycyszyn 5af61d161a validator: printing out network services as they start 2020-03-16 14:07:03 +00:00
Dave Hrycyszyn ebd2c25d60 Merge branch 'develop' into feature/add-http-interface 2020-03-16 13:54:38 +00:00
jstuczyn c0044499da Missing quoation mark 2020-03-16 13:33:09 +00:00
Dave Hrycyszyn d8e4c8d24d Extracting logging setup for all binaries 2020-03-16 13:22:15 +00:00
Dave Hrycyszyn b4805d27e2 Heheh one newline for the fail :) 2020-03-16 13:18:45 +00:00
Dave Hrycyszyn e76fc79a33 Getting initial REST API working 2020-03-16 13:18:07 +00:00
jstuczyn f5e3e10707 Updated merged changes in config to be consistent with previous updates 2020-03-16 13:12:15 +00:00
jstuczyn 2eb237cc0e Merge branch 'develop' into feature/windows_fix 2020-03-16 13:08:26 +00:00
Dave Hrycyszyn a7ac2e1ad7 Merge pull request #144 from nymtech/feature/optional_location_in_configs
Feature/optional location in configs
2020-03-16 12:58:22 +00:00
jstuczyn 5d2fb6bdfa Updated quotation marks used in config templates to work on windows with paths containing \U sequences 2020-03-16 12:37:09 +00:00
Dave Hrycyszyn b08a4c0930 Extracting the log setup 2020-03-16 12:28:52 +00:00
Dave Hrycyszyn 64bb7ea350 Renamed binaries with correct binary names 2020-03-16 11:42:35 +00:00
Jedrzej Stuczynski 0546c561a9 Actually fixed tests this time 2020-03-13 16:50:30 +00:00
Jedrzej Stuczynski 72ed65dc5f Fixed broken tests 2020-03-13 16:46:18 +00:00
Jedrzej Stuczynski b8bd872cdf ibid. 2020-03-13 16:46:12 +00:00
Jedrzej Stuczynski 3ade837579 Added location to CocoPresence 2020-03-13 16:46:04 +00:00
Jedrzej Stuczynski ab5656ce94 Updated configs and args with location 2020-03-13 16:34:06 +00:00
Jedrzej Stuczynski 78e1f916f2 Updated presence information with location 2020-03-13 16:33:50 +00:00
Jedrzej Stuczynski b99a52bc1b Removed oversensitive logging messages 2020-03-13 12:18:54 +00:00
Jedrzej Stuczynski 1271d6c1f5 Comment regarding future work on getting possible responses back to the callee 2020-03-13 09:36:14 +00:00
Jedrzej Stuczynski fe85fefb5b Client and mixnode adjustments due to previous changes 2020-03-12 16:24:04 +00:00
Jedrzej Stuczynski 7143ab9b53 Changed connection manager to be accessed via a channel 2020-03-12 16:23:47 +00:00
Jedrzej Stuczynski 8279efb684 Exposed methods 2020-03-12 16:22:40 +00:00
Jedrzej Stuczynski f00bc5a3d1 Moved the error reader level up 2020-03-12 16:22:18 +00:00
Jedrzej Stuczynski 51ae70c02b Simple connection error listener 2020-03-12 11:16:00 +00:00
Dave Hrycyszyn dd466281dd Merge pull request #140 from nymtech/hotfix/default_logging_level
Defaulting for global 'Info' logging level if not set in .env
2020-03-12 08:36:19 +00:00
Jedrzej Stuczynski e8a5320ae6 Defaulting for global 'Info' logging level if not set in .env 2020-03-11 14:53:28 +00:00
Dave Hrycyszyn c5efc716c9 Merge pull request #139 from nymtech/feature/ignoring_loop_messages
Provider not storing loop cover messages
2020-03-11 11:28:05 +00:00
Dave Hrycyszyn 1b23b87abe Merge pull request #138 from nymtech/feature/timestamped_logs
Using log builder to include timestamps + filters
2020-03-11 11:27:26 +00:00
Dave Hrycyszyn 486980b906 Merge pull request #134 from nymtech/feature/client-ws-refactoring
Feature/client ws refactoring
2020-03-11 11:26:58 +00:00
Jedrzej Stuczynski 8160c5295b Provider not storing loop cover messages 2020-03-11 10:54:56 +00:00
Jedrzej Stuczynski c625c00d58 Using log builder to include timestamps + filters 2020-03-11 10:36:24 +00:00
Jedrzej Stuczynski 8226a6f0e8 get_all_clients method on topology accessor 2020-03-10 17:03:46 +00:00
Jedrzej Stuczynski 58f59277cc Split and cleaned up websocket handler 2020-03-10 17:03:29 +00:00
Jedrzej Stuczynski c6eb6cf552 More human readable addresses 2020-03-10 11:33:08 +00:00
Jedrzej Stuczynski 858481e1d2 Changed presence and metrics interval to use deadlines rather than fixed delays 2020-03-10 10:11:59 +00:00
Jedrzej Stuczynski a9a3e98801 Reverts changes in 744a004d06 2020-03-10 09:26:44 +00:00
Jedrzej Stuczynski fdd243a012 Merge branch 'develop' of github.com:nymtech/nym into develop 2020-03-09 16:58:13 +00:00
Jedrzej Stuczynski 30fcc54d8f Decreased default metrics and presence sending delay 2020-03-09 16:43:08 +00:00
Jedrzej Stuczynski aa7898eca2 Changed read to read_exact for reading sphinx packets to increase reliability 2020-03-09 16:42:46 +00:00
Dave Hrycyszyn b349b0e166 Merge pull request #131 from nymtech/feature/old-sample-configs
Removed outdated and redundant sample-configs
2020-03-09 12:11:36 +00:00
Jedrzej Stuczynski 9b7b359351 Merge branch 'develop' of github.com:nymtech/nym into develop 2020-03-09 12:05:28 +00:00
Dave Hrycyszyn d84951b6a5 Merge branch 'develop' of github.com:nymtech/nym into develop 2020-03-06 15:07:20 +00:00
Dave Hrycyszyn 744a004d06 Temporarily bumping up log levels to show good v bad packet ratio 2020-03-06 15:07:11 +00:00
Jedrzej Stuczynski 29f4ea25e8 Merge branch 'develop' of github.com:nymtech/nym into develop 2020-03-06 14:46:36 +00:00
Dave Hrycyszyn f0aa297054 Merge pull request #130 from nymtech/bugfix/default_announce_host
If not overridden, 'announce-host' should default to 'host'
2020-03-06 14:14:41 +00:00
Jedrzej Stuczynski 1b35de4326 Removed outdated and redundant sample-configs 2020-03-06 14:13:33 +00:00
Jędrzej Stuczyński 0caddb1610 Merge pull request #129 from nymtech/feature/add-directory-server-url-to-node-start
Nice to know who we're talking to at startup...
2020-03-06 14:11:30 +00:00
Jedrzej Stuczynski 3ccda81a24 Merge branch 'develop' of github.com:nymtech/nym into develop 2020-03-06 14:06:04 +00:00
Dave Hrycyszyn 817fc91a33 Nice to know who we're talking to at startup... 2020-03-06 14:05:03 +00:00
Jedrzej Stuczynski 562aeefc7a If not overridden, 'announce-host' should default to 'host' 2020-03-06 14:03:50 +00:00
Jedrzej Stuczynski cf01679c5c Merge tag 'v0.5.0-rc.1' into develop
v0.5.0-rc.1
2020-03-06 12:52:04 +00:00
Jedrzej Stuczynski 17b7f69b0c Merge branch 'release/v0.5.0-rc.1' 2020-03-06 12:51:52 +00:00
Jedrzej Stuczynski 4abb4d0b45 Updated run_local_network script to work with 0.5.0 2020-03-06 12:51:24 +00:00
Dave Hrycyszyn 986f285f4c Removing semi-confusing initial message to user 2020-03-06 12:34:39 +00:00
Jedrzej Stuczynski 2053eff036 Updated changelog 2020-03-06 12:04:40 +00:00
Jedrzej Stuczynski 2b1781b06d Updated binary versions 2020-03-06 11:47:52 +00:00
Dave Hrycyszyn 1a344a4331 Merge pull request #128 from nymtech/feature/client-refactoring
Feature/client refactoring
2020-03-06 11:41:07 +00:00
Jedrzej Stuczynski 6c730c217f Trying to run travis test in single threaded mode 2020-03-06 11:39:47 +00:00
Jedrzej Stuczynski d3594b620c Replaced cryptic unwrap with an expect 2020-03-05 15:29:25 +00:00
Jedrzej Stuczynski e194194478 experimental native rust api 2020-03-05 15:24:19 +00:00
Jedrzej Stuczynski f73d6371d2 Made clippy happier 2020-03-05 15:18:07 +00:00
Jedrzej Stuczynski 8b90953ae0 Allowed used of deprecated function inside a deprecated function 2020-03-05 15:07:33 +00:00
Jedrzej Stuczynski 9eae7a23ce Significantly reduced number of calls to clone topology 2020-03-05 14:59:55 +00:00
Jedrzej Stuczynski 374da49bcd Initial version of nym-client using persistent tcp connections
Not yet fully refactored
2020-03-05 12:54:17 +00:00
Jedrzej Stuczynski b343410840 Updated client config with tcp client related fields 2020-03-05 10:04:33 +00:00
Jedrzej Stuczynski 76cf73b70b Exposed new method 2020-03-04 15:34:57 +00:00
Jedrzej Stuczynski 9f416b6570 Converted cover traffic stream into an actual stream 2020-03-04 15:33:32 +00:00
Jedrzej Stuczynski 8cde30459b Made new and start method on buffer controller public to the crate 2020-03-04 14:39:16 +00:00
Jedrzej Stuczynski 7ea3c68820 Refactored received buffer controller 2020-03-04 14:37:27 +00:00
Dave Hrycyszyn 1d26ec1ada Merge pull request #125 from nymtech/feature/provider-refactoring
Feature/provider refactoring
2020-03-03 14:13:51 +00:00
Jedrzej Stuczynski 4992498942 Refactored client handling 2020-03-03 12:45:04 +00:00
Jedrzej Stuczynski 3852c99f9e Removed commented code 2020-03-03 12:44:50 +00:00
Jedrzej Stuczynski ff4284a3b9 Redundant code in mix handling 2020-03-03 12:44:37 +00:00
Jedrzej Stuczynski c167aca3e3 Theoretically thread safe client storage 2020-03-03 12:44:18 +00:00
Jedrzej Stuczynski 937e15e631 Removed unused 'has_client' method from the ledger 2020-03-03 12:43:50 +00:00
Jedrzej Stuczynski 59dcf77bf5 Defined ErrorResponse type 2020-03-03 12:43:28 +00:00
Jedrzej Stuczynski a411dec540 Client changes due to updates in sphinx 2020-03-03 10:23:55 +00:00
Jedrzej Stuczynski 20f2f1e04f Updated mockito to fix build issues 2020-03-03 10:21:58 +00:00
Jedrzej Stuczynski b6727ac7b4 Replaced retrieve token method with verify token to bypass lifetime issues 2020-03-02 17:04:58 +00:00
Jedrzej Stuczynski 8ed53847d3 Method to actually retrieve stored auth token to compare it against one sent 2020-03-02 15:55:52 +00:00
Jedrzej Stuczynski 0f5167b57f Added ledger method to remove existing token 2020-03-02 15:44:29 +00:00
Jedrzej Stuczynski 30611d0a68 Reversed Client ledger mapping 2020-03-02 15:43:52 +00:00
Jedrzej Stuczynski 3a2ad5ae10 sphinx version upgrade 2020-03-02 15:40:12 +00:00
Jedrzej Stuczynski 63dfbc1465 Using native to_base58_string in client ledger 2020-03-02 12:21:24 +00:00
Jedrzej Stuczynski 1f69f09072 Fixed address derivation 2020-03-02 12:19:38 +00:00
Jedrzej Stuczynski 575bcaa43b Adjusted field access to AuthToken 2020-03-02 12:13:53 +00:00
Jedrzej Stuczynski b85bc53002 Fix to provider requests due to previous sphinx changes 2020-03-02 12:13:31 +00:00
Jedrzej Stuczynski b8f0fdefee made has token method on client ledger public 2020-03-02 11:12:07 +00:00
Jedrzej Stuczynski 3851e9e350 Constructor for client storage 2020-03-02 09:52:51 +00:00
Jedrzej Stuczynski 73ea1e29e0 Pending work 2020-02-28 13:03:55 +00:00
Jedrzej Stuczynski a4c9bc1df6 Adjusted clients ledger 2020-02-28 13:03:43 +00:00
Jedrzej Stuczynski ec93fdbbde Extra comments + derived traits 2020-02-28 13:03:29 +00:00
Jedrzej Stuczynski 1d36f73e89 Handling of received sphinx packet (incl. store) 2020-02-28 13:02:52 +00:00
Jedrzej Stuczynski da9593cee2 Missed updated sphinx cargo.toml file 2020-02-28 12:33:21 +00:00
Jedrzej Stuczynski b6e2c25c09 Made relevant mix methods private 2020-02-28 12:33:09 +00:00
Jedrzej Stuczynski 03aac5bd35 Updated sphinx 2020-02-28 12:32:47 +00:00
Jedrzej Stuczynski 3cb813d056 Updated Storage to work with async io 2020-02-28 11:48:08 +00:00
Jędrzej Stuczyński 6606ba7279 Merge pull request #123 from nymtech/feature/persistence-typo-fix
all: fixing mis-spelling
2020-02-28 09:14:37 +00:00
Dave Hrycyszyn e600dc7c4f all: fixing mis-spelling 2020-02-27 17:14:52 +00:00
Jedrzej Stuczynski 88eef54cc5 dead code 2020-02-27 14:44:14 +00:00
Jedrzej Stuczynski b922c869f0 Got rid of compiler warnings 2020-02-27 14:42:46 +00:00
Jedrzej Stuczynski 0c90afeaa2 Adjusted tcp client tests to work concurrently + without "wait" 2020-02-27 14:37:01 +00:00
Jedrzej Stuczynski 3756de9e86 processing data -> packet processor 2020-02-27 14:22:50 +00:00
Jedrzej Stuczynski 7fd3e28f2a Renamed reconnection backoff to initial reconnection backoff 2020-02-27 14:22:36 +00:00
Jedrzej Stuczynski 511ec78b2c Removed resolved comment 2020-02-27 14:22:11 +00:00
Jedrzej Stuczynski c71a1ae71d Changes due to updated sphinx 2020-02-27 13:08:25 +00:00
Jedrzej Stuczynski 8c6744dd96 Mixes starting with empty list of endpoints 2020-02-27 13:07:55 +00:00
Jedrzej Stuczynski b489d422a2 Dynamic list of tcp connections 2020-02-27 13:07:41 +00:00
Jedrzej Stuczynski 71c465afd5 Updated sphinx rev 2020-02-27 12:49:49 +00:00
Jedrzej Stuczynski c6cceb8d4d Starting and using the forwarding channel 2020-02-27 12:20:00 +00:00
Jedrzej Stuczynski 8f48836fd4 Full sphinx packet processing 2020-02-27 12:19:44 +00:00
Jedrzej Stuczynski 594e42793e Updated client error message 2020-02-27 12:19:30 +00:00
Jedrzej Stuczynski dfb7c82c31 Updated mixnode config with forwarding data 2020-02-27 12:19:08 +00:00
Jedrzej Stuczynski 1418d068b0 Mixnode packet forwarder 2020-02-27 12:18:50 +00:00
Jedrzej Stuczynski 8febd59588 Changed LocalBoxFuture to BoxFuture in reconnector (adds Send requirement) 2020-02-27 12:18:38 +00:00
Jedrzej Stuczynski 0e6d0c5bda Beginning of listener and packet processing refactoring 2020-02-26 17:08:06 +00:00
Jedrzej Stuczynski f297ed7323 Refactored mixnode startup and moved a lot of code outside of mod.rs 2020-02-26 17:07:45 +00:00
Jedrzej Stuczynski 811e18b36e Refactored how metrics are handled - separate sender, receiver and reporter 2020-02-26 17:07:18 +00:00
Jedrzej Stuczynski d808c9dab4 changed presence notifier to return JoinHandle 2020-02-26 17:06:47 +00:00
Jedrzej Stuczynski 2eec9dc8a1 Required provider adjustments due to previous changes 2020-02-26 17:06:17 +00:00
Jedrzej Stuczynski 3f3dfd404c Removed derivation of copy on private keys 2020-02-26 17:05:36 +00:00
Jedrzej Stuczynski e03fd54739 Updated sphinx version 2020-02-26 17:05:18 +00:00
Jedrzej Stuczynski f136f8e75a Presence reporter responsible for starting own task 2020-02-26 11:31:27 +00:00
Jedrzej Stuczynski b27ebc3eed Updated travis to run tests in single threaded fashion 2020-02-25 16:34:43 +00:00
Jedrzej Stuczynski 732bf7472e Cleaned some imports by moving them to test module 2020-02-25 16:05:57 +00:00
Jedrzej Stuczynski 87bbe9c864 Remaining lifetime changes required by ibid. 2020-02-25 16:04:28 +00:00
Jedrzej Stuczynski d77f2b20ce Replaced scary looking Pin<Box<dyn Future<Output = ... >>> with LocalBoxFuture<...> 2020-02-25 16:01:48 +00:00
Jedrzej Stuczynski 04dec97109 Adjusted logging messages 2020-02-25 15:57:36 +00:00
Jedrzej Stuczynski 9b81c2eb68 Initial version of the reconnecting tcp client 2020-02-25 15:54:50 +00:00
Jedrzej Stuczynski f599502eab log dependency required by ibid. 2020-02-24 15:23:52 +00:00
Jedrzej Stuczynski a5c65b27d9 Experimenting with connection reconnector 2020-02-24 15:23:29 +00:00
Jedrzej Stuczynski bd86ef07a9 Client is now constructed with a config struct 2020-02-21 14:49:57 +00:00
Jedrzej Stuczynski 3f80a00bf1 Introduced backoff fields to connection writer 2020-02-21 14:49:44 +00:00
Jedrzej Stuczynski bfad2168b1 Maintaining persistent connection to server (no reconnection yet) 2020-02-21 14:30:16 +00:00
Jedrzej Stuczynski d807bcd1ee Created the multi-tcp-client crate 2020-02-21 14:29:26 +00:00
Dave Hrycyszyn 9612141129 Merge pull request #121 from nymtech/feature/further_clippy_fixes
Feature/further clippy fixes
2020-02-19 16:50:12 +00:00
Jedrzej Stuczynski 285e5dc5ec Clippy ignoring new_without_default for MixClient 2020-02-19 16:49:31 +00:00
Jedrzej Stuczynski 0928a5aaeb Making clippy nice and happy 2020-02-19 16:48:53 +00:00
Dave Hrycyszyn f2eb52fbcf Merge pull request #120 from nymtech/feature/tokio_tungstenite_dependency_fix
Feature/tokio tungstenite dependency fix
2020-02-19 16:25:10 +00:00
Dave Hrycyszyn aa93e611ee Merge pull request #119 from nymtech/feature/config_files_cleanup
Feature/config files cleanup
2020-02-19 16:22:59 +00:00
Jedrzej Stuczynski b68689dc4b Using proper release version of tokio-tungstenite rather than pointing to specific commit 2020-02-19 16:01:39 +00:00
Jedrzej Stuczynski 8229cb2c74 Logging message when binding to socket 2020-02-19 16:01:07 +00:00
Jedrzej Stuczynski bdf1e5bef9 Fixed further linter warnings 2020-02-19 15:47:38 +00:00
Jedrzej Stuczynski 1a8573632f 'new_without_default' clippy warnings 2020-02-19 15:38:46 +00:00
Jedrzej Stuczynski a62744a177 Fixed clippy warnings 2020-02-19 15:33:37 +00:00
Jedrzej Stuczynski a6c389b5a6 Renamed 'average_delay_duration' to just 'average_delay' 2020-02-19 15:19:13 +00:00
Jedrzej Stuczynski f72b456cdd Renamed poisson::sample_from_duration to poisson::sample 2020-02-19 15:18:00 +00:00
Jedrzej Stuczynski 6515666b84 Removed comments regarding keypair for sfw-provider init 2020-02-19 11:41:27 +00:00
Jedrzej Stuczynski 16c92bebdf Removed the fake-news comments 2020-02-19 11:37:47 +00:00
Jedrzej Stuczynski 15b626bb6f Removed comments regarding keypair for mixnode init 2020-02-19 11:24:36 +00:00
Dave Hrycyszyn ef4929dacc Fixed banner usage 2020-02-17 16:32:46 +00:00
Dave Hrycyszyn 9391e7148a Merge branch 'feature/config_files' into develop 2020-02-17 14:56:26 +00:00
Jedrzej Stuczynski 1f06aa2fb9 ibid. 2020-02-05 16:53:31 +00:00
Jedrzej Stuczynski 800c41ce97 Removed unused imports 2020-02-05 16:52:17 +00:00
Jedrzej Stuczynski 1fa599dd63 Getting rid of direct Scalar and MontgomeryPoint imports 2020-02-05 16:51:56 +00:00
Jedrzej Stuczynski bf93739ef5 Updated validator config template 2020-02-05 16:36:32 +00:00
Jedrzej Stuczynski a9e0a1d634 Updated config override for validator 2020-02-05 16:31:26 +00:00
Jedrzej Stuczynski ab24008c87 Fixed compilation error due to old imports 2020-02-05 16:29:07 +00:00
Jedrzej Stuczynski 1f53dcc56f Removed no longe used toml dependency from the validator 2020-02-05 16:28:56 +00:00
Jedrzej Stuczynski 9f49746b44 Actually using proper config 2020-02-05 16:27:31 +00:00
Jedrzej Stuczynski 7f999d5893 Validator using new config 2020-02-05 16:25:47 +00:00
Jedrzej Stuczynski 852d127a2a Mix mining config section 2020-02-05 16:25:34 +00:00
Jedrzej Stuczynski 0d3084b956 Updated validator dependencies 2020-02-05 16:02:59 +00:00
Jedrzej Stuczynski da8365ee14 Running validator via commands::run::execute 2020-02-05 16:02:44 +00:00
Jedrzej Stuczynski 95d1912e18 More typos 2020-02-05 15:57:36 +00:00
Jedrzej Stuczynski ae27a5e4c3 Corrected run description for sfw-provider 2020-02-05 15:55:14 +00:00
Jedrzej Stuczynski 28b5673cbf Corrected description to say validator instead of mixnode 2020-02-05 15:54:31 +00:00
Jedrzej Stuczynski 5aee54fc1d Stubs for validator configs 2020-02-05 15:53:02 +00:00
Jedrzej Stuczynski 84cb98ca96 Override config stub 2020-02-05 15:52:42 +00:00
Jedrzej Stuczynski 8ea9b14e94 Init command for the validator 2020-02-05 15:52:35 +00:00
Jedrzej Stuczynski 83e22dbad9 Moved built_info module to separate file 2020-02-05 15:52:19 +00:00
Jedrzej Stuczynski 3497ae1043 Pushing those new debug options down the provider processing stack 2020-02-05 13:00:20 +00:00
Jedrzej Stuczynski 4e4024aba6 Fixed broken tests 2020-02-05 12:49:47 +00:00
Jedrzej Stuczynski 95160a2ba3 Additional debug options 2020-02-05 12:45:47 +00:00
Jedrzej Stuczynski 3fdf7b4f10 Provider starting to use new config 2020-02-05 12:38:32 +00:00
Jedrzej Stuczynski c5ec0591e1 Changes to provider presence notifier similar to the ones in mixnode 2020-02-05 12:31:00 +00:00
Jedrzej Stuczynski 82bcb3f79f made net_client private 2020-02-05 12:30:39 +00:00
Jedrzej Stuczynski 0ab7e4ddd9 mix-host and client-host no longer required for 'run' 2020-02-05 12:15:06 +00:00
Jedrzej Stuczynski 2df3a262ef Fixed errors in template causing loading errors 2020-02-05 12:11:51 +00:00
Jedrzej Stuczynski 5f393de34b Provider pathfinder (identical to mixnode's) 2020-02-05 12:08:21 +00:00
Jedrzej Stuczynski 48c77bcb0d Template for provider config 2020-02-05 12:08:01 +00:00
Jedrzej Stuczynski 0084c74f97 typo 2020-02-05 12:05:46 +00:00
Jedrzej Stuczynski 7d9e2ef64a "mixnode" => "provider" 2020-02-05 11:58:35 +00:00
Jedrzej Stuczynski 75df3a87b8 Provider sphinx key loading 2020-02-05 11:49:40 +00:00
Jedrzej Stuczynski 4c9c742795 Updated provider dependencies 2020-02-05 11:49:27 +00:00
Jedrzej Stuczynski 30bf382d0a Better argument description 2020-02-05 11:49:11 +00:00
Jedrzej Stuczynski 881ab4f28e config changes required by ibid. 2020-02-05 11:48:46 +00:00
Jedrzej Stuczynski 851ccfd736 Ability to start provider with new 'run' method (but still using old config) 2020-02-05 11:48:33 +00:00
Jedrzej Stuczynski 133d36b559 override config function 2020-02-05 11:23:54 +00:00
Jedrzej Stuczynski d6824ccad2 announce-X-host/port => X-announce-host/port 2020-02-05 11:15:14 +00:00
Jedrzej Stuczynski 273a61d7de client => clients 2020-02-05 11:12:22 +00:00
Jedrzej Stuczynski e8b9d641ba Init command for the provider 2020-02-05 11:02:02 +00:00
Jedrzej Stuczynski 61b9fac25b Initial definition of new sfw provider config 2020-02-05 10:39:27 +00:00
Jedrzej Stuczynski 0d5fe1a788 Starting provider via commands::run::execute 2020-02-04 15:55:36 +00:00
Jedrzej Stuczynski bc8e5fd6f6 Adjusted mixnode config template to new changes 2020-02-04 15:24:12 +00:00
Jedrzej Stuczynski 441e586915 Accidentally removed import path 2020-02-04 15:18:52 +00:00
Jedrzej Stuczynski bed0badc15 Defaults in the config + using said fields when starting mixnode 2020-02-04 15:17:25 +00:00
Jedrzej Stuczynski 448fc4a361 ibid. for metrics 2020-02-04 15:15:51 +00:00
Jedrzej Stuczynski fd33589326 Using sending delay from config for the presence notifier 2020-02-04 15:14:17 +00:00
Jedrzej Stuczynski 1080ad5ac1 Two debug directory servers - presence and metrics 2020-02-04 15:08:13 +00:00
Jedrzej Stuczynski 7723dc7aed constant default port 2020-02-04 14:50:20 +00:00
Jedrzej Stuczynski b2f41de27b Constructor for notifier config 2020-02-04 14:36:02 +00:00
Jedrzej Stuczynski ed9ee27340 Uncommited mixnode persitance module 2020-02-04 13:18:00 +00:00
Jedrzej Stuczynski e1cc16fe81 Using new config in mixnode constructor 2020-02-04 13:12:17 +00:00
Jedrzej Stuczynski 937becb1ac Removed runner 2020-02-04 13:11:37 +00:00
Jedrzej Stuczynski fe93a3f4d5 Removed client keys being loaded twice 2020-02-04 13:08:21 +00:00
Jedrzej Stuczynski fee81aaff7 Changed layer from usize to u64 for better serialization 2020-02-04 13:04:41 +00:00
Jedrzej Stuczynski b1207caf7c Inner methods on private/public encryption keys 2020-02-04 12:58:24 +00:00
Jedrzej Stuczynski 5fd8987eb9 More easily expandable list of 'special' addresses that show binding warning 2020-02-04 12:54:16 +00:00
Jedrzej Stuczynski f858d407ca Starting the mixnode with commands::run::execute 2020-02-04 12:48:40 +00:00
Jedrzej Stuczynski 8caf218aed To and from b58 string on encryption public key 2020-02-04 12:39:03 +00:00
Jedrzej Stuczynski 6c32d64194 Changed config to be more explicit about type of keys used 2020-02-04 12:36:06 +00:00
Jedrzej Stuczynski 7a99905f1d Generating and saving keys on mixnode init 2020-02-04 12:34:53 +00:00
Jedrzej Stuczynski 25a8f63912 Extracted config overriding, similarly to nym-client 2020-02-04 12:34:38 +00:00
Jedrzej Stuczynski c6fa539845 Pemstore capable of using slightly more generic types 2020-02-04 12:14:09 +00:00
Jedrzej Stuczynski 4c900bbfff Extended pemstorable traits with methods required for more generic store 2020-02-04 12:13:49 +00:00
Jedrzej Stuczynski 165d022015 Defined 'PemStorableKeypair' trait and implemented it on existing keypairs 2020-02-04 11:28:49 +00:00
Jedrzej Stuczynski 495b0c7ed9 Renamed 'PemStorable' trait to 'PemStorableKey' 2020-02-04 11:21:00 +00:00
Jedrzej Stuczynski a491f7543a More builder methods, incl. announce host/port parsers 2020-02-03 17:20:29 +00:00
Jedrzej Stuczynski 901996345c announce address in template 2020-02-03 17:19:52 +00:00
Jedrzej Stuczynski 15c0c731e9 Saving mixnode's config on init 2020-02-03 15:24:31 +00:00
Jedrzej Stuczynski fad5c98629 Initial mix config with working default test 2020-02-03 15:02:13 +00:00
Jedrzej Stuczynski de2dbf7156 Started creating mixnode commands, similarly to client 2020-02-03 14:15:22 +00:00
Jedrzej Stuczynski 1e1e1db4f5 Printing nym banner even in case of invalid command 2020-02-03 13:15:24 +00:00
Jedrzej Stuczynski c7c52e68b5 Moved args definition to specific commands file 2020-02-03 13:07:45 +00:00
Jedrzej Stuczynski ac5d16899e Using the new config options + slightly better constructor for topology controller 2020-02-03 12:25:08 +00:00
Jedrzej Stuczynski 9e890da986 Additional debug config options 2020-02-03 12:02:43 +00:00
Jedrzej Stuczynski ab2703e6c1 Updated comments on ibid. 2020-02-03 11:57:50 +00:00
Jedrzej Stuczynski 21877c240b Added topology resolution timeout to client debug config 2020-02-03 11:56:39 +00:00
Jedrzej Stuczynski e091d30f6e Slightly better logging messages 2020-02-03 11:51:01 +00:00
Jedrzej Stuczynski 04e415eb0c No more panics on websocket handshake error 2020-02-03 11:48:26 +00:00
Jedrzej Stuczynski 35f5816da8 Using auth token obtained during init 2020-02-03 11:36:29 +00:00
Jedrzej Stuczynski efda3ee834 Further decreased logging level during healthcheck 2020-02-03 11:36:02 +00:00
Jedrzej Stuczynski ce6d858b88 Additional comments 2020-02-03 11:07:31 +00:00
Jedrzej Stuczynski 82232f970a Choosing provider at startup + (if applicable) performing registration 2020-02-03 11:07:13 +00:00
Jedrzej Stuczynski b72ce283b4 Derived Into<String> for AuthToken using existing to base58 method 2020-02-03 11:06:43 +00:00
Jedrzej Stuczynski cc5627f0c3 Notice regarding client address 2020-02-03 09:57:06 +00:00
Jedrzej Stuczynski 0f03221fb9 Removed redundant key info print 2020-02-03 09:54:43 +00:00
Jedrzej Stuczynski 98ea9dccdf Removed duplicate code for overwriting config values 2020-02-03 09:40:53 +00:00
Jedrzej Stuczynski 8747dc9d72 Unused import 2020-02-03 09:31:31 +00:00
Jedrzej Stuczynski a4d500f0f5 Additional optional arguments for client init 2020-01-31 16:32:32 +00:00
Jedrzej Stuczynski 9e0735498b Corrected client config template comments 2020-01-31 16:27:56 +00:00
Jedrzej Stuczynski 12fc906542 Changing poisson sampling to sample from time::Duration 2020-01-31 16:24:14 +00:00
Jedrzej Stuczynski 94479cdeec Loop cover messages having parameterized delays 2020-01-31 16:20:49 +00:00
Jedrzej Stuczynski bcbebe944d Borrow checker 2020-01-31 16:16:26 +00:00
Jedrzej Stuczynski 199377d466 Made 'run' command compilable again 2020-01-31 16:15:52 +00:00
Jedrzej Stuczynski 98a19e7823 Removed websocket and tcpsocket commands 2020-01-31 16:15:09 +00:00
Jedrzej Stuczynski d9a95917e3 Moved SocketType enum to config 2020-01-31 16:13:23 +00:00
Jedrzej Stuczynski 6432e708d6 Extra argument to cover traffic stream 2020-01-31 16:10:00 +00:00
Jedrzej Stuczynski 409bfb4f08 ibid. for provider poller 2020-01-31 16:05:22 +00:00
Jedrzej Stuczynski c921223ac2 Changed topology control to also use time::duration 2020-01-31 16:02:34 +00:00
Jedrzej Stuczynski 8c68a812e2 Made client config delay getters return time::duration 2020-01-31 16:00:17 +00:00
Jedrzej Stuczynski 79b18a4789 Fixed initial real packet timing bias + duration parameterization 2020-01-31 15:57:45 +00:00
Jedrzej Stuczynski f3da6d4258 Updated used sphinx revision 2020-01-31 15:07:38 +00:00
Jedrzej Stuczynski 1e938dfd55 Provider poller getting rate from the provided config value 2020-01-31 13:04:39 +00:00
Jedrzej Stuczynski e48b28eefd Generating proper tmp random dir on each test run 2020-01-31 12:51:17 +00:00
Jedrzej Stuczynski ea5223ddf5 Custom deserializer for Option<String> to fix receiving Some("") rather than None 2020-01-31 12:50:56 +00:00
Jedrzej Stuczynski 65772cdc1e Fixed how ensuring config save directory exists 2020-01-31 12:40:16 +00:00
Jedrzej Stuczynski f8a468135a Replaced AuthToken with new implementation 2020-01-31 11:59:27 +00:00
Jedrzej Stuczynski 5a4bf6f08a ibid. 2020-01-31 11:49:45 +00:00
Jedrzej Stuczynski dbf3c0d6ea Created new version of AuthToken that can be converted to and from String 2020-01-31 11:49:36 +00:00
Jedrzej Stuczynski abd937e308 Started modifying NymClient to hold config struct 2020-01-31 11:49:03 +00:00
Jedrzej Stuczynski f23fd57e8d TCP and WebSocket taking only port as an argument rather than whole SocketAddr 2020-01-31 11:48:41 +00:00
Jedrzej Stuczynski e9f96e030f Extra bit of information in template indicating AuthToken is expected to be b58 2020-01-31 11:48:16 +00:00
Jedrzej Stuczynski 02add8d416 More config getters + extra comments 2020-01-31 11:47:46 +00:00
Jedrzej Stuczynski a5cee1fa62 Topology refresh switching to millis interval 2020-01-31 11:47:20 +00:00
Jedrzej Stuczynski bc18173ffa Made builder methods on config more generic to accept any kind of strings 2020-01-31 10:19:10 +00:00
Jedrzej Stuczynski 3ac46255f0 ibid. 2020-01-31 10:18:40 +00:00
Jedrzej Stuczynski b8530c91c1 Made conversion into 'SocketType' enum more generic
Now it works for anything that can be converted into String
2020-01-31 10:10:52 +00:00
Jedrzej Stuczynski f13e5ae186 Allow using "ws" alias for websocket 2020-01-31 10:07:58 +00:00
Jedrzej Stuczynski 0780f6c501 Added optional provider auth token to config 2020-01-31 10:04:29 +00:00
Jedrzej Stuczynski 09ac19fb45 Using except rather than unwrap during client init 2020-01-31 10:04:10 +00:00
Jedrzej Stuczynski bb29421854 Ensuring the whole path to pem files exist before saving 2020-01-31 10:03:51 +00:00
Jedrzej Stuczynski 2ac707d57c Constructing client config + printing it 2020-01-30 17:07:05 +00:00
Jedrzej Stuczynski af5c389eea Ability to convert SocketType from &str or String 2020-01-30 17:06:45 +00:00
Jedrzej Stuczynski b27b619412 Debug on Pathfinder 2020-01-30 16:13:11 +00:00
Jedrzej Stuczynski 7b0aee7a2c Using correct methods 2020-01-30 16:13:04 +00:00
Jedrzej Stuczynski 807e4234d6 Default save_to_file method making sure the directory exists 2020-01-30 16:12:44 +00:00
Jedrzej Stuczynski 51e43547ed Changed NymConfig to take optional id for some of its method 2020-01-30 16:09:53 +00:00
Jedrzej Stuczynski 2e63f95b76 More descriptive variable names in pemstore 2020-01-30 16:08:44 +00:00
Jedrzej Stuczynski 32f067256b Pemstore no longer creating directory for config file 2020-01-30 16:08:30 +00:00
Jedrzej Stuczynski e97102d3e4 Generating and saving client config on client init 2020-01-30 14:55:33 +00:00
Jedrzej Stuczynski 851bad7864 Extra logging for pemstore 2020-01-30 14:55:21 +00:00
Jedrzej Stuczynski 728f5e237a Ability to create client pathfinder from the config 2020-01-30 14:55:10 +00:00
Jedrzej Stuczynski 9767dd58ca Additional methods on client config 2020-01-30 14:54:58 +00:00
Jedrzej Stuczynski f33e9e80f6 Added config_file_name() to NymConfig trait 2020-01-30 14:54:45 +00:00
Jedrzej Stuczynski 0ad648703f Changed delays/intervals values to use millis rather than seconds 2020-01-30 14:21:44 +00:00
Dave Hrycyszyn a3b3cc1edd validator: minor variable name change 2020-01-30 13:04:43 +00:00
Dave Hrycyszyn 793d42c33a mixnode: running without args isn't an error 2020-01-30 13:01:26 +00:00
Jedrzej Stuczynski 03f7be502b Updated import path for serde 2020-01-30 12:57:06 +00:00
Jedrzej Stuczynski 3409dfcdf3 Merge branch 'develop' into feature/config_files 2020-01-30 12:50:35 +00:00
Jędrzej Stuczyński fd89dc36ec Merge pull request #111 from nymtech/feature/un-genericize-keys
Feature/un genericize keys
2020-01-30 12:49:19 +00:00
Dave Hrycyszyn 9797b8da74 crypto: simplified keypairs a bit 2020-01-30 12:27:00 +00:00
Dave Hrycyszyn 6b879e88e7 nym: removing type parameters on keypairs 2020-01-30 12:19:23 +00:00
Dave Hrycyszyn d3199778e4 validator: starting removal of keypair generics 2020-01-30 11:55:15 +00:00
Dave Hrycyszyn c426b09b07 validator: placeholder comment for Ethereum integration 2020-01-30 11:50:37 +00:00
Jędrzej Stuczyński 3c6e6d1ad7 Merge pull request #110 from nymtech/feature/abci
Feature/abci
2020-01-30 11:46:31 +00:00
Dave Hrycyszyn 46055fe8c4 validator: removing unused config 2020-01-30 11:33:04 +00:00
Dave Hrycyszyn d75ac203d2 validator: simplified task spawning 2020-01-30 11:32:06 +00:00
Dave Hrycyszyn c4c004cd9c validator: WIP on merge conflicts 2020-01-30 11:25:00 +00:00
Dave Hrycyszyn c956576231 Merge pull request #109 from nymtech/feature/keypair_generic_cleanup
Simplified the use of generics on identity keypair by using output types
2020-01-30 10:33:02 +00:00
Jedrzej Stuczynski 2d99b2b93a Fixed validator compilation error 2020-01-30 10:19:55 +00:00
Jedrzej Stuczynski 713a7a6fe8 Initial fields for the client config 2020-01-29 16:04:57 +00:00
Jedrzej Stuczynski 00dc25a94f Definition of NymConfig trait + default methods 2020-01-29 16:04:27 +00:00
Jedrzej Stuczynski a73585e13a Simplified the use of generics on identity keypair by using output types 2020-01-29 15:30:20 +00:00
Dave Hrycyszyn acc0f8430a validator: updating run instructions 2020-01-29 13:05:16 +00:00
Dave Hrycyszyn aa251c2450 validator: multi-threading tendermint so that health check also works 2020-01-29 13:02:48 +00:00
Dave Hrycyszyn bb0737e0c8 validator: removing logging for now 2020-01-29 13:01:00 +00:00
Dave Hrycyszyn 536b84c55c validator: removing logging calls 2020-01-29 12:59:02 +00:00
Dave Hrycyszyn b427ffc80d validator: removing serde stuff in abci 2020-01-29 12:58:40 +00:00
Dave Hrycyszyn d729e05d98 ibid 2020-01-29 12:55:04 +00:00
Dave Hrycyszyn b93457b863 validator: changing tendermint start to run() 2020-01-29 12:54:30 +00:00
Dave Hrycyszyn f02b37f5c9 validator: pulling tendermint ABCI out into its own type. 2020-01-29 12:50:09 +00:00
Dave Hrycyszyn 8c9d68041c validator: renamed tendermint integration 2020-01-29 12:49:51 +00:00
Dave Hrycyszyn d9613043ec validator: comment on networks 2020-01-29 12:28:29 +00:00
Dave Hrycyszyn 4c4ec08122 validator: fixing health_check typo in Validator struct 2020-01-29 11:35:39 +00:00
Dave Hrycyszyn 62f4c8bebd validator: import the abci interface for use by the runner 2020-01-29 11:34:49 +00:00
Dave Hrycyszyn 7a68499c11 validator: easier log level switches 2020-01-29 11:34:18 +00:00
Dave Hrycyszyn ef64871f78 validator: adding an async start() method to abci network interface 2020-01-29 11:33:47 +00:00
Dave Hrycyszyn 81ed98d3ec validator: pulling all log levels into main 2020-01-29 11:33:23 +00:00
Dave Hrycyszyn 657e092887 mixnode: minor re-ordering of start() operations 2020-01-29 10:47:46 +00:00
Jedrzej Stuczynski 53a3ceaa00 Merge branch 'develop' into feature/config_files 2020-01-29 10:18:39 +00:00
Jedrzej Stuczynski b9f3000dcc Updated changelog 2020-01-29 10:17:47 +00:00
Jedrzej Stuczynski 04db04ff62 Merge tag 'v0.4.1' into develop
Release 0.4.1
2020-01-29 10:15:44 +00:00
Jedrzej Stuczynski b06b842885 Merge branch 'release/v0.4.1' 2020-01-29 10:15:30 +00:00
Jedrzej Stuczynski 2b73aa9976 Updated packages versions 2020-01-29 10:14:53 +00:00
Dave Hrycyszyn e63012d979 validator: removed separate "tm" command 2020-01-29 09:33:38 +00:00
Dave Hrycyszyn 17a513d5fb validator: Tendermint ABCI works with Validator struct. 2020-01-29 09:31:01 +00:00
Dave Hrycyszyn ae7c1467ae validator: simplifying structure of networking interface files 2020-01-29 09:26:08 +00:00
Dave Hrycyszyn 80f92254e0 Ignoring validator config file inside repo 2020-01-29 09:25:34 +00:00
Dave Hrycyszyn 4ab9b8414d Removing the validator folder, having two seems overly nested 2020-01-29 08:49:13 +00:00
Dave Hrycyszyn 79f9372ebb validator: banging structure around a bit 2020-01-29 08:46:09 +00:00
Dave Hrycyszyn 482deb718c validator: more docs 2020-01-29 08:45:51 +00:00
Dave Hrycyszyn 473c5cd43d validator: using info logging 2020-01-29 08:20:06 +00:00
Dave Hrycyszyn 07061c2ca7 Merge pull request #108 from nymtech/bugfix/healthcheck_on_provided_topology
Bugfix/healthcheck on provided topology
2020-01-28 18:24:58 +00:00
Jedrzej Stuczynski e23dd57213 Client using pre-filtered topology for the healthchecker 2020-01-28 18:07:24 +00:00
Jedrzej Stuczynski eb3aa0baf1 healthchecker no longer pulling entire topology itself 2020-01-28 18:06:59 +00:00
Jedrzej Stuczynski d7b069e0e5 validator responsible for running healtchecker loop 2020-01-28 18:06:39 +00:00
Dave Hrycyszyn 24d9825a49 Fixed changelog v prefix on version 2020-01-28 17:04:37 +00:00
Jedrzej Stuczynski ca1d5b0803 Merge branch 'develop' into feature/config_files 2020-01-28 16:42:57 +00:00
Dave Hrycyszyn 00ab655848 Merge tag 'v0.4.0' into develop
0.4.0 final release
2020-01-28 16:27:26 +00:00
Dave Hrycyszyn d21a4bd4de Merge branch 'release/v0.4.0' 2020-01-28 16:27:15 +00:00
Dave Hrycyszyn 30da43060f Changelog for 0.4.0 2020-01-28 16:26:57 +00:00
Dave Hrycyszyn 922223219d Version bump for release 0.4.0 2020-01-28 16:19:56 +00:00
Dave Hrycyszyn dee2541cc3 Merge tag '0.4.0-rc.2' into develop
0.4.0-rc.2 pre-release
2020-01-28 15:38:33 +00:00
Dave Hrycyszyn a6cbdf5662 Merge branch 'release/0.4.0-rc.2' 2020-01-28 15:38:19 +00:00
Dave Hrycyszyn d189e6f55d Regenerated changelog 2020-01-28 15:38:09 +00:00
Dave Hrycyszyn 1d58d1c2f1 Fixed changelog generator script 2020-01-28 15:38:01 +00:00
Dave Hrycyszyn 78e93cfa15 Merge branch 'master' into release/0.4.0-rc.2 2020-01-28 15:32:22 +00:00
Dave Hrycyszyn 516077086c all: bumped version numbers to 0.4.0-rc.2 2020-01-28 15:32:09 +00:00
Dave Hrycyszyn b20555c622 validator: slight comment change 2020-01-28 13:31:13 +00:00
Dave Hrycyszyn 742c428a25 validator: sample tendermint counter app is breathing. 2020-01-28 13:28:42 +00:00
Dave Hrycyszyn 58f839ecd8 ibid 2020-01-28 13:28:20 +00:00
Dave Hrycyszyn dd2e4f153a validator: adding byteorder crate 2020-01-28 13:28:11 +00:00
Dave Hrycyszyn 74bf2ed9f4 validator: using exact Tendermint version specified by rust-abci crate docs 2020-01-28 13:03:24 +00:00
Dave Hrycyszyn 677791d64c ibid 2020-01-28 12:49:34 +00:00
Dave Hrycyszyn cdbadaf581 scripts: changelog generation script 2020-01-28 12:49:28 +00:00
Dave Hrycyszyn ee8da3a019 validator: starting a README so docs will be easier to write when we switch from Go 2020-01-28 12:47:16 +00:00
Dave Hrycyszyn 6a33168973 validator: adding the abci crate 2020-01-28 12:46:53 +00:00
Jedrzej Stuczynski 8f5a27cb4a Merge branch 'develop' into feature/config_files 2020-01-28 12:37:28 +00:00
Dave Hrycyszyn 9d024f35a3 Merge pull request #106 from nymtech/hotfix/semver_compatibility
Hotfix/semver compatibility
2020-01-28 12:28:22 +00:00
Jedrzej Stuczynski 3e40d90b72 Restored commented tests 2020-01-28 12:26:46 +00:00
Jedrzej Stuczynski 8731934f46 Fixed semver version compatibility 2020-01-28 12:26:24 +00:00
Dave Hrycyszyn ef8872896f Merge tag 'v0.4.0-rc.1' into develop
Pre-release of version 0.4.0.
2020-01-28 12:06:58 +00:00
Dave Hrycyszyn c9cefa9b66 Merge branch 'release/v0.4.0-rc.1' 2020-01-28 12:06:31 +00:00
Dave Hrycyszyn 1bc68ddfa1 changelog: moving to a unified, autogenerated changelog 2020-01-28 12:05:39 +00:00
Dave Hrycyszyn b8fed18c77 cargo: bumping all binary crate version numbers to 0.4.0-rc.1 2020-01-28 11:50:11 +00:00
Jedrzej Stuczynski 0785ad67f5 Merge with develop 2020-01-28 10:10:52 +00:00
Dave Hrycyszyn 1a6226f2bf Merge pull request #105 from nymtech/feature/health_checker_with_existing_keys
Feature/health checker with existing keys
2020-01-27 17:17:48 +00:00
Jedrzej Stuczynski b0e5f7c808 Validator using new healthcheck + added identity key 2020-01-27 17:11:28 +00:00
Jedrzej Stuczynski a9ad990452 Missing cargo.toml changes 2020-01-27 17:11:09 +00:00
Jedrzej Stuczynski 52aede3d99 More generic nym-client with regards to identity keypair 2020-01-27 17:10:53 +00:00
Jedrzej Stuczynski c662dad57f Healthchecker getting keypair from outside rather than generating new one every run 2020-01-27 17:10:29 +00:00
Jedrzej Stuczynski 4ace90ad8b Clone requirement on identity keys + 'derive address' method on public key 2020-01-27 17:08:50 +00:00
Jedrzej Stuczynski 6168cb7276 Decreased logging severity for failing to close read tcp socket 2020-01-27 17:08:12 +00:00
Jędrzej Stuczyński b112f82a7b Merge pull request #104 from nymtech/feature/remove-topology-equality-check
Feature/remove topology equality check
2020-01-27 15:09:48 +00:00
Jędrzej Stuczyński 3c45d17e71 Merge pull request #102 from nymtech/feature/base58
Feature/base58
2020-01-27 15:01:09 +00:00
Dave Hrycyszyn e5580df77b directory-client: removed premature equality check which caused a lock update problem 2020-01-27 14:59:56 +00:00
Dave Hrycyszyn a55b87809e encoding: updating all remaining usages of base64 to base58 2020-01-27 12:10:18 +00:00
Dave Hrycyszyn 1ab4e3efeb ibid 2020-01-27 12:09:57 +00:00
Dave Hrycyszyn b009eb0a4d ibid 2020-01-27 12:09:50 +00:00
Dave Hrycyszyn 416e1f19e0 cargo: updating sphinx to latest pinned version 2020-01-27 12:09:39 +00:00
Dave Hrycyszyn bdda6e2cf5 Removed base64 in favour of base58. 2020-01-27 11:52:44 +00:00
Dave Hrycyszyn c94691d68e nym-client: swapping bs58 for base64 2020-01-27 11:35:11 +00:00
Dave Hrycyszyn 83aa0a37b1 sfw-provider: changed on-disk storage location from hex to base58 2020-01-24 16:50:06 +00:00
Dave Hrycyszyn a198268009 nym-client: renamed suspicious hex variable (which contains bytes) 2020-01-24 16:46:12 +00:00
Dave Hrycyszyn e1b3a22bc5 nym-client: removed the hex crate 2020-01-24 16:45:40 +00:00
Dave Hrycyszyn 398fa5c643 Merge branch 'develop' into feature/base58 2020-01-24 16:40:32 +00:00
Dave Hrycyszyn 559cffdb56 sfw-provider: swapping out base64 for base58 2020-01-24 16:37:35 +00:00
Dave Hrycyszyn da6aac176b nym-client: adding bs58 crate 2020-01-24 16:34:55 +00:00
Dave Hrycyszyn d71d2effe6 topology: removing base64 crate 2020-01-24 16:29:41 +00:00
Dave Hrycyszyn aa7ff75be7 mixnode: replaced base64 with base58 2020-01-24 16:29:02 +00:00
Dave Hrycyszyn 80537045b4 directory-client: fullpath on std::io::Error needed for some reason 2020-01-24 16:22:44 +00:00
Dave Hrycyszyn 8cf37e10ce directory-client: removing unused imports 2020-01-24 16:21:23 +00:00
Dave Hrycyszyn a1af0b9345 directory-client: ripped presence apart a bit 2020-01-24 16:18:22 +00:00
Dave Hrycyszyn ea2be1a7ec Merge pull request #101 from nymtech/feature/panic_improvements
Feature/panic improvements
2020-01-24 16:12:05 +00:00
Dave Hrycyszyn d6ce495e08 git: ignoring local dictionary 2020-01-24 15:42:27 +00:00
Dave Hrycyszyn 0e85f6de0f topology: using base58 for decoding keys 2020-01-24 15:39:27 +00:00
Jedrzej Stuczynski 1b787c94bf Removed unwrap/expect calls wherever feasible and introduced Result types where appropriate 2020-01-24 15:31:40 +00:00
Dave Hrycyszyn a4ead85a01 topology: added bs58 crate 2020-01-24 15:11:16 +00:00
Dave Hrycyszyn d744fa587f topology: removing curve25519_dalek crate, it's no longer needed 2020-01-24 15:11:03 +00:00
Dave Hrycyszyn 0fee2b0ceb Merge branch 'develop' into feature/base58 2020-01-24 15:05:34 +00:00
Dave Hrycyszyn 28d8fbedc9 nym-client: revamped error message in websocket 2020-01-24 14:57:39 +00:00
Dave Hrycyszyn 6fb991a1b0 mixnode: typo fix in comments 2020-01-24 14:54:27 +00:00
Jedrzej Stuczynski d41023d26f Better unwrap usage for nym-client 2020-01-24 14:44:40 +00:00
Jedrzej Stuczynski 0093951507 Improved usage of unwraps and expects for provider 2020-01-24 14:37:36 +00:00
Jedrzej Stuczynski 3db34e7717 typo 2020-01-24 14:14:49 +00:00
Jedrzej Stuczynski 9913f6f041 Additional mixnode error checks 2020-01-24 14:12:41 +00:00
Jedrzej Stuczynski 6f83785b3a Creating mix peer checks for correct address 2020-01-24 14:12:28 +00:00
Jedrzej Stuczynski ce56b525bb socket_address_from_encoded_bytes returning Result 2020-01-24 14:12:07 +00:00
Jedrzej Stuczynski 44e146e2a2 Removed calls to unwrap at mixnode 2020-01-24 14:03:43 +00:00
Jędrzej Stuczyński ef20979753 Merge pull request #100 from nymtech/feature/fix-sphinx-unwraps-65
Feature/fix sphinx unwraps
2020-01-24 13:38:27 +00:00
Dave Hrycyszyn a187399c7d sphinx: gracefully handling packet unwrap failures 2020-01-24 13:17:37 +00:00
Dave Hrycyszyn f5bbfa8975 cargo: updating all crates to use newest Sphinx 2020-01-24 13:17:15 +00:00
Jędrzej Stuczyński 18be267b64 Merge pull request #99 from nymtech/feature/check-packet-length
Feature/check packet length
2020-01-24 13:16:30 +00:00
Dave Hrycyszyn 2d35ec354e Merge branch 'develop' into feature/check-packet-length 2020-01-24 12:57:14 +00:00
Jędrzej Stuczyński b7d8dc4769 Merge pull request #96 from nymtech/feature/version-filtering-improvements
Feature/version filtering improvements
2020-01-24 12:56:02 +00:00
Dave Hrycyszyn 5c1559dd78 nym-client: using the new Sphinx max packet length constant 2020-01-24 12:52:16 +00:00
Dave Hrycyszyn 9dbe74bdb1 topology: renamed filter trait 2020-01-24 12:48:46 +00:00
Dave Hrycyszyn 6e676fc1e4 ibid 2020-01-24 12:38:55 +00:00
Dave Hrycyszyn 94314e332d sphinx: restoring commit version 2020-01-24 12:36:57 +00:00
Dave Hrycyszyn 383539bd25 Merge branch 'develop' into feature/version-filtering-improvements 2020-01-24 12:24:33 +00:00
Dave Hrycyszyn 8510924ebb Merge pull request #94 from nymtech/feature/refreshing_topology
Feature/refreshing topology
2020-01-24 12:13:12 +00:00
Dave Hrycyszyn 772d428158 version-checker: toughened up on version parsing panics 2020-01-24 12:02:01 +00:00
Dave Hrycyszyn 1579aa58d5 version checker: renamed is_compatible() to is_minor_version_compatible() 2020-01-24 11:53:27 +00:00
Dave Hrycyszyn 5e22d3e9a9 topology: get_version() is now version() 2020-01-24 11:48:03 +00:00
Dave Hrycyszyn 6e03375ec7 topology: moved filtering into its own home 2020-01-24 11:47:41 +00:00
Dave Hrycyszyn 4c44df46f8 topology: removing unused PhantomData import 2020-01-24 11:19:09 +00:00
Dave Hrycyszyn af1cdccda2 Using the new topology filter 2020-01-24 11:09:36 +00:00
Dave Hrycyszyn 4cb1719ee4 Back to compiling after some self-experimentation and learning... 2020-01-24 11:03:02 +00:00
Jedrzej Stuczynski 143d45904c missing import 2020-01-23 17:19:40 +00:00
Jedrzej Stuczynski 4a2eab76e7 Decreased log severity for failing to send test packet during healthcheck 2020-01-23 17:19:08 +00:00
Jedrzej Stuczynski d9ac85abb2 Removed hardcoded version numbers 2020-01-23 17:17:28 +00:00
Jedrzej Stuczynski c61b49c353 Corrected warnin message for out queue control 2020-01-23 17:08:26 +00:00
Jedrzej Stuczynski 6348f9e2e1 Merge branch 'develop' into feature/refreshing_topology 2020-01-23 17:00:11 +00:00
Jedrzej Stuczynski 54c244e4ea Everything put together in mod.rs 2020-01-23 16:55:59 +00:00
Jedrzej Stuczynski 6f69641443 Made sockets more generic to work on any NymTopology object 2020-01-23 16:55:39 +00:00
Jedrzej Stuczynski 35451a05de And by real traffic stream + necessary adjustments 2020-01-23 16:55:11 +00:00
Jedrzej Stuczynski 2079b8f926 Said module used by cover traffic stream 2020-01-23 16:54:43 +00:00
Jedrzej Stuczynski 8c26ef848a Created a module responsible for periodically refreshing topology 2020-01-23 16:54:16 +00:00
Jedrzej Stuczynski 52272d6119 Added restriction on NymTopology to require Debug and Send + Sync 2020-01-23 16:53:30 +00:00
Jedrzej Stuczynski e5b3a29c5f Defined ability to compare two 'Topology' instances
The comparison ignores 'last-seen' field or ordering of nodes and
clients
2020-01-23 16:53:02 +00:00
Dave Hrycyszyn dea363e813 Minor docs formatting 2020-01-23 16:26:40 +00:00
Dave Hrycyszyn 2b9ed29ebd Minor smoothing of the README 2020-01-23 16:10:53 +00:00
Dave Hrycyszyn 753ecf6b6a crypto: replaced base64 with bs58 2020-01-23 15:06:10 +00:00
Jędrzej Stuczyński c05ce62df0 Merge pull request #93 from nymtech/feature/consistent-logging
Feature/consistent logging
2020-01-22 18:57:45 +00:00
Jędrzej Stuczyński 8e4027947b Merge pull request #92 from nymtech/feature/semver-client
Feature/semver client
2020-01-22 18:55:22 +00:00
Dave Hrycyszyn b5e2f9fca8 all: adding dotenv to all binary crates 2020-01-22 17:27:30 +00:00
Dave Hrycyszyn 1e8423b339 Started to use logging instead of println 2020-01-22 17:22:03 +00:00
Dave Hrycyszyn ac61196fc6 all: initializing logger at start 2020-01-22 16:34:42 +00:00
Dave Hrycyszyn c592ac6655 project: removing env_logger from the Cargo project file 2020-01-22 16:30:20 +00:00
Dave Hrycyszyn 09cb17e6ab all: using pretty_env_logger pretty much everywhere 2020-01-22 16:29:59 +00:00
Dave Hrycyszyn 65f5683b12 topology: checking for compatible semver between nodes and clients 2020-01-22 16:18:00 +00:00
Dave Hrycyszyn 44116e4907 common: adding a version-checker crate 2020-01-22 16:17:35 +00:00
Dave Hrycyszyn d34907eccf ibid 2020-01-22 12:57:41 +00:00
Dave Hrycyszyn f785637cd5 provider-client: removing unused commands module 2020-01-22 12:57:35 +00:00
Jedrzej Stuczynski 91eb03fbb6 Derived PartialEq on Topology 2020-01-22 12:22:15 +00:00
Jedrzej Stuczynski 566e17719c added PartialEq restriction on NymTopology for convenience sake 2020-01-22 12:22:05 +00:00
Dave Hrycyszyn e93e3e0554 Merge pull request #91 from nymtech/feature/client-refactor
Feature/client refactor
2020-01-22 10:58:12 +00:00
Jedrzej Stuczynski 974ac5ef65 compiler warnings 2020-01-22 10:52:30 +00:00
Jedrzej Stuczynski 7045db7d70 ibid. 2020-01-22 10:50:22 +00:00
Jedrzej Stuczynski 2364fbdc09 Moved sphinx packet encapsulation and poisson delay sampling to mix client 2020-01-22 10:50:03 +00:00
Dave Hrycyszyn 1fbbd7cd70 Merge pull request #89 from nymtech/feature/no_silent_failures
Release builds should no longer silently fail - everything will be im…
2020-01-22 10:41:44 +00:00
Jedrzej Stuczynski b4c15eae12 Sending real traffic at poisson rate rather than at uniform rate 2020-01-21 18:02:35 +00:00
Jedrzej Stuczynski 98610e20dc Removed unused utils/bytes module 2020-01-21 17:50:07 +00:00
Jedrzej Stuczynski da575f3657 ibid 2020-01-21 17:49:48 +00:00
Jedrzej Stuczynski 55e473d04e Moved Pemstore as separate crate + defined pathfinder as trait 2020-01-21 17:46:34 +00:00
Jedrzej Stuczynski ac988c62e9 Removed 'toml' from client-persistence as it will be module-specific 2020-01-21 17:21:02 +00:00
Jedrzej Stuczynski 551d0eb161 More comments regarding uses of specific channels 2020-01-21 17:16:22 +00:00
Jedrzej Stuczynski 2e817a9a6b Comments explaining purposes of different futures 2020-01-21 17:09:28 +00:00
Jedrzej Stuczynski 73438b672a Change in how OutQueueControl is spawned - not entirely sure at this point why its required 2020-01-21 17:09:12 +00:00
Jedrzej Stuczynski c92177402d Implemented OutQueueControl as a proper Stream to get rid of the select! macro 2020-01-21 17:08:19 +00:00
Jedrzej Stuczynski 641dc78903 Removed too aggressive logging 2020-01-21 17:07:21 +00:00
Jedrzej Stuczynski ee812a86c6 Moved definition of extended duration to before the loop 2020-01-21 14:30:17 +00:00
Jedrzej Stuczynski fe48c11cd6 Moved real traffic controller to separate module 2020-01-21 14:29:56 +00:00
Jedrzej Stuczynski a57708d936 Separate module for cover traffic stream 2020-01-21 14:21:41 +00:00
Jedrzej Stuczynski f1debb91c6 Obtaining initial compatible topology in separate method 2020-01-21 13:29:59 +00:00
Jedrzej Stuczynski 06b96bd2c1 Moved provider-polling related functionalities to new module 2020-01-21 13:08:26 +00:00
Jedrzej Stuczynski 7889ab4778 Removed redundant logging statement 2020-01-21 13:07:51 +00:00
Jedrzej Stuczynski 2af18a85e5 Added "is_registered" method to provider client 2020-01-21 12:26:10 +00:00
Jedrzej Stuczynski ea383871ab ReceivedBuffer is now responsible for starting both controllers 2020-01-21 12:02:21 +00:00
Jedrzej Stuczynski e4c7d211b5 Better handling of when messages failed to be sent to the requester
Now rather than causing a panic, they will simply be readded back to the
buffer
2020-01-21 10:50:34 +00:00
Jedrzej Stuczynski af6a8f5546 Better logging for ibid. 2020-01-21 10:49:56 +00:00
Jedrzej Stuczynski e9e5c83ab3 Moved ReceivedMessagesBuffer to seperate module 2020-01-21 10:33:26 +00:00
Jedrzej Stuczynski e57cb4f562 Release builds should no longer silently fail - everything will be immediately stopped on any panic 2020-01-21 10:21:46 +00:00
Jedrzej Stuczynski 6625f6f7fe Slightly decreases the aggressive logging in mix traffic controller 2020-01-21 10:16:43 +00:00
Jedrzej Stuczynski abd88c0c01 Fixed accidentally broken pathfinder 2020-01-21 10:07:22 +00:00
Jedrzej Stuczynski 9f69cc92fe Moved MixTrafficController to separate module 2020-01-21 10:04:20 +00:00
Jedrzej Stuczynski 74aa9b1136 Merge tag 'v0.3.3' into develop
* websocket handling of 'ping', 'pong' and 'close' messages
* websocket not crashing on binary messages
* websocket returning text rather than base64
* restored `nym-client` lib functionality
2020-01-20 17:52:35 +00:00
Jedrzej Stuczynski bec0223899 Merge branch 'release/v0.3.3' 2020-01-20 17:52:22 +00:00
Jedrzej Stuczynski 89087a3dfd Updated changelogs 2020-01-20 17:52:09 +00:00
Jedrzej Stuczynski 2a55f8cd32 Increased version numbers in cargo files 2020-01-20 17:50:05 +00:00
Dave Hrycyszyn a1f91fd676 Merge pull request #88 from nymtech/feature/websocket_improvements
Feature/websocket improvements
2020-01-20 16:52:06 +00:00
Jedrzej Stuczynski 33dafd9bba Websocket handling 'Ping', 'Pong' and 'Close' messages + general improvements
Also fixes https://github.com/nymtech/nym/issues/56
2020-01-20 16:49:13 +00:00
Jędrzej Stuczyński e098445588 Merge pull request #87 from nymtech/feature/cleanup-client-start
Using println rather than log for startup banner, it's not an error
2020-01-20 16:47:00 +00:00
Jedrzej Stuczynski 35086ec63e Checking for plaintext length before sending it to nym-client 2020-01-20 16:46:52 +00:00
Dave Hrycyszyn d66cf696fe Merge branch 'develop' into feature/cleanup-client-start 2020-01-20 16:46:45 +00:00
Jedrzej Stuczynski fbb0f2485f Removing some print statements in favour of log 2020-01-20 16:44:57 +00:00
Dave Hrycyszyn 5c95a70aaf nym-client: removing unused import 2020-01-20 16:44:19 +00:00
Dave Hrycyszyn 2e6aaf16d3 Merge pull request #61 from nymtech/feature/nym_client_lib
Feature/nym client lib
2020-01-20 15:42:14 +00:00
Dave Hrycyszyn dbc6365749 Using println rather than log for startup banner, it's not an error 2020-01-20 15:27:35 +00:00
Dave Hrycyszyn c9d632c8b6 Update README.md 2020-01-20 14:59:34 +00:00
Dave Hrycyszyn bed1a33e68 readme: noted existence of validator node in new code 2020-01-20 14:46:42 +00:00
Dave Hrycyszyn d4ed8cbeaa Merge branch 'develop' of github.com:nymtech/nym into develop 2020-01-20 14:46:15 +00:00
Jedrzej Stuczynski dc64921e0e Removed commented code 2020-01-20 11:13:24 +00:00
Jedrzej Stuczynski bce448937b Fixes #55 2020-01-20 11:12:51 +00:00
Jedrzej Stuczynski 32a978d932 Removed call to 'banner' from external modules 2020-01-20 10:32:07 +00:00
Jedrzej Stuczynski 3737c535ff Moved built_info to module in separate file 2020-01-20 10:31:49 +00:00
Jedrzej Stuczynski 58b8bc1a68 lib definition in cargo.toml 2020-01-20 10:31:18 +00:00
Jedrzej Stuczynski 1357ae8ff1 Updated tokio-tungstenite dependency to point to the main repo 2020-01-17 14:13:04 +00:00
Jedrzej Stuczynski b9a6f63cfa Merge tag 'v0.3.2' into develop
v0.3.2
2020-01-17 13:15:49 +00:00
Jedrzej Stuczynski fe88e20350 Merge branch 'release/v0.3.2' 2020-01-17 13:15:31 +00:00
Jedrzej Stuczynski aaa8e54c80 Updated changelogs 2020-01-17 13:15:20 +00:00
Jedrzej Stuczynski 766dbee75a Updated version numbers 2020-01-17 13:12:22 +00:00
Dave Hrycyszyn 2e2c90983a Merge pull request #59 from nymtech/feature/separate_presence_address
Feature/separate presence address
2020-01-17 13:10:53 +00:00
Jedrzej Stuczynski 518244f6bf presence client: conversion of MixNodePresence into topology::MixNode returns a Result 2020-01-17 13:07:54 +00:00
Jedrzej Stuczynski 809db67efd nym-client: resolving dns names to ips 2020-01-17 12:35:04 +00:00
Jedrzej Stuczynski ac79a0da69 mixnode: changed announce address from SocketAddr to String 2020-01-17 12:21:26 +00:00
Dave Hrycyszyn 45033fbeae Merge branch 'develop' of github.com:nymtech/nym into develop 2020-01-17 12:20:55 +00:00
Jedrzej Stuczynski 1769fa8a5a mixnode: added announce-host and announce-port arguments 2020-01-17 11:59:59 +00:00
Jedrzej Stuczynski 4cc7fc309b Fixed run local network script 2020-01-17 11:44:24 +00:00
Jedrzej Stuczynski f966df4fb1 Additional healthcheck logging 2020-01-17 11:44:08 +00:00
Dave Hrycyszyn ff141a5d47 travis: adding cargo fmt check to build server 2020-01-16 19:06:15 +00:00
Jedrzej Stuczynski 781c4c551d Fixed incorrect hashmap reads in healtcheck 2020-01-16 18:14:53 +00:00
Jedrzej Stuczynski ac0566aa17 Merge tag '0.3.1' into develop
0.3.1
2020-01-16 15:04:12 +00:00
Jedrzej Stuczynski 66b2429b2e Merge branch 'release/0.3.1' 2020-01-16 15:04:03 +00:00
Jedrzej Stuczynski 325670e540 Changelogs 2020-01-16 15:03:55 +00:00
Jedrzej Stuczynski 8d84523c32 Increased version numbers in cargo files 2020-01-16 15:01:34 +00:00
Jedrzej Stuczynski 851082dc6e Cargo.lock updates 2020-01-16 14:59:04 +00:00
Jedrzej Stuczynski dcb548ee8e Updated sample validator config to point to the qa mixnet 2020-01-16 14:58:55 +00:00
Dave Hrycyszyn 330e7d8d29 Merge pull request #58 from nymtech/bugfix/presence_client_crash
Bugfix/presence client crash
2020-01-16 14:55:58 +00:00
Jedrzej Stuczynski 3ab4b94a8a Provider no longer crashing when failed to send presence 2020-01-16 13:44:39 +00:00
Jedrzej Stuczynski 09e88da1a9 Mixnode no longer crashing when failed to send metrics or presence 2020-01-16 13:42:50 +00:00
Jedrzej Stuczynski 773fbceff7 Unused import 2020-01-16 13:37:12 +00:00
Jedrzej Stuczynski 84e2292ed0 Moved mix presence reporting from std::thread to tokio task 2020-01-16 13:29:00 +00:00
Jedrzej Stuczynski 59ea4306b8 Merge branch 'release/0.3.0' 2020-01-14 15:04:39 +00:00
Jedrzej Stuczynski b1edf54403 Updated version numbers 2020-01-14 15:04:17 +00:00
Jedrzej Stuczynski a0654b9b59 Updated changelogs 2020-01-14 15:04:00 +00:00
Jedrzej Stuczynski fe35bcbe1c Printing binding warning for provider 2020-01-14 14:57:24 +00:00
Dave Hrycyszyn fcf11a1c36 Merge pull request #54 from nymtech/feature/client_topology_filtering
Feature/client topology filtering
2020-01-14 14:40:57 +00:00
Dave Hrycyszyn 05db16677d clients: knocking 0-scored nodes out of the effective topology 2020-01-14 14:40:37 +00:00
Dave Hrycyszyn 330cfdc259 rustfmt 2020-01-14 14:39:25 +00:00
Dave Hrycyszyn 6cad7bcbef cargo: health check added to cargo.lock 2020-01-14 14:39:15 +00:00
Dave Hrycyszyn bf9463b24a Merge pull request #52 from nymtech/feature/mix_warning
Showing binding warning on binding to localhost, 0.0.0.0 or 127.0.0.1
2020-01-14 13:58:00 +00:00
Jędrzej Stuczyński d69603f87b Merge pull request #53 from mileschet/client-pubkey
print public key for nym client tools
2020-01-14 13:55:32 +00:00
Jedrzej Stuczynski 173daa7305 Fixed broken test 2020-01-14 13:47:47 +00:00
Jedrzej Stuczynski b9c37f2845 Removed unused typ() method on NodeScore 2020-01-14 12:50:30 +00:00
Roberto Santacroce Martins 8237f5d885 changed the place for print the public key 2020-01-14 13:48:08 +01:00
Jedrzej Stuczynski 76432cf253 Client obtaining healthy topology on startup 2020-01-14 12:41:38 +00:00
Jedrzej Stuczynski c1c41ebde1 Moved built_info module definition to top of file 2020-01-14 12:40:46 +00:00
Jedrzej Stuczynski 9082e93826 Helper function to determine if any path can be constructred through topology 2020-01-14 12:40:25 +00:00
Jedrzej Stuczynski 63cebd27cd Filtering topology by node version 2020-01-14 12:40:04 +00:00
Jedrzej Stuczynski 505a0bd0b0 Ability to filter topolgy by predefined node score threshold 2020-01-14 12:39:37 +00:00
Jedrzej Stuczynski fb6ec68046 Calculating node score in separate method 2020-01-14 12:38:54 +00:00
Jedrzej Stuczynski 5121e2fb0c Added node type enum to NodeScore 2020-01-14 12:38:40 +00:00
Jedrzej Stuczynski 25c9ee5b3c Defined std::error::Error for HealthCheckerError 2020-01-14 12:35:20 +00:00
Jedrzej Stuczynski a6014a6ad5 Formatting 2020-01-14 12:33:31 +00:00
Jedrzej Stuczynski ea7a5cf044 Fixed bug in converting MixNode to MixNodePresence 2020-01-14 12:33:13 +00:00
Jedrzej Stuczynski cef1568e33 Removed nym-client lib definition 2020-01-14 12:30:53 +00:00
Jedrzej Stuczynski 315ece38ae Temporarily moved healthcheck from validator to separate common crate 2020-01-14 10:44:05 +00:00
Jedrzej Stuczynski 6fbc6c6680 Renamed version filtering 2020-01-14 10:30:20 +00:00
Jedrzej Stuczynski 7895eb8c38 Initial topology version filtering 2020-01-14 10:28:48 +00:00
Jedrzej Stuczynski 164ebf47be From nymtopology nodes for prence topology 2020-01-14 10:26:54 +00:00
Roberto Santacroce Martins 1c85ba266f print public key for nym client tools 2020-01-14 11:19:11 +01:00
Jedrzej Stuczynski e34a55c60a Separated versions for mixes, providers and coco nodes for filtering 2020-01-14 10:12:26 +00:00
Jedrzej Stuczynski 9bd4c49be9 Default implementation for filtering topology by node versions 2020-01-14 10:10:55 +00:00
Jedrzej Stuczynski c1eb553cc0 Derived clone trait for Topology node types 2020-01-14 10:10:29 +00:00
Jedrzej Stuczynski 04f11ecafa Added version to topology for coconodes 2020-01-14 10:10:05 +00:00
Jedrzej Stuczynski 2d7fff06fe Showing binding warning on binding to localhost, 0.0.0.0 or 127.0.0.1 2020-01-14 09:54:16 +00:00
Dave Hrycyszyn 1d2481e558 whitespace 2020-01-13 18:26:45 +00:00
Dave Hrycyszyn 19dff546b4 readme: typo fix 2020-01-13 18:26:37 +00:00
Dave Hrycyszyn 507e910e72 Pulled nym-client binary out to top-level 2020-01-13 18:25:05 +00:00
Jędrzej Stuczyński 6b68998e93 Merge pull request #51 from nymtech/feature/validator-config-sample
validator: moving sample config files into sample configs directory
2020-01-13 18:02:51 +00:00
Dave Hrycyszyn aad70d65b8 validator: moving sample config files into sample configs directory 2020-01-13 18:00:35 +00:00
Dave Hrycyszyn f670c7f58f Merge pull request #50 from nymtech/feature/validator_health_checker
Feature/validator health checker
2020-01-13 17:57:26 +00:00
Dave Hrycyszyn 3ec3b4a793 Merge branch 'develop' into feature/validator_health_checker 2020-01-13 17:57:06 +00:00
Dave Hrycyszyn d92cee59a0 validator: removing scary comment in main() 2020-01-13 17:36:30 +00:00
Dave Hrycyszyn 350eeae8da README: adding a note about .env file 2020-01-13 17:35:39 +00:00
Dave Hrycyszyn 40fee72161 .env: ignoring the .env file and providing a sample 2020-01-13 17:33:33 +00:00
Jedrzej Stuczynski 51d802d1c7 Provider related compiler warnings 2020-01-13 17:03:32 +00:00
Jedrzej Stuczynski ee32b97fbb Compiler warning 2020-01-13 17:01:05 +00:00
Jedrzej Stuczynski ee1a0033ac Sorting NodeScores before printing 2020-01-13 16:54:58 +00:00
Jedrzej Stuczynski a615dacf64 Defined Ord (+ required traits) for NodeScore 2020-01-13 16:54:40 +00:00
Jedrzej Stuczynski 34de9cc10b Another sphinx revision update 2020-01-13 16:50:10 +00:00
Jedrzej Stuczynski 03d04d5aa7 Updated used sphinx revision 2020-01-13 15:49:55 +00:00
Jedrzej Stuczynski 05ca3e147f Using the new updated healthchecker 2020-01-13 15:26:12 +00:00
Jedrzej Stuczynski 0b1bae6ea1 Formatting 2020-01-13 15:25:52 +00:00
Jedrzej Stuczynski c056485471 resolving all available paths 2020-01-13 15:25:31 +00:00
Jedrzej Stuczynski d152d0fd12 Sending all tests packets before trying to resolve them 2020-01-13 15:25:02 +00:00
Jedrzej Stuczynski 5bc5974bdb Conversion of vec of pub keys into unique path id and vice verse 2020-01-13 15:23:56 +00:00
Jedrzej Stuczynski 5e870e4c8a ibid. 2020-01-13 15:23:20 +00:00
Jedrzej Stuczynski 8178d505c3 PathChecker holding mapping of paths to their statuses 2020-01-13 15:23:06 +00:00
Jedrzej Stuczynski 78a52df0ec Assertion on maximum number of iterations 2020-01-13 15:22:26 +00:00
Jedrzej Stuczynski 0ecab55959 Added itertools 2020-01-13 15:21:28 +00:00
Jedrzej Stuczynski b3f056b933 More informative error message 2020-01-13 15:20:47 +00:00
Jedrzej Stuczynski 520973b578 Using resolution timeout as part of healtchecker 2020-01-13 15:20:33 +00:00
Jedrzej Stuczynski d4ab7f96f1 Separated increasing packet count into explicit sent and received 2020-01-13 15:19:47 +00:00
Jedrzej Stuczynski 911ab8ff4c Added resolution timeout to healthcheck config 2020-01-13 10:58:55 +00:00
Jedrzej Stuczynski 9596060972 Provider no longer printing string message that its storing 2020-01-10 16:56:32 +00:00
Jedrzej Stuczynski 4b7971899c Actually sending test packets through network (not retrieving status yet) 2020-01-10 16:54:49 +00:00
Jedrzej Stuczynski 6eeedf858d decreased default logging level 2020-01-10 16:54:28 +00:00
Jedrzej Stuczynski 7045d76039 Using correct case for existence in hashmap 2020-01-10 16:09:22 +00:00
Jedrzej Stuczynski 90266175a1 Removed some unused imports 2020-01-10 16:06:41 +00:00
Jedrzej Stuczynski c810d0d957 Async registration at all available providers 2020-01-10 16:05:55 +00:00
Jedrzej Stuczynski a4990f1944 Added to bytes conversion of node keys for topology 2020-01-10 16:05:31 +00:00
Jedrzej Stuczynski 52054f8b46 PathChecker constructor returning result type 2020-01-10 15:25:07 +00:00
Jedrzej Stuczynski 489c806292 Split healthchecker into multiple files 2020-01-10 15:20:49 +00:00
Jędrzej Stuczyński db69105813 Merge pull request #49 from nymtech/feature/better-socket-errors
Improving websocket connection errors
2020-01-10 15:05:15 +00:00
Dave Hrycyszyn d39e532e4b Improving websocket connection errors 2020-01-10 15:01:36 +00:00
Jedrzej Stuczynski 25575b4598 Running healthcheck specified number of times 2020-01-10 15:01:12 +00:00
Jedrzej Stuczynski 769598d40a Added layer information to healthcheck 2020-01-10 14:56:50 +00:00
Jedrzej Stuczynski 227f69befb Fixed compilation errors 2020-01-10 14:50:30 +00:00
Jedrzej Stuczynski 9d760a515a Updated sphinx revision 2020-01-10 14:42:10 +00:00
Dave Hrycyszyn 26663100b4 Removed duplicate build instructions in favour of a pointer to the docs site. 2020-01-10 14:41:17 +00:00
Jedrzej Stuczynski 7f6ec5ecdf Merge branch 'develop' into feature/validator_health_checker 2020-01-10 14:38:59 +00:00
Dave Hrycyszyn a58c3dbb25 travis: it's no longer necessary to grab Sphinx separately 2020-01-10 14:23:34 +00:00
Dave Hrycyszyn be0616b524 cargo: pinning Sphinx to a specific rev to get rid of build flapping 2020-01-10 14:23:09 +00:00
Dave Hrycyszyn 92390f9ad7 cargo: lockfile change 2020-01-10 14:18:19 +00:00
Dave Hrycyszyn 3e9221f6af Merge pull request #48 from nymtech/feature/crypto_crate
Feature/crypto crate
2020-01-10 14:16:10 +00:00
Jedrzej Stuczynski 1ad651fe72 Updated comments regarding DummyMix pair 2020-01-10 14:14:59 +00:00
Jedrzej Stuczynski e4501852d5 Made curve generator private 2020-01-10 14:12:29 +00:00
Jedrzej Stuczynski 402b226080 Updated depenencies 2020-01-10 13:53:10 +00:00
Jedrzej Stuczynski c772b9a4df Same for request handling + removed dependency on entiry nym-client 2020-01-10 13:53:01 +00:00
Jedrzej Stuczynski 95cd4123b5 Ibid for provider presence 2020-01-10 13:52:38 +00:00
Jedrzej Stuczynski 4164491bc2 Provider using new key types 2020-01-10 13:52:28 +00:00
Jedrzej Stuczynski 0492a21bcf Easier conversion of keypairs from bytes 2020-01-10 13:51:50 +00:00
Jedrzej Stuczynski 50d54d44c7 ibid. for sockets 2020-01-10 13:51:32 +00:00
Jedrzej Stuczynski 1cc1d2ddf9 client init using new key structure 2020-01-10 13:51:20 +00:00
Jedrzej Stuczynski 0dda60cd81 ibid 2020-01-10 13:51:03 +00:00
Jedrzej Stuczynski 114c927028 removed identity client crate 2020-01-10 13:50:57 +00:00
Jedrzej Stuczynski e18ed7e0fd More generic client pem store 2020-01-10 13:50:47 +00:00
Jedrzej Stuczynski 3e533cdee2 ibid for identity keys 2020-01-10 13:50:32 +00:00
Jedrzej Stuczynski 6e3b2c36fe encryption keys now need to implement PemStorable 2020-01-10 13:49:44 +00:00
Jedrzej Stuczynski 73028f85a9 Defined trait for returning key pem type 2020-01-10 13:49:00 +00:00
Jedrzej Stuczynski d0d894a309 Implementing said traits on dummy struct using x25519 2020-01-10 11:50:48 +00:00
Jedrzej Stuczynski db92f898d3 MixnetIdentity Key traits 2020-01-10 11:50:30 +00:00
Jedrzej Stuczynski 740a2fb2ff X25519 impl of said traits 2020-01-10 11:50:12 +00:00
Jedrzej Stuczynski 84e34e5490 MixnetEncryption Key traits 2020-01-10 11:50:03 +00:00
Jedrzej Stuczynski 2a05d77d94 Initial crypto crate 2020-01-10 11:49:49 +00:00
Dave Hrycyszyn 97d7f6d7cb README: drying up the build and usage instructions a bit 2020-01-10 11:35:05 +00:00
Jedrzej Stuczynski 4f23d7e58b Fixed author strings for other common crates 2020-01-10 10:09:18 +00:00
Jedrzej Stuczynski ccf1e6fe1a Fixed root cargo file 2020-01-10 10:07:01 +00:00
Jedrzej Stuczynski 7068dc7089 Fixed compilation errors due to changes in sphinx crate 2020-01-10 10:05:01 +00:00
Jedrzej Stuczynski 7f6f366e51 Logic for calculating health 2020-01-09 18:01:28 +00:00
Jedrzej Stuczynski 4d997ef03b Using new methods on NodeAddressBytes from sphinx 2020-01-09 17:17:50 +00:00
Jedrzej Stuczynski 65042e7210 Storing node key as bytes rather than string 2020-01-09 16:42:15 +00:00
Jedrzej Stuczynski 89e17b0ffa Added number of test packets to healthcheck config 2020-01-09 16:30:56 +00:00
Jedrzej Stuczynski 6e52afef79 Method for modyfing node score count of packets sent and received 2020-01-09 16:26:01 +00:00
Jedrzej Stuczynski a37d9aedc4 Changed NodeScore constructors 2020-01-09 16:24:29 +00:00
Jedrzej Stuczynski fbd1f05eb9 Moved score calculation to HealthCheckResult 2020-01-09 16:21:11 +00:00
Jedrzej Stuczynski 3efbea8263 error log on failure to format addresses 2020-01-09 16:17:47 +00:00
Jedrzej Stuczynski 582c8dbc98 Printing formatted zero health node status 2020-01-09 16:16:42 +00:00
Jedrzej Stuczynski 1e0d84fb8b Healthcheck getting new topology every run 2020-01-09 15:07:23 +00:00
Jedrzej Stuczynski ca2faf0095 Required dependency for ibid. 2020-01-09 15:06:59 +00:00
Jedrzej Stuczynski e0c110ee55 Generating all possible paths from topology 2020-01-09 15:06:44 +00:00
Jedrzej Stuczynski db2f803023 Making use of the code simplification 2020-01-09 15:03:24 +00:00
Jedrzej Stuczynski d7f444c659 simplified mix_route by using the traits 2020-01-09 15:02:31 +00:00
Jedrzej Stuczynski 3b7f5c7c68 semicolon 2020-01-09 15:01:59 +00:00
Jedrzej Stuczynski 3072d56417 Into SphinxNode trait for ProviderNode 2020-01-09 15:01:41 +00:00
Jedrzej Stuczynski 59bff7a0d5 Into SphinxNode trait for MixNode 2020-01-09 15:01:27 +00:00
Jedrzej Stuczynski fadd781fc3 comment regarding future work 2020-01-09 15:00:24 +00:00
Jedrzej Stuczynski b5518babac Constructor for directory client config 2020-01-09 14:35:41 +00:00
Jędrzej Stuczyński cd28f8051b Merge pull request #43 from nymtech/feature/chill-log-messages
Feature/chill log messages
2020-01-09 13:15:47 +00:00
Dave Hrycyszyn 4966d8ecef Update README.md 2020-01-09 12:36:18 +00:00
Dave Hrycyszyn 3b7d22e675 clients: set up a logger to chill out output 2020-01-09 12:30:35 +00:00
Jędrzej Stuczyński 6ceec8e737 Merge pull request #42 from nymtech/feature/improve-pemstore-errors
persistence: improving PEM file reading and parsing failure messages
2020-01-09 12:27:55 +00:00
Dave Hrycyszyn 077c59f761 sfw-provider: moving test filesystem output to /tmp 2020-01-09 11:39:56 +00:00
Dave Hrycyszyn fd9829bedd persistence: improving PEM file reading and parsing failure messages 2020-01-09 10:48:36 +00:00
Jędrzej Stuczyński 1d79c43782 Merge pull request #39 from nymtech/feature/remove-run
Removing the run command from code and documentation
2020-01-09 10:18:51 +00:00
Dave Hrycyszyn c029117674 Merge branch 'develop' into feature/remove-run 2020-01-09 10:03:55 +00:00
Jędrzej Stuczyński ac78e160df Merge pull request #41 from nymtech/feature/better-error-message-for-bad-topology
Providing a nicer error than "failed on unwrap()" when topology retri…
2020-01-09 10:01:58 +00:00
Jędrzej Stuczyński eb75362307 Merge pull request #40 from nymtech/feature/provider-banner
Prettying up sfw-provider start sequence a bit.
2020-01-09 10:01:28 +00:00
Dave Hrycyszyn 6c3e7b6256 nym-client: taking run right out of circulation 2020-01-08 19:33:14 +00:00
Dave Hrycyszyn 7a3d61374f Providing a nicer error than "failed on unwrap()" when topology retrieval fails 2020-01-08 18:53:12 +00:00
Dave Hrycyszyn ec78c45ea0 Prettying up sfw-provider start sequence a bit. 2020-01-08 18:32:41 +00:00
Dave Hrycyszyn 1337f93c33 Removing the run command from code and documentation 2020-01-08 18:00:07 +00:00
Jedrzej Stuczynski 1f3875f39c Using ibid. in client code 2020-01-08 17:17:25 +00:00
Jedrzej Stuczynski f735befd52 Create 'route_to' function 2020-01-08 17:17:10 +00:00
Jedrzej Stuczynski 2a9e21538f Moved make layered topology to separate function + validation 2020-01-08 17:16:26 +00:00
Jedrzej Stuczynski 8ac1e58ef6 Fixed teammate's typo :) 2020-01-08 17:15:09 +00:00
Jedrzej Stuczynski c97b1b5edf Merge branch 'develop' into feature/validator_health_checker 2020-01-08 16:41:13 +00:00
Dave Hrycyszyn e773b251b9 Fixed tests. 2020-01-08 16:33:12 +00:00
Dave Hrycyszyn 9c8347aa72 Fixing compilation to handle new provider listener split fields 2020-01-08 16:25:16 +00:00
Dave Hrycyszyn fcaa23fd77 Re-arranged client directories 2020-01-08 16:22:03 +00:00
Jędrzej Stuczyński 5fa3eb35e4 Merge pull request #37 from nymtech/feature/script/localnet
Feature/script/localnet
2020-01-08 15:56:17 +00:00
Dave Hrycyszyn 67a900701e Updated script copyright date 2020-01-08 15:56:01 +00:00
Dave Hrycyszyn 8314d647d9 script: proper invocation for testnet runnign 2020-01-08 15:53:27 +00:00
Dave Hrycyszyn b88ca3ed91 script: killing old testnet processes in case they're already running 2020-01-08 15:53:11 +00:00
Dave Hrycyszyn ee43e82235 Removing unused import 2020-01-08 15:52:51 +00:00
Dave Hrycyszyn ce866bd987 Setting a 0.1 second average delay time. 2020-01-08 15:52:35 +00:00
Dave Hrycyszyn 95f103b4fd scripts: local network now runs 2020-01-08 15:13:30 +00:00
Dave Hrycyszyn 5ad6db9232 removed commented logging code 2020-01-08 14:58:18 +00:00
Dave Hrycyszyn c1cd6557eb whitespace 2020-01-08 14:58:03 +00:00
Dave Hrycyszyn 8c3cbe6646 Split provider host/ports for mixnet listener and clients listener 2020-01-08 14:57:55 +00:00
Dave Hrycyszyn add94ed70a Merge branch 'develop' of github.com:nymtech/nym into feature/script/localnet 2020-01-08 14:18:57 +00:00
Dave Hrycyszyn 6fe9dc899b Merge pull request #36 from nymtech/feature/arguments_fix
Feature/arguments fix
2020-01-08 14:17:54 +00:00
Jedrzej Stuczynski 6fedba093b Explicitly required values for mixHost and clientHost by clap 2020-01-08 14:17:16 +00:00
Jedrzej Stuczynski fb15c636eb Correct version for mix 2020-01-08 14:17:02 +00:00
Dave Hrycyszyn 043403b1e0 Merge branch 'develop' into feature/script/localnet 2020-01-08 14:10:49 +00:00
Dave Hrycyszyn 13eda7f68f Merge pull request #34 from nymtech/feature/crates_cleanup
Feature/crates cleanup
2020-01-08 13:56:04 +00:00
Jedrzej Stuczynski 9b94b1d72b Fixed broken directory client tests 2020-01-08 13:05:01 +00:00
Jedrzej Stuczynski 07db413f2c Possibly gotten rid of compiler warnings 2020-01-08 12:59:29 +00:00
Jedrzej Stuczynski db67744b19 Further topology cleanup by defining NymTopology trait 2020-01-08 12:55:40 +00:00
Jedrzej Stuczynski 1292cdb145 Moved topology to separate crate 2020-01-08 12:07:34 +00:00
Jedrzej Stuczynski 7fa42d16eb Moved addressing to separate crate and removed mixnode dependency on entire client crate 2020-01-08 12:02:18 +00:00
Jedrzej Stuczynski a673f9f206 Fixed authors strings 2020-01-08 11:50:58 +00:00
Jedrzej Stuczynski 8706f7ed06 Moved provider client to separate crate 2020-01-08 11:48:49 +00:00
Jedrzej Stuczynski 883ce22c5b Moved mix client to separate crate 2020-01-08 11:45:43 +00:00
Jedrzej Stuczynski 9ba1ea203b Moved directory client to separate crate 2020-01-08 11:34:39 +00:00
Jedrzej Stuczynski 2cef804a34 Allowed for calling get_topology from outside the crate 2020-01-08 10:13:26 +00:00
Jedrzej Stuczynski 46ce9eaff7 Made healthcheck async and repeating and action at config-specified interval 2020-01-08 10:06:36 +00:00
Jedrzej Stuczynski d4cba72118 Added interval to healthcheck config 2020-01-08 10:02:13 +00:00
Jedrzej Stuczynski 708d6d5aed Changed default validator config to use localhost directory 2020-01-08 09:57:24 +00:00
Jedrzej Stuczynski ff7af13080 Added futures and tokio to the validator 2020-01-08 09:57:10 +00:00
Jedrzej Stuczynski f325ea6b92 Creating and running healthchecker instance 2020-01-08 09:51:51 +00:00
Dave Hrycyszyn d42a75cea9 scripts: run_local_network.sh port of the old Go code
Currently non-functional
2020-01-07 19:10:46 +00:00
Jedrzej Stuczynski f4d4556ced initial changelog (to be updated before actual release) 2020-01-07 17:49:15 +00:00
Jedrzej Stuczynski d79d57fcaa updated cargo.lock 2020-01-07 17:49:04 +00:00
Jedrzej Stuczynski 9712322597 sample config 2020-01-07 17:48:54 +00:00
Jedrzej Stuczynski e3038b2b57 missing imports + dependencies 2020-01-07 17:48:47 +00:00
Jedrzej Stuczynski ba1ebd18e0 initial healthcheck 2020-01-07 17:48:33 +00:00
Jedrzej Stuczynski 9c70c64825 missing build.rs file 2020-01-07 17:48:14 +00:00
Jedrzej Stuczynski ddc988a10d reading .env file with logging level 2020-01-07 17:48:04 +00:00
Jedrzej Stuczynski aa4d759c38 logging 2020-01-07 17:47:45 +00:00
Jedrzej Stuczynski d94dcea7ee actual config definition 2020-01-07 17:47:18 +00:00
Jedrzej Stuczynski 3d98ed7b6c obtaining config file location from arguments and parsing 2020-01-07 17:46:52 +00:00
Dave Hrycyszyn 18ac7e90ed travis: moving the build image down a bit 2020-01-07 15:49:13 +00:00
Dave Hrycyszyn b04b62ed27 travis: adding build status 2020-01-07 15:48:06 +00:00
Dave Hrycyszyn 4066b4db42 travis: even more cowbell 2020-01-07 15:44:29 +00:00
Dave Hrycyszyn 037f05f323 travis: more cowbell 2020-01-07 15:41:19 +00:00
Dave Hrycyszyn 3f358a6929 travis: more travis 2020-01-07 15:39:49 +00:00
Dave Hrycyszyn e79a63588a more travis experimentation 2020-01-07 15:38:17 +00:00
Dave Hrycyszyn 60f15d57bd Let's see what's going on 2020-01-07 15:36:26 +00:00
Dave Hrycyszyn e422ce0a13 travis: maybe a branch problem? 2020-01-07 15:33:22 +00:00
Dave Hrycyszyn 598d68a822 travis: fixing Sphinx dir path 2020-01-07 15:30:53 +00:00
Dave Hrycyszyn f3900f3659 travis: clone Sphinx first to make the build work 2020-01-07 15:26:31 +00:00
Dave Hrycyszyn fa2d881442 Linking the Sphinx repo properly 2020-01-07 15:19:48 +00:00
Dave Hrycyszyn 435b7ae7e9 Adding a Travis build file 2020-01-07 15:14:06 +00:00
Dave Hrycyszyn 950a1ec0f8 Merge pull request #25 from nymtech/features/version_number_to_presence
Features/version number to presence
2020-01-07 15:11:23 +00:00
aniampio b483e15d5d Add version for the provider 2020-01-07 14:34:04 +00:00
Jedrzej Stuczynski 4d67d11a39 Initialised crate for the validator with health checker 2020-01-07 14:29:22 +00:00
Jedrzej Stuczynski 1e719a8861 Updated Readme 2020-01-07 13:57:58 +00:00
Jedrzej Stuczynski d856911a1d Created top level cargo workspace 2020-01-07 13:57:49 +00:00
aniampio d50666df0c Add version to MixNodePresence struct 2020-01-07 13:46:14 +00:00
Dave Hrycyszyn f6bf239cc2 Merge branch 'develop' of github.com:nymtech/nym into develop 2020-01-07 13:36:26 +00:00
Dave Hrycyszyn bd5c1dd357 Small docs change. 2020-01-07 13:35:39 +00:00
Dave Hrycyszyn 8a558746fe Merge pull request #7 from nymtech/feature/minor-client-changes
Feature/minor client changes
2020-01-07 12:49:32 +00:00
Jedrzej Stuczynski df23148ccf Changes in cargo.lock files 2020-01-07 12:39:51 +00:00
Jedrzej Stuczynski cf62a7ba12 Killing application on possible yet undetected bug + minor improvements in select! macro loop 2020-01-07 12:39:18 +00:00
Jedrzej Stuczynski bfad7d1087 Temporarily increased recursion limit 2020-01-07 12:38:11 +00:00
Jedrzej Stuczynski 71d23f44c2 Clap using cargo.toml version 2020-01-07 12:37:40 +00:00
Dave Hrycyszyn f57e485ceb Fleshing out the README 2020-01-07 12:30:43 +00:00
Dave Hrycyszyn 0531b716cc Setting up all paths so that builds work 2020-01-07 12:30:30 +00:00
Dave Hrycyszyn bfb91c58c8 Ditching .idea folder 2020-01-07 12:09:50 +00:00
Dave Hrycyszyn 57eab1bc85 Merge branch 'master' of github.com:nymtech/nym 2020-01-07 12:06:45 +00:00
Dave Hrycyszyn 6fb438a994 Added a README 2020-01-07 12:04:35 +00:00
Dave Hrycyszyn 23e0aee0a1 Moved nym-sfw-provider into sfw-provider directory 2020-01-07 12:03:07 +00:00
Dave Hrycyszyn 2f98568edf Merge remote-tracking branch 'nym-sfw-provider/master' 2020-01-07 12:02:20 +00:00
Dave Hrycyszyn 2b2bd5b688 Moved nym-mixnode into mixnode directory 2020-01-07 12:00:59 +00:00
Dave Hrycyszyn d05924e070 Merge remote-tracking branch 'nym-mixnode/master' 2020-01-07 12:00:16 +00:00
Dave Hrycyszyn e02c90457e Moving nym-client into the client directory 2020-01-07 11:58:42 +00:00
Dave Hrycyszyn 6f3d7b8f49 Initial commit 2020-01-07 11:42:54 +00:00
Dave Hrycyszyn 712ca4bbb2 Merge branch 'release/0.2.0' 2020-01-06 18:01:57 +00:00
Dave Hrycyszyn 62b137b3b9 Fixed up Authors file. Ania next. 2020-01-06 18:01:32 +00:00
Dave Hrycyszyn 6b508e829f Changelog for 0.2.0 2020-01-06 18:01:16 +00:00
Dave Hrycyszyn 4e7bd2d88f Merge pull request #27 from nymtech/feature/arguments_changes
Feature/arguments changes
2020-01-06 17:56:19 +00:00
Dave Hrycyszyn b584316caa Merge branch 'release/0.2.0' 2020-01-06 17:43:35 +00:00
Dave Hrycyszyn 220ef1b0ef Version number bump 2020-01-06 17:43:12 +00:00
Dave Hrycyszyn 38e747104e Added the glorious and talented Jędrzej Stuczyński to authors 2020-01-06 17:42:44 +00:00
Dave Hrycyszyn 4fc2e3bc0d Changelog for 0.2.0 release 2020-01-06 17:42:04 +00:00
Jedrzej Stuczynski 7f3ea6af1a Changelog file 2020-01-06 15:26:43 +00:00
Jedrzej Stuczynski fc7635dc27 Changelog file 2020-01-06 15:26:31 +00:00
Jędrzej Stuczyński e8b6cabfe3 Merge pull request #26 from nymtech/feature/built-versions
Added build info to the provider
2020-01-06 14:57:58 +00:00
Jedrzej Stuczynski d29ea67f9b Explicitly required values for mixHost and clientHost 2020-01-06 14:57:19 +00:00
Jedrzej Stuczynski c241ecfa36 Removed local flag and replaced it with explicit directory server 2020-01-06 14:56:36 +00:00
Dave Hrycyszyn 3553f88909 Added build info to the provider 2020-01-06 14:54:04 +00:00
Dave Hrycyszyn 6f5b44d016 Merge pull request #23 from nymtech/feature/ipv6_addressing
ipv6_addressing
2020-01-06 14:45:18 +00:00
Jedrzej Stuczynski d5a0e7d355 ipv6_addressing 2020-01-06 14:43:19 +00:00
Dave Hrycyszyn c3ce96afe9 Merge pull request #22 from nymtech/feature/flags-cleanup
Feature/flags cleanup
2020-01-06 12:24:24 +00:00
Dave Hrycyszyn f15588f617 Merge pull request #21 from nymtech/mileschet-patch-1
updated readme with dependencies instructions
2020-01-06 12:24:04 +00:00
Jedrzej Stuczynski 0bb6959755 Printing directory server on start 2020-01-06 12:20:08 +00:00
Jedrzej Stuczynski efb4660fe7 Requiring explicit host + printing bound address on startup 2020-01-06 12:12:40 +00:00
Jedrzej Stuczynski 27c61cb194 Printing node version number on startup 2020-01-06 12:04:45 +00:00
mileschet cddc61fe57 updated readme with dependencies instructions
added some information about the dependencies until we fix cargo dependencies.
2019-12-29 17:07:41 +01:00
Dave Hrycyszyn 489ea16749 Merge pull request #20 from 0xjac/develop
runner: print public key on startup
2019-12-29 15:20:06 +00:00
0xjac b59b9fa4a5 runner: print public key on startup
Closes #19
2019-12-29 16:13:32 +01:00
Dave Hrycyszyn 57d2cab98a Merge tag '0.1.0' into develop
Initial release (0.1.0)
2019-12-23 20:39:35 +00:00
Dave Hrycyszyn 5c697a3a4d Merge branch 'release/0.1.0' 2019-12-23 20:39:14 +00:00
Dave Hrycyszyn 21f0c3e2ac Including a pointer to the Rust install docs 2019-12-20 14:57:18 +00:00
Dave Hrycyszyn 42ab21c133 whitespace 2019-12-20 14:57:07 +00:00
Dave Hrycyszyn a39eed123e main: setting a default port (1789) 2019-12-20 14:54:48 +00:00
Dave Hrycyszyn 1954895e16 Building out the README a bit. 2019-12-20 14:53:57 +00:00
Dave Hrycyszyn f6ad70bff9 Upping message size limit 2019-12-19 17:43:11 +00:00
Dave Hrycyszyn b9747669d3 Merge pull request #25 from nymtech/feature/presence_with_clients
Feature/presence with clients
2019-12-19 13:58:06 +00:00
Jedrzej Stuczynski cbac85fbf4 Fixed compiler warnings 2019-12-19 13:49:45 +00:00
Jedrzej Stuczynski 76f503a664 Provider sending registered clients with presence 2019-12-19 13:49:04 +00:00
Jedrzej Stuczynski a8eb5ec4c2 Moved client processing data behind just an arc but put the ledger behind arc+mutex 2019-12-19 13:07:07 +00:00
Jedrzej Stuczynski 56a8118ea3 Sending presence inside tokio reactor 2019-12-19 12:55:18 +00:00
Dave Hrycyszyn 234bf7d0a0 cargo fmt run 2019-12-19 11:50:47 +00:00
Jędrzej Stuczyński ac8f04959e Merge pull request #18 from nymtech/feature/use-keys
Feature/use keys
2019-12-19 11:48:36 +00:00
Dave Hrycyszyn 016f5829a5 Removing required arguments and setting default values 2019-12-19 11:46:30 +00:00
Dave Hrycyszyn d79ab40988 Merge branch 'develop' into feature/use-keys 2019-12-19 11:37:31 +00:00
Dave Hrycyszyn f0a1ce50bc Merge pull request #23 from nymtech/features/auth_token
Features/auth token
2019-12-18 15:52:36 +00:00
Dave Hrycyszyn ef82d4327c Merge pull request #18 from nymtech/feature/presence-fix
presence: removing last-seen from MixNodePresence, it's set by server
2019-12-18 15:49:44 +00:00
Dave Hrycyszyn 8da639cd11 Merge branch 'develop' into feature/presence-fix 2019-12-18 15:49:04 +00:00
Jedrzej Stuczynski 428f202cbc Got rid of most of compiler warnings 2019-12-18 14:39:54 +00:00
Jedrzej Stuczynski 073ef2776e Returning result from delete_file function + some extra notes 2019-12-18 14:28:44 +00:00
Jedrzej Stuczynski 091104be8f Register response using concrete authToken type + defined from_bytes method 2019-12-18 13:25:15 +00:00
Jedrzej Stuczynski 8bbe771229 Potentially working mutex on register request 2019-12-18 13:20:18 +00:00
Jedrzej Stuczynski 0ead20764b Pull request using the mutex 2019-12-18 13:06:51 +00:00
Jedrzej Stuczynski 8f451283dc Put the client processing data behind a mutex 2019-12-18 12:39:16 +00:00
Jedrzej Stuczynski 6ae5142166 Changes required by the merge 2019-12-18 11:43:09 +00:00
Jedrzej Stuczynski a8e46d34df Merge branch 'develop' into features/auth_token 2019-12-18 11:41:13 +00:00
Jedrzej Stuczynski 20fe59b9ba Tests for marshaling/unmarshaling register request 2019-12-18 10:48:44 +00:00
Jedrzej Stuczynski d0902218d4 Fixed ProviderRequest marshaling and unmarshaling 2019-12-18 10:45:17 +00:00
Jedrzej Stuczynski 38517e41ba constructor for registerrequest 2019-12-18 10:38:01 +00:00
Jedrzej Stuczynski 507f37fcec Made AuthToken be type alias for u8;32 + Used correct type alliases for the clients ledger 2019-12-18 10:03:12 +00:00
Jedrzej Stuczynski 06c645cf56 Using destination address type alias rather than just array of 32
( + rustfmt)
2019-12-18 09:41:29 +00:00
aniampio b63494f686 Add check of the token when pulling 2019-12-17 18:14:40 +01:00
aniampio f78ce3f9b6 Remove lost comment 2019-12-17 17:36:01 +01:00
aniampio 671e55f4d5 Change SHA256 to HMAC 2019-12-17 17:29:10 +01:00
aniampio 85d147ef62 Change token from vec to fixed size array 2019-12-17 15:46:55 +01:00
aniampio cb69182e02 Make sure the client is registered only once and there is only one directory for it 2019-12-17 14:49:29 +01:00
Dave Hrycyszyn 8dd8873a03 using new Config object for provider 2019-12-17 13:34:18 +00:00
Dave Hrycyszyn 4e55c6c395 rustfmt 2019-12-17 13:33:59 +00:00
Dave Hrycyszyn 381e85f0bc main: setting default provider parameters 2019-12-17 13:33:42 +00:00
Dave Hrycyszyn 8ef95ac522 main: making provider module public 2019-12-17 13:33:08 +00:00
Dave Hrycyszyn 59133ed862 cargo: adding base64 crate 2019-12-17 13:32:53 +00:00
Dave Hrycyszyn 65aa1ba29d rustfmt 2019-12-17 13:32:29 +00:00
Dave Hrycyszyn c71f494974 presence: comment re directory server 2019-12-17 13:29:59 +00:00
Dave Hrycyszyn ae25f335f4 mix_peer: adding Debug so we can print 2019-12-17 13:29:29 +00:00
aniampio 3101bb6980 Code cleanup 2019-12-17 12:29:21 +01:00
aniampio 4a241bb59a Move AuthToken into requests 2019-12-17 12:28:38 +01:00
aniampio 63f30bf9d0 Move creating inboxes directory to register_client function 2019-12-17 11:49:22 +01:00
Jedrzej Stuczynski b39ccf26b6 Allowing the two provider listeners to run in parallel rather than just concurrently 2019-12-17 10:31:04 +00:00
Dave Hrycyszyn 21834fde41 Merge pull request #17 from nymtech/feature/metrics_reporting
Feature/metrics reporting
2019-12-17 10:13:19 +00:00
Dave Hrycyszyn b6db1bf1af presence: removing last-seen from MixNodePresence, it's set by server 2019-12-17 10:11:14 +00:00
aniampio 0b3ce4739b Represent registered_clients_ledger as HashTable 2019-12-16 21:32:21 +01:00
Jedrzej Stuczynski f262b2924b Fixed some compiler warnings 2019-12-16 17:59:09 +00:00
Jedrzej Stuczynski 724af12e03 Removed debug prints 2019-12-16 17:45:06 +00:00
Jedrzej Stuczynski 3a59f3cef9 Metrics reporting 2019-12-16 17:42:55 +00:00
Dave Hrycyszyn 6aba3f08f1 Merge branch 'develop' of github.com:nymtech/nym-mixnode into develop 2019-12-16 16:29:47 +00:00
Dave Hrycyszyn 8cd2be7edc cargo: mysterious lock action 2019-12-16 16:29:39 +00:00
Jędrzej Stuczyński d768eff303 Merge pull request #16 from nymtech/feature/use-keys
Feature/use keys
2019-12-16 16:27:58 +00:00
Dave Hrycyszyn ddf0d762d7 mix_peer: adding a to_string() definition 2019-12-16 16:26:30 +00:00
Dave Hrycyszyn aa207e2c13 mix_peer: using constant sized byte array for addressing 2019-12-16 16:25:49 +00:00
Dave Hrycyszyn c192afe9eb mix_peer: converting address to strongly typed socket address 2019-12-16 16:25:29 +00:00
aniampio 415ba8185e Add to_bytes function 2019-12-16 16:36:59 +01:00
aniampio fdbb2549f8 Add template for register response 2019-12-16 15:49:03 +01:00
Dave Hrycyszyn 3f5e219b1c whitespace 2019-12-16 14:47:18 +00:00
Dave Hrycyszyn e6350a0ea4 main: removing superseded comment 2019-12-16 14:46:37 +00:00
Dave Hrycyszyn 56858c4109 provider: sending proper public keys to directory server 2019-12-16 14:46:15 +00:00
aniampio 509b222052 Add register function and types 2019-12-16 15:40:05 +01:00
Jędrzej Stuczyński 29e1488714 Merge pull request #15 from nymtech/feature/use-keys
Feature/use keys
2019-12-16 13:55:42 +00:00
Dave Hrycyszyn 37a493439d presence: sending URL-safe public key 2019-12-16 13:54:38 +00:00
Dave Hrycyszyn ab02eec824 Using the node socket address to send to the directory server 2019-12-16 13:54:20 +00:00
Dave Hrycyszyn efb900a538 node: adding a config struct and using it to pass args around 2019-12-16 13:30:18 +00:00
Dave Hrycyszyn 9d969904f2 cargo: adding base64 crate 2019-12-16 13:29:48 +00:00
Dave Hrycyszyn 2b5b61ea26 node: adding a config struct 2019-12-16 12:54:16 +00:00
Dave Hrycyszyn 287d2b31a5 main: deleting unused key_file argument 2019-12-16 12:54:00 +00:00
Jędrzej Stuczyński de63fff1a1 Merge pull request #14 from nymtech/feature/directory-server-option
Feature/directory server option
2019-12-16 12:31:57 +00:00
Jędrzej Stuczyński d2f8ffdc2b Merge pull request #17 from nymtech/feature/directory-server-option
presence: ability to configure local directory server
2019-12-16 12:31:25 +00:00
Dave Hrycyszyn 4143e53598 presence: ability to configure local directory server 2019-12-16 12:27:50 +00:00
Dave Hrycyszyn 265ef22838 main: can now be started with a local directory server for testing purposes 2019-12-16 12:20:48 +00:00
aniampio ca28ce9e19 Add function to generate SHA256 tokens 2019-12-16 12:47:52 +01:00
Dave Hrycyszyn f0cf92b542 cargo: removed ws deps 2019-12-16 11:46:12 +00:00
Dave Hrycyszyn aceb6df848 Merge pull request #16 from nymtech/feature/presence
Feature/presence
2019-12-16 11:21:50 +00:00
Dave Hrycyszyn ec849cfc0c Merge pull request #13 from nymtech/feature/presence
Feature/presence
2019-12-16 11:21:23 +00:00
Dave Hrycyszyn 233dc5ce9d cargo: lockfile including new nym-client dependencies 2019-12-16 10:28:51 +00:00
Dave Hrycyszyn e4cfab537e presence: renamed to non-stutter names 2019-12-14 15:46:53 +00:00
Dave Hrycyszyn 9fc01cee73 provider: move presence notifications into its own module 2019-12-14 15:35:10 +00:00
Dave Hrycyszyn 842c0b10b9 node: moving presence notification into a thread. 2019-12-14 14:44:07 +00:00
Dave Hrycyszyn f10a403045 cargo: re-ordering 2019-12-14 14:43:49 +00:00
Dave Hrycyszyn 3ab41835a2 provider: importing types and code for presence notifications. Not yet working. 2019-12-13 13:45:36 +00:00
Dave Hrycyszyn 0b41badab0 cargo: alphabetizing 2019-12-13 13:28:31 +00:00
Dave Hrycyszyn 028cc66db3 cargo: added nym-client library 2019-12-13 13:27:03 +00:00
Dave Hrycyszyn 60dc3b4650 cargo: newline 2019-12-13 13:26:47 +00:00
Dave Hrycyszyn 3d9181a913 main: removing assert so that the node starts 2019-12-13 13:25:59 +00:00
Dave Hrycyszyn 1633f54f4f node: adding presence notifications (note: doesn't work yet) 2019-12-13 13:19:58 +00:00
Dave Hrycyszyn 86d27b06df cargo: depending on the nym-client library 2019-12-13 13:19:40 +00:00
Dave Hrycyszyn 07bb0a69fa cargo: newline action 2019-12-13 13:19:26 +00:00
Jędrzej Stuczyński 138814f26c Merge pull request #12 from nymtech/feature/routing
mix_peer: now using the real address from the packet
2019-12-12 19:19:03 +00:00
Dave Hrycyszyn 06540f5ce1 node: removing more lifetimes 2019-12-12 19:15:28 +00:00
Dave Hrycyszyn 4feadb6352 mix_peer: now using the real address from the packet 2019-12-12 19:01:53 +00:00
Dave Hrycyszyn fdf49ff804 runner: cleaning up text to prep for release 2019-12-12 17:47:13 +00:00
Dave Hrycyszyn eb49ef1013 node: removing socket mutabilitiy 2019-12-12 17:10:24 +00:00
Dave Hrycyszyn 17deec7720 runner: removing host assertion so default takes effect 2019-12-12 17:10:08 +00:00
Dave Hrycyszyn 76c2eac3bd main: adding usage banner 2019-12-12 16:59:01 +00:00
Dave Hrycyszyn f095dd114e main: breaking the run command out so that it lives with the node code 2019-12-12 16:57:01 +00:00
Jędrzej Stuczyński 5004f6d07a Merge pull request #15 from nymtech/feature/banner-and-commands
main: re-arranged so main() is at the top, and added a banner
2019-12-12 16:50:39 +00:00
Dave Hrycyszyn 31fbe3c265 main: re-arranged so main() is at the top, and added a banner 2019-12-12 16:46:39 +00:00
Dave Hrycyszyn 478fe628ca Merge pull request #12 from nymtech/feature/client_packet_retrieval
Feature/client packet retrieval
2019-12-12 15:25:40 +00:00
Jedrzej Stuczynski fbb675e815 Future comment 2019-12-12 15:14:04 +00:00
Jedrzej Stuczynski 96f5d45877 Removal of retrieved messages 2019-12-12 15:13:04 +00:00
Jedrzej Stuczynski 5d356847fa Some additional cleanup 2019-12-12 15:02:01 +00:00
Jedrzej Stuczynski 16ddb50159 Moved client-related functionalities to separate module 2019-12-12 14:55:23 +00:00
Jedrzej Stuczynski 48bead3ac9 Moved mix-related functionalities to separate module 2019-12-12 14:46:41 +00:00
Jedrzej Stuczynski 35cff8dfcd Moved store related functionalities to separate module 2019-12-12 14:40:10 +00:00
Jedrzej Stuczynski 2850c71317 Sending back messages to the client 2019-12-12 12:37:17 +00:00
Jedrzej Stuczynski 534a4aedc7 Pull messages response + marshaling 2019-12-12 12:27:02 +00:00
Jedrzej Stuczynski 27b55a7e60 Moved requests to separate module 2019-12-12 12:26:33 +00:00
Jedrzej Stuczynski dc5660728e Moved dummy message content to requests crate 2019-12-12 10:45:06 +00:00
Jedrzej Stuczynski 86693ab983 Reading constant number of stored messages and when below limit putting dummy data 2019-12-12 10:43:32 +00:00
Jedrzej Stuczynski 10d31abbf8 Added my test inbox to gitignore... 2019-12-12 10:05:15 +00:00
Jedrzej Stuczynski c4779e3428 printing all files with given clients' messages 2019-12-12 10:04:17 +00:00
Jedrzej Stuczynski 8bb462bda1 Basic structure for client message retrieval 2019-12-11 17:24:56 +00:00
Jedrzej Stuczynski 427b83875a Changed read_to_end to normal read with 1024 buffer 2019-12-11 16:59:46 +00:00
Jedrzej Stuczynski 8393910016 Closing socket to client on being done 2019-12-11 16:42:37 +00:00
Jedrzej Stuczynski e283d162e5 Updated gitignore... 2019-12-11 15:49:26 +00:00
Jedrzej Stuczynski d869d427e4 Removed the build information for the subcrate... 2019-12-11 15:48:57 +00:00
Jedrzej Stuczynski a08bbc98db Moved provider requests to subcrate in sfw provider 2019-12-11 15:48:30 +00:00
Jedrzej Stuczynski c02665f71e Fixed using incorrect address for client listener 2019-12-11 11:26:58 +00:00
Jedrzej Stuczynski 9ddbaf42d5 Actually spawning new thread and calling processing function 2019-12-11 11:25:46 +00:00
Jedrzej Stuczynski bc77ddadfa Opening dedicated client tcp socket 2019-12-11 11:24:59 +00:00
Jedrzej Stuczynski 688376f757 Fixed linter error about unused results 2019-12-11 11:15:13 +00:00
Jedrzej Stuczynski 1c0eab2fa2 Running two concurrent futures 2019-12-11 11:13:48 +00:00
Jedrzej Stuczynski fb456c0bd0 Added client-related host and port arguments 2019-12-11 10:45:32 +00:00
Dave Hrycyszyn 8d0afbd21e Merge pull request #7 from nymtech/feature/provider_type
Provider storing received messages
2019-12-10 16:00:12 +00:00
Jedrzej Stuczynski 528ba87492 Removed unused imports 2019-12-10 15:36:14 +00:00
Jedrzej Stuczynski d08a9965c8 Removed commented code with an experiment on usage of tokio tcp listener 2019-12-10 15:34:58 +00:00
Jedrzej Stuczynski bf360473d5 Removed accidentally added tmp store directory 2019-12-10 15:29:08 +00:00
Jedrzej Stuczynski fd2f565af2 Provider storing received messages 2019-12-10 15:28:51 +00:00
Jedrzej Stuczynski 7a3f16548b Creating full store path 2019-12-10 14:35:44 +00:00
Jedrzej Stuczynski 6fdc4a6434 Calling store_processed_data after processing each sphinx packet 2019-12-10 14:25:30 +00:00
Dave Hrycyszyn b5c5ea3193 Merge pull request #7 from nymtech/feature/removal_of_processing_data_copy
Removed processing data copy on every connection and instead use Arc …
2019-12-10 13:18:39 +00:00
Jedrzej Stuczynski 1371b94599 Removed processing data copy on every connection and instead use Arc with RwLock 2019-12-10 13:12:58 +00:00
Jedrzej Stuczynski 2c986efcb1 Finally won first fight with the borrow checker for concurrent code 2019-12-10 13:05:44 +00:00
Jedrzej Stuczynski 9b8b0bff1d Moved socket processing to separate function 2019-12-09 17:07:42 +00:00
Jedrzej Stuczynski cd94ecde19 Passing entire processing data struct for dealing with sphinx packets 2019-12-09 13:59:22 +00:00
Jedrzej Stuczynski 385e41a920 Added store directory as additional provider argument 2019-12-09 12:57:18 +00:00
Jedrzej Stuczynski 836cff226a Moved listening loop to provider struct impl 2019-12-09 12:47:38 +00:00
Dave Hrycyszyn 86861ccb70 Merge pull request #6 from nymtech/feature/command_line_arguments
Feature/command line arguments
2019-12-09 11:48:11 +00:00
Dave Hrycyszyn 0b4f10cfe6 Merge pull request #6 from nymtech/feature/command_line_arguments
Feature/command line arguments
2019-12-09 11:44:35 +00:00
Jedrzej Stuczynski 8ac76cb152 passing arguments to the service provider startup 2019-12-09 10:44:21 +00:00
Jedrzej Stuczynski 818389839f Moved provider related functionalities to separate module 2019-12-09 10:38:01 +00:00
Jedrzej Stuczynski 3a069f18e2 Adjusted packet content 2019-12-09 10:27:30 +00:00
Jedrzej Stuczynski 31d0aa7fe4 Added layer as mixnode attribute 2019-12-06 16:21:04 +00:00
Jedrzej Stuczynski 256afa3be9 Removed example code 2019-12-06 16:20:26 +00:00
Jedrzej Stuczynski 777c40bd97 Starting mixnode with provided command line arguments 2019-12-06 16:20:07 +00:00
Jedrzej Stuczynski 9deaad8a2a Initial set of mixnode arguments 2019-12-06 16:14:29 +00:00
AniaPiotrowska 1ad60582ba Merge pull request #5 from nymtech/feature/andrew_experiments
Delays + some code reorganisation
2019-12-06 15:57:27 +00:00
Jedrzej Stuczynski 2aaf2465e4 Moved mix code to separate module 2019-12-06 14:47:14 +00:00
Jedrzej Stuczynski 0fb9c352d6 - 2019-12-06 13:30:39 +00:00
Jedrzej Stuczynski ad289e531b Calling start_listening on mix node instance 2019-12-06 13:26:47 +00:00
Jedrzej Stuczynski 2fbf2456ec More async cleanup 2019-12-06 13:18:50 +00:00
Jedrzej Stuczynski 2c2ecfb785 Initial minor cleanup + actually waiting for time specified in the packet 2019-12-06 12:58:51 +00:00
Jedrzej Stuczynski 9478460893 Waiting 2s before forwarding packet 2019-12-05 17:08:46 +00:00
Dave Hrycyszyn 6ae04b7ed3 Removing print statements 2019-12-02 13:50:21 +00:00
Dave Hrycyszyn fff78cfade Updating to work with constant sized packets 2019-11-29 15:54:44 +00:00
Dave Hrycyszyn e8472e07f9 Updating to work with constant sized packets 2019-11-29 15:54:34 +00:00
Jędrzej Stuczyński 2c0a4b11db Added README - git was asking so nicely to do it : ) 2019-11-29 12:32:14 +00:00
Jędrzej Stuczyński 1eee313e6e Added README - git was asking so nicely to do it : ) 2019-11-29 12:31:49 +00:00
Dave Hrycyszyn 14dfa4795a Initial commit 2019-11-29 12:28:25 +00:00
Dave Hrycyszyn d7ed6b5a13 WIP 2019-11-29 12:26:12 +00:00
Dave Hrycyszyn f4a62fd64c Initial commit 2019-11-28 19:33:20 +00:00
275 changed files with 49062 additions and 3663 deletions
+2
View File
@@ -0,0 +1,2 @@
RUST_LOG=info
RUST_BACKTRACE=1
+10 -2
View File
@@ -1,3 +1,11 @@
/target
/targetString
**/*.rs.bk
/.idea/
/*/target
/test_inbox
.idea
target
.env
/.vscode/settings.json
validator/.vscode
sample-configs/validator-config.toml
.vscode
+15
View File
@@ -0,0 +1,15 @@
language: rust
rust:
- stable
- beta
- nightly
jobs:
allow_failures:
- rust: nightly
fast_finish: true
before_script:
- rustup component add rustfmt
script:
- cargo build
- cargo test -- --test-threads=1
- cargo fmt -- --check
+376 -12
View File
@@ -1,12 +1,376 @@
# nym-client Changelog
* removed the `--local` flag
* introduced `--directory` argument to support arbitrary directory servers. Leaving it out will point the node at the "https://directory.nymtech.net" alpha testnet server
* IPv6 support
* client version number is now shown at node start
* directory server location is now shown at node start
* decrease default delays
## 0.1.0 - Initial Release
* The bare minimum set of features required by a Nym Client
# Changelog
## [v0.7.0](https://github.com/nymtech/nym/tree/HEAD)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.6.0...HEAD)
The main features of this release are:
* the addition of gateway nodes
* the retiring of the store-and-forward providers in favour of gateway nodes
* got rid of TCP connections for clients, everything now happens through websockets
* a new [Nym webassembly client](https://www.npmjs.com/package/@nymproject/nym-client-wasm), making it possible interact with Nym easily in browser-based runtimes
* reliability and performance improvements for mixnode networking
* initial validator code running (little functionality yet though)
See the [changelog](https://github.com/nymtech/nym/blob/develop/CHANGELOG.md) for detailed release notes.
**Implemented enhancements:**
- Use tokio codecs for multi\_tcp\_client [\#207](https://github.com/nymtech/nym/issues/207)
- Consider rewriting sfw\_provider\_requests using tokio Framed + Codec [\#181](https://github.com/nymtech/nym/issues/181)
**Fixed bugs:**
- Unexplained traffic increase in presence of unroutable node [\#232](https://github.com/nymtech/nym/issues/232)
- Gateway won't send to restarted layer1 nodes [\#231](https://github.com/nymtech/nym/issues/231)
**Closed issues:**
- Move to userpubkey@gatewaypubkey addresses. [\#235](https://github.com/nymtech/nym/issues/235)
- Get `start\_local\_network.sh` working with the js example [\#227](https://github.com/nymtech/nym/issues/227)
- Fix indeterminate test failure [\#218](https://github.com/nymtech/nym/issues/218)
- Remove 'fetch' mechanism from desktop client's client in favour of push [\#211](https://github.com/nymtech/nym/issues/211)
- Mixnode - load Sphinx keys like Gateway [\#209](https://github.com/nymtech/nym/issues/209)
- Publish NPM package for WebAssembly client [\#206](https://github.com/nymtech/nym/issues/206)
- Change --sockettype option on desktop client [\#203](https://github.com/nymtech/nym/issues/203)
- Remove TCP sockets from desktop client [\#202](https://github.com/nymtech/nym/issues/202)
- Desktop client currently hard-codes first provider [\#198](https://github.com/nymtech/nym/issues/198)
- Webassembly client currently hard-codes first provider [\#197](https://github.com/nymtech/nym/issues/197)
- Add Rust-based route construction to wasm client [\#196](https://github.com/nymtech/nym/issues/196)
- Remove fetch event [\#195](https://github.com/nymtech/nym/issues/195)
- Control messages should all be JSON [\#194](https://github.com/nymtech/nym/issues/194)
- Desktop Client should attach to gateway websocket [\#193](https://github.com/nymtech/nym/issues/193)
- Merge gateway and provider nodes [\#192](https://github.com/nymtech/nym/issues/192)
- Remove direct Sphinx dependencies [\#184](https://github.com/nymtech/nym/issues/184)
- \[Windows\] Presence notification fill OS socket queue [\#170](https://github.com/nymtech/nym/issues/170)
- Figure out connection hiccups between client and provider [\#162](https://github.com/nymtech/nym/issues/162)
- Improve the healthchecker [\#160](https://github.com/nymtech/nym/issues/160)
- Rethink client addressability [\#135](https://github.com/nymtech/nym/issues/135)
- Give some love to the service provider client ledger [\#116](https://github.com/nymtech/nym/issues/116)
- Start Gateway node type [\#80](https://github.com/nymtech/nym/issues/80)
- Bring health-checker into validator mix-mining [\#78](https://github.com/nymtech/nym/issues/78)
- Solidify TCPSocket on client [\#72](https://github.com/nymtech/nym/issues/72)
- scripts: run\_local\_network.sh doesn't die nicely [\#45](https://github.com/nymtech/nym/issues/45)
- WASM version of the Sphinx packet [\#19](https://github.com/nymtech/nym/issues/19)
- Persistent socket connection \(TCP Socket with provider\) [\#18](https://github.com/nymtech/nym/issues/18)
- Persistent socket connection \(Websocket with client\) [\#17](https://github.com/nymtech/nym/issues/17)
- Persistent socket connection \(TCP Socket with client\) [\#13](https://github.com/nymtech/nym/issues/13)
- Persistent socket connection \(Websocket with client\) [\#12](https://github.com/nymtech/nym/issues/12)
- Persistently store ledger with registered clients and their auth tokens [\#6](https://github.com/nymtech/nym/issues/6)
**Merged pull requests:**
- renaming desktop to native client [\#251](https://github.com/nymtech/nym/pull/251) ([futurechimp](https://github.com/futurechimp))
- Adding a pipenv dependencies file to the python client example [\#250](https://github.com/nymtech/nym/pull/250) ([futurechimp](https://github.com/futurechimp))
- Cleaning up startup messages in native client [\#249](https://github.com/nymtech/nym/pull/249) ([futurechimp](https://github.com/futurechimp))
- fixing up readme, bumping version number [\#246](https://github.com/nymtech/nym/pull/246) ([futurechimp](https://github.com/futurechimp))
- Feature/sphinx socket packet encoder [\#245](https://github.com/nymtech/nym/pull/245) ([jstuczyn](https://github.com/jstuczyn))
- Adding some documentation to the webassembly client [\#244](https://github.com/nymtech/nym/pull/244) ([futurechimp](https://github.com/futurechimp))
- Simplified some names and used the published npm package [\#242](https://github.com/nymtech/nym/pull/242) ([futurechimp](https://github.com/futurechimp))
- Feature/make andrew happy [\#241](https://github.com/nymtech/nym/pull/241) ([futurechimp](https://github.com/futurechimp))
- Removed redundant console.log [\#240](https://github.com/nymtech/nym/pull/240) ([jstuczyn](https://github.com/jstuczyn))
- Feature/explicit gateway addressing [\#239](https://github.com/nymtech/nym/pull/239) ([jstuczyn](https://github.com/jstuczyn))
- Feature/clean up [\#238](https://github.com/nymtech/nym/pull/238) ([futurechimp](https://github.com/futurechimp))
- Feature/addressing update [\#237](https://github.com/nymtech/nym/pull/237) ([jstuczyn](https://github.com/jstuczyn))
- Added hidden init flag to increase default traffic volume [\#234](https://github.com/nymtech/nym/pull/234) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/issue\#231 [\#233](https://github.com/nymtech/nym/pull/233) ([jstuczyn](https://github.com/jstuczyn))
- Fixed unwrap on none value [\#230](https://github.com/nymtech/nym/pull/230) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/gateway crash on incomplete ws handshake [\#229](https://github.com/nymtech/nym/pull/229) ([jstuczyn](https://github.com/jstuczyn))
- Feature/start local network improvements [\#228](https://github.com/nymtech/nym/pull/228) ([jstuczyn](https://github.com/jstuczyn))
- Updated directory\_client reqwest to 0.10 [\#226](https://github.com/nymtech/nym/pull/226) ([jstuczyn](https://github.com/jstuczyn))
- Updated js-example to get gateway from topology [\#225](https://github.com/nymtech/nym/pull/225) ([jstuczyn](https://github.com/jstuczyn))
- Requiring explicit timestamp when converting from rest to service mix… [\#224](https://github.com/nymtech/nym/pull/224) ([jstuczyn](https://github.com/jstuczyn))
- Feature/minor docs fixes [\#223](https://github.com/nymtech/nym/pull/223) ([futurechimp](https://github.com/futurechimp))
- Removed having to care about SURB\_ID [\#222](https://github.com/nymtech/nym/pull/222) ([jstuczyn](https://github.com/jstuczyn))
- Moved relevant parts of old mix-client to nymsphinx [\#221](https://github.com/nymtech/nym/pull/221) ([jstuczyn](https://github.com/jstuczyn))
- Feature/load keys on run [\#220](https://github.com/nymtech/nym/pull/220) ([jstuczyn](https://github.com/jstuczyn))
- Updated wasm code to work with new gateway and updated the example [\#219](https://github.com/nymtech/nym/pull/219) ([jstuczyn](https://github.com/jstuczyn))
- validator: removing health checker [\#217](https://github.com/nymtech/nym/pull/217) ([futurechimp](https://github.com/futurechimp))
- The great sfw-provider purge of 2020 [\#216](https://github.com/nymtech/nym/pull/216) ([jstuczyn](https://github.com/jstuczyn))
- Fixed compilation warnings on unreachable code when compiling with fe… [\#215](https://github.com/nymtech/nym/pull/215) ([jstuczyn](https://github.com/jstuczyn))
- Feature/healthchecker removal [\#214](https://github.com/nymtech/nym/pull/214) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/send to correct gateway [\#213](https://github.com/nymtech/nym/pull/213) ([jstuczyn](https://github.com/jstuczyn))
- Feature/client socket adjustments [\#212](https://github.com/nymtech/nym/pull/212) ([jstuczyn](https://github.com/jstuczyn))
- Sending sphinx packet independent of the receiver task [\#210](https://github.com/nymtech/nym/pull/210) ([jstuczyn](https://github.com/jstuczyn))
- Feature/gateway provider merge [\#208](https://github.com/nymtech/nym/pull/208) ([jstuczyn](https://github.com/jstuczyn))
- Feature/route from topology [\#201](https://github.com/nymtech/nym/pull/201) ([futurechimp](https://github.com/futurechimp))
- Intermediate gateway-heart surgery checkpoint [\#199](https://github.com/nymtech/nym/pull/199) ([jstuczyn](https://github.com/jstuczyn))
- Feature/wasm js demo [\#191](https://github.com/nymtech/nym/pull/191) ([futurechimp](https://github.com/futurechimp))
- Feature/improve js example [\#190](https://github.com/nymtech/nym/pull/190) ([futurechimp](https://github.com/futurechimp))
- Feature/limit direct sphinx dependency + remove direct curve25519 dependency from wasm client [\#189](https://github.com/nymtech/nym/pull/189) ([jstuczyn](https://github.com/jstuczyn))
- Feature/very minor refactoring [\#188](https://github.com/nymtech/nym/pull/188) ([jstuczyn](https://github.com/jstuczyn))
- Feature/persistent ledger [\#187](https://github.com/nymtech/nym/pull/187) ([jstuczyn](https://github.com/jstuczyn))
- Optimising wasm build size, shaves about 10% size off our wasm output. [\#186](https://github.com/nymtech/nym/pull/186) ([futurechimp](https://github.com/futurechimp))
- Ran `npm audit fix` on the wasm demo directory. [\#185](https://github.com/nymtech/nym/pull/185) ([futurechimp](https://github.com/futurechimp))
- Feature/nym sphinx wasm [\#183](https://github.com/nymtech/nym/pull/183) ([futurechimp](https://github.com/futurechimp))
- Improvements to sfw-provider - client communcation [\#180](https://github.com/nymtech/nym/pull/180) ([jstuczyn](https://github.com/jstuczyn))
- Adding Apache 2 license headers to all files [\#178](https://github.com/nymtech/nym/pull/178) ([futurechimp](https://github.com/futurechimp))
- Feature/service persistence [\#171](https://github.com/nymtech/nym/pull/171) ([futurechimp](https://github.com/futurechimp))
## [v0.6.0](https://github.com/nymtech/nym/tree/v0.6.0) (2020-04-07)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.5.0...v0.6.0)
This release fixes bugs in v0.5.0. All testnet node operators are advised to upgrade from v0.5.0.
* fixed premature EOFs on socket connections by using the new multi-TCP client
* fixed a bug causing client and mixnode connection hangs for misconfigured nodes
* by default 'Debug' section of saved configs is now empty and default values are used unless explicitly overridden
* introduced packet chunking allowing clients to send messages of arbitrary length. Note that packet retransmission is not implemented yet, so for longer messages, you might not get anything
* mixnodes now periodically log stats regarding number of packets mixed
* fixed possible client hang ups when sending high rates of traffic
* preventing mixes from starting with same announce-host as an existing node
* fixed overflow multiplication if connection backoff was set to a high value
**Closed issues:**
- Periodic activity summary [\#172](https://github.com/nymtech/nym/issues/172)
- Move contents of 'common/addressing' into 'common/nymsphinx' [\#161](https://github.com/nymtech/nym/issues/161)
- Make builds simpler for node operators [\#114](https://github.com/nymtech/nym/issues/114)
- Chunking in `nym-client` \(receive\) [\#83](https://github.com/nymtech/nym/issues/83)
- Chunking in `nym-client` \(send\) [\#82](https://github.com/nymtech/nym/issues/82)
**Merged pull requests:**
- Feature/tcp client connection timeout [\#176](https://github.com/nymtech/nym/pull/176) ([jstuczyn](https://github.com/jstuczyn))
- Feature/mixing stats logging [\#175](https://github.com/nymtech/nym/pull/175) ([jstuczyn](https://github.com/jstuczyn))
- Preventing multiplication overflow for reconnection backoff [\#174](https://github.com/nymtech/nym/pull/174) ([jstuczyn](https://github.com/jstuczyn))
- Feature/non mandatory debug config [\#173](https://github.com/nymtech/nym/pull/173) ([jstuczyn](https://github.com/jstuczyn))
- Feature/addressing move [\#169](https://github.com/nymtech/nym/pull/169) ([jstuczyn](https://github.com/jstuczyn))
- Checking if any other node is already announcing the same host [\#168](https://github.com/nymtech/nym/pull/168) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/closing tcp client connections on drop [\#167](https://github.com/nymtech/nym/pull/167) ([jstuczyn](https://github.com/jstuczyn))
- Yielding tokio task upon creating loop/real traffic message [\#166](https://github.com/nymtech/nym/pull/166) ([jstuczyn](https://github.com/jstuczyn))
- Feature/minor healthchecker improvements [\#165](https://github.com/nymtech/nym/pull/165) ([jstuczyn](https://github.com/jstuczyn))
- Feature/packet chunking [\#158](https://github.com/nymtech/nym/pull/158) ([jstuczyn](https://github.com/jstuczyn))
## [v0.5.0](https://github.com/nymtech/nym/tree/v0.5.0) (2020-03-23)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.5.0-rc.1...v0.5.0)
1. Introduced proper configuration options for mixnodes, clients and providers. Everything is initialised with the `init` command that creates a saved config.toml file. To run the binary you now use `nym-<binary-name> run`, for example `nym-mixnode run`. Each flag can be overwritten at any stage with the following priority: run flags, data in config.toml and finally init flags.
2. Made mixnet TCP connections persistent. When sending a Sphinx packet, it should no longer go through the lengthy process of establishing a TCP connection only to immediately tear it down after sending a single packet. This significantly boosts throughput.
3. A lot of work on code clean up and refactoring including some performance fixes.
4. Client now determines its default nym-sfw-provider at startup and should always try to connect to the same one. Note: we still can't reliably run more than a single provider on the network.
5. Logging messages now have timestamps and when running at more aggressive log mode (like debug or even trace) we should no longer be overwhelmed with messages from external crates.
6. Initial compatibility with Windows. Please let us know if you have problems.
7. More work on validator, including initial Tendermint integration in Rust, and the start of the mixmining system.
**Closed issues:**
- Introduce timestamps to log messages [\#124](https://github.com/nymtech/nym/issues/124)
**Merged pull requests:**
- removing spooky startup warning message [\#155](https://github.com/nymtech/nym/pull/155) ([futurechimp](https://github.com/futurechimp))
- Some more startup fixes [\#154](https://github.com/nymtech/nym/pull/154) ([futurechimp](https://github.com/futurechimp))
- Entering runtime context when creating mix traffic controller [\#153](https://github.com/nymtech/nym/pull/153) ([jstuczyn](https://github.com/jstuczyn))
- Friendlification of startup messages [\#151](https://github.com/nymtech/nym/pull/151) ([futurechimp](https://github.com/futurechimp))
- Entering runtime context when creating packet forwarder [\#150](https://github.com/nymtech/nym/pull/150) ([jstuczyn](https://github.com/jstuczyn))
- Feature/add topology to validator [\#149](https://github.com/nymtech/nym/pull/149) ([futurechimp](https://github.com/futurechimp))
- Making code work on windows machines [\#148](https://github.com/nymtech/nym/pull/148) ([jstuczyn](https://github.com/jstuczyn))
- validator: adding HTTP interface [\#146](https://github.com/nymtech/nym/pull/146) ([futurechimp](https://github.com/futurechimp))
- Extracting the log setup [\#145](https://github.com/nymtech/nym/pull/145) ([futurechimp](https://github.com/futurechimp))
- Feature/optional location in configs [\#144](https://github.com/nymtech/nym/pull/144) ([jstuczyn](https://github.com/jstuczyn))
- Feature/concurrent connection managers [\#142](https://github.com/nymtech/nym/pull/142) ([jstuczyn](https://github.com/jstuczyn))
- Defaulting for global 'Info' logging level if not set in .env [\#140](https://github.com/nymtech/nym/pull/140) ([jstuczyn](https://github.com/jstuczyn))
- Provider not storing loop cover messages [\#139](https://github.com/nymtech/nym/pull/139) ([jstuczyn](https://github.com/jstuczyn))
- Using log builder to include timestamps + filters [\#138](https://github.com/nymtech/nym/pull/138) ([jstuczyn](https://github.com/jstuczyn))
- Feature/client ws refactoring [\#134](https://github.com/nymtech/nym/pull/134) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/metrics presence delay fix [\#133](https://github.com/nymtech/nym/pull/133) ([jstuczyn](https://github.com/jstuczyn))
- Removed outdated and redundant sample-configs [\#131](https://github.com/nymtech/nym/pull/131) ([jstuczyn](https://github.com/jstuczyn))
- If not overridden, 'announce-host' should default to 'host' [\#130](https://github.com/nymtech/nym/pull/130) ([jstuczyn](https://github.com/jstuczyn))
- Nice to know who we're talking to at startup... [\#129](https://github.com/nymtech/nym/pull/129) ([futurechimp](https://github.com/futurechimp))
## [v0.5.0-rc.1](https://github.com/nymtech/nym/tree/v0.5.0-rc.1) (2020-03-06)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.4.1...v0.5.0-rc.1)
**Closed issues:**
- COMPILE: Could not compile project using Cargo [\#118](https://github.com/nymtech/nym/issues/118)
- Wherever unbounded mpsc channel is used, prefer unbounded\_send\(\) over send\(\).await [\#90](https://github.com/nymtech/nym/issues/90)
- Add a `Send` method in nym-client [\#81](https://github.com/nymtech/nym/issues/81)
- Start on Tendermint integration [\#79](https://github.com/nymtech/nym/issues/79)
- Ditch DummyKeyPair [\#75](https://github.com/nymtech/nym/issues/75)
- Replace args with proper config files [\#69](https://github.com/nymtech/nym/issues/69)
- Fix incorrectly used Arcs [\#47](https://github.com/nymtech/nym/issues/47)
- nym-mixnode mandatory host option [\#26](https://github.com/nymtech/nym/issues/26)
- Create config struct for mixnode \(possibly also for client\) [\#21](https://github.com/nymtech/nym/issues/21)
- Reuse TCP socket connection between client and mixnodes [\#20](https://github.com/nymtech/nym/issues/20)
- Once implementation is available, wherever appropriate, replace `futures::lock::Mutex` with `futures::lock::RwLock` [\#9](https://github.com/nymtech/nym/issues/9)
- Check if RwLock on MixProcessingData is still needed [\#8](https://github.com/nymtech/nym/issues/8)
- Reuse TCP socket connection between mixnodes and providers [\#3](https://github.com/nymtech/nym/issues/3)
- Persistent socket connection with other mixes [\#2](https://github.com/nymtech/nym/issues/2)
**Merged pull requests:**
- Feature/client refactoring [\#128](https://github.com/nymtech/nym/pull/128) ([jstuczyn](https://github.com/jstuczyn))
- Feature/provider refactoring [\#125](https://github.com/nymtech/nym/pull/125) ([jstuczyn](https://github.com/jstuczyn))
- all: fixing mis-spelling [\#123](https://github.com/nymtech/nym/pull/123) ([futurechimp](https://github.com/futurechimp))
- Feature/further clippy fixes [\#121](https://github.com/nymtech/nym/pull/121) ([jstuczyn](https://github.com/jstuczyn))
- Feature/tokio tungstenite dependency fix [\#120](https://github.com/nymtech/nym/pull/120) ([jstuczyn](https://github.com/jstuczyn))
- Feature/config files cleanup [\#119](https://github.com/nymtech/nym/pull/119) ([jstuczyn](https://github.com/jstuczyn))
- Feature/config files [\#117](https://github.com/nymtech/nym/pull/117) ([jstuczyn](https://github.com/jstuczyn))
- Feature/un genericize keys [\#111](https://github.com/nymtech/nym/pull/111) ([futurechimp](https://github.com/futurechimp))
- Feature/abci [\#110](https://github.com/nymtech/nym/pull/110) ([futurechimp](https://github.com/futurechimp))
- Simplified the use of generics on identity keypair by using output types [\#109](https://github.com/nymtech/nym/pull/109) ([jstuczyn](https://github.com/jstuczyn))
## [v0.4.1](https://github.com/nymtech/nym/tree/v0.4.1) (2020-01-29)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.4.0...v0.4.1)
**Closed issues:**
- Change healthcheck to run on provided topology rather than pull one itself [\#95](https://github.com/nymtech/nym/issues/95)
**Merged pull requests:**
- Bugfix/healthcheck on provided topology [\#108](https://github.com/nymtech/nym/pull/108) ([jstuczyn](https://github.com/jstuczyn))
## [v0.4.0](https://github.com/nymtech/nym/tree/v0.4.0) (2020-01-28)
[Full Changelog](https://github.com/nymtech/nym/compare/0.4.0-rc.2...v0.4.0)
Nym 0.4.0 Platform
In this release, we're taking a lot more care with version numbers, so that we can ensure upgrade compatibility for mixnodes, providers, clients, and validators more easily.
This release also integrates a health-checker and network topology refresh into the Nym client, so that the client can intelligently choose paths which route around any non-functional or incompatible nodes.
## [0.4.0-rc.2](https://github.com/nymtech/nym/tree/0.4.0-rc.2) (2020-01-28)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.4.0-rc.2...0.4.0-rc.2)
## [v0.4.0-rc.2](https://github.com/nymtech/nym/tree/v0.4.0-rc.2) (2020-01-28)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.4.0-rc.1...v0.4.0-rc.2)
**Merged pull requests:**
- Hotfix/semver compatibility [\#106](https://github.com/nymtech/nym/pull/106) ([jstuczyn](https://github.com/jstuczyn))
## [v0.4.0-rc.1](https://github.com/nymtech/nym/tree/v0.4.0-rc.1) (2020-01-28)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.3...v0.4.0-rc.1)
**Closed issues:**
- Check Sphinx packet length in client [\#98](https://github.com/nymtech/nym/issues/98)
- workflow test [\#97](https://github.com/nymtech/nym/issues/97)
- Client SemVer [\#85](https://github.com/nymtech/nym/issues/85)
- Move PemStore [\#74](https://github.com/nymtech/nym/issues/74)
- Periodic client refresh [\#70](https://github.com/nymtech/nym/issues/70)
- Logging [\#68](https://github.com/nymtech/nym/issues/68)
- Nym-client refactor [\#67](https://github.com/nymtech/nym/issues/67)
- Stop panicking! [\#66](https://github.com/nymtech/nym/issues/66)
- Fix Mixnode Panic on Sphinx packet replay [\#65](https://github.com/nymtech/nym/issues/65)
- Convert older code to start using logging [\#35](https://github.com/nymtech/nym/issues/35)
- Convert to non-url-safe base64 \(everywhere\) [\#28](https://github.com/nymtech/nym/issues/28)
- If a thread blows at startup, panic the entire application [\#15](https://github.com/nymtech/nym/issues/15)
- Split provider/mod.rs [\#10](https://github.com/nymtech/nym/issues/10)
**Merged pull requests:**
- Feature/health checker with existing keys [\#105](https://github.com/nymtech/nym/pull/105) ([jstuczyn](https://github.com/jstuczyn))
- Feature/remove topology equality check [\#104](https://github.com/nymtech/nym/pull/104) ([futurechimp](https://github.com/futurechimp))
- Feature/base58 [\#102](https://github.com/nymtech/nym/pull/102) ([futurechimp](https://github.com/futurechimp))
- Feature/panic improvements [\#101](https://github.com/nymtech/nym/pull/101) ([jstuczyn](https://github.com/jstuczyn))
- Feature/fix sphinx unwraps [\#100](https://github.com/nymtech/nym/pull/100) ([futurechimp](https://github.com/futurechimp))
- Feature/check packet length [\#99](https://github.com/nymtech/nym/pull/99) ([futurechimp](https://github.com/futurechimp))
- Feature/version filtering improvements [\#96](https://github.com/nymtech/nym/pull/96) ([futurechimp](https://github.com/futurechimp))
- Feature/refreshing topology [\#94](https://github.com/nymtech/nym/pull/94) ([jstuczyn](https://github.com/jstuczyn))
- Feature/consistent logging [\#93](https://github.com/nymtech/nym/pull/93) ([futurechimp](https://github.com/futurechimp))
- Feature/semver client [\#92](https://github.com/nymtech/nym/pull/92) ([futurechimp](https://github.com/futurechimp))
- Feature/client refactor [\#91](https://github.com/nymtech/nym/pull/91) ([jstuczyn](https://github.com/jstuczyn))
- Release builds should no longer silently fail - everything will be im… [\#89](https://github.com/nymtech/nym/pull/89) ([jstuczyn](https://github.com/jstuczyn))
## [v0.3.3](https://github.com/nymtech/nym/tree/v0.3.3) (2020-01-20)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.2...v0.3.3)
**Fixed bugs:**
- Nym client crashing and disconnecting local websocket with complaint about binary data [\#56](https://github.com/nymtech/nym/issues/56)
**Closed issues:**
- Websocket text fix [\#64](https://github.com/nymtech/nym/issues/64)
- Restore nym-client lib in crate [\#63](https://github.com/nymtech/nym/issues/63)
- Make websocket not crash on ping or pong messages [\#62](https://github.com/nymtech/nym/issues/62)
- Messages returned by fetch are base64 encoded [\#55](https://github.com/nymtech/nym/issues/55)
- Check layer 1 connectivity at client start [\#38](https://github.com/nymtech/nym/issues/38)
- Check required sfw-provider args [\#27](https://github.com/nymtech/nym/issues/27)
- Make Electron app work with new Rust mixnet client [\#16](https://github.com/nymtech/nym/issues/16)
- Take version numbers into account when picking routes [\#14](https://github.com/nymtech/nym/issues/14)
**Merged pull requests:**
- Feature/websocket improvements [\#88](https://github.com/nymtech/nym/pull/88) ([jstuczyn](https://github.com/jstuczyn))
- Using println rather than log for startup banner, it's not an error [\#87](https://github.com/nymtech/nym/pull/87) ([futurechimp](https://github.com/futurechimp))
- Feature/nym client lib [\#61](https://github.com/nymtech/nym/pull/61) ([jstuczyn](https://github.com/jstuczyn))
## [v0.3.2](https://github.com/nymtech/nym/tree/v0.3.2) (2020-01-17)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.1...v0.3.2)
**Merged pull requests:**
- Feature/separate presence address [\#59](https://github.com/nymtech/nym/pull/59) ([jstuczyn](https://github.com/jstuczyn))
## [v0.3.1](https://github.com/nymtech/nym/tree/v0.3.1) (2020-01-16)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.0...v0.3.1)
**Merged pull requests:**
- Bugfix/presence client crash [\#58](https://github.com/nymtech/nym/pull/58) ([jstuczyn](https://github.com/jstuczyn))
## [v0.3.0](https://github.com/nymtech/nym/tree/v0.3.0) (2020-01-14)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.2.0...v0.3.0)
**Closed issues:**
- Error referring to mismatched types caused by topology [\#46](https://github.com/nymtech/nym/issues/46)
- Provider needs to announce two of its addresses \(+ issue of hardcoded port\) [\#32](https://github.com/nymtech/nym/issues/32)
- Port run\_network.sh from old Go mixnet [\#30](https://github.com/nymtech/nym/issues/30)
- Health Checker inside Validator [\#29](https://github.com/nymtech/nym/issues/29)
- Combine Rust repositories into a single master repo containing multiple crates [\#24](https://github.com/nymtech/nym/issues/24)
- Fix the version numbers on provider and mixnode [\#23](https://github.com/nymtech/nym/issues/23)
- Travis releases for Nym [\#22](https://github.com/nymtech/nym/issues/22)
- Add version number to presence [\#4](https://github.com/nymtech/nym/issues/4)
- Add version number to presence [\#1](https://github.com/nymtech/nym/issues/1)
**Merged pull requests:**
- Feature/client topology filtering [\#54](https://github.com/nymtech/nym/pull/54) ([jstuczyn](https://github.com/jstuczyn))
- print public key for nym client tools [\#53](https://github.com/nymtech/nym/pull/53) ([mileschet](https://github.com/mileschet))
- Showing binding warning on binding to localhost, 0.0.0.0 or 127.0.0.1 [\#52](https://github.com/nymtech/nym/pull/52) ([jstuczyn](https://github.com/jstuczyn))
- validator: moving sample config files into sample configs directory [\#51](https://github.com/nymtech/nym/pull/51) ([futurechimp](https://github.com/futurechimp))
- Feature/validator health checker [\#50](https://github.com/nymtech/nym/pull/50) ([jstuczyn](https://github.com/jstuczyn))
- Improving websocket connection errors [\#49](https://github.com/nymtech/nym/pull/49) ([futurechimp](https://github.com/futurechimp))
- Feature/crypto crate [\#48](https://github.com/nymtech/nym/pull/48) ([jstuczyn](https://github.com/jstuczyn))
- Feature/chill log messages [\#43](https://github.com/nymtech/nym/pull/43) ([futurechimp](https://github.com/futurechimp))
- persistence: improving PEM file reading and parsing failure messages [\#42](https://github.com/nymtech/nym/pull/42) ([futurechimp](https://github.com/futurechimp))
- Providing a nicer error than "failed on unwrap\(\)" when topology retri… [\#41](https://github.com/nymtech/nym/pull/41) ([futurechimp](https://github.com/futurechimp))
- Prettying up sfw-provider start sequence a bit. [\#40](https://github.com/nymtech/nym/pull/40) ([futurechimp](https://github.com/futurechimp))
- Removing the run command from code and documentation [\#39](https://github.com/nymtech/nym/pull/39) ([futurechimp](https://github.com/futurechimp))
- Feature/script/localnet [\#37](https://github.com/nymtech/nym/pull/37) ([futurechimp](https://github.com/futurechimp))
- Feature/arguments fix [\#36](https://github.com/nymtech/nym/pull/36) ([jstuczyn](https://github.com/jstuczyn))
- Feature/crates cleanup [\#34](https://github.com/nymtech/nym/pull/34) ([jstuczyn](https://github.com/jstuczyn))
- Features/version number to presence [\#25](https://github.com/nymtech/nym/pull/25) ([aniampio](https://github.com/aniampio))
- Feature/minor client changes [\#7](https://github.com/nymtech/nym/pull/7) ([jstuczyn](https://github.com/jstuczyn))
## [v0.2.0](https://github.com/nymtech/nym/tree/v0.2.0) (2020-01-07)
[Full Changelog](https://github.com/nymtech/nym/compare/0.2.0...v0.2.0)
## [0.2.0](https://github.com/nymtech/nym/tree/0.2.0) (2020-01-06)
[Full Changelog](https://github.com/nymtech/nym/compare/0.1.0...0.2.0)
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
Generated
+2145 -975
View File
File diff suppressed because it is too large Load Diff
+22 -37
View File
@@ -1,39 +1,24 @@
[package]
build = "build.rs"
name = "nym-client"
version = "0.2.0"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2018"
[profile.release]
panic = "abort"
opt-level = "s"
[lib]
name = "nym_client"
path = "src/lib.rs"
[workspace]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
base64 = "0.11.0"
clap = "2.33.0"
curve25519-dalek = "1.2.3"
dirs = "2.0.2"
futures = "0.3.1"
hex = "0.4.0"
pem = "0.7.0"
rand = "0.7.2"
rand_distr = "0.2.2"
reqwest = "0.9.22"
serde = { version = "1.0.104", features = ["derive"] }
serde_json = "1.0.44"
sphinx = { path = "../sphinx" }
sfw-provider-requests = { path = "../nym-sfw-provider/sfw-provider-requests" }
tokio = { version = "0.2", features = ["full"] }
tungstenite = "0.9.2"
# putting this explicitly below everything and most likely, the next time we look into it, it will already have a proper release
tokio-tungstenite = { git = "https://github.com/dbcfd/tokio-tungstenite", rev="6dc2018cbfe8fe7ddd75ff977343086503135b38" }
[build-dependencies]
built = "0.3.2"
[dev-dependencies]
mockito = "0.22.0"
members = [
"clients/native",
"clients/webassembly",
"common/client-libs/directory-client",
"common/client-libs/gateway-client",
"common/client-libs/mixnet-client",
"common/client-libs/validator-client",
"common/config",
"common/crypto",
"common/healthcheck",
"common/nymsphinx",
"common/pemstore",
"common/topology",
"gateway",
"gateway/gateway-requests",
"mixnode",
"validator",
]
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
+20 -6
View File
@@ -1,10 +1,24 @@
# Nym Client
## The Nym Privacy Platform
The Nym Client communicates with the remote, decentralised nodes which make up the Nym system as a whole.
This repository contains the full Nym platform.
It needs to handle communication with 3 types of remote nodes. Here's the development status of each:
The platform is composed of multiple Rust crates. Top-level executable binary crates include:
- [ ] Directory nodes
- [ ] Mix nodes
- [ ] Validator nodes
* nym-mixnode - shuffles [Sphinx](https://github.com/nymtech/sphinx) packets together to provide privacy against network-level attackers.
* nym-client - an executable which you can build into your own applications. Use it for interacting with Nym nodes.
* nym-sfw-provider - a store-and-forward service provider. The provider acts sort of like a mailbox for mixnet messages.
* nym-validator - currently just starting development. Handles consensus ordering of transactions, mixmining, and coconut credential generation and validation.
[![Build Status](https://travis-ci.com/nymtech/nym.svg?branch=develop)](https://travis-ci.com/nymtech/nym)
### Building
Platform build instructions are available on [our docs site](https://nymtech.net/docs).
### Developing
There's a `.env.sample-dev` file provided which you can rename to `.env` if you want convenient logging, backtrace, or other environment variables pre-set. The `.env` file is ignored so you don't need to worry about checking it in.
### Developer chat
You can chat to us in [Keybase](https://keybase.io). Download their chat app, then click **Teams -> Join a team**. Type **nymtech.friends** into the team name and hit **continue**. For general chat, hang out in the **#general** channel. Our development takes places in the **#dev** channel. Node operators should be in the **#node-operators** channel.
-5
View File
@@ -1,5 +0,0 @@
use built;
fn main() {
built::write_built_file().expect("Failed to acquire build-time information");
}
+2402
View File
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
[package]
build = "build.rs"
name = "nym-client"
version = "0.7.0"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "nym_client"
path = "src/lib.rs"
[dependencies]
bs58 = "0.3.0"
clap = "2.33.0"
curve25519-dalek = "2.0.0"
dirs = "2.0.2"
dotenv = "0.15.0"
futures = "0.3.1"
log = "0.4"
pem = "0.7.0"
pretty_env_logger = "0.3"
reqwest = "0.9.22"
serde = { version = "1.0.104", features = ["derive"] }
serde_json = "1.0.44"
tokio = { version = "0.2", features = ["full"] }
tokio-tungstenite = "0.10.1"
url = "2.1"
## internal
config = {path = "../../common/config"}
crypto = {path = "../../common/crypto"}
directory-client = { path = "../../common/client-libs/directory-client" }
gateway-client = { path = "../../common/client-libs/gateway-client" }
gateway-requests = { path = "../../gateway/gateway-requests" }
mixnet-client = { path = "../../common/client-libs/mixnet-client" }
nymsphinx = { path = "../../common/nymsphinx" }
pemstore = {path = "../../common/pemstore"}
topology = {path = "../../common/topology" }
[build-dependencies]
built = "0.3.2"
[dev-dependencies]
tempfile = "3.1.0"
+3
View File
@@ -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.
+19
View File
@@ -0,0 +1,19 @@
// 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 built;
fn main() {
built::write_built_file().expect("Failed to acquire build-time information");
}
+9
View File
@@ -0,0 +1,9 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis efficitur neque. Quisque aliquet vulputate ante, eget vehicula odio feugiat ac. Nulla ut mattis magna. Aenean tincidunt quis nulla eget eleifend. Cras in pretium sem. Nunc lorem metus, blandit sit amet egestas ut, feugiat quis tellus. Aenean tristique, enim a tincidunt condimentum, eros est blandit nunc, id viverra metus erat at nulla. Vivamus at tellus sodales, feugiat odio vel, laoreet neque. Vivamus posuere nulla ac sodales bibendum.
Vestibulum pulvinar nisi non ultricies egestas. Integer finibus ultrices justo vitae suscipit. Etiam interdum eu justo vel interdum. Morbi sagittis ac nisl quis consequat. Mauris dapibus ut risus ac facilisis. Pellentesque non tortor feugiat, consectetur arcu vel, ullamcorper sapien. Proin sodales purus non orci bibendum, sit amet ultrices justo ullamcorper. Nullam ac risus ac justo ultricies efficitur auctor nec arcu. Etiam sed finibus felis. Suspendisse potenti. Phasellus malesuada velit ac ullamcorper egestas. Sed elementum diam ut est gravida ultricies.
Pellentesque sed metus massa. Cras imperdiet lacus sit amet dolor aliquam, luctus posuere justo hendrerit. Morbi augue ex, gravida a metus sed, scelerisque euismod lacus. Nam consequat sapien ac pellentesque sagittis. Morbi a ultrices massa, vel aliquet ex. Maecenas ac sem diam. Nunc sed erat et ipsum volutpat auctor. Etiam elit felis, commodo vitae ipsum ac, fermentum lobortis arcu. Aliquam eu tempus enim. Curabitur vulputate imperdiet aliquam. Morbi iaculis rhoncus risus at malesuada. Donec accumsan feugiat ligula ut facilisis. Nunc porttitor sit amet est eget malesuada. Sed sed consectetur augue, non dapibus orci. Mauris aliquam pellentesque quam, sit amet pellentesque velit cursus vitae. Morbi sit amet molestie risus.
Nam gravida non ligula a egestas. Fusce sodales, purus id rhoncus mattis, purus est vehicula urna, vel finibus augue velit et est. Donec dictum erat eleifend lobortis iaculis. Praesent id venenatis ante. Donec feugiat, ipsum eget porttitor pulvinar, nisl odio posuere lorem, ut placerat elit nulla a ligula. Suspendisse nec nibh tincidunt, sollicitudin mi a, volutpat ligula. In maximus quam lacus, eget semper dolor sagittis sit amet.
In vitae hendrerit est, quis facilisis dui. In eu ante enim. Nullam hendrerit odio sit amet odio tincidunt eleifend. Aliquam erat volutpat. Curabitur commodo, purus pharetra lobortis rhoncus, tortor massa imperdiet nisl, vel dignissim tortor sem at orci. Aliquam maximus lobortis lacus, eu porttitor purus dapibus ut. Praesent at dapibus felis, efficitur blandit tortor. In hac habitasse platea dictumst. Aenean ultrices, nisl a pretium sagittis, tellus sapien mollis erat, eu consectetur erat mauris sed libero. Duis feugiat dapibus mi, vel ornare velit vehicula mattis. Ut suscipit pharetra leo et sollicitudin.
@@ -0,0 +1,9 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis efficitur neque. Quisque aliquet vulputate ante, eget vehicula odio feugiat ac. Nulla ut mattis magna. Aenean tincidunt quis nulla eget eleifend. Cras in pretium sem. Nunc lorem metus, blandit sit amet egestas ut, feugiat quis tellus. Aenean tristique, enim a tincidunt condimentum, eros est blandit nunc, id viverra metus erat at nulla. Vivamus at tellus sodales, feugiat odio vel, laoreet neque. Vivamus posuere nulla ac sodales bibendum.
Vestibulum pulvinar nisi non ultricies egestas. Integer finibus ultrices justo vitae suscipit. Etiam interdum eu justo vel interdum. Morbi sagittis ac nisl quis consequat. Mauris dapibus ut risus ac facilisis. Pellentesque non tortor feugiat, consectetur arcu vel, ullamcorper sapien. Proin sodales purus non orci bibendum, sit amet ultrices justo ullamcorper. Nullam ac risus ac justo ultricies efficitur auctor nec arcu. Etiam sed finibus felis. Suspendisse potenti. Phasellus malesuada velit ac ullamcorper egestas. Sed elementum diam ut est gravida ultricies.
Pellentesque sed metus massa. Cras imperdiet lacus sit amet dolor aliquam, luctus posuere justo hendrerit. Morbi augue ex, gravida a metus sed, scelerisque euismod lacus. Nam consequat sapien ac pellentesque sagittis. Morbi a ultrices massa, vel aliquet ex. Maecenas ac sem diam. Nunc sed erat et ipsum volutpat auctor. Etiam elit felis, commodo vitae ipsum ac, fermentum lobortis arcu. Aliquam eu tempus enim. Curabitur vulputate imperdiet aliquam. Morbi iaculis rhoncus risus at malesuada. Donec accumsan feugiat ligula ut facilisis. Nunc porttitor sit amet est eget malesuada. Sed sed consectetur augue, non dapibus orci. Mauris aliquam pellentesque quam, sit amet pellentesque velit cursus vitae. Morbi sit amet molestie risus.
Nam gravida non ligula a egestas. Fusce sodales, purus id rhoncus mattis, purus est vehicula urna, vel finibus augue velit et est. Donec dictum erat eleifend lobortis iaculis. Praesent id venenatis ante. Donec feugiat, ipsum eget porttitor pulvinar, nisl odio posuere lorem, ut placerat elit nulla a ligula. Suspendisse nec nibh tincidunt, sollicitudin mi a, volutpat ligula. In maximus quam lacus, eget semper dolor sagittis sit amet.
In vitae hendrerit est, quis facilisis dui. In eu ante enim. Nullam hendrerit odio sit amet odio tincidunt eleifend. Aliquam erat volutpat. Curabitur commodo, purus pharetra lobortis rhoncus, tortor massa imperdiet nisl, vel dignissim tortor sem at orci. Aliquam maximus lobortis lacus, eu porttitor purus dapibus ut. Praesent at dapibus felis, efficitur blandit tortor. In hac habitasse platea dictumst. Aenean ultrices, nisl a pretium sagittis, tellus sapien mollis erat, eu consectetur erat mauris sed libero. Duis feugiat dapibus mi, vel ornare velit vehicula mattis. Ut suscipit pharetra leo et sollicitudin.
@@ -0,0 +1,76 @@
package main
import (
"encoding/json"
"fmt"
"github.com/btcsuite/btcutil/base58"
"github.com/gorilla/websocket"
"io/ioutil"
"strings"
)
func getSelfAddress(conn *websocket.Conn) string {
selfAddressRequest, err := json.Marshal(map[string]string{"type": "selfAddress"})
if err != nil {
panic(err)
}
if err = conn.WriteMessage(websocket.TextMessage, []byte(selfAddressRequest)); err != nil {
panic(err)
}
responseJSON := make(map[string]interface{})
err = conn.ReadJSON(&responseJSON)
if err != nil {
panic(err)
}
return responseJSON["address"].(string)
}
func main() {
uri := "ws://localhost:1977"
conn, _, err := websocket.DefaultDialer.Dial(uri, nil)
if err != nil {
panic(err)
}
defer conn.Close()
selfAddress := getSelfAddress(conn)
fmt.Printf("our address is: %v\n", selfAddress)
// we receive our address in string format of OUR_PUB_KEY @ OUR_GATE_PUB_KEY
// both keys are 32 bytes and we need to encode them as binary without the '@' sign
splitAddress := strings.Split(selfAddress, "@");
decodedDestination := base58.Decode(splitAddress[0])
decodedGateway := base58.Decode(splitAddress[1])
read_data, err := ioutil.ReadFile("dummy_file")
if err != nil {
panic(err)
}
payload := append(decodedDestination[:], append(decodedGateway[:], read_data[:]...)...)
fmt.Printf("sending content of 'dummy file' over the mix network...\n")
if err = conn.WriteMessage(websocket.BinaryMessage, payload); err != nil {
panic(err)
}
sendConfirmationJSON := make(map[string]interface{})
err = conn.ReadJSON(&sendConfirmationJSON)
if err != nil {
panic(err)
}
if sendConfirmationJSON["type"].(string) != "send" {
panic("invalid send confirmation")
}
fmt.Printf("waiting to receive a message from the mix network...\n")
_, receivedMessage, err := conn.ReadMessage()
if err != nil {
panic(err)
}
fmt.Printf("writing the file back to the disk!\n")
ioutil.WriteFile("received_file", receivedMessage, 0644)
}
@@ -0,0 +1,67 @@
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/websocket"
)
func getSelfAddress(conn *websocket.Conn) string {
selfAddressRequest, err := json.Marshal(map[string]string{"type": "selfAddress"})
if err != nil {
panic(err)
}
if err = conn.WriteMessage(websocket.TextMessage, []byte(selfAddressRequest)); err != nil {
panic(err)
}
responseJSON := make(map[string]interface{})
err = conn.ReadJSON(&responseJSON)
if err != nil {
panic(err)
}
return responseJSON["address"].(string)
}
func main() {
message := "Hello Nym!"
uri := "ws://localhost:1977"
conn, _, err := websocket.DefaultDialer.Dial(uri, nil)
if err != nil {
panic(err)
}
defer conn.Close()
selfAddress := getSelfAddress(conn)
fmt.Printf("our address is: %v\n", selfAddress)
sendRequest, err := json.Marshal(map[string]string{"type": "send", "recipient": selfAddress, "message": message})
if err != nil {
panic(err)
}
fmt.Printf("sending '%v' over the mix network...\n", message)
if err = conn.WriteMessage(websocket.TextMessage, []byte(sendRequest)); err != nil {
panic(err)
}
sendConfirmationJSON := make(map[string]interface{})
err = conn.ReadJSON(&sendConfirmationJSON)
if err != nil {
panic(err)
}
if sendConfirmationJSON["type"].(string) != "send" {
panic("invalid send confirmation")
}
fmt.Printf("waiting to receive a message from the mix network...\n")
_, receivedMessage, err := conn.ReadMessage()
if err != nil {
panic(err)
}
fmt.Printf("received %v from the mix network!\n", string(receivedMessage))
}
@@ -0,0 +1,2 @@
dist/bundle.js
node_modules
@@ -0,0 +1,10 @@
### Prerequisites
* Reasonably up to date Node + `npm`
### Running it
```
npm install
npm start # starts a webserver on port 8888
```
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,31 @@
{
"name": "nym-client-websocket-demo",
"version": "0.7.0",
"description": "Connect to a local Nym client, send and retrieve from the Nym network. ",
"private": true,
"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
},
"keywords": [
"nym",
"anonymity",
"mixnet",
"client",
"rust",
"websockets"
],
"author": "Dave Hrycyszyn",
"license": "Apache-2.0",
"devDependencies": {
"autoprefixer": "^9.8.0",
"clean-webpack-plugin": "^3.0.0",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"dependencies": {
"core-js": "^3.6.5",
"html-webpack-plugin": "^4.2.0"
}
}
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nym Client Demo</title>
</head>
<body>
<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>
</body>
</html>
@@ -0,0 +1,99 @@
var ourAddress;
async function main() {
var port = '1977' // client websocket listens on 1977 by default, change if yours is different
var localClientUrl = "ws://127.0.0.1:" + port;
// Set up and handle websocket connection to our desktop client.
var connection = await connectWebsocket(localClientUrl).then(function (c) {
return c;
}).catch(function (err) {
display("Websocket connection error. Is the client running with <pre>--connection-type WebSocket</pre> on port " + port + "?");
})
connection.onmessage = function (e) {
handleResponse(e);
};
sendSelfAddressRequest(connection);
// Set up the send button
const sendButton = document.querySelector('#send-button');
sendButton.onclick = function () {
sendMessageToMixnet(connection);
}
}
// Handle any messages that come back down the websocket.
function handleResponse(resp) {
// hacky workaround for receiving pushed 'text' messages,
// basically we can either receive proper server responses, i.e. 'error', 'send', 'selfAddress'
// or actual messages, without any framing, so they do not have 'type' field
try {
let response = JSON.parse(resp.data);
if (response.type == "error") {
displayJsonResponse("Server responded with error: " + response.message);
} else if (response.type == "selfAddress") {
displayJsonResponse(response);
ourAddress = response.address;
display("Our address is: " + ourAddress + ", we will now send messages to ourself.");
}
} catch (_) {
displayJsonResponse(resp.data)
}
}
// Send a message to the mixnet.
function sendMessageToMixnet(connection) {
var sendText = document.getElementById("sendtext").value;
var message = {
type: "send",
message: sendText,
recipient: ourAddress
}
displayJsonSend(message);
connection.send(JSON.stringify(message));
}
// Send a message to the mixnet client, asking what our own address is.
// In this simplistic demo, we'll just use our own address to send ourselves messages.
//
// In a real application, you might want to ensure that somebody else got your
// address so that they could send messages to you.
function sendSelfAddressRequest(connection) {
var selfAddress = {
type: "selfAddress"
}
displayJsonSend(selfAddress);
connection.send(JSON.stringify(selfAddress));
}
function display(message) {
document.getElementById("output").innerHTML += "<p>" + message + "</p >";
}
function displayJsonSend(message) {
document.getElementById("output").innerHTML += "<p style='color: blue;'>sent >>> " + JSON.stringify(message) + "</p >";
}
function displayJsonResponse(message) {
document.getElementById("output").innerHTML += "<p style='color: green;'>received <<<" + JSON.stringify(message) + "</p >";
}
// Connect to a websocket.
function connectWebsocket(url) {
return new Promise(function (resolve, reject) {
var server = new WebSocket(url);
server.onopen = function () {
resolve(server);
};
server.onerror = function (err) {
reject(err);
};
});
}
// Start it!
main();
@@ -0,0 +1,25 @@
const autoprefixer = require('autoprefixer');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
// path: path.resolve(__dirname, 'dist'),
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
hash: true,
template: './src/index.html',
filename: '.././dist/index.html' //relative to root of the application
})
],
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 8888
}
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,14 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
base58 = "*"
websockets = "*"
asyncio = "*"
[requires]
python_version = "3.8"
@@ -0,0 +1,67 @@
{
"_meta": {
"hash": {
"sha256": "f72ba1bebddbc91273647a33428eb911071d256cf3fc20e04f51060a7610f293"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.8"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"asyncio": {
"hashes": [
"sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41",
"sha256:b62c9157d36187eca799c378e572c969f0da87cd5fc42ca372d92cdb06e7e1de",
"sha256:c46a87b48213d7464f22d9a497b9eef8c1928b68320a2fa94240f969f6fec08c",
"sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d"
],
"index": "pypi",
"version": "==3.4.3"
},
"base58": {
"hashes": [
"sha256:4c7f5687da771b519cf86b3236250e7c3543368c576404c9fe2d992a287666e0",
"sha256:c83584a8b917dc52dd634307137f2ad2721a9efb4f1de32fc7eaaaf87844177e"
],
"index": "pypi",
"version": "==2.0.0"
},
"websockets": {
"hashes": [
"sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5",
"sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5",
"sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308",
"sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb",
"sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a",
"sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c",
"sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170",
"sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422",
"sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8",
"sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485",
"sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f",
"sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8",
"sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc",
"sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779",
"sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989",
"sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1",
"sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092",
"sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824",
"sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d",
"sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55",
"sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36",
"sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"
],
"index": "pypi",
"version": "==8.1"
}
},
"develop": {}
}
@@ -0,0 +1,9 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis efficitur neque. Quisque aliquet vulputate ante, eget vehicula odio feugiat ac. Nulla ut mattis magna. Aenean tincidunt quis nulla eget eleifend. Cras in pretium sem. Nunc lorem metus, blandit sit amet egestas ut, feugiat quis tellus. Aenean tristique, enim a tincidunt condimentum, eros est blandit nunc, id viverra metus erat at nulla. Vivamus at tellus sodales, feugiat odio vel, laoreet neque. Vivamus posuere nulla ac sodales bibendum.
Vestibulum pulvinar nisi non ultricies egestas. Integer finibus ultrices justo vitae suscipit. Etiam interdum eu justo vel interdum. Morbi sagittis ac nisl quis consequat. Mauris dapibus ut risus ac facilisis. Pellentesque non tortor feugiat, consectetur arcu vel, ullamcorper sapien. Proin sodales purus non orci bibendum, sit amet ultrices justo ullamcorper. Nullam ac risus ac justo ultricies efficitur auctor nec arcu. Etiam sed finibus felis. Suspendisse potenti. Phasellus malesuada velit ac ullamcorper egestas. Sed elementum diam ut est gravida ultricies.
Pellentesque sed metus massa. Cras imperdiet lacus sit amet dolor aliquam, luctus posuere justo hendrerit. Morbi augue ex, gravida a metus sed, scelerisque euismod lacus. Nam consequat sapien ac pellentesque sagittis. Morbi a ultrices massa, vel aliquet ex. Maecenas ac sem diam. Nunc sed erat et ipsum volutpat auctor. Etiam elit felis, commodo vitae ipsum ac, fermentum lobortis arcu. Aliquam eu tempus enim. Curabitur vulputate imperdiet aliquam. Morbi iaculis rhoncus risus at malesuada. Donec accumsan feugiat ligula ut facilisis. Nunc porttitor sit amet est eget malesuada. Sed sed consectetur augue, non dapibus orci. Mauris aliquam pellentesque quam, sit amet pellentesque velit cursus vitae. Morbi sit amet molestie risus.
Nam gravida non ligula a egestas. Fusce sodales, purus id rhoncus mattis, purus est vehicula urna, vel finibus augue velit et est. Donec dictum erat eleifend lobortis iaculis. Praesent id venenatis ante. Donec feugiat, ipsum eget porttitor pulvinar, nisl odio posuere lorem, ut placerat elit nulla a ligula. Suspendisse nec nibh tincidunt, sollicitudin mi a, volutpat ligula. In maximus quam lacus, eget semper dolor sagittis sit amet.
In vitae hendrerit est, quis facilisis dui. In eu ante enim. Nullam hendrerit odio sit amet odio tincidunt eleifend. Aliquam erat volutpat. Curabitur commodo, purus pharetra lobortis rhoncus, tortor massa imperdiet nisl, vel dignissim tortor sem at orci. Aliquam maximus lobortis lacus, eu porttitor purus dapibus ut. Praesent at dapibus felis, efficitur blandit tortor. In hac habitasse platea dictumst. Aenean ultrices, nisl a pretium sagittis, tellus sapien mollis erat, eu consectetur erat mauris sed libero. Duis feugiat dapibus mi, vel ornare velit vehicula mattis. Ut suscipit pharetra leo et sollicitudin.
@@ -0,0 +1,38 @@
import asyncio
import base58
import json
import websockets
self_address_request = json.dumps({
"type": "selfAddress"
})
async def send_file():
uri = "ws://localhost:1977"
async with websockets.connect(uri) as websocket:
await websocket.send(self_address_request)
self_address = json.loads(await websocket.recv())
print("our address is: {}".format(self_address["address"]))
# we receive our address in string format of OUR_PUB_KEY @ OUR_GATE_PUB_KEY
# both keys are 32 bytes and we need to encode them as binary without the '@' sign
split_address = self_address["address"].split("@")
bin_payload = bytearray(base58.b58decode(split_address[0]))
bin_payload += base58.b58decode(split_address[1])
with open("dummy_file", "rb") as input_file:
read_data = input_file.read()
bin_payload += read_data
print("sending content of 'dummy_file' over the mix network...")
await websocket.send(bin_payload)
msg_send_confirmation = json.loads(await websocket.recv())
assert msg_send_confirmation["type"], "send"
print("waiting to receive the 'dummy_file' from the mix network...")
received_data = await websocket.recv()
with open("received_file", "wb") as output_file:
print("writing the file back to the disk!")
output_file.write(received_data)
asyncio.get_event_loop().run_until_complete(send_file())
@@ -0,0 +1,34 @@
import asyncio
import json
import websockets
self_address_request = json.dumps({
"type": "selfAddress"
})
async def send_text():
message = "Hello Nym!"
uri = "ws://localhost:1977"
async with websockets.connect(uri) as websocket:
await websocket.send(self_address_request)
self_address = json.loads(await websocket.recv())
print("our address is: {}".format(self_address["address"]))
text_send = json.dumps({
"type": "send",
"message": message,
"recipient": self_address["address"]
})
print("sending '{}' over the mix network...".format(message))
await websocket.send(text_send)
msg_send_confirmation = json.loads(await websocket.recv())
assert msg_send_confirmation["type"], "send"
print("waiting to receive a message from the mix network...")
received_message = await websocket.recv()
print("received '{}' from the mix network".format(received_message))
asyncio.get_event_loop().run_until_complete(send_text())
@@ -0,0 +1,57 @@
use futures::{SinkExt, StreamExt};
use nym_client::websocket::{BinaryClientRequest, ClientRequest, ServerResponse};
use nymsphinx::addressing::clients::Recipient;
use std::convert::TryFrom;
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
#[tokio::main]
async fn main() {
let uri = "ws://localhost:1977";
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
let self_address_request = ClientRequest::SelfAddress;
ws_stream.send(self_address_request.into()).await.unwrap();
let raw_response = ws_stream.next().await.unwrap().unwrap();
// what we received now is just a json, but we know it's exact format
// so might as well use that
let response = match raw_response {
Message::Text(txt_msg) => ServerResponse::try_from(txt_msg).unwrap(),
_ => panic!("received an unexpected response type!"),
};
let recipient = match response {
ServerResponse::SelfAddress { address } => Recipient::try_from_string(address).unwrap(),
_ => panic!("received an unexpected response type!"),
};
println!("our full address is: {}", recipient.to_string());
let read_data = std::fs::read("examples/dummy_file").unwrap();
let send_request = BinaryClientRequest::Send {
recipient,
data: read_data,
};
println!("sending content of 'dummy_file' over the mix network...");
ws_stream.send(send_request.into()).await.unwrap();
let raw_send_confirmation = ws_stream.next().await.unwrap().unwrap();
let _send_confirmation = match raw_send_confirmation {
Message::Text(txt_msg) => match ServerResponse::try_from(txt_msg).unwrap() {
ServerResponse::Send => (),
_ => panic!("received an unexpected response type!"),
},
_ => panic!("received an unexpected response type!"),
};
println!("waiting to receive the 'dummy_file' from the mix network...");
let raw_message = ws_stream.next().await.unwrap().unwrap();
let message = match raw_message {
Message::Binary(bin_payload) => bin_payload,
_ => panic!("received an unexpected response type!"),
};
println!("writing the file back to the disk!");
std::fs::write("examples/received_file", message).unwrap();
}
@@ -0,0 +1,54 @@
use futures::{SinkExt, StreamExt};
use nym_client::websocket::{ClientRequest, ServerResponse};
use std::convert::TryFrom;
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
#[tokio::main]
async fn main() {
let message = "Hello Nym!".to_string();
let uri = "ws://localhost:1977";
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
let self_address_request = ClientRequest::SelfAddress;
ws_stream.send(self_address_request.into()).await.unwrap();
let raw_response = ws_stream.next().await.unwrap().unwrap();
// what we received now is just a json, but we know it's exact format
// so might as well use that
let response = match raw_response {
Message::Text(txt_msg) => ServerResponse::try_from(txt_msg).unwrap(),
_ => panic!("received an unexpected response type!"),
};
let self_address = match response {
ServerResponse::SelfAddress { address } => address,
_ => panic!("received an unexpected response type!"),
};
println!("our address is: {}", self_address.clone());
let send_request = ClientRequest::Send {
message: message.clone(),
recipient: self_address,
};
println!("sending {:?} over the mix network...", message);
ws_stream.send(send_request.into()).await.unwrap();
let raw_send_confirmation = ws_stream.next().await.unwrap().unwrap();
let _send_confirmation = match raw_send_confirmation {
Message::Text(txt_msg) => match ServerResponse::try_from(txt_msg).unwrap() {
ServerResponse::Send => (),
_ => panic!("received an unexpected response type!"),
},
_ => panic!("received an unexpected response type!"),
};
println!("waiting to receive a message from the mix network...");
let raw_message = ws_stream.next().await.unwrap().unwrap();
let message = match raw_message {
Message::Text(txt_msg) => txt_msg,
_ => panic!("received an unexpected response type!"),
};
println!("received {:?} from the mix network!", message);
}
+16
View File
@@ -0,0 +1,16 @@
// 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.
// The file has been placed there by the build script.
include!(concat!(env!("OUT_DIR"), "/built.rs"));
@@ -0,0 +1,139 @@
// 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 crate::client::mix_traffic::{MixMessage, MixMessageSender};
use crate::client::topology_control::TopologyAccessor;
use futures::task::{Context, Poll};
use futures::{Future, Stream, StreamExt};
use log::*;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::utils::{encapsulation, poisson};
use std::pin::Pin;
use std::time::Duration;
use tokio::runtime::Handle;
use tokio::task::JoinHandle;
use tokio::time;
use topology::NymTopology;
pub(crate) struct LoopCoverTrafficStream<T: NymTopology> {
average_packet_delay: Duration,
average_cover_message_sending_delay: Duration,
next_delay: time::Delay,
mix_tx: MixMessageSender,
our_full_destination: Recipient,
topology_access: TopologyAccessor<T>,
}
impl<T: NymTopology> Stream for LoopCoverTrafficStream<T> {
// Item is only used to indicate we should create a new message rather than actual cover message
// reason being to not introduce unnecessary complexity by having to keep state of topology
// mutex when trying to acquire it. So right now the Stream trait serves as a glorified timer.
// Perhaps this should be changed in the future.
type Item = ();
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
// it is not yet time to return a message
if Pin::new(&mut self.next_delay).poll(cx).is_pending() {
return Poll::Pending;
};
// we know it's time to send a message, so let's prepare delay for the next one
// Get the `now` by looking at the current `delay` deadline
let now = self.next_delay.deadline();
let next_poisson_delay = poisson::sample(self.average_cover_message_sending_delay);
// The next interval value is `next_poisson_delay` after the one that just
// yielded.
let next = now + next_poisson_delay;
self.next_delay.reset(next);
Poll::Ready(Some(()))
}
}
impl<T: 'static + NymTopology> LoopCoverTrafficStream<T> {
pub(crate) fn new(
mix_tx: MixMessageSender,
our_full_destination: Recipient,
topology_access: TopologyAccessor<T>,
average_cover_message_sending_delay: time::Duration,
average_packet_delay: time::Duration,
) -> Self {
LoopCoverTrafficStream {
average_packet_delay,
average_cover_message_sending_delay,
next_delay: time::delay_for(Default::default()),
mix_tx,
our_full_destination,
topology_access,
}
}
async fn on_new_message(&mut self) {
trace!("next cover message!");
let route = match self
.topology_access
.random_route_to_gateway(&self.our_full_destination.gateway())
.await
{
None => {
warn!("No valid topology detected - won't send any loop cover message this time");
return;
}
Some(route) => route,
};
let cover_message = match encapsulation::loop_cover_message_route(
self.our_full_destination.destination().clone(),
route,
self.average_packet_delay,
) {
Ok(message) => message,
Err(err) => {
error!(
"Somehow we managed to create an invalid cover message - {:?}",
err
);
return;
}
};
// if this one fails, there's no retrying because it means that either:
// - we run out of memory
// - the receiver channel is closed
// in either case there's no recovery and we can only panic
self.mix_tx
.unbounded_send(MixMessage::new(cover_message.0, cover_message.1))
.unwrap();
// JS: due to identical logical structure to OutQueueControl::on_message(), this is also
// presumably required to prevent bugs in the future. Exact reason is still unknown to me.
tokio::task::yield_now().await;
}
async fn run(&mut self) {
// we should set initial delay only when we actually start the stream
self.next_delay =
time::delay_for(poisson::sample(self.average_cover_message_sending_delay));
while let Some(_) = self.next().await {
self.on_new_message().await;
}
}
pub(crate) fn start(mut self, handle: &Handle) -> JoinHandle<()> {
handle.spawn(async move {
self.run().await;
})
}
}
@@ -0,0 +1,22 @@
use futures::channel::mpsc;
use nymsphinx::addressing::clients::Recipient;
pub(crate) type InputMessageSender = mpsc::UnboundedSender<InputMessage>;
pub(crate) type InputMessageReceiver = mpsc::UnboundedReceiver<InputMessage>;
#[derive(Debug)]
pub(crate) struct InputMessage {
recipient: Recipient,
data: Vec<u8>,
}
impl InputMessage {
pub(crate) fn new(recipient: Recipient, data: Vec<u8>) -> Self {
InputMessage { recipient, data }
}
// I'm open to suggestions on how to rename this.
pub(crate) fn destruct(self) -> (Recipient, Vec<u8>) {
(self.recipient, self.data)
}
}
+75
View File
@@ -0,0 +1,75 @@
// 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 futures::channel::mpsc;
use futures::StreamExt;
use gateway_client::GatewayClient;
use log::*;
use nymsphinx::SphinxPacket;
use std::net::SocketAddr;
use tokio::runtime::Handle;
use tokio::task::JoinHandle;
pub(crate) struct MixMessage(SocketAddr, SphinxPacket);
pub(crate) type MixMessageSender = mpsc::UnboundedSender<MixMessage>;
pub(crate) type MixMessageReceiver = mpsc::UnboundedReceiver<MixMessage>;
impl MixMessage {
pub(crate) fn new(address: SocketAddr, packet: SphinxPacket) -> Self {
MixMessage(address, packet)
}
}
pub(crate) struct MixTrafficController<'a> {
// TODO: most likely to be replaced by some higher level construct as
// later on gateway_client will need to be accessible by other entities
gateway_client: GatewayClient<'a, url::Url>,
mix_rx: MixMessageReceiver,
}
impl<'a> MixTrafficController<'static> {
pub(crate) fn new(
mix_rx: MixMessageReceiver,
gateway_client: GatewayClient<'a, url::Url>,
) -> MixTrafficController<'a> {
MixTrafficController {
gateway_client,
mix_rx,
}
}
async fn on_message(&mut self, mix_message: MixMessage) {
debug!("Got a mix_message for {:?}", mix_message.0);
match self
.gateway_client
.send_sphinx_packet(mix_message.0, mix_message.1)
.await
{
Err(e) => error!("Failed to send sphinx packet to the gateway! - {:?}", e),
Ok(_) => trace!("We *might* have managed to forward sphinx packet to the gateway!"),
}
}
pub(crate) async fn run(&mut self) {
while let Some(mix_message) = self.mix_rx.next().await {
self.on_message(mix_message).await;
}
}
pub(crate) fn start(mut self, handle: &Handle) -> JoinHandle<()> {
handle.spawn(async move {
self.run().await;
})
}
}
+388
View File
@@ -0,0 +1,388 @@
// 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 crate::client::cover_traffic_stream::LoopCoverTrafficStream;
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender};
use crate::client::mix_traffic::{MixMessageReceiver, MixMessageSender, MixTrafficController};
use crate::client::received_buffer::{
ReceivedBufferRequestReceiver, ReceivedBufferRequestSender, ReceivedMessagesBufferController,
};
use crate::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
};
use crate::config::{Config, SocketType};
use crate::websocket;
use crypto::identity::MixIdentityKeyPair;
use directory_client::presence;
use futures::channel::mpsc;
use gateway_client::{GatewayClient, SphinxPacketReceiver, SphinxPacketSender};
use gateway_requests::auth_token::AuthToken;
use log::*;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::chunking::split_and_prepare_payloads;
use nymsphinx::NodeAddressBytes;
use received_buffer::{ReceivedBufferMessage, ReconstructedMessagesReceiver};
use tokio::runtime::Runtime;
use topology::NymTopology;
mod cover_traffic_stream;
pub(crate) mod inbound_messages;
mod mix_traffic;
mod real_traffic_stream;
pub(crate) mod received_buffer;
pub(crate) mod topology_control;
pub struct NymClient {
config: Config,
runtime: Runtime,
identity_keypair: MixIdentityKeyPair,
// to be used by "send" function or socket, etc
input_tx: Option<InputMessageSender>,
// to be used by "receive" function or socket, etc
receive_tx: Option<ReconstructedMessagesReceiver>,
}
impl NymClient {
pub fn new(config: Config, identity_keypair: MixIdentityKeyPair) -> Self {
NymClient {
runtime: Runtime::new().unwrap(),
config,
identity_keypair,
input_tx: None,
receive_tx: None,
}
}
pub fn as_mix_recipient(&self) -> Recipient {
Recipient::new(
self.identity_keypair.public_key.derive_address(),
// TODO: below only works under assumption that gateway address == gateway id
// (which currently is true)
NodeAddressBytes::try_from_base58_string(self.config.get_gateway_id()).unwrap(),
)
}
// future constantly pumping loop cover traffic at some specified average rate
// the pumped traffic goes to the MixTrafficController
fn start_cover_traffic_stream<T: 'static + NymTopology>(
&self,
topology_accessor: TopologyAccessor<T>,
mix_tx: MixMessageSender,
) {
info!("Starting loop cover traffic stream...");
// we need to explicitly enter runtime due to "next_delay: time::delay_for(Default::default())"
// set in the constructor which HAS TO be called within context of a tokio runtime
self.runtime
.enter(|| {
LoopCoverTrafficStream::new(
mix_tx,
self.as_mix_recipient(),
topology_accessor,
self.config.get_loop_cover_traffic_average_delay(),
self.config.get_average_packet_delay(),
)
})
.start(self.runtime.handle());
}
fn start_real_traffic_stream<T: 'static + NymTopology>(
&self,
topology_accessor: TopologyAccessor<T>,
mix_tx: MixMessageSender,
input_rx: InputMessageReceiver,
) {
info!("Starting real traffic stream...");
// we need to explicitly enter runtime due to "next_delay: time::delay_for(Default::default())"
// set in the constructor which HAS TO be called within context of a tokio runtime
self.runtime
.enter(|| {
real_traffic_stream::OutQueueControl::new(
mix_tx,
input_rx,
self.as_mix_recipient(),
topology_accessor,
self.config.get_average_packet_delay(),
self.config.get_message_sending_average_delay(),
)
})
.start(self.runtime.handle());
}
// buffer controlling all messages fetched from provider
// required so that other components would be able to use them (say the websocket)
fn start_received_messages_buffer_controller(
&self,
query_receiver: ReceivedBufferRequestReceiver,
sphinx_receiver: SphinxPacketReceiver,
) {
info!("Starting received messages buffer controller...");
ReceivedMessagesBufferController::new(query_receiver, sphinx_receiver)
.start(self.runtime.handle())
}
fn start_gateway_client(
&mut self,
sphinx_packet_sender: SphinxPacketSender,
gateway_address: url::Url,
) -> GatewayClient<'static, url::Url> {
let auth_token = self
.config
.get_gateway_auth_token()
.map(|str_token| AuthToken::try_from_base58_string(str_token).ok())
.unwrap_or(None);
let mut gateway_client = GatewayClient::new(
gateway_address,
self.as_mix_recipient().destination(),
auth_token,
sphinx_packet_sender,
self.config.get_gateway_response_timeout(),
);
let auth_token = self.runtime.block_on(async {
gateway_client
.establish_connection()
.await
.expect("could not establish initial connection with the gateway");
gateway_client
.perform_initial_authentication()
.await
.expect("could not perform initial authentication with the gateway")
});
// TODO: if we didn't have an auth_token initially, save it to config or something?
info!(
"Performed initial authentication. Auth token is {:?}",
auth_token.to_base58_string()
);
gateway_client
}
// TODO: this information should be just put in the config on init...
async fn get_gateway_address<T: NymTopology>(
gateway_id: String,
topology_accessor: TopologyAccessor<T>,
) -> url::Url {
// we already have our gateway written in the config
let gateway_address = topology_accessor
.get_gateway_socket_url(&gateway_id)
.await
.unwrap_or_else(|| {
panic!(
"Could not find gateway with id {:?}.\
It does not seem to be present in the current network topology.\
Are you sure it is still online?\
Perhaps try to run `nym-client init` again to obtain a new gateway",
gateway_id
)
});
url::Url::parse(&gateway_address).expect("provided gateway address is invalid!")
}
// future responsible for periodically polling directory server and updating
// the current global view of topology
fn start_topology_refresher<T: 'static + NymTopology>(
&mut self,
topology_accessor: TopologyAccessor<T>,
) {
let topology_refresher_config = TopologyRefresherConfig::new(
self.config.get_directory_server(),
self.config.get_topology_refresh_rate(),
);
let mut topology_refresher =
TopologyRefresher::new(topology_refresher_config, topology_accessor);
// before returning, block entire runtime to refresh the current network view so that any
// components depending on topology would see a non-empty view
info!(
"Obtaining initial network topology from {}",
self.config.get_directory_server()
);
self.runtime.block_on(topology_refresher.refresh());
// TODO: a slightly more graceful termination here
if !self
.runtime
.block_on(topology_refresher.is_topology_routable())
{
panic!(
"The current network topology seem to be insufficient to route any packets through\
- check if enough nodes and a gateway are online"
);
}
info!("Starting topology refresher...");
topology_refresher.start(self.runtime.handle());
}
// controller for sending sphinx packets to mixnet (either real traffic or cover traffic)
// TODO: if we want to send control messages to gateway_client, this CAN'T take the ownership
// over it. Perhaps GatewayClient needs to be thread-shareable or have some channel for
// requests?
fn start_mix_traffic_controller(
&mut self,
mix_rx: MixMessageReceiver,
gateway_client: GatewayClient<'static, url::Url>,
) {
info!("Starting mix traffic controller...");
MixTrafficController::new(mix_rx, gateway_client).start(self.runtime.handle());
}
fn start_websocket_listener<T: 'static + NymTopology>(
&self,
topology_accessor: TopologyAccessor<T>,
buffer_requester: ReceivedBufferRequestSender,
msg_input: InputMessageSender,
) {
info!("Starting websocket listener...");
let websocket_handler = websocket::Handler::new(
msg_input,
buffer_requester,
self.as_mix_recipient(),
topology_accessor,
);
websocket::Listener::new(self.config.get_listening_port())
.start(self.runtime.handle(), websocket_handler);
}
/// EXPERIMENTAL DIRECT RUST API
/// It's untested and there are absolutely no guarantees about it (but seems to have worked
/// well enough in local tests)
pub fn send_message(&mut self, recipient: Recipient, message: Vec<u8>) {
let split_message = split_and_prepare_payloads(&message);
debug!(
"Splitting message into {:?} fragments!",
split_message.len()
);
for message_fragment in split_message {
let input_msg = InputMessage::new(recipient.clone(), message_fragment);
self.input_tx
.as_ref()
.expect("start method was not called before!")
.unbounded_send(input_msg)
.unwrap()
}
}
/// EXPERIMENTAL DIRECT RUST API
/// It's untested and there are absolutely no guarantees about it (but seems to have worked
/// well enough in local tests)
/// Note: it waits for the first occurrence of messages being sent to ourselves. If you expect multiple
/// messages, you might have to call this function repeatedly.
pub async fn wait_for_messages(&mut self) -> Vec<Vec<u8>> {
use futures::StreamExt;
self.receive_tx
.as_mut()
.expect("start method was not called before!")
.next()
.await
.expect("buffer controller seems to have somehow died!")
}
/// blocking version of `start` method. Will run forever (or until SIGINT is sent)
pub fn run_forever(&mut self) {
self.start();
if let Err(e) = self.runtime.block_on(tokio::signal::ctrl_c()) {
error!(
"There was an error while capturing SIGINT - {:?}. We will terminate regardless",
e
);
}
println!(
"Received SIGINT - the client will terminate now (threads are not YET nicely stopped)"
);
}
pub fn start(&mut self) {
info!("Starting nym client");
// channels for inter-component communication
// TODO: make the channels be internally created by the relevant components
// rather than creating them here, so say for example the buffer controller would create the request channels
// and would allow anyone to clone the sender channel
// sphinx_message_sender is the transmitter for any component generating sphinx packets that are to be sent to the mixnet
// they are used by cover traffic stream and real traffic stream
// sphinx_message_receiver is the receiver used by MixTrafficController that sends the actual traffic
let (sphinx_message_sender, sphinx_message_receiver) = mpsc::unbounded();
// unwrapped_sphinx_sender is the transmitter of [unwrapped] sphinx messages received from the gateway
// unwrapped_sphinx_receiver is the receiver for said messages - used by ReceivedMessagesBuffer
let (unwrapped_sphinx_sender, unwrapped_sphinx_receiver) = mpsc::unbounded();
// used for announcing connection or disconnection of a channel for pushing re-assembled messages to
let (received_buffer_request_sender, received_buffer_request_receiver) = mpsc::unbounded();
// channels responsible for controlling real messages
let (input_sender, input_receiver) = mpsc::unbounded::<InputMessage>();
// TODO: when we switch to our graph topology, we need to remember to change 'presence::Topology' type
let shared_topology_accessor = TopologyAccessor::<presence::Topology>::new();
// the components are started in very specific order. Unless you know what you are doing,
// do not change that.
self.start_topology_refresher(shared_topology_accessor.clone());
self.start_received_messages_buffer_controller(
received_buffer_request_receiver,
unwrapped_sphinx_receiver,
);
let gateway_url = self.runtime.block_on(Self::get_gateway_address(
self.config.get_gateway_id(),
shared_topology_accessor.clone(),
));
let gateway_client = self.start_gateway_client(unwrapped_sphinx_sender, gateway_url);
self.start_mix_traffic_controller(sphinx_message_receiver, gateway_client);
self.start_cover_traffic_stream(
shared_topology_accessor.clone(),
sphinx_message_sender.clone(),
);
self.start_real_traffic_stream(
shared_topology_accessor.clone(),
sphinx_message_sender,
input_receiver,
);
match self.config.get_socket_type() {
SocketType::WebSocket => self.start_websocket_listener(
shared_topology_accessor,
received_buffer_request_sender,
input_sender,
),
SocketType::None => {
// if we did not start the socket, it means we're running (supposedly) in the native mode
// and hence we should announce 'ourselves' to the buffer
let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded();
// tell the buffer to start sending stuff to us
received_buffer_request_sender
.unbounded_send(ReceivedBufferMessage::ReceiverAnnounce(
reconstructed_sender,
))
.expect("the buffer request failed!");
self.receive_tx = Some(reconstructed_receiver);
self.input_tx = Some(input_sender);
}
}
info!("Client startup finished!");
}
}
@@ -0,0 +1,189 @@
// 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 crate::client::inbound_messages::InputMessage;
use crate::client::mix_traffic::MixMessage;
use crate::client::topology_control::TopologyAccessor;
use futures::channel::mpsc;
use futures::task::{Context, Poll};
use futures::{Future, Stream, StreamExt};
use log::{error, info, trace, warn};
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::utils::{encapsulation, poisson};
use std::pin::Pin;
use std::time::Duration;
use tokio::runtime::Handle;
use tokio::task::JoinHandle;
use tokio::time;
use topology::NymTopology;
pub(crate) struct OutQueueControl<T: NymTopology> {
average_packet_delay: Duration,
average_message_sending_delay: Duration,
next_delay: time::Delay,
mix_tx: mpsc::UnboundedSender<MixMessage>,
input_rx: mpsc::UnboundedReceiver<InputMessage>,
our_full_destination: Recipient,
topology_access: TopologyAccessor<T>,
}
pub(crate) enum StreamMessage {
Cover,
Real(InputMessage),
}
impl<T: NymTopology> Stream for OutQueueControl<T> {
type Item = StreamMessage;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
// it is not yet time to return a message
if Pin::new(&mut self.next_delay).poll(cx).is_pending() {
return Poll::Pending;
};
// we know it's time to send a message, so let's prepare delay for the next one
// Get the `now` by looking at the current `delay` deadline
let now = self.next_delay.deadline();
let next_poisson_delay = poisson::sample(self.average_message_sending_delay);
// The next interval value is `next_poisson_delay` after the one that just
// yielded.
let next = now + next_poisson_delay;
self.next_delay.reset(next);
// decide what kind of message to send
match Pin::new(&mut self.input_rx).poll_next(cx) {
// in the case our real message channel stream was closed, we should also indicate we are closed
// (and whoever is using the stream should panic)
Poll::Ready(None) => Poll::Ready(None),
// if there's an actual message - return it
Poll::Ready(Some(real_message)) => Poll::Ready(Some(StreamMessage::Real(real_message))),
// otherwise construct a dummy one
Poll::Pending => Poll::Ready(Some(StreamMessage::Cover)),
}
}
}
impl<T: 'static + NymTopology> OutQueueControl<T> {
pub(crate) fn new(
mix_tx: mpsc::UnboundedSender<MixMessage>,
input_rx: mpsc::UnboundedReceiver<InputMessage>,
our_full_destination: Recipient,
topology_access: TopologyAccessor<T>,
average_packet_delay: Duration,
average_message_sending_delay: Duration,
) -> Self {
OutQueueControl {
average_packet_delay,
average_message_sending_delay,
next_delay: time::delay_for(Default::default()),
mix_tx,
input_rx,
our_full_destination,
topology_access,
}
}
async fn get_route(&self, other_recipient: Option<&Recipient>) -> Option<Vec<nymsphinx::Node>> {
match other_recipient {
// we are sending to ourselves
None => {
self.topology_access
.random_route_to_gateway(&self.our_full_destination.gateway())
.await
}
Some(other_recipient) => {
self.topology_access
.random_route_to_gateway(&other_recipient.gateway())
.await
}
}
}
async fn on_message(&mut self, next_message: StreamMessage) {
trace!("created new message");
let next_packet = match next_message {
StreamMessage::Cover => {
let route = self.get_route(None).await;
if route.is_none() {
warn!("No valid topology detected - won't send any real or loop message this time");
return;
}
let route = route.unwrap();
encapsulation::loop_cover_message_route(
self.our_full_destination.destination().clone(),
route,
self.average_packet_delay,
)
}
StreamMessage::Real(real_message) => {
let (recipient, data) = real_message.destruct();
let route = self.get_route(Some(&recipient)).await;
if route.is_none() {
warn!("No valid topology detected - won't send any real or loop message this time");
return;
}
let route = route.unwrap();
encapsulation::encapsulate_message_route(
recipient.destination(),
data,
route,
self.average_packet_delay,
)
}
};
let next_packet = match next_packet {
Ok(message) => message,
Err(err) => {
error!(
"Somehow we managed to create an invalid traffic message - {:?}",
err
);
return;
}
};
// if this one fails, there's no retrying because it means that either:
// - we run out of memory
// - the receiver channel is closed
// in either case there's no recovery and we can only panic
self.mix_tx
.unbounded_send(MixMessage::new(next_packet.0, next_packet.1))
.unwrap();
// JS: Not entirely sure why or how it fixes stuff, but without the yield call,
// the UnboundedReceiver [of mix_rx] will not get a chance to read anything
// JS2: Basically it was the case that with high enough rate, the stream had already a next value
// ready and hence was immediately re-scheduled causing other tasks to be starved;
// yield makes it go back the scheduling queue regardless of its value availability
tokio::task::yield_now().await;
}
pub(crate) async fn run_out_queue_control(mut self) {
// we should set initial delay only when we actually start the stream
self.next_delay = time::delay_for(poisson::sample(self.average_message_sending_delay));
info!("Starting out queue controller...");
while let Some(next_message) = self.next().await {
self.on_message(next_message).await;
}
}
pub(crate) fn start(self, handle: &Handle) -> JoinHandle<()> {
handle.spawn(async move { self.run_out_queue_control().await })
}
}
@@ -0,0 +1,242 @@
// 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 futures::channel::mpsc;
use futures::lock::Mutex;
use futures::StreamExt;
use gateway_client::SphinxPacketReceiver;
use log::*;
use nymsphinx::{
chunking::reconstruction::MessageReconstructor,
utils::encapsulation::LOOP_COVER_MESSAGE_PAYLOAD,
};
use std::sync::Arc;
use tokio::runtime::Handle;
use tokio::task::JoinHandle;
// Buffer Requests to say "hey, send any reconstructed messages to this channel"
// or to say "hey, I'm going offline, don't send anything more to me. Just buffer them instead"
pub(crate) type ReceivedBufferRequestSender = mpsc::UnboundedSender<ReceivedBufferMessage>;
pub(crate) type ReceivedBufferRequestReceiver = mpsc::UnboundedReceiver<ReceivedBufferMessage>;
// The channel set for the above
pub(crate) type ReconstructedMessagesSender = mpsc::UnboundedSender<Vec<Vec<u8>>>;
pub(crate) type ReconstructedMessagesReceiver = mpsc::UnboundedReceiver<Vec<Vec<u8>>>;
struct ReceivedMessagesBufferInner {
messages: Vec<Vec<u8>>,
message_reconstructor: MessageReconstructor,
message_sender: Option<ReconstructedMessagesSender>,
}
#[derive(Debug, Clone)]
// Note: you should NEVER create more than a single instance of this using 'new()'.
// You should always use .clone() to create additional instances
struct ReceivedMessagesBuffer {
inner: Arc<Mutex<ReceivedMessagesBufferInner>>,
}
impl ReceivedMessagesBuffer {
fn new() -> Self {
ReceivedMessagesBuffer {
inner: Arc::new(Mutex::new(ReceivedMessagesBufferInner {
messages: Vec::new(),
message_reconstructor: MessageReconstructor::new(),
message_sender: None,
})),
}
}
async fn disconnect_sender(&mut self) {
let mut guard = self.inner.lock().await;
if guard.message_sender.is_none() {
// in theory we could just ignore it, but that situation should have never happened
// in the first place, so this way we at least know we have an important bug to fix
panic!("trying to disconnect non-existent sender!")
}
guard.message_sender = None;
}
async fn connect_sender(&mut self, sender: ReconstructedMessagesSender) {
let mut guard = self.inner.lock().await;
if guard.message_sender.is_some() {
// in theory we could just ignore it, but that situation should have never happened
// in the first place, so this way we at least know we have an important bug to fix
panic!("trying overwrite an existing sender!")
}
// while we're at it, also empty the buffer if we happened to receive anything while
// no sender was connected
let stored_messages = std::mem::replace(&mut guard.messages, Vec::new());
if !stored_messages.is_empty() {
if let Err(err) = sender.unbounded_send(stored_messages) {
error!(
"The sender channel we just received is already invalidated - {:?}",
err
);
// put the values back to the buffer
// the returned error has two fields: err: SendError and val: T,
// where val is the value that was failed to get sent;
// it's returned by the `into_inner` call
guard.messages = err.into_inner();
return;
}
}
guard.message_sender = Some(sender);
}
async fn add_reconstructed_messages(&mut self, msgs: Vec<Vec<u8>>) {
debug!("Adding {:?} new messages to the buffer!", msgs.len());
trace!("Adding new messages to the buffer! {:?}", msgs);
self.inner.lock().await.messages.extend(msgs)
}
async fn add_new_message_fragments(&mut self, msgs: Vec<Vec<u8>>) {
debug!(
"Adding {:?} new message fragments to the buffer!",
msgs.len()
);
trace!("Adding new message fragments to the buffer! {:?}", msgs);
let mut completed_messages = Vec::new();
let mut inner_guard = self.inner.lock().await;
for msg_fragment in msgs {
if msg_fragment == LOOP_COVER_MESSAGE_PAYLOAD {
trace!("The message was a loop cover message! Skipping it");
continue;
}
if let Some(reconstructed_message) =
inner_guard.message_reconstructor.new_fragment(msg_fragment)
{
completed_messages.push(reconstructed_message);
}
}
if !completed_messages.is_empty() {
if let Some(sender) = &inner_guard.message_sender {
trace!("Sending reconstructed messages to announced sender");
if let Err(err) = sender.unbounded_send(completed_messages) {
warn!("The reconstructed message receiver went offline without explicit notification (relevant error: - {:?})", err);
// make sure to drop the lock to not deadlock
// (it is required by `add_reconstructed_messages`)
inner_guard.message_sender = None;
drop(inner_guard);
self.add_reconstructed_messages(err.into_inner()).await;
}
} else {
// make sure to drop the lock to not deadlock
// (it is required by `add_reconstructed_messages`)
drop(inner_guard);
trace!("No sender available - buffering reconstructed messages");
self.add_reconstructed_messages(completed_messages).await;
}
}
}
}
pub(crate) enum ReceivedBufferMessage {
// Signals a websocket connection (or a native implementation) was established and we should stop buffering messages,
// and instead send them directly to the received channel
ReceiverAnnounce(ReconstructedMessagesSender),
// Explicit signal that Receiver connection will no longer accept messages
ReceiverDisconnect,
}
struct RequestReceiver {
received_buffer: ReceivedMessagesBuffer,
query_receiver: ReceivedBufferRequestReceiver,
}
impl RequestReceiver {
fn new(
received_buffer: ReceivedMessagesBuffer,
query_receiver: ReceivedBufferRequestReceiver,
) -> Self {
RequestReceiver {
received_buffer,
query_receiver,
}
}
fn start(mut self, handle: &Handle) -> JoinHandle<()> {
handle.spawn(async move {
while let Some(request) = self.query_receiver.next().await {
match request {
ReceivedBufferMessage::ReceiverAnnounce(sender) => {
self.received_buffer.connect_sender(sender).await;
}
ReceivedBufferMessage::ReceiverDisconnect => {
self.received_buffer.disconnect_sender().await
}
}
}
})
}
}
struct FragmentedMessageReceiver {
received_buffer: ReceivedMessagesBuffer,
sphinx_packet_receiver: SphinxPacketReceiver,
}
impl FragmentedMessageReceiver {
fn new(
received_buffer: ReceivedMessagesBuffer,
sphinx_packet_receiver: SphinxPacketReceiver,
) -> Self {
FragmentedMessageReceiver {
received_buffer,
sphinx_packet_receiver,
}
}
fn start(mut self, handle: &Handle) -> JoinHandle<()> {
handle.spawn(async move {
while let Some(new_messages) = self.sphinx_packet_receiver.next().await {
self.received_buffer
.add_new_message_fragments(new_messages)
.await;
}
})
}
}
pub(crate) struct ReceivedMessagesBufferController {
fragmented_messsage_receiver: FragmentedMessageReceiver,
request_receiver: RequestReceiver,
}
impl ReceivedMessagesBufferController {
pub(crate) fn new(
query_receiver: ReceivedBufferRequestReceiver,
sphinx_packet_receiver: SphinxPacketReceiver,
) -> Self {
let received_buffer = ReceivedMessagesBuffer::new();
ReceivedMessagesBufferController {
fragmented_messsage_receiver: FragmentedMessageReceiver::new(
received_buffer.clone(),
sphinx_packet_receiver,
),
request_receiver: RequestReceiver::new(received_buffer, query_receiver),
}
}
pub(crate) fn start(self, handle: &Handle) {
// TODO: should we do anything with JoinHandle(s) returned by start methods?
self.fragmented_messsage_receiver.start(handle);
self.request_receiver.start(handle);
}
}
@@ -0,0 +1,187 @@
// 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 crate::built_info;
use futures::lock::Mutex;
use log::*;
use nymsphinx::NodeAddressBytes;
use std::sync::Arc;
use std::time;
use std::time::Duration;
use tokio::runtime::Handle;
use tokio::task::JoinHandle;
use topology::{provider, NymTopology};
struct TopologyAccessorInner<T: NymTopology>(Option<T>);
impl<T: NymTopology> TopologyAccessorInner<T> {
fn new() -> Self {
TopologyAccessorInner(None)
}
fn update(&mut self, new: Option<T>) {
self.0 = new;
}
}
#[derive(Clone, Debug)]
pub(crate) struct TopologyAccessor<T: NymTopology> {
// TODO: this requires some actual benchmarking to determine if obtaining mutex is not going
// to cause some bottlenecking and whether perhaps RwLock would be better
inner: Arc<Mutex<TopologyAccessorInner<T>>>,
}
impl<T: NymTopology> TopologyAccessor<T> {
pub(crate) fn new() -> Self {
TopologyAccessor {
inner: Arc::new(Mutex::new(TopologyAccessorInner::new())),
}
}
async fn update_global_topology(&mut self, new_topology: Option<T>) {
self.inner.lock().await.update(new_topology);
}
pub(crate) async fn get_gateway_socket_url(&self, id: &str) -> Option<String> {
match &self.inner.lock().await.0 {
None => None,
Some(ref topology) => topology
.gateways()
.iter()
.find(|gateway| gateway.pub_key == id)
.map(|gateway| gateway.client_listener.clone()),
}
}
// only used by the client at startup to get a slightly more reasonable error message
// (currently displays as unused because healthchecker is disabled due to required changes)
pub(crate) async fn is_routable(&self) -> bool {
match &self.inner.lock().await.0 {
None => false,
Some(ref topology) => topology.can_construct_path_through(),
}
}
pub(crate) async fn get_all_clients(&self) -> Option<Vec<provider::Client>> {
// TODO: this will need to be modified to instead return pairs (provider, client)
match &self.inner.lock().await.0 {
None => None,
Some(ref topology) => Some(
topology
.providers()
.iter()
.flat_map(|provider| provider.registered_clients.iter())
.cloned()
.collect::<Vec<_>>(),
),
}
}
pub(crate) async fn random_route_to_gateway(
&self,
gateway: &NodeAddressBytes,
) -> Option<Vec<nymsphinx::Node>> {
let b58_address = gateway.to_base58_string();
let guard = self.inner.lock().await;
let topology = guard.0.as_ref()?;
let gateway = topology
.gateways()
.iter()
.cloned()
.find(|gateway| gateway.pub_key == b58_address.clone())?;
topology.random_route_to_gateway(gateway.into()).ok()
}
// // this is a rather temporary solution as each client will have an associated provider
// // currently that is not implemented yet and there only exists one provider in the network
// pub(crate) async fn random_route(&self) -> Option<Vec<nymsphinx::Node>> {
// match &self.inner.lock().await.0 {
// None => None,
// Some(ref topology) => {
// let mut gateways = topology.gateways();
// if gateways.is_empty() {
// return None;
// }
// // unwrap is fine here as we asserted there is at least single provider
// let provider = gateways.pop().unwrap().into();
// topology.random_route_to_gateway(provider).ok()
// }
// }
// }
}
pub(crate) struct TopologyRefresherConfig {
directory_server: String,
refresh_rate: time::Duration,
}
impl TopologyRefresherConfig {
pub(crate) fn new(directory_server: String, refresh_rate: time::Duration) -> Self {
TopologyRefresherConfig {
directory_server,
refresh_rate,
}
}
}
pub(crate) struct TopologyRefresher<T: NymTopology> {
directory_server: String,
topology_accessor: TopologyAccessor<T>,
refresh_rate: Duration,
}
impl<T: 'static + NymTopology> TopologyRefresher<T> {
pub(crate) fn new(
cfg: TopologyRefresherConfig,
topology_accessor: TopologyAccessor<T>,
) -> Self {
TopologyRefresher {
directory_server: cfg.directory_server,
topology_accessor,
refresh_rate: cfg.refresh_rate,
}
}
async fn get_current_compatible_topology(&self) -> T {
// note: this call makes it necessary that `T::new()`does *not* have 'static lifetime
let full_topology = T::new(self.directory_server.clone()).await;
// just filter by version and assume the validators will remove all bad behaving
// nodes with the staking
full_topology.filter_system_version(built_info::PKG_VERSION)
}
pub(crate) async fn refresh(&mut self) {
trace!("Refreshing the topology");
let new_topology = Some(self.get_current_compatible_topology().await);
self.topology_accessor
.update_global_topology(new_topology)
.await;
}
pub(crate) async fn is_topology_routable(&self) -> bool {
self.topology_accessor.is_routable().await
}
pub(crate) fn start(mut self, handle: &Handle) -> JoinHandle<()> {
handle.spawn(async move {
loop {
tokio::time::delay_for(self.refresh_rate).await;
self.refresh().await;
}
})
}
}
+172
View File
@@ -0,0 +1,172 @@
// 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 crate::built_info;
use crate::commands::override_config;
use crate::config::persistence::pathfinder::ClientPathfinder;
use clap::{App, Arg, ArgMatches};
use config::NymConfig;
use crypto::identity::MixIdentityKeyPair;
use directory_client::presence::Topology;
use futures::channel::mpsc;
use gateway_client::GatewayClient;
use gateway_requests::AuthToken;
use nymsphinx::DestinationAddressBytes;
use pemstore::pemstore::PemStore;
use std::time::Duration;
use topology::gateway::Node;
use topology::NymTopology;
pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
App::new("init")
.about("Initialise a Nym client. Do this first!")
.arg(Arg::with_name("id")
.long("id")
.help("Id of the nym-mixnet-client we want to create config for.")
.takes_value(true)
.required(true)
)
.arg(Arg::with_name("gateway")
.long("gateway")
.help("Id of the gateway we have preference to connect to. If left empty, a random gateway will be chosen.")
.takes_value(true)
)
.arg(Arg::with_name("directory")
.long("directory")
.help("Address of the directory server the client is getting topology from")
.takes_value(true),
)
.arg(Arg::with_name("disable-socket")
.long("disable-socket")
.help("Whether to not start the websocket")
)
.arg(Arg::with_name("port")
.short("p")
.long("port")
.help("Port for the socket (if applicable) to listen on in all subsequent runs")
.takes_value(true)
)
.arg(Arg::with_name("fastmode")
.long("fastmode")
.hidden(true) // this will prevent this flag from being displayed in `--help`
.help("Mostly debug-related option to increase default traffic rate so that you would not need to modify config post init")
)
}
async fn try_gateway_registration(
gateways: Vec<Node>,
our_address: DestinationAddressBytes,
) -> Option<(String, AuthToken)> {
// TODO: having to do something like this suggests that perhaps GatewayClient's constructor
// could be improved
let (sphinx_tx, _) = mpsc::unbounded();
let timeout = Duration::from_millis(1500);
for gateway in gateways {
let mut gateway_client = GatewayClient::new(
url::Url::parse(&gateway.client_listener).unwrap(),
our_address.clone(),
None,
sphinx_tx.clone(),
timeout,
);
if gateway_client.establish_connection().await.is_ok() {
if let Ok(token) = gateway_client.register().await {
return Some((gateway.pub_key, token));
}
}
}
None
}
async fn choose_gateway(
directory_server: String,
our_address: DestinationAddressBytes,
) -> (String, AuthToken) {
// TODO: once we change to graph topology this here will need to be updated!
let topology = Topology::new(directory_server.clone()).await;
let version_filtered_topology = topology.filter_system_version(built_info::PKG_VERSION);
// don't care about health of the networks as mixes can go up and down any time,
// but DO care about gateways
let gateways = version_filtered_topology.gateways();
// try to perform registration so that we wouldn't need to do it at startup
// + at the same time we'll know if we can actually talk with that gateway
let registration_result = try_gateway_registration(gateways, our_address).await;
match registration_result {
None => {
// while technically there's no issue client-side, it will be impossible to execute
// `nym-client run` as no gateway is available so it might be best to not finalize
// the init and rely on users trying to init another time?
panic!(
"Currently there are no valid gateways available on the network ({}). \
Please try to run `init` again at later time or change your directory server",
directory_server
)
}
Some((gateway_id, auth_token)) => (gateway_id, auth_token),
}
}
pub fn execute(matches: &ArgMatches) {
println!("Initialising client...");
let id = matches.value_of("id").unwrap(); // required for now
let mut config = crate::config::Config::new(id);
config = override_config(config, matches);
if matches.is_present("fastmode") {
config = config.set_high_default_traffic_volume();
}
let mix_identity_keys = MixIdentityKeyPair::new();
// if there is no gateway chosen, get a random-ish one from the topology
if config.get_gateway_id().is_empty() {
let our_address = mix_identity_keys.public_key().derive_address();
// TODO: is there perhaps a way to make it work without having to spawn entire runtime?
let mut rt = tokio::runtime::Runtime::new().unwrap();
let (gateway_id, auth_token) =
rt.block_on(choose_gateway(config.get_directory_server(), our_address));
// TODO: this isn't really a gateway, but gateway, yet another change to make
config = config
.with_gateway_id(gateway_id)
.with_gateway_auth_token(auth_token);
}
let pathfinder = ClientPathfinder::new_from_config(&config);
let pem_store = PemStore::new(pathfinder);
pem_store
.write_identity(mix_identity_keys)
.expect("Failed to save identity keys");
println!("Saved mixnet identity keypair");
let config_save_location = config.get_config_file_save_location();
config
.save_to_file(None)
.expect("Failed to save the config file");
println!("Saved configuration file to {:?}", config_save_location);
println!(
"Unless overridden in all `nym-client run` we will be talking to the following gateway: {}...",
config.get_gateway_id(),
);
if config.get_gateway_auth_token().is_some() {
println!(
"using optional AuthToken: {:?}",
config.get_gateway_auth_token().unwrap()
)
}
println!("Client configuration completed.\n\n\n")
}
+43
View File
@@ -0,0 +1,43 @@
// 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 crate::config::{Config, SocketType};
use clap::ArgMatches;
pub mod init;
pub mod run;
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if let Some(directory) = matches.value_of("directory") {
config = config.with_custom_directory(directory);
}
if let Some(gateway_id) = matches.value_of("gateway") {
config = config.with_gateway_id(gateway_id);
}
if matches.is_present("disable-socket") {
config = config.with_socket(SocketType::None);
}
if let Some(port) = matches.value_of("port").map(|port| port.parse::<u16>()) {
if let Err(err) = port {
// if port was overridden, it must be parsable
panic!("Invalid port value provided - {:?}", err);
}
config = config.with_port(port.unwrap());
}
config
}
+81
View File
@@ -0,0 +1,81 @@
// 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 crate::client::NymClient;
use crate::commands::override_config;
use crate::config::{persistence::pathfinder::ClientPathfinder, Config};
use clap::{App, Arg, ArgMatches};
use config::NymConfig;
use crypto::identity::MixIdentityKeyPair;
use pemstore::pemstore::PemStore;
pub fn command_args<'a, 'b>() -> clap::App<'a, 'b> {
App::new("run")
.about("Run the Nym client with provided configuration client optionally overriding set parameters")
.arg(Arg::with_name("id")
.long("id")
.help("Id of the nym-mixnet-client we want to run.")
.takes_value(true)
.required(true)
)
// the rest of arguments are optional, they are used to override settings in config file
.arg(Arg::with_name("config")
.long("config")
.help("Custom path to the nym-mixnet-client configuration file")
.takes_value(true)
)
.arg(Arg::with_name("directory")
.long("directory")
.help("Address of the directory server the client is getting topology from")
.takes_value(true),
)
.arg(Arg::with_name("gateway")
.long("gateway")
.help("Id of the gateway we want to connect to. If overridden, it is user's responsibility to ensure prior registration happened")
.takes_value(true)
)
.arg(Arg::with_name("disable-socket")
.long("disable-socket")
.help("Whether to not start the websocket")
)
.arg(Arg::with_name("port")
.short("p")
.long("port")
.help("Port for the socket (if applicable) to listen on")
.takes_value(true)
)
}
fn load_identity_keys(config_file: &Config) -> MixIdentityKeyPair {
let identity_keypair = PemStore::new(ClientPathfinder::new_from_config(&config_file))
.read_identity()
.expect("Failed to read stored identity key files");
println!(
"Public identity key: {}\n",
identity_keypair.public_key.to_base58_string()
);
identity_keypair
}
pub fn execute(matches: &ArgMatches) {
let id = matches.value_of("id").unwrap();
let mut config =
Config::load_from_file(matches.value_of("config").map(|path| path.into()), Some(id))
.expect("Failed to load config file");
config = override_config(config, matches);
let identity_keypair = load_identity_keys(&config);
NymClient::new(config, identity_keypair).run_forever();
}
+375
View File
@@ -0,0 +1,375 @@
// 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 crate::config::template::config_template;
use config::NymConfig;
use serde::{Deserialize, Deserializer, Serialize};
use std::path::PathBuf;
use std::time;
pub mod persistence;
mod template;
// 'CLIENT'
const DEFAULT_LISTENING_PORT: u16 = 1977;
const DEFAULT_DIRECTORY_SERVER: &str = "https://directory.nymtech.net";
// 'DEBUG'
// where applicable, the below are defined in milliseconds
const DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY: u64 = 1000; // 1s
const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: u64 = 500; // 0.5s
const DEFAULT_AVERAGE_PACKET_DELAY: u64 = 200; // 0.2s
const DEFAULT_TOPOLOGY_REFRESH_RATE: u64 = 30_000; // 30s
const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: u64 = 5_000; // 5s
const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: u64 = 1_500; // 1.5s
#[derive(Debug, Deserialize, PartialEq, Serialize, Clone, Copy)]
#[serde(deny_unknown_fields)]
pub enum SocketType {
WebSocket,
None,
}
impl SocketType {
pub fn from_string<S: Into<String>>(val: S) -> Self {
let mut upper = val.into();
upper.make_ascii_uppercase();
match upper.as_ref() {
"WEBSOCKET" | "WS" => SocketType::WebSocket,
_ => SocketType::None,
}
}
}
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Config {
client: Client,
socket: Socket,
#[serde(default)]
logging: Logging,
#[serde(default)]
debug: Debug,
}
impl NymConfig for Config {
fn template() -> &'static str {
config_template()
}
fn config_file_name() -> String {
"config.toml".to_string()
}
fn default_root_directory() -> PathBuf {
dirs::home_dir()
.expect("Failed to evaluate $HOME value")
.join(".nym")
.join("clients")
}
fn root_directory(&self) -> PathBuf {
self.client.nym_root_directory.clone()
}
fn config_directory(&self) -> PathBuf {
self.client
.nym_root_directory
.join(&self.client.id)
.join("config")
}
fn data_directory(&self) -> PathBuf {
self.client
.nym_root_directory
.join(&self.client.id)
.join("data")
}
}
impl Config {
pub fn new<S: Into<String>>(id: S) -> Self {
Config::default().with_id(id)
}
// builder methods
pub fn with_id<S: Into<String>>(mut self, id: S) -> Self {
let id = id.into();
if self.client.private_identity_key_file.as_os_str().is_empty() {
self.client.private_identity_key_file =
self::Client::default_private_identity_key_file(&id);
}
if self.client.public_identity_key_file.as_os_str().is_empty() {
self.client.public_identity_key_file =
self::Client::default_public_identity_key_file(&id);
}
self.client.id = id;
self
}
pub fn with_gateway_id<S: Into<String>>(mut self, id: S) -> Self {
self.client.gateway_id = id.into();
self
}
pub fn with_gateway_auth_token<S: Into<String>>(mut self, token: S) -> Self {
self.client.gateway_authtoken = Some(token.into());
self
}
pub fn with_custom_directory<S: Into<String>>(mut self, directory_server: S) -> Self {
self.client.directory_server = directory_server.into();
self
}
pub fn with_socket(mut self, socket_type: SocketType) -> Self {
self.socket.socket_type = socket_type;
self
}
pub fn with_port(mut self, port: u16) -> Self {
self.socket.listening_port = port;
self
}
pub fn set_high_default_traffic_volume(mut self) -> Self {
self.debug.average_packet_delay = 10;
self.debug.loop_cover_traffic_average_delay = 20; // 50 cover messages / s
self.debug.message_sending_average_delay = 5; // 200 "real" messages / s
self
}
// getters
pub fn get_config_file_save_location(&self) -> PathBuf {
self.config_directory().join(Self::config_file_name())
}
pub fn get_private_identity_key_file(&self) -> PathBuf {
self.client.private_identity_key_file.clone()
}
pub fn get_public_identity_key_file(&self) -> PathBuf {
self.client.public_identity_key_file.clone()
}
pub fn get_directory_server(&self) -> String {
self.client.directory_server.clone()
}
pub fn get_gateway_id(&self) -> String {
self.client.gateway_id.clone()
}
pub fn get_gateway_auth_token(&self) -> Option<String> {
self.client.gateway_authtoken.clone()
}
pub fn get_socket_type(&self) -> SocketType {
self.socket.socket_type
}
pub fn get_listening_port(&self) -> u16 {
self.socket.listening_port
}
// Debug getters
pub fn get_average_packet_delay(&self) -> time::Duration {
time::Duration::from_millis(self.debug.average_packet_delay)
}
pub fn get_loop_cover_traffic_average_delay(&self) -> time::Duration {
time::Duration::from_millis(self.debug.loop_cover_traffic_average_delay)
}
pub fn get_message_sending_average_delay(&self) -> time::Duration {
time::Duration::from_millis(self.debug.message_sending_average_delay)
}
pub fn get_gateway_response_timeout(&self) -> time::Duration {
time::Duration::from_millis(self.debug.gateway_response_timeout)
}
pub fn get_topology_refresh_rate(&self) -> time::Duration {
time::Duration::from_millis(self.debug.topology_refresh_rate)
}
pub fn get_topology_resolution_timeout(&self) -> time::Duration {
time::Duration::from_millis(self.debug.topology_resolution_timeout)
}
}
fn de_option_string<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
if s.is_empty() {
Ok(None)
} else {
Ok(Some(s))
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Client {
/// ID specifies the human readable ID of this particular client.
id: String,
/// URL to the directory server.
directory_server: String,
/// Path to file containing private identity key.
private_identity_key_file: PathBuf,
/// Path to file containing public identity key.
public_identity_key_file: PathBuf,
/// gateway_id specifies ID of the gateway to which the client should send messages.
/// If initially omitted, a random gateway will be chosen from the available topology.
gateway_id: String,
/// A gateway specific, optional, base58 stringified authentication token used for
/// communication with particular gateway.
#[serde(deserialize_with = "de_option_string")]
gateway_authtoken: Option<String>,
/// nym_home_directory specifies absolute path to the home nym Clients directory.
/// It is expected to use default value and hence .toml file should not redefine this field.
nym_root_directory: PathBuf,
}
impl Default for Client {
fn default() -> Self {
// there must be explicit checks for whether id is not empty later
Client {
id: "".to_string(),
directory_server: DEFAULT_DIRECTORY_SERVER.to_string(),
private_identity_key_file: Default::default(),
public_identity_key_file: Default::default(),
gateway_id: "".to_string(),
gateway_authtoken: None,
nym_root_directory: Config::default_root_directory(),
}
}
}
impl Client {
fn default_private_identity_key_file(id: &str) -> PathBuf {
Config::default_data_directory(Some(id)).join("private_identity.pem")
}
fn default_public_identity_key_file(id: &str) -> PathBuf {
Config::default_data_directory(Some(id)).join("public_identity.pem")
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Socket {
socket_type: SocketType,
listening_port: u16,
}
impl Default for Socket {
fn default() -> Self {
Socket {
socket_type: SocketType::WebSocket,
listening_port: DEFAULT_LISTENING_PORT,
}
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Logging {}
impl Default for Logging {
fn default() -> Self {
Logging {}
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct Debug {
/// The parameter of Poisson distribution determining how long, on average,
/// sent packet is going to be delayed at any given mix node.
/// So for a packet going through three mix nodes, on average, it will take three times this value
/// until the packet reaches its destination.
/// The provided value is interpreted as milliseconds.
average_packet_delay: u64,
/// The parameter of Poisson distribution determining how long, on average,
/// it is going to take for another loop cover traffic message to be sent.
/// The provided value is interpreted as milliseconds.
loop_cover_traffic_average_delay: u64,
/// The parameter of Poisson distribution determining how long, on average,
/// it is going to take another 'real traffic stream' message to be sent.
/// If no real packets are available and cover traffic is enabled,
/// a loop cover message is sent instead in order to preserve the rate.
/// The provided value is interpreted as milliseconds.
message_sending_average_delay: u64,
/// How long we're willing to wait for a response to a message sent to the gateway,
/// before giving up on it.
/// The provided value is interpreted as milliseconds.
gateway_response_timeout: u64,
/// The uniform delay every which clients are querying the directory server
/// to try to obtain a compatible network topology to send sphinx packets through.
/// The provided value is interpreted as milliseconds.
topology_refresh_rate: u64,
/// During topology refresh, test packets are sent through every single possible network
/// path. This timeout determines waiting period until it is decided that the packet
/// did not reach its destination.
/// The provided value is interpreted as milliseconds.
topology_resolution_timeout: u64,
}
impl Default for Debug {
fn default() -> Self {
Debug {
average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY,
loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY,
message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY,
gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT,
topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE,
topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
}
}
}
#[cfg(test)]
mod client_config {
use super::*;
#[test]
fn after_saving_default_config_the_loaded_one_is_identical() {
// need to figure out how to do something similar but without touching the disk
// or the file system at all...
let temp_location = tempfile::tempdir().unwrap().path().join("config.toml");
let default_config = Config::default().with_id("foomp".to_string());
default_config
.save_to_file(Some(temp_location.clone()))
.unwrap();
let loaded_config = Config::load_from_file(Some(temp_location), None).unwrap();
assert_eq!(default_config, loaded_config);
}
}
@@ -0,0 +1,15 @@
// 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.
pub mod pathfinder;
@@ -0,0 +1,60 @@
// 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 crate::config::Config;
use pemstore::pathfinder::PathFinder;
use std::path::PathBuf;
#[derive(Debug)]
pub struct ClientPathfinder {
pub config_dir: PathBuf,
pub private_mix_key: PathBuf,
pub public_mix_key: PathBuf,
}
impl ClientPathfinder {
pub fn new(id: String) -> Self {
let os_config_dir = dirs::config_dir().unwrap(); // grabs the OS default config dir
let config_dir = os_config_dir.join("nym").join("clients").join(id);
let private_mix_key = config_dir.join("private.pem");
let public_mix_key = config_dir.join("public.pem");
ClientPathfinder {
config_dir,
private_mix_key,
public_mix_key,
}
}
pub fn new_from_config(config: &Config) -> Self {
ClientPathfinder {
config_dir: config.get_config_file_save_location(),
private_mix_key: config.get_private_identity_key_file(),
public_mix_key: config.get_public_identity_key_file(),
}
}
}
impl PathFinder for ClientPathfinder {
fn config_dir(&self) -> PathBuf {
self.config_dir.clone()
}
fn private_identity_key(&self) -> PathBuf {
self.private_mix_key.clone()
}
fn public_identity_key(&self) -> PathBuf {
self.public_mix_key.clone()
}
}
+84
View File
@@ -0,0 +1,84 @@
// 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.
pub(crate) fn config_template() -> &'static str {
// While using normal toml marshalling would have been way simpler with less overhead,
// I think it's useful to have comments attached to the saved config file to explain behaviour of
// particular fields.
// Note: any changes to the template must be reflected in the appropriate structs in mod.rs.
r#"
# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
##### main base client config options #####
[client]
# Human readable ID of this particular client.
id = '{{ client.id }}'
# URL to the directory server.
directory_server = '{{ client.directory_server }}'
# Path to file containing private identity key.
private_identity_key_file = '{{ client.private_identity_key_file }}'
# Path to file containing public identity key.
public_identity_key_file = '{{ client.public_identity_key_file }}'
##### additional client config options #####
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_id }}'
# A gateway specific, optional, base58 stringified authentication token used for
# communication with particular gateway.
gateway_authtoken = '{{ client.gateway_authtoken }}'
##### advanced configuration options #####
# Absolute path to the home Nym Clients directory.
nym_root_directory = '{{ client.nym_root_directory }}'
##### socket config options #####
[socket]
# allowed values are 'WebSocket' or 'None'
socket_type = '{{ socket.socket_type }}'
# if applicable (for the case of 'WebSocket'), the port on which the client
# will be listening for incoming requests
listening_port = {{ socket.listening_port }}
##### logging configuration options #####
[logging]
# TODO
##### debug configuration options #####
# The following options should not be modified unless you know EXACTLY what you are doing
# as if set incorrectly, they may impact your anonymity.
[debug]
average_packet_delay = {{ debug.average_packet_delay }}
loop_cover_traffic_average_delay = {{ debug.loop_cover_traffic_average_delay }}
message_sending_average_delay = {{ debug.message_sending_average_delay }}
"#
}
+18
View File
@@ -0,0 +1,18 @@
// 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.
pub mod built_info;
pub mod client;
pub mod config;
pub mod websocket;
+86
View File
@@ -0,0 +1,86 @@
// 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 clap::{App, ArgMatches};
pub mod built_info;
pub mod client;
mod commands;
pub mod config;
pub mod websocket;
fn main() {
dotenv::dotenv().ok();
setup_logging();
println!("{}", banner());
let arg_matches = App::new("Nym Client")
.version(built_info::PKG_VERSION)
.author("Nymtech")
.about("Implementation of the Nym Client")
.subcommand(commands::init::command_args())
.subcommand(commands::run::command_args())
.get_matches();
execute(arg_matches);
}
fn execute(matches: ArgMatches) {
match matches.subcommand() {
("init", Some(m)) => commands::init::execute(m),
("run", Some(m)) => commands::run::execute(m),
_ => println!("{}", usage()),
}
}
fn usage() -> &'static str {
"usage: --help to see available options.\n\n"
}
fn banner() -> String {
format!(
r#"
_ __ _ _ _ __ ___
| '_ \| | | | '_ \ _ \
| | | | |_| | | | | | |
|_| |_|\__, |_| |_| |_|
|___/
(client - version {:})
"#,
built_info::PKG_VERSION
)
}
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)
.filter_module("tungstenite", log::LevelFilter::Warn)
.filter_module("tokio_tungstenite", log::LevelFilter::Warn)
.init();
}
+327
View File
@@ -0,0 +1,327 @@
// 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 super::types::{BinaryClientRequest, ClientRequest, ServerResponse};
use crate::client::{
inbound_messages::{InputMessage, InputMessageSender},
received_buffer::{
ReceivedBufferMessage, ReceivedBufferRequestSender, ReconstructedMessagesReceiver,
},
topology_control::TopologyAccessor,
};
use futures::channel::mpsc;
use futures::{SinkExt, StreamExt};
use log::*;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::chunking::split_and_prepare_payloads;
use std::convert::TryFrom;
use tokio::net::TcpStream;
use tokio_tungstenite::{
accept_async,
tungstenite::{protocol::Message, Error as WsError},
WebSocketStream,
};
use topology::NymTopology;
enum ReceivedResponseType {
Binary,
Text,
}
impl Default for ReceivedResponseType {
fn default() -> Self {
ReceivedResponseType::Binary
}
}
pub(crate) struct Handler<T: NymTopology> {
msg_input: InputMessageSender,
buffer_requester: ReceivedBufferRequestSender,
self_full_address: Recipient,
topology_accessor: TopologyAccessor<T>,
socket: Option<WebSocketStream<TcpStream>>,
received_response_type: ReceivedResponseType,
}
// clone is used to use handler on a new connection, which initially is `None`
impl<T: NymTopology> Clone for Handler<T> {
fn clone(&self) -> Self {
Handler {
msg_input: self.msg_input.clone(),
buffer_requester: self.buffer_requester.clone(),
self_full_address: self.self_full_address.clone(),
topology_accessor: self.topology_accessor.clone(),
socket: None,
received_response_type: Default::default(),
}
}
}
impl<T: NymTopology> Drop for Handler<T> {
fn drop(&mut self) {
self.buffer_requester
.unbounded_send(ReceivedBufferMessage::ReceiverDisconnect)
.expect("the buffer request failed!")
}
}
impl<T: NymTopology> Handler<T> {
pub(crate) fn new(
msg_input: InputMessageSender,
buffer_requester: ReceivedBufferRequestSender,
self_full_address: Recipient,
topology_accessor: TopologyAccessor<T>,
) -> Self {
Handler {
msg_input,
buffer_requester,
self_full_address,
topology_accessor,
socket: None,
received_response_type: Default::default(),
}
}
fn handle_text_send(&mut self, msg: String, full_recipient_address: String) -> ServerResponse {
let message_bytes = msg.into_bytes();
let recipient = match Recipient::try_from_string(full_recipient_address) {
Ok(address) => address,
Err(e) => {
trace!("failed to parse received Recipient: {:?}", e);
return ServerResponse::new_error("malformed recipient address");
}
};
// in case the message is too long and needs to be split into multiple packets:
let split_message = split_and_prepare_payloads(&message_bytes);
for message_fragment in split_message {
let input_msg = InputMessage::new(recipient.clone(), message_fragment);
self.msg_input.unbounded_send(input_msg).unwrap();
}
self.received_response_type = ReceivedResponseType::Text;
ServerResponse::Send
}
async fn handle_text_get_clients(&mut self) -> ServerResponse {
match self.topology_accessor.get_all_clients().await {
Some(clients) => {
let client_keys = clients.into_iter().map(|client| client.pub_key).collect();
ServerResponse::GetClients {
clients: client_keys,
}
}
None => ServerResponse::new_error("invalid network topology"),
}
}
fn handle_text_self_address(&self) -> ServerResponse {
ServerResponse::SelfAddress {
address: self.self_full_address.to_string(),
}
}
async fn handle_text_message(&mut self, msg: String) -> Message {
debug!("Handling text message request");
trace!("Content: {:?}", msg.clone());
match ClientRequest::try_from(msg) {
Err(e) => ServerResponse::Error {
message: format!("received invalid request. err: {:?}", e),
}
.into(),
Ok(req) => match req {
ClientRequest::Send { message, recipient } => {
self.handle_text_send(message, recipient)
}
ClientRequest::GetClients => self.handle_text_get_clients().await,
ClientRequest::SelfAddress => self.handle_text_self_address(),
}
.into(),
}
}
async fn handle_binary_send(&mut self, recipient: Recipient, data: Vec<u8>) -> ServerResponse {
// in case the message is too long and needs to be split into multiple packets:
let split_message = split_and_prepare_payloads(&data);
for message_fragment in split_message {
let input_msg = InputMessage::new(recipient.clone(), message_fragment);
self.msg_input.unbounded_send(input_msg).unwrap();
}
self.received_response_type = ReceivedResponseType::Binary;
ServerResponse::Send
}
// if it's binary we assume it's a sphinx packet formatted the same way as we'd have sent
// it to the gateway
async fn handle_binary_message(&mut self, msg: Vec<u8>) -> Message {
debug!("Handling binary message request");
self.received_response_type = ReceivedResponseType::Binary;
// make sure it is correctly formatted
let binary_request = BinaryClientRequest::try_from_bytes(&msg);
if binary_request.is_none() {
return ServerResponse::new_error("invalid binary request").into();
}
match binary_request.unwrap() {
BinaryClientRequest::Send { recipient, data } => {
self.handle_binary_send(recipient, data).await
}
}
.into()
}
async fn handle_request(&mut self, raw_request: Message) -> Option<Message> {
// apparently tungstenite auto-handles ping/pong/close messages so for now let's ignore
// them and let's test that claim. If that's not the case, just copy code from
// old version of this file.
match raw_request {
Message::Text(text_message) => Some(self.handle_text_message(text_message).await),
Message::Binary(binary_message) => {
Some(self.handle_binary_message(binary_message).await)
}
_ => None,
}
}
async fn push_websocket_received_plaintexts(
&mut self,
messages_bytes: Vec<Vec<u8>>,
) -> Result<(), WsError> {
let response_messages: Vec<_> = match self.received_response_type {
ReceivedResponseType::Binary => messages_bytes
.into_iter()
.map(|msg| Ok(Message::Binary(msg)))
.collect(),
ReceivedResponseType::Text => {
let mut decoded_messages = Vec::new();
// either all succeed or all fall back
let mut did_fail = false;
for message in messages_bytes.iter() {
match std::str::from_utf8(message) {
Ok(msg) => decoded_messages.push(msg),
Err(err) => {
did_fail = true;
warn!("Invalid UTF-8 sequence in response message - {:?}", err);
break;
}
}
}
if did_fail {
messages_bytes
.into_iter()
.map(|msg| Ok(Message::Binary(msg)))
.collect()
} else {
decoded_messages
.into_iter()
.map(|msg| Ok(Message::Text(msg.to_string())))
.collect()
}
}
};
let mut send_stream = futures::stream::iter(response_messages);
self.socket
.as_mut()
.unwrap()
.send_all(&mut send_stream)
.await
}
async fn send_websocket_response(&mut self, msg: Message) -> Result<(), WsError> {
match self.socket {
// TODO: more closely investigate difference between `Sink::send` and `Sink::send_all`
// it got something to do with batching and flushing - it might be important if it
// turns out somehow we've got a bottleneck here
Some(ref mut ws_stream) => ws_stream.send(msg).await,
_ => panic!("impossible state - websocket handshake was somehow reverted"),
}
}
async fn next_websocket_request(&mut self) -> Option<Result<Message, WsError>> {
match self.socket {
Some(ref mut ws_stream) => ws_stream.next().await,
None => None,
}
}
async fn listen_for_requests(&mut self, mut msg_receiver: ReconstructedMessagesReceiver) {
loop {
tokio::select! {
socket_msg = self.next_websocket_request() => {
if socket_msg.is_none() {
break;
}
let socket_msg = match socket_msg.unwrap() {
Ok(socket_msg) => socket_msg,
Err(err) => {
error!("failed to obtain message from websocket stream! stopping connection handler: {}", err);
break;
}
};
if socket_msg.is_close() {
break;
}
if let Some(response) = self.handle_request(socket_msg).await {
if let Err(err) = self.send_websocket_response(response).await {
warn!(
"Failed to send message over websocket: {}. Assuming the connection is dead.",
err
);
break;
}
}
}
mix_messages = msg_receiver.next() => {
let mix_messages = mix_messages.expect(
"mix messages sender was unexpectedly closed! this shouldn't have ever happened!",
);
if let Err(e) = self.push_websocket_received_plaintexts(mix_messages).await {
warn!("failed to send sphinx packets back to the client - {:?}, assuming the connection is dead", e);
break;
}
}
}
}
}
// consume self to make sure `drop` is called after this is done
pub(crate) async fn handle_connection(mut self, socket: TcpStream) {
let ws_stream = match accept_async(socket).await {
Ok(ws_stream) => ws_stream,
Err(err) => {
warn!("error while performing the websocket handshake - {:?}", err);
return;
}
};
self.socket = Some(ws_stream);
let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded();
// tell the buffer to start sending stuff to us
self.buffer_requester
.unbounded_send(ReceivedBufferMessage::ReceiverAnnounce(
reconstructed_sender,
))
.expect("the buffer request failed!");
self.listen_for_requests(reconstructed_receiver).await;
}
}
+112
View File
@@ -0,0 +1,112 @@
// 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 super::handler::Handler;
use log::*;
use std::{
net::{Shutdown, SocketAddr},
sync::Arc,
};
use tokio::runtime;
use tokio::{sync::Notify, task::JoinHandle};
use topology::NymTopology;
enum State {
Connected,
AwaitingConnection,
}
impl State {
fn is_connected(&self) -> bool {
match self {
State::Connected => true,
_ => false,
}
}
}
pub(crate) struct Listener {
address: SocketAddr,
state: State,
}
impl Listener {
pub(crate) fn new(port: u16) -> Self {
Listener {
// unless we find compelling reason not to, just listen on local only
address: SocketAddr::new("127.0.0.1".parse().unwrap(), port),
state: State::AwaitingConnection,
}
}
pub(crate) async fn run<T: NymTopology + 'static>(&mut self, handler: Handler<T>) {
let mut tcp_listener = tokio::net::TcpListener::bind(self.address)
.await
.expect("Failed to start websocket listener");
let notify = Arc::new(Notify::new());
loop {
tokio::select! {
_ = notify.notified() => {
// our connection terminated - we are open to a new one now!
self.state = State::AwaitingConnection;
}
new_conn = tcp_listener.accept() => {
match new_conn {
Ok((socket, remote_addr)) => {
debug!("Received connection from {:?}", remote_addr);
if self.state.is_connected() {
warn!("tried to duplicate!");
// if we've already got a connection, don't allow another one
debug!("but there was already a connection present!");
// while we only ever want to accept a single connection, we don't want
// to leave clients hanging (and also allow for reconnection if it somehow
// was dropped)
match socket.shutdown(Shutdown::Both) {
Ok(_) => trace!(
"closed the connection between attempting websocket handshake"
),
Err(e) => warn!("failed to cleanly close the connection - {:?}", e),
};
} else {
// even though we're spawning a new task with the handler here, we will only ever spawn a single one.
// it's done so that any new connections to this listener could be rejected rather than left
// hanging because the executor doesn't come back here
let notify_clone = Arc::clone(&notify);
let fresh_handler = handler.clone();
tokio::spawn(async move {
fresh_handler.handle_connection(socket).await;
notify_clone.notify();
});
self.state = State::Connected;
}
}
Err(e) => warn!("failed to get client: {:?}", e),
}
}
}
}
}
pub(crate) fn start<T: NymTopology + 'static>(
mut self,
rt_handle: &runtime::Handle,
handler: Handler<T>,
) -> JoinHandle<()> {
info!("Running websocket on {:?}", self.address.to_string());
rt_handle.spawn(async move { self.run(handler).await })
}
}
+22
View File
@@ -0,0 +1,22 @@
// 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.
pub(crate) mod handler;
pub(crate) mod listener;
pub(crate) mod types;
pub(crate) use handler::Handler;
pub(crate) use listener::Listener;
pub use types::{BinaryClientRequest, ClientRequest, ServerResponse};
+114
View File
@@ -0,0 +1,114 @@
// 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 nymsphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use tokio_tungstenite::tungstenite::protocol::Message;
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum ClientRequest {
Send { message: String, recipient: String },
GetClients,
SelfAddress,
}
impl TryFrom<String> for ClientRequest {
type Error = serde_json::Error;
fn try_from(msg: String) -> Result<Self, Self::Error> {
serde_json::from_str(&msg)
}
}
impl Into<Message> for ClientRequest {
fn into(self) -> Message {
let str_req = serde_json::to_string(&self).unwrap();
Message::Text(str_req)
}
}
pub enum BinaryClientRequest {
Send { recipient: Recipient, data: Vec<u8> },
}
impl BinaryClientRequest {
// TODO: perhaps do it the proper way and introduce an error type
pub fn try_from_bytes(req: &[u8]) -> Option<Self> {
if req.len() < Recipient::LEN {
return None;
}
let mut recipient_bytes = [0u8; Recipient::LEN];
recipient_bytes.copy_from_slice(&req[..Recipient::LEN]);
let recipient = Recipient::from_bytes(recipient_bytes);
Some(BinaryClientRequest::Send {
recipient,
data: req[Recipient::LEN..].to_vec(),
})
}
pub fn into_bytes(self) -> Vec<u8> {
match self {
Self::Send { recipient, data } => recipient
.into_bytes()
.iter()
.cloned()
.chain(data.into_iter())
.collect(),
}
}
}
impl Into<Message> for BinaryClientRequest {
fn into(self) -> Message {
Message::Binary(self.into_bytes())
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum ServerResponse {
Send,
Received { messages: Vec<String> },
GetClients { clients: Vec<String> },
SelfAddress { address: String },
Error { message: String },
}
impl ServerResponse {
pub fn new_error<S: Into<String>>(msg: S) -> Self {
ServerResponse::Error {
message: msg.into(),
}
}
}
impl TryFrom<String> for ServerResponse {
type Error = serde_json::Error;
fn try_from(msg: String) -> Result<Self, <ServerResponse as TryFrom<String>>::Error> {
serde_json::from_str(&msg)
}
}
impl Into<Message> for ServerResponse {
fn into(self) -> Message {
// it should be safe to call `unwrap` here as the message is generated by the server
// so if it fails (and consequently panics) it's a bug that should be resolved
let str_res = serde_json::to_string(&self).unwrap();
Message::Text(str_res)
}
}
+11
View File
@@ -0,0 +1,11 @@
install:
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --locked
View File
+7
View File
@@ -0,0 +1,7 @@
/target
**/*.rs.bk
Cargo.lock
bin/
pkg/
wasm-pack.log
node_modules
+69
View File
@@ -0,0 +1,69 @@
language: rust
sudo: false
cache: cargo
matrix:
include:
# Builds with wasm-pack.
- rust: beta
env: RUST_BACKTRACE=1
addons:
firefox: latest
chrome: stable
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
script:
- cargo generate --git . --name testing
# Having a broken Cargo.toml (in that it has curlies in fields) anywhere
# in any of our parent dirs is problematic.
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- wasm-pack build
- wasm-pack test --chrome --firefox --headless
# Builds on nightly.
- rust: nightly
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
- cargo check --no-default-features --features "console_error_panic_hook wee_alloc"
- cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc"
# Builds on beta.
- rust: beta
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
# Note: no enabling the `wee_alloc` feature here because it requires
# nightly for now.
+43
View File
@@ -0,0 +1,43 @@
[package]
name = "nym-client-wasm"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "0.7.5"
edition = "2018"
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"]
license = "Apache-2.0"
repository = "https://github.com/nymtech/nym"
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
log = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
slice_as_array = "1.1.0"
wasm-bindgen = "0.2"
rand = "0.7.2"
# internal
crypto = { path = "../../common/crypto" }
nymsphinx = { path = "../../common/nymsphinx" }
topology = { path = "../../common/topology" }
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.1", optional = true }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
#
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
wee_alloc = { version = "0.4.2", optional = true }
[dev-dependencies]
wasm-bindgen-test = "0.2"
+176
View File
@@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
+42
View File
@@ -0,0 +1,42 @@
# Nym Sphinx webassembly client
Produces layer-encrypted Sphinx packets for use with Nym mixnets.
[Sphinx](http://www0.cs.ucl.ac.uk/staff/G.Danezis/papers/sphinx-eprint.pdf) packets ensure the privacy of information in transit, even when the adversary is able to monitor the network in its entirety. When used with a mixnet, both content (what you said) and metadata (who you said it to, when you said it) are protected.
This helps browser-based and mobile applications get stronger privacy, in a way that wasn't previously possible.
This client is part of the [Nym](https://nymtech.net/docs) project. It's written in Rust and compiled to WebAssembly.
## Security Status
From a security point of view, this module is not yet complete. A key missing feature, cover traffic, will be implemented soon. You can build your applications, but don't rely on it for strong anonymity yet if your application needs cover traffic.
## Using it
See the [Nym docs](https://nymtech.net/docs).
### Demo
There's a demo web application in the `js-example` folder. To run it, first make sure you've got a recent `npm` installed, then follow the instructions in its README.
## Developing
This is a Rust crate which is set up to automatically cross-compile the contents of `src` to WebAssembly (aka wasm). It's published from the main [Nym platform monorepo](https://github.com/nymtech/nym) in the `clients/webassembly` directory.
First, make sure you've got all the [Rust wasm toolchain](https://rustwasm.github.io/book/game-of-life/setup.html) installed. Cross-compilation sounds scary but the Rust crew have enabled a remarkably simple setup.
Whenever you change any Rust in the `src` directory, run `wasm-pack build --scope nymproject` to update the built wasm artefact in the `pkg` directory.
For now, when you compile `nym-client-wasm` using `wasm-pack build --scope nymproject` you will need to manually copy the file `client.js` into the `pkg` and `package.json` with entries from `package.json` on the main path. Once [these](https://github.com/rustwasm/wasm-pack/issues/840) [issues](https://github.com/rustwasm/rfcs/pull/8#issuecomment-564725214) get closed, this annoying extra step will go away.
To be clear, this is not something that most JS developers need to worry about, this is only for Nym devs. The packages on NPM have all files in place. Just install and enjoy!
### Packaging
If you're a Nym platform developer who's made changes to the Rust (or JS) files and wants to re-publish the package to NPM, here's how you do it:
1. `wasm-pack build --scope nymproject` builds the wasm binaries into the `pkg` directory (not in source control)
2. copy `client.js` into the `pkg` folder and update `package.json` manifest with the provided one
3. bump version numbers as necessary for SemVer
4. `wasm-pack publish --access=public` will publish your changed package to NPM
+330
View File
@@ -0,0 +1,330 @@
import * as wasm from ".";
import { version } from './package.json';
import { major, minor, parse } from "semver";
/**
* A Nym identity, consisting of a public/private keypair and a Nym
* gateway address.
*/
export class Identity {
// in the future this should allow for loading from local storage
constructor() {
const raw_identity = JSON.parse(wasm.keygen());
this.address = raw_identity.address;
this.privateKey = raw_identity.private_key;
this.publicKey = raw_identity.public_key;
}
}
/**
* A Client which connects to a Nym gateway via websocket. All communication
* with the Nym network happens through this connection.
*/
export class Client {
constructor(directoryUrl, identity, authToken) {
this.authToken = authToken
this.gateway = null; // {socketAddress, mixAddress, conn}
this.identity = identity;
this.topology = null;
this.topologyEndpoint = directoryUrl + "/api/presence/topology";
}
/**
* @return {string} a user-pubkey@nym-gateway recipient address
*/
formatAsRecipient() {
return `${this.identity.address}@${this.gateway.mixAddress}`
}
/**
* Get the current network topology, then connect to this client's Nym gateway
* via websocket.
*/
async start() {
await this.updateTopology();
this._getInitialGateway();
await this.connect();
// TODO: a way to somehow await for our authenticate response to be processed
}
_isRegistered() {
return this.authToken !== null
}
/**
* Checks if given node is compatible with this client
*/
isNodeVersionCompatible(node) {
const clientVersion = parse(version);
const mixVersion = parse(node.version);
return major(clientVersion) === major(mixVersion) && minor(clientVersion) === minor(mixVersion)
}
/**
* Update the Nym network topology.
*
* @returns an object containing the current Nym network topology
*/
async updateTopology() {
let response = await http('get', this.topologyEndpoint);
let topology = JSON.parse(response); // make sure it's a valid json
topology.mixNodes = topology.mixNodes.filter(this.isNodeVersionCompatible)
topology.gatewayNodes = topology.gatewayNodes.filter(this.isNodeVersionCompatible)
this.topology = topology;
this.onUpdatedTopology();
return topology;
}
/**
* Gets the address of a Nym gateway to send the Sphinx packet to.
* At present we choose the first gateway as the network should only be
* running one. Later, we will implement multiple gateways.
*/
_getInitialGateway() {
if (this.gateway !== null) {
console.error("tried to re-initialise gateway data");
return;
}
if (this.topology === null || this.topology.gatewayNodes.length === 0) {
console.error("No gateways available on the network")
}
this.gateway = {
socketAddress: this.topology.gatewayNodes[0].clientListener,
mixAddress: this.topology.gatewayNodes[0].pubKey,
conn: null,
}
}
/**
* Connect to the client's defined Nym gateway via websocket.
*/
connect() {
return new Promise((resolve, reject) => {
const conn = new WebSocket(this.gateway.socketAddress);
conn.onclose = this.onConnectionClose;
conn.onerror = (event) => {
this.onConnectionError(event);
reject(event);
};
conn.onmessage = (event) => this.onMessage(event);
conn.onopen = (event) => {
this.onConnect(event);
if (this._isRegistered()) {
this.sendAuthenticateRequest();
resolve(); // TODO: we should wait for authenticateResponse...
} else {
this.sendRegisterRequest();
resolve(); // TODO: we should wait for registerResponse...
}
}
this.gateway.conn = conn;
})
}
/**
* Sends a registration request to a Nym gateway node. Use it only if you
* haven't registered this client before.
*/
sendRegisterRequest() {
const registerReq = buildRegisterRequest(this.identity.address);
this.gateway.conn.send(registerReq);
this.onRegisterRequestSend();
}
/**
* Authenticates with a Nym gateway for this client.
*
* @param {string} token
*/
sendAuthenticateRequest(token) {
const authenticateReq = buildAuthenticateRequest(this.identity.address, token);
this.conn.send(authenticateReq);
this.onAuthenticateRequestSend();
}
/**
* Sends a message up the websocket to this client's Nym gateway.
*
* NOTE: this currently does not implement chunking and messages over ~1KB
* will cause a panic. This will be fixed in a future version.
*
* `message` must be a {string} at the moment. Binary `Blob` and `ArrayBuffer`
* will be supported soon.
*
* @param {*} message
* @param {string} recipient
*/
sendMessage(message, recipient) {
if (this.gateway === null || this.gateway.conn === null) {
console.error("Client was not initialised");
return
}
if (message instanceof Blob || message instanceof ArrayBuffer) {
// but it wouldn't be difficult to implement it.
console.error("Binary messages are not yet supported");
return
}
const sphinxPacket = wasm.create_sphinx_packet(JSON.stringify(this.topology), message, recipient);
this.gateway.conn.send(sphinxPacket);
this.onMessageSend();
}
/**
* A callback triggered when a message is received from this client's Nym
* gateway.
*
* The `event` may be a binary blob which was the payload of a Sphinx packet,
* or it may be a JSON control message (for example, the result of an
* authenticate request).
* @param {*} event
*/
onMessage(event) {
if (event.data instanceof Blob) {
this.onBlobResponse(event);
} else {
const receivedData = JSON.parse(event.data);
switch (receivedData.type) {
case "send": return this.onSendConfirmation(event);
case "authenticate": return this.onAuthenticateResponse(event);
case "error": return this.onErrorResponse(event);
case "register": return this.onRegisterResponse(event);
default: return this.onUnknownResponse(event);
}
}
}
// all the callbacks that can be overwritten
/**
* A callback that fires when network topology is updated.
*/
onUpdatedTopology() {
console.log("Default: Updated topology")
}
/**
*
* @param {*} event
*/
onConnect(event) {
console.log("Default: Established gateway connection", event);
}
onConnectionClose(event) {
console.log("Default: The the connection to gateway was closed", event);
}
onConnectionError(event) {
console.error("Default: Gateway connection error: ", event);
}
onAuthenticateRequestSend() {
console.log("Default: sent authentication request");
}
onRegisterRequestSend() {
console.log("Default: sent register request");
}
onMessageSend() {
console.log("Default: sent message through gateway to the mixnet");
}
onAuthenticated() {
console.log("Default: we are authenticated");
}
onSendConfirmation(event) {
console.log("Default: received send confirmation", event.data);
}
onRegisterResponse(event) {
console.log("Default: received register response", event.data);
}
onAuthenticateResponse(event) {
console.log("Default: received authentication response", event.data);
}
onErrorResponse(event) {
console.error("Received error response", event.data);
}
onUnknownResponse(event) {
console.error("Received unknown response", event);
}
// Gateway returns any received data from the mix network as a Blob,
// So most likely this is your best bet to override
onBlobResponse(event) {
// note that the actual handling depends on the expected content, however,
// in this example we're just sending a text messages to ourselves and hence
// we can safely read it as text
let reader = new FileReader();
reader.onload = () => {
this.onText(reader.result)
};
reader.readAsText(event.data);
}
/**
* @callback that makes a best-effort attempt to return decrypted Sphinx bytes as text.
*
* Note that no checks are performed to determine whether something is
* really text. If the received data is in fact binary, you'll get
* binary-as-text from this callback.
*/
onText(data) {
console.log("Default: parsed the following data", data);
}
}
/**
* Build a JSON registration request.
*
* @param {string} address
*/
function buildRegisterRequest(address) {
return JSON.stringify({ "type": "register", "address": address });
}
/**
* Build a JSON authentication request.
*
* @param {string} address
* @param {string} token
*/
function buildAuthenticateRequest(address, token) {
return JSON.stringify({ "type": "authenticate", "address": address, "token": token });
}
/**
* Make an HTTP request.
* @param {string} method
* @param {string} url
*/
function http(method, url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
@@ -0,0 +1,24 @@
#!/usr/bin/env node
const { spawn } = require("child_process");
const fs = require("fs");
let folderName = '.';
if (process.argv.length >= 3) {
folderName = process.argv[2];
if (!fs.existsSync(folderName)) {
fs.mkdirSync(folderName);
}
}
const clone = spawn("git", ["clone", "https://github.com/rustwasm/create-wasm-app.git", folderName]);
clone.on("close", code => {
if (code !== 0) {
console.error("cloning the template failed!")
process.exit(code);
} else {
console.log("🦀 Rust + 🕸 Wasm = ❤");
}
});
@@ -0,0 +1,2 @@
node_modules
dist
@@ -0,0 +1,5 @@
language: node_js
node_js: "10"
script:
- ./node_modules/.bin/webpack
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
+18
View File
@@ -0,0 +1,18 @@
# Nym Sphinx Wasm Demo
This example application demonstrates how to use WebAssembly to create Sphinx packets, in the browser, and forward them to a Nym gateway.
## 🚴 Usage
```
npm install # set up dependencies
npm run start # starts a web server at http://localhost:8001
```
Check your dev console for output.
### Rebuild after Rust source changes
Install `wasm-pack`. Instruction are at the [Rust WASM tutorial](https://rustwasm.github.io/docs/book/game-of-life/hello-world.html).
`wasm-pack build` in the `clients/webassembly` directory (one up) will rebuild the wasm package if you make changes to the Rust source. That will be automatically picked up (and reloaded, if need be) by the npm dev server.
+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));
+37
View File
@@ -0,0 +1,37 @@
<!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>Sender: </label><input disabled="true" size="85" type="text" id="sender" value="">
</p>
<p>
<label>Recipient: </label><input size="85" type="text" id="recipient" value="">
</p>
<p>
<label>Message: </label><input type="text" id="message" value="Hello mixnet!">
</p>
<p>
<button id="send-button">Send</button>
</p>
<p>Send messages from your browser, through the mixnet, and to the recipient 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>
+85
View File
@@ -0,0 +1,85 @@
// 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.
import {
Client,
Identity
} from "@nymproject/nym-client-wasm/client"
async function main() {
// Set up identity and client
let directory = "https://directory.nymtech.net";
let identity = new Identity();
let nymClient = new Client(directory, identity, null);
// Wire up events callbacks
nymClient.onConnect = (_) => displaySenderAddress(nymClient);
nymClient.onText = displayReceived;
nymClient.onErrorResponse = (event) => alert("Received invalid gateway response", event.data);
const sendButton = document.querySelector('#send-button');
sendButton.onclick = function () {
sendMessageTo(nymClient);
}
// Start the Nym client. Connects to a Nym gateway via websocket.
await nymClient.start();
}
/**
* 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.
*
* @param {Client} nymClient the nym client to use for message sending
*/
function sendMessageTo(nymClient) {
var message = document.getElementById("message").value;
var recipient = document.getElementById("recipient").value;
nymClient.sendMessage(message, recipient);
displaySend(message);
}
/**
* 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 out = "<p style='color: blue; word-break: break-all;'>" + timestamp + " <b>sent</b> >>> " + message + "</p >";
document.getElementById("output").innerHTML = out + document.getElementById("output").innerHTML;
}
/**
* Display received text messages in the browser. Colour them green.
*
* @param {string} message
*/
function displayReceived(message) {
let timestamp = new Date().toISOString().substr(11, 12);
let out = "<p style='color: green; word-break: break-all;'>" + timestamp + " <b>received</b> >>> " + message + "</p >";
document.getElementById("output").innerHTML = out + document.getElementById("output").innerHTML;
}
/**
* Display the nymClient's sender address in the user interface
*
* @param {Client} nymClient
*/
function displaySenderAddress(nymClient) {
document.getElementById("sender").value = nymClient.formatAsRecipient();
}
// Let's get started!
main();
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,39 @@
{
"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",
"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": "Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/nymtech/nym/issues"
},
"homepage": "https://nymtech.net/docs",
"devDependencies": {
"copy-webpack-plugin": "^5.0.0",
"hello-wasm-pack": "^0.1.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"@nymproject/nym-client-wasm": "^0.7.5"
}
}
@@ -0,0 +1,14 @@
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require('path');
module.exports = {
entry: "./bootstrap.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bootstrap.js",
},
mode: "development",
plugins: [
new CopyWebpackPlugin(['index.html'])
],
};
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
}
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"files": [
"client.js"
],
"dependencies": {
"semver": "^7.3.2"
}
}
+322
View File
@@ -0,0 +1,322 @@
// 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 crypto::identity::MixIdentityPublicKey;
use models::Topology;
use nymsphinx::addressing::nodes::NymNodeRoutingAddress;
use nymsphinx::Node as SphinxNode;
use nymsphinx::{delays, Destination, NodeAddressBytes, SphinxPacket};
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use std::convert::TryInto;
use std::net::SocketAddr;
use std::time::Duration;
use wasm_bindgen::prelude::*;
mod models;
mod utils;
pub use models::keys::keygen;
use nymsphinx::addressing::clients::Recipient;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[derive(Serialize, Deserialize)]
pub struct JsonRoute {
nodes: Vec<NodeData>,
}
#[wasm_bindgen]
#[derive(Clone, Serialize, Deserialize)]
pub struct NodeData {
address: String,
public_key: String,
}
/// Creates a Gateway payload for use in JavaScript applications, using wasm.
/// It contains encoded address of first hop as well as the actual Sphinx Packet with the data.
///
/// The `wasm-pack build` command will cause this to output JS bindings and a
/// wasm executable in the `pkg/` directory.
///
/// Message chunking is currently not implemented. If the message exceeds the
/// capacity of a single Sphinx packet, the extra information will be discarded.
#[wasm_bindgen]
pub fn create_sphinx_packet(topology_json: &str, msg: &str, recipient: &str) -> Vec<u8> {
utils::set_panic_hook(); // nicer js errors.
let recipient = Recipient::try_from_string(recipient).unwrap();
let route = sphinx_route_to(topology_json, &recipient.gateway());
let average_delay = Duration::from_secs_f64(0.1);
let delays = delays::generate_from_average_duration(route.len(), average_delay);
// TODO: once we are able to reconstruct split messages use this instead
// let split_message = split_and_prepare_payloads(&msg.as_bytes());
// assert_eq!(split_message.len(), 1);
// let message = split_message.first().unwrap().clone();
let message = msg.as_bytes().to_vec();
let destination = Destination::new(recipient.destination(), Default::default());
let sphinx_packet = SphinxPacket::new(message, &route, &destination, &delays, None).unwrap();
payload(sphinx_packet, route)
}
/// Concatenate the gateway address bytes with the Sphinx packet.
///
/// The Nym gateway node has no idea what is inside the Sphinx packet, or where
/// it should send a packet it receives. So we prepend the packet with the
/// address bytes of the first mix inside the packet, so that the gateway can
/// forward the packet to it.
fn payload(sphinx_packet: SphinxPacket, route: Vec<SphinxNode>) -> Vec<u8> {
let packet = sphinx_packet.to_bytes();
let first_node_address =
NymNodeRoutingAddress::try_from(route.first().unwrap().address.clone()).unwrap();
first_node_address
.as_bytes()
.into_iter()
.chain(packet.into_iter())
.collect()
}
/// Attempts to create a Sphinx route, which is a `Vec<sphinx::Node>`, from a
/// JSON string.
///
/// # Panics
///
/// This function panics if the supplied `raw_route` json string can't be
/// extracted to a `JsonRoute`.
fn sphinx_route_to(topology_json: &str, gateway_address: &NodeAddressBytes) -> Vec<SphinxNode> {
let topology = Topology::new(topology_json);
let route = topology
.random_route_to_gateway(gateway_address)
.expect("invalid route produced");
assert_eq!(4, route.len());
route
}
impl TryFrom<NodeData> for SphinxNode {
type Error = ();
fn try_from(node_data: NodeData) -> Result<Self, Self::Error> {
let addr: SocketAddr = node_data.address.parse().unwrap();
let address: NodeAddressBytes = NymNodeRoutingAddress::from(addr).try_into().unwrap();
// this has to be temporarily moved out of separate function as we can't return private types
let pub_key = {
let src = MixIdentityPublicKey::from_base58_string(node_data.public_key).to_bytes();
let mut dest: [u8; 32] = [0; 32];
dest.copy_from_slice(&src);
nymsphinx::key::new(dest)
};
Ok(SphinxNode { address, pub_key })
}
}
#[cfg(test)]
mod test_constructing_a_sphinx_packet {
use super::*;
// the below test is no longer true, as the produced length is 1372 bytes + 7 (for IPV4) or + 19 (for IPV6)
// conceptually everything works as before, only the 0 padding was removed as it served no purpose here
// #[test]
// fn produces_1404_bytes() {
// // 32 byte address + 1372 byte sphinx packet
// let packet = create_gateway_sphinx_packet(
// topology_fixture(),
// "foomp",
// "AetTDvynUNB2N35rvCVDxkPR593Cx4PCe4QQKrMgm5RR",
// );
// assert_eq!(1404, packet.len());
// }
#[test]
fn starts_with_a_mix_address() {
let mut payload = create_sphinx_packet(
topology_fixture(),
"foomp",
"5pgrc4gPHP2tBQgfezcdJ2ZAjipoAsy6evrqHdxBbVXq@7vhgER4Gz789QHNTSu4apMpTcpTuUaRiLxJnbz1g2HFh",
);
// you don't really need 32 bytes here, but giving too much won't make it fail
let mut address_buffer = [0; 32];
let _ = payload.split_off(32);
address_buffer.copy_from_slice(payload.as_slice());
let address = NymNodeRoutingAddress::try_from_bytes(&address_buffer);
assert!(address.is_ok());
}
}
#[cfg(test)]
mod building_a_topology_from_json {
use super::*;
#[test]
#[should_panic]
fn panics_on_empty_string() {
sphinx_route_to(
"",
&NodeAddressBytes::try_from_base58_string(
"7vhgER4Gz789QHNTSu4apMpTcpTuUaRiLxJnbz1g2HFh",
)
.unwrap(),
);
}
#[test]
#[should_panic]
fn panics_on_bad_json() {
sphinx_route_to(
"bad bad bad not json",
&NodeAddressBytes::try_from_base58_string(
"7vhgER4Gz789QHNTSu4apMpTcpTuUaRiLxJnbz1g2HFh",
)
.unwrap(),
);
}
#[test]
#[should_panic]
fn panics_when_there_are_no_mixnodes() {
let mut topology: Topology = serde_json::from_str(topology_fixture()).unwrap();
topology.mix_nodes = vec![];
let json = serde_json::to_string(&topology).unwrap();
sphinx_route_to(
&json,
&NodeAddressBytes::try_from_base58_string(
"7vhgER4Gz789QHNTSu4apMpTcpTuUaRiLxJnbz1g2HFh",
)
.unwrap(),
);
}
#[test]
#[should_panic]
fn panics_when_there_are_not_enough_mixnodes() {
let mut topology: Topology = serde_json::from_str(topology_fixture()).unwrap();
let node = topology.mix_nodes.first().unwrap().clone();
topology.mix_nodes = vec![node]; // 1 mixnode isn't enough. Panic!
let json = serde_json::to_string(&topology).unwrap();
sphinx_route_to(
&json,
&NodeAddressBytes::try_from_base58_string(
"7vhgER4Gz789QHNTSu4apMpTcpTuUaRiLxJnbz1g2HFh",
)
.unwrap(),
);
}
#[test]
fn test_works_on_happy_json() {
let route = sphinx_route_to(
topology_fixture(),
&NodeAddressBytes::try_from_base58_string(
"7vhgER4Gz789QHNTSu4apMpTcpTuUaRiLxJnbz1g2HFh",
)
.unwrap(),
);
assert_eq!(4, route.len());
}
}
#[cfg(test)]
fn topology_fixture() -> &'static str {
r#"
{
"cocoNodes": [],
"mixNodes": [
{
"host": "nym.300baud.de:1789",
"pubKey": "AetTDvynUNB2N35rvCVDxkPR593Cx4PCe4QQKrMgm5RR",
"version": "0.6.0",
"location": "Falkenstein, DE",
"layer": 3,
"lastSeen": 1587572945877713700
},
{
"host": "testnet_nymmixnode.roussel-zeter.eu:1789",
"pubKey": "9wJ3zLoyat41e4ZgT1AWeueExv5c6uwnjvkRepj8Ebis",
"version": "0.6.0",
"location": "Geneva, CH",
"layer": 3,
"lastSeen": 1587572945907250400
},
{
"host": "185.144.83.134:1789",
"pubKey": "59tCzpCYsiKXz89rtvNiEYwQDdkseSShPEkifQXhsCgA",
"version": "0.6.0",
"location": "Bucharest",
"layer": 1,
"lastSeen": 1587572946007431400
},
{
"host": "[2a0a:e5c0:2:2:0:c8ff:fe68:bf6b]:1789",
"pubKey": "J9f9uS1hN8iwcN2STqH55fPRYqt7McEPyhNzpTYsxNdG",
"version": "0.6.0",
"location": "Glarus",
"layer": 1,
"lastSeen": 1587572945920982000
},
{
"host": "[2a0a:e5c0:2:2:0:c8ff:fe68:bf6b]:1789",
"pubKey": "J9f9uS1hN8iwcN2STqH55fPRYqt7McEPyhNzpTYsxNdG",
"version": "0.6.0",
"location": "Glarus",
"layer": 2,
"lastSeen": 1587572945920982000
},
{
"host": "[2a0a:e5c0:2:2:0:c8ff:fe68:bf6b]:1789",
"pubKey": "J9f9uS1hN8iwcN2STqH55fPRYqt7McEPyhNzpTYsxNdG",
"version": "0.6.0",
"location": "Glarus",
"layer": 2,
"lastSeen": 1587572945920982000
}
],
"mixProviderNodes":[],
"gatewayNodes": [
{
"clientListener": "139.162.246.48:9000",
"mixnetListener": "139.162.246.48:1789",
"pubKey": "7vhgER4Gz789QHNTSu4apMpTcpTuUaRiLxJnbz1g2HFh",
"version": "0.6.0",
"location": "London, UK",
"registeredClients": [
{
"pubKey": "5pgrc4gPHP2tBQgfezcdJ2ZAjipoAsy6evrqHdxBbVXq"
}
],
"lastSeen": 1587572946261865200
},
{
"clientListener": "127.0.0.1:9000",
"mixnetListener": "127.0.0.1:1789",
"pubKey": "2XK8RDcUTRcJLUWoDfoXc2uP4YViscMLEM5NSzhSi87M",
"version": "0.6.0",
"location": "unknown",
"registeredClients": [],
"lastSeen": 1587572946304564700
}
]
}
"#
}
@@ -0,0 +1,50 @@
// 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 serde::{Deserialize, Serialize};
use topology::coco;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CocoPresence {
pub location: String,
pub host: String,
pub pub_key: String,
pub last_seen: u64,
pub version: String,
}
impl Into<topology::coco::Node> for CocoPresence {
fn into(self) -> topology::coco::Node {
topology::coco::Node {
location: self.location,
host: self.host,
pub_key: self.pub_key,
last_seen: self.last_seen,
version: self.version,
}
}
}
impl From<topology::coco::Node> for CocoPresence {
fn from(cn: coco::Node) -> Self {
CocoPresence {
location: cn.location,
host: cn.host,
pub_key: cn.pub_key,
last_seen: cn.last_seen,
version: cn.version,
}
}
}
@@ -0,0 +1,86 @@
// 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 serde::{Deserialize, Serialize};
use topology::gateway;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GatewayPresence {
pub location: String,
pub client_listener: String,
pub mixnet_listener: String,
pub pub_key: String,
pub registered_clients: Vec<GatewayClient>,
pub last_seen: u64,
pub version: String,
}
impl Into<topology::gateway::Node> for GatewayPresence {
fn into(self) -> topology::gateway::Node {
topology::gateway::Node {
location: self.location,
client_listener: self.client_listener.parse().unwrap(),
mixnet_listener: self.mixnet_listener.parse().unwrap(),
pub_key: self.pub_key,
registered_clients: self
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: self.last_seen,
version: self.version,
}
}
}
impl From<topology::gateway::Node> for GatewayPresence {
fn from(mpn: gateway::Node) -> Self {
GatewayPresence {
location: mpn.location,
client_listener: mpn.client_listener.to_string(),
mixnet_listener: mpn.mixnet_listener.to_string(),
pub_key: mpn.pub_key,
registered_clients: mpn
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: mpn.last_seen,
version: mpn.version,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GatewayClient {
pub pub_key: String,
}
impl Into<topology::gateway::Client> for GatewayClient {
fn into(self) -> topology::gateway::Client {
topology::gateway::Client {
pub_key: self.pub_key,
}
}
}
impl From<topology::gateway::Client> for GatewayClient {
fn from(mpc: topology::gateway::Client) -> Self {
GatewayClient {
pub_key: mpc.pub_key,
}
}
}
+41
View File
@@ -0,0 +1,41 @@
use crypto::identity::MixIdentityKeyPair;
use serde::{Deserialize, Serialize};
use std::convert::{TryFrom, TryInto};
use wasm_bindgen::prelude::*;
#[derive(Serialize, Deserialize, Debug)]
pub struct GatewayIdentity {
private_key: String,
public_key: String,
address: String,
}
impl TryFrom<String> for GatewayIdentity {
type Error = serde_json::Error;
fn try_from(msg: String) -> Result<Self, Self::Error> {
serde_json::from_str(&msg)
}
}
impl TryInto<String> for GatewayIdentity {
type Error = serde_json::Error;
fn try_into(self) -> Result<String, Self::Error> {
serde_json::to_string(&self)
}
}
#[wasm_bindgen]
pub fn keygen() -> String {
let keypair = MixIdentityKeyPair::new();
let address = keypair.public_key().derive_address();
GatewayIdentity {
private_key: keypair.private_key().to_base58_string(),
public_key: keypair.public_key().to_base58_string(),
address: address.to_base58_string(),
}
.try_into()
.unwrap()
}
@@ -0,0 +1,66 @@
// 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 serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::io;
use std::net::ToSocketAddrs;
use topology::mix;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixNodePresence {
pub location: String,
pub host: String,
pub pub_key: String,
pub layer: u64,
pub last_seen: u64,
pub version: String,
}
impl TryInto<topology::mix::Node> for MixNodePresence {
type Error = io::Error;
fn try_into(self) -> Result<topology::mix::Node, Self::Error> {
let resolved_hostname = self.host.to_socket_addrs()?.next();
if resolved_hostname.is_none() {
return Err(io::Error::new(
io::ErrorKind::Other,
"no valid socket address",
));
}
Ok(topology::mix::Node {
location: self.location,
host: resolved_hostname.unwrap(),
pub_key: self.pub_key,
layer: self.layer,
last_seen: self.last_seen,
version: self.version,
})
}
}
impl From<topology::mix::Node> for MixNodePresence {
fn from(mn: mix::Node) -> Self {
MixNodePresence {
location: mn.location,
host: mn.host.to_string(),
pub_key: mn.pub_key,
layer: mn.layer,
last_seen: mn.last_seen,
version: mn.version,
}
}
}
+186
View File
@@ -0,0 +1,186 @@
// 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 nymsphinx::Node as SphinxNode;
use nymsphinx::NodeAddressBytes;
use rand::seq::IteratorRandom;
use serde::{Deserialize, Serialize};
use std::cmp::max;
use std::collections::HashMap;
use std::convert::TryInto;
use topology::{gateway, mix, provider};
pub mod coconodes;
pub mod gateways;
pub mod keys;
pub mod mixnodes;
pub mod providers;
// JS: can we just get rid of this? It's mostly just copied (and un-updated) code from NymTopology trait
// Topology shows us the current state of the overall Nym network
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Topology {
pub coco_nodes: Vec<coconodes::CocoPresence>,
pub mix_nodes: Vec<mixnodes::MixNodePresence>,
pub mix_provider_nodes: Vec<providers::MixProviderPresence>,
pub gateway_nodes: Vec<gateways::GatewayPresence>,
}
impl Topology {
pub fn new(json: &str) -> Self {
if json.is_empty() {
panic!("empty json passed");
}
serde_json::from_str(json).unwrap()
}
fn make_layered_topology(&self) -> Result<HashMap<u64, Vec<mix::Node>>, NymTopologyError> {
let mut layered_topology: HashMap<u64, Vec<mix::Node>> = HashMap::new();
let mut highest_layer = 0;
for mix in self.mix_nodes() {
// we need to have extra space for provider
if mix.layer > nymsphinx::MAX_PATH_LENGTH as u64 {
return Err(NymTopologyError::InvalidMixLayerError);
}
highest_layer = max(highest_layer, mix.layer);
let layer_nodes = layered_topology.entry(mix.layer).or_insert_with(Vec::new);
layer_nodes.push(mix);
}
// verify the topology - make sure there are no gaps and there is at least one node per layer
let mut missing_layers = Vec::new();
for layer in 1..=highest_layer {
if !layered_topology.contains_key(&layer) {
missing_layers.push(layer);
}
if layered_topology[&layer].is_empty() {
missing_layers.push(layer);
}
}
if !missing_layers.is_empty() {
return Err(NymTopologyError::MissingLayerError(missing_layers));
}
Ok(layered_topology)
}
// Tries to get a route through the mix network
fn random_mix_route(&self) -> Result<Vec<SphinxNode>, NymTopologyError> {
let mut layered_topology = self.make_layered_topology()?;
let num_layers = layered_topology.len();
let route = (1..=num_layers as u64)
// unwrap is safe for 'remove' as it it failed, it implied the entry never existed
// in the map in the first place which would contradict what we've just done
.map(|layer| layered_topology.remove(&layer).unwrap()) // for each layer
.map(|nodes| nodes.into_iter().choose(&mut rand::thread_rng()).unwrap()) // choose random node
.map(|random_node| random_node.into()) // and convert it into sphinx specific node format
.collect();
Ok(route)
}
// Sets up a route to a specific gateway
pub fn random_route_to_gateway(
&self,
gateway_address: &NodeAddressBytes,
) -> Result<Vec<SphinxNode>, NymTopologyError> {
let b58_address = gateway_address.to_base58_string();
let gateway_node = self
.gateways()
.iter()
.cloned()
.find(|gateway| gateway.pub_key == b58_address.clone())
.ok_or_else(|| NymTopologyError::InvalidMixLayerError)?;
Ok(self
.random_mix_route()?
.into_iter()
.chain(std::iter::once(gateway_node.into()))
.collect())
}
pub fn mix_nodes(&self) -> Vec<mix::Node> {
self.mix_nodes
.iter()
.filter_map(|x| x.clone().try_into().ok())
.collect()
}
// it's intesting how compiler knows this function is unused even though it's public
// but it will be removed once our topology is refactored and the concept of "provider"
// goes away.
#[allow(dead_code)]
pub fn providers(&self) -> Vec<provider::Node> {
self.mix_provider_nodes
.iter()
.map(|x| x.clone().into())
.collect()
}
pub fn gateways(&self) -> Vec<gateway::Node> {
self.gateway_nodes
.iter()
.map(|x| x.clone().into())
.collect()
}
}
#[derive(Debug)]
pub enum NymTopologyError {
InvalidMixLayerError,
MissingLayerError(Vec<u64>),
}
#[cfg(test)]
mod converting_mixnode_presence_into_topology_mixnode {
use super::*;
#[test]
fn it_returns_error_on_unresolvable_hostname() {
let unresolvable_hostname = "foomp.foomp.foomp:1234";
let mix_presence = mixnodes::MixNodePresence {
location: "".to_string(),
host: unresolvable_hostname.to_string(),
pub_key: "".to_string(),
layer: 0,
last_seen: 0,
version: "".to_string(),
};
let _result: Result<mix::Node, std::io::Error> = mix_presence.try_into();
// assert!(result.is_err()) // This fails only for me. Why?
// ¯\_(ツ)_/¯ - works on my machine (and travis)
}
#[test]
fn it_returns_resolved_ip_on_resolvable_hostname() {
let resolvable_hostname = "nymtech.net:1234";
let mix_presence = mixnodes::MixNodePresence {
location: "".to_string(),
host: resolvable_hostname.to_string(),
pub_key: "".to_string(),
layer: 0,
last_seen: 0,
version: "".to_string(),
};
let result: Result<topology::mix::Node, std::io::Error> = mix_presence.try_into();
assert!(result.is_ok())
}
}
@@ -0,0 +1,86 @@
// 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 serde::{Deserialize, Serialize};
use topology::provider;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixProviderPresence {
pub location: String,
pub client_listener: String,
pub mixnet_listener: String,
pub pub_key: String,
pub registered_clients: Vec<MixProviderClient>,
pub last_seen: u64,
pub version: String,
}
impl Into<topology::provider::Node> for MixProviderPresence {
fn into(self) -> topology::provider::Node {
topology::provider::Node {
location: self.location,
client_listener: self.client_listener.parse().unwrap(),
mixnet_listener: self.mixnet_listener.parse().unwrap(),
pub_key: self.pub_key,
registered_clients: self
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: self.last_seen,
version: self.version,
}
}
}
impl From<topology::provider::Node> for MixProviderPresence {
fn from(mpn: provider::Node) -> Self {
MixProviderPresence {
location: mpn.location,
client_listener: mpn.client_listener.to_string(),
mixnet_listener: mpn.mixnet_listener.to_string(),
pub_key: mpn.pub_key,
registered_clients: mpn
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: mpn.last_seen,
version: mpn.version,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixProviderClient {
pub pub_key: String,
}
impl Into<topology::provider::Client> for MixProviderClient {
fn into(self) -> topology::provider::Client {
topology::provider::Client {
pub_key: self.pub_key,
}
}
}
impl From<topology::provider::Client> for MixProviderClient {
fn from(mpc: topology::provider::Client) -> Self {
MixProviderClient {
pub_key: mpc.pub_key,
}
}
}
+10
View File
@@ -0,0 +1,10 @@
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
+13
View File
@@ -0,0 +1,13 @@
//! Test suite for the Web and headless browsers.
#![cfg(target_arch = "wasm32")]
extern crate wasm_bindgen_test;
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn pass() {
assert_eq!(1 + 1, 2);
}
@@ -0,0 +1,21 @@
[package]
name = "directory-client"
version = "0.1.0"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4"
futures = "0.3"
pretty_env_logger = "0.3"
reqwest = { version = "0.10", features = ["json"] }
serde = { version = "1.0.104", features = ["derive"] }
## internal
topology = {path = "../../topology"}
[dev-dependencies]
mockito = "0.23.0"
tokio = { version = "0.2", features = ["macros"] }
@@ -0,0 +1,146 @@
// 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 crate::requests::health_check_get::Request as HealthCheckRequest;
use crate::requests::metrics_mixes_get::Request as MetricsMixRequest;
use crate::requests::metrics_mixes_post::Request as MetricsMixPost;
use crate::requests::presence_coconodes_post::Request as PresenceCocoNodesPost;
use crate::requests::presence_gateways_post::Request as PresenceGatewayPost;
use crate::requests::presence_mixnodes_post::Request as PresenceMixNodesPost;
use crate::requests::presence_providers_post::Request as PresenceProvidersPost;
use crate::requests::presence_topology_get::Request as PresenceTopologyRequest;
use metrics::{MixMetric, PersistedMixMetric};
use presence::{
coconodes::CocoPresence, gateways::GatewayPresence, mixnodes::MixNodePresence,
providers::MixProviderPresence, Topology,
};
use requests::{health_check_get::HealthCheckResponse, DirectoryGetRequest, DirectoryPostRequest};
pub mod metrics;
pub mod presence;
pub mod requests;
pub struct Config {
pub base_url: String,
}
impl Config {
pub fn new(base_url: String) -> Self {
Config { base_url }
}
}
pub trait DirectoryClient {
fn new(config: Config) -> Self;
}
pub struct Client {
base_url: String,
reqwest_client: reqwest::Client,
}
impl DirectoryClient for Client {
fn new(config: Config) -> Client {
let reqwest_client = reqwest::Client::new();
Client {
base_url: config.base_url,
reqwest_client,
}
}
}
impl Client {
async fn post<R: DirectoryPostRequest>(
&self,
request: R,
) -> reqwest::Result<reqwest::Response> {
self.reqwest_client
.post(&request.url())
.json(request.json_payload())
.send()
.await
}
async fn get<R: DirectoryGetRequest>(&self, request: R) -> reqwest::Result<R::JSONResponse> {
self.reqwest_client
.get(&request.url())
.send()
.await?
.json()
.await
}
pub async fn get_healthcheck(&self) -> reqwest::Result<HealthCheckResponse> {
let req = HealthCheckRequest::new(&self.base_url);
self.get(req).await
}
pub async fn post_mix_metrics(&self, metrics: MixMetric) -> reqwest::Result<reqwest::Response> {
let req = MetricsMixPost::new(&self.base_url, metrics);
self.post(req).await
}
pub async fn get_mix_metrics(&self) -> reqwest::Result<Vec<PersistedMixMetric>> {
let req = MetricsMixRequest::new(&self.base_url);
self.get(req).await
}
pub async fn post_coconode_presence(
&self,
presence: CocoPresence,
) -> reqwest::Result<reqwest::Response> {
let req = PresenceCocoNodesPost::new(&self.base_url, presence);
self.post(req).await
}
pub async fn post_gateway_presence(
&self,
presence: GatewayPresence,
) -> reqwest::Result<reqwest::Response> {
let req = PresenceGatewayPost::new(&self.base_url, presence);
self.post(req).await
}
pub async fn post_mixnode_presence(
&self,
presence: MixNodePresence,
) -> reqwest::Result<reqwest::Response> {
let req = PresenceMixNodesPost::new(&self.base_url, presence);
self.post(req).await
}
// this should be soft-deprecated as the whole concept of provider will
// be removed in the next topology rework
pub async fn post_provider_presence(
&self,
presence: MixProviderPresence,
) -> reqwest::Result<reqwest::Response> {
let req = PresenceProvidersPost::new(&self.base_url, presence);
self.post(req).await
}
pub async fn get_topology(&self) -> reqwest::Result<Topology> {
let req = PresenceTopologyRequest::new(&self.base_url);
self.get(req).await
}
}
#[cfg(test)]
pub(crate) fn client_test_fixture(base_url: &str) -> Client {
Client {
base_url: base_url.to_string(),
reqwest_client: reqwest::Client::new(),
}
}
@@ -0,0 +1,33 @@
// 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 serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PersistedMixMetric {
pub pub_key: String,
pub received: u64,
pub sent: HashMap<String, u64>,
pub timestamp: u64,
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixMetric {
pub pub_key: String,
pub received: u64,
pub sent: HashMap<String, u64>,
}
@@ -0,0 +1,50 @@
// 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 serde::{Deserialize, Serialize};
use topology::coco;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CocoPresence {
pub location: String,
pub host: String,
pub pub_key: String,
pub last_seen: u64,
pub version: String,
}
impl Into<topology::coco::Node> for CocoPresence {
fn into(self) -> topology::coco::Node {
topology::coco::Node {
location: self.location,
host: self.host,
pub_key: self.pub_key,
last_seen: self.last_seen,
version: self.version,
}
}
}
impl From<topology::coco::Node> for CocoPresence {
fn from(cn: coco::Node) -> Self {
CocoPresence {
location: cn.location,
host: cn.host,
pub_key: cn.pub_key,
last_seen: cn.last_seen,
version: cn.version,
}
}
}
@@ -0,0 +1,86 @@
// 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 serde::{Deserialize, Serialize};
use topology::gateway;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GatewayPresence {
pub location: String,
pub client_listener: String,
pub mixnet_listener: String,
pub pub_key: String,
pub registered_clients: Vec<GatewayClient>,
pub last_seen: u64,
pub version: String,
}
impl Into<topology::gateway::Node> for GatewayPresence {
fn into(self) -> topology::gateway::Node {
topology::gateway::Node {
location: self.location,
client_listener: self.client_listener.parse().unwrap(),
mixnet_listener: self.mixnet_listener.parse().unwrap(),
pub_key: self.pub_key,
registered_clients: self
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: self.last_seen,
version: self.version,
}
}
}
impl From<topology::gateway::Node> for GatewayPresence {
fn from(mpn: gateway::Node) -> Self {
GatewayPresence {
location: mpn.location,
client_listener: mpn.client_listener.to_string(),
mixnet_listener: mpn.mixnet_listener.to_string(),
pub_key: mpn.pub_key,
registered_clients: mpn
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: mpn.last_seen,
version: mpn.version,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GatewayClient {
pub pub_key: String,
}
impl Into<topology::gateway::Client> for GatewayClient {
fn into(self) -> topology::gateway::Client {
topology::gateway::Client {
pub_key: self.pub_key,
}
}
}
impl From<topology::gateway::Client> for GatewayClient {
fn from(mpc: topology::gateway::Client) -> Self {
GatewayClient {
pub_key: mpc.pub_key,
}
}
}
@@ -0,0 +1,66 @@
// 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 serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::io;
use std::net::ToSocketAddrs;
use topology::mix;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixNodePresence {
pub location: String,
pub host: String,
pub pub_key: String,
pub layer: u64,
pub last_seen: u64,
pub version: String,
}
impl TryInto<topology::mix::Node> for MixNodePresence {
type Error = io::Error;
fn try_into(self) -> Result<topology::mix::Node, Self::Error> {
let resolved_hostname = self.host.to_socket_addrs()?.next();
if resolved_hostname.is_none() {
return Err(io::Error::new(
io::ErrorKind::Other,
"no valid socket address",
));
}
Ok(topology::mix::Node {
location: self.location,
host: resolved_hostname.unwrap(),
pub_key: self.pub_key,
layer: self.layer,
last_seen: self.last_seen,
version: self.version,
})
}
}
impl From<topology::mix::Node> for MixNodePresence {
fn from(mn: mix::Node) -> Self {
MixNodePresence {
location: mn.location,
host: mn.host.to_string(),
pub_key: mn.pub_key,
layer: mn.layer,
last_seen: mn.last_seen,
version: mn.version,
}
}
}
@@ -0,0 +1,21 @@
// 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.
pub mod coconodes;
pub mod gateways;
pub mod mixnodes;
pub mod providers;
pub mod topology;
pub use self::topology::Topology;
@@ -0,0 +1,86 @@
// 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 serde::{Deserialize, Serialize};
use topology::provider;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixProviderPresence {
pub location: String,
pub client_listener: String,
pub mixnet_listener: String,
pub pub_key: String,
pub registered_clients: Vec<MixProviderClient>,
pub last_seen: u64,
pub version: String,
}
impl Into<topology::provider::Node> for MixProviderPresence {
fn into(self) -> topology::provider::Node {
topology::provider::Node {
location: self.location,
client_listener: self.client_listener.parse().unwrap(),
mixnet_listener: self.mixnet_listener.parse().unwrap(),
pub_key: self.pub_key,
registered_clients: self
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: self.last_seen,
version: self.version,
}
}
}
impl From<topology::provider::Node> for MixProviderPresence {
fn from(mpn: provider::Node) -> Self {
MixProviderPresence {
location: mpn.location,
client_listener: mpn.client_listener.to_string(),
mixnet_listener: mpn.mixnet_listener.to_string(),
pub_key: mpn.pub_key,
registered_clients: mpn
.registered_clients
.into_iter()
.map(|c| c.into())
.collect(),
last_seen: mpn.last_seen,
version: mpn.version,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixProviderClient {
pub pub_key: String,
}
impl Into<topology::provider::Client> for MixProviderClient {
fn into(self) -> topology::provider::Client {
topology::provider::Client {
pub_key: self.pub_key,
}
}
}
impl From<topology::provider::Client> for MixProviderClient {
fn from(mpc: topology::provider::Client) -> Self {
MixProviderClient {
pub_key: mpc.pub_key,
}
}
}
@@ -0,0 +1,133 @@
// 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 super::{coconodes, gateways, mixnodes, providers};
use crate::{Client, Config, DirectoryClient};
use futures::future::BoxFuture;
use log::*;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use topology::{coco, gateway, mix, provider, NymTopology};
// Topology shows us the current state of the overall Nym network
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Topology {
pub coco_nodes: Vec<coconodes::CocoPresence>,
pub mix_nodes: Vec<mixnodes::MixNodePresence>,
pub mix_provider_nodes: Vec<providers::MixProviderPresence>,
pub gateway_nodes: Vec<gateways::GatewayPresence>,
}
impl NymTopology for Topology {
// TODO: this will need some changes to not imply having to make an HTTP request in constructor
// TODO2: and also be reworked/removed with the topology re-work
fn new<'a>(directory_server: String) -> BoxFuture<'a, Self> {
debug!("Using directory server: {:?}", directory_server);
let directory_config = Config {
base_url: directory_server,
};
let directory = Client::new(directory_config);
Box::pin({
async move {
directory
.get_topology()
.await
.expect("Failed to retrieve network topology.")
}
})
}
fn new_from_nodes(
mix_nodes: Vec<mix::Node>,
mix_provider_nodes: Vec<provider::Node>,
coco_nodes: Vec<coco::Node>,
gateway_nodes: Vec<gateway::Node>,
) -> Self {
Topology {
coco_nodes: coco_nodes.into_iter().map(|node| node.into()).collect(),
mix_nodes: mix_nodes.into_iter().map(|node| node.into()).collect(),
mix_provider_nodes: mix_provider_nodes
.into_iter()
.map(|node| node.into())
.collect(),
gateway_nodes: gateway_nodes.into_iter().map(|node| node.into()).collect(),
}
}
fn mix_nodes(&self) -> Vec<mix::Node> {
self.mix_nodes
.iter()
.filter_map(|x| x.clone().try_into().ok())
.collect()
}
fn providers(&self) -> Vec<provider::Node> {
self.mix_provider_nodes
.iter()
.map(|x| x.clone().into())
.collect()
}
fn gateways(&self) -> Vec<gateway::Node> {
self.gateway_nodes
.iter()
.map(|x| x.clone().into())
.collect()
}
fn coco_nodes(&self) -> Vec<topology::coco::Node> {
self.coco_nodes.iter().map(|x| x.clone().into()).collect()
}
}
#[cfg(test)]
mod converting_mixnode_presence_into_topology_mixnode {
use super::*;
#[test]
fn it_returns_error_on_unresolvable_hostname() {
let unresolvable_hostname = "foomp.foomp.foomp:1234";
let mix_presence = mixnodes::MixNodePresence {
location: "".to_string(),
host: unresolvable_hostname.to_string(),
pub_key: "".to_string(),
layer: 0,
last_seen: 0,
version: "".to_string(),
};
let result: Result<mix::Node, std::io::Error> = mix_presence.try_into();
assert!(result.is_err()) // This fails only for me. Why?
// ¯\_(ツ)_/¯ - works on my machine (and travis)
// Is it still broken?
}
#[test]
fn it_returns_resolved_ip_on_resolvable_hostname() {
let resolvable_hostname = "nymtech.net:1234";
let mix_presence = mixnodes::MixNodePresence {
location: "".to_string(),
host: resolvable_hostname.to_string(),
pub_key: "".to_string(),
layer: 0,
last_seen: 0,
version: "".to_string(),
};
let result: Result<topology::mix::Node, std::io::Error> = mix_presence.try_into();
assert!(result.is_ok())
}
}
@@ -0,0 +1,85 @@
// 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 super::{DirectoryGetRequest, DirectoryRequest};
use serde::{Deserialize, Serialize};
const PATH: &str = "/api/healthcheck";
#[derive(Deserialize, Serialize)]
pub struct HealthCheckResponse {
pub ok: bool,
}
pub struct Request {
base_url: String,
path: String,
}
impl DirectoryRequest for Request {
fn url(&self) -> String {
format!("{}{}", self.base_url, self.path)
}
}
impl DirectoryGetRequest for Request {
type JSONResponse = HealthCheckResponse;
fn new(base_url: &str) -> Self {
Request {
base_url: base_url.to_string(),
path: PATH.to_string(),
}
}
}
#[cfg(test)]
mod healthcheck_requests {
use crate::client_test_fixture;
use mockito::mock;
#[cfg(test)]
mod on_a_400_status {
use super::*;
#[tokio::test]
async fn it_returns_an_error() {
let _m = mock("GET", "/api/healthcheck").with_status(400).create();
let client = client_test_fixture(&mockito::server_url());
let res = client.get_healthcheck().await;
assert!(res.is_err());
_m.assert();
}
}
#[cfg(test)]
mod on_a_200 {
use super::*;
#[tokio::test]
async fn it_returns_a_response_with_200_status() {
let json = r#"{
"ok": true
}"#;
let _m = mock("GET", "/api/healthcheck")
.with_status(200)
.with_body(json)
.create();
let client = client_test_fixture(&mockito::server_url());
let res = client.get_healthcheck().await;
assert!(res.unwrap().ok);
_m.assert();
}
}
}
@@ -1,47 +1,60 @@
use crate::clients::directory::metrics::PersistedMixMetric;
// 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 super::{DirectoryGetRequest, DirectoryRequest};
use crate::metrics::PersistedMixMetric;
const PATH: &str = "/api/metrics/mixes";
pub struct Request {
base_url: String,
path: String,
}
pub trait MetricsMixRequester {
fn new(base_url: String) -> Self;
fn get(&self) -> Result<Vec<PersistedMixMetric>, reqwest::Error>;
impl DirectoryRequest for Request {
fn url(&self) -> String {
format!("{}{}", self.base_url, self.path)
}
}
impl MetricsMixRequester for Request {
fn new(base_url: String) -> Self {
Request {
base_url,
path: "/api/metrics/mixes".to_string(),
}
}
impl DirectoryGetRequest for Request {
type JSONResponse = Vec<PersistedMixMetric>;
fn get(&self) -> Result<Vec<PersistedMixMetric>, reqwest::Error> {
let url = format!("{}{}", self.base_url, self.path);
let mix_metric_vec = reqwest::get(&url)?.json()?;
Ok(mix_metric_vec)
fn new(base_url: &str) -> Self {
Request {
base_url: base_url.to_string(),
path: PATH.to_string(),
}
}
}
#[cfg(test)]
mod metrics_get_request {
use super::*;
#[cfg(test)]
use crate::client_test_fixture;
use mockito::mock;
#[cfg(test)]
mod on_a_400_status {
use super::*;
#[test]
#[should_panic]
fn it_returns_an_error() {
let _m = mock("GET", "/api/metrics/mixes").with_status(400).create();
let req = Request::new(mockito::server_url());
req.get().unwrap();
#[tokio::test]
async fn it_returns_an_error() {
let _m = mock("GET", PATH).with_status(400).create();
let client = client_test_fixture(&mockito::server_url());
let result = client.get_mix_metrics().await;
assert!(result.is_err());
_m.assert();
}
}
@@ -49,20 +62,15 @@ mod metrics_get_request {
#[cfg(test)]
mod on_a_200 {
use super::*;
#[test]
fn it_returns_a_response_with_200_status_and_a_correct_topology() {
#[tokio::test]
async fn it_returns_a_response_with_200_status_and_a_correct_metrics() {
let json = fixtures::mix_metrics_response_json();
let _m = mock("GET", "/api/metrics/mixes")
.with_status(200)
.with_body(json)
.create();
let req = Request::new(mockito::server_url());
let result = req.get();
assert_eq!(true, result.is_ok());
assert_eq!(
1576061080635800000,
result.unwrap().first().unwrap().timestamp
);
let _m = mock("GET", PATH).with_status(200).with_body(json).create();
let client = client_test_fixture(&mockito::server_url());
let result = client.get_mix_metrics().await;
let unwrapped = result.unwrap();
assert_eq!(10, unwrapped.first().unwrap().received);
_m.assert();
}
}
@@ -70,7 +78,7 @@ mod metrics_get_request {
#[cfg(test)]
mod fixtures {
#[cfg(test)]
pub fn mix_metrics_response_json() -> String {
pub fn mix_metrics_response_json() -> &'static str {
r#"[
{
"pubKey": "OwOqwWjh_IlnaWS2PxO6odnhNahOYpRCkju50beQCTA=",
@@ -233,7 +241,6 @@ mod metrics_get_request {
"timestamp": 1576061080501732900
}
]"#
.to_string()
}
}
}
@@ -0,0 +1,112 @@
// 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 super::{DirectoryPostRequest, DirectoryRequest};
use crate::metrics::MixMetric;
const PATH: &str = "/api/metrics/mixes";
pub struct Request {
base_url: String,
path: String,
payload: MixMetric,
}
impl DirectoryRequest for Request {
fn url(&self) -> String {
format!("{}{}", self.base_url, self.path)
}
}
impl DirectoryPostRequest for Request {
type Payload = MixMetric;
fn json_payload(&self) -> &MixMetric {
&self.payload
}
fn new(base_url: &str, payload: Self::Payload) -> Self {
Request {
base_url: base_url.to_string(),
path: PATH.to_string(),
payload,
}
}
}
#[cfg(test)]
mod metrics_post_request {
use super::*;
use crate::client_test_fixture;
use mockito::mock;
#[cfg(test)]
mod on_a_400_status {
use super::*;
#[tokio::test]
async fn it_returns_an_error() {
let _m = mock("POST", PATH).with_status(400).create();
let client = client_test_fixture(&mockito::server_url());
let result = client.post_mix_metrics(fixtures::new_metric()).await;
assert_eq!(400, result.unwrap().status());
_m.assert();
}
}
#[cfg(test)]
mod on_a_200 {
use super::*;
#[tokio::test]
async fn it_returns_a_response_with_200() {
let json = fixtures::mix_metrics_response_json();
let _m = mock("POST", "/api/metrics/mixes")
.with_status(201)
.with_body(json)
.create();
let client = client_test_fixture(&mockito::server_url());
let result = client.post_mix_metrics(fixtures::new_metric()).await;
assert!(result.is_ok());
_m.assert();
}
}
#[cfg(test)]
mod fixtures {
use crate::metrics::MixMetric;
pub fn new_metric() -> MixMetric {
MixMetric {
pub_key: "abc".to_string(),
received: 666,
sent: Default::default(),
}
}
#[cfg(test)]
pub fn mix_metrics_response_json() -> String {
r#"
{
"pubKey": "OwOqwWjh_IlnaWS2PxO6odnhNahOYpRCkju50beQCTA=",
"sent": {
"35.178.213.77:1789": 1,
"52.56.99.196:1789": 2
},
"received": 10,
"timestamp": 1576061080635800000
}
"#
.to_string()
}
}
}
@@ -0,0 +1,45 @@
// 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.
pub mod health_check_get;
pub mod metrics_mixes_get;
pub mod metrics_mixes_post;
pub mod presence_coconodes_post;
pub mod presence_gateways_post;
pub mod presence_mixnodes_post;
pub mod presence_providers_post;
pub mod presence_topology_get;
use serde::{de::DeserializeOwned, Serialize};
pub(crate) trait DirectoryRequest {
fn url(&self) -> String;
}
pub(crate) trait DirectoryGetRequest: DirectoryRequest {
// perhaps the name of this is not the best because it's technically not a JSON,
// but something that can be deserialised from JSON.
// I'm open to all suggestions on how to rename it
type JSONResponse: DeserializeOwned;
fn new(base_url: &str) -> Self;
}
pub(crate) trait DirectoryPostRequest: DirectoryRequest {
// Similarly this, it's something that can be serialized into a JSON
type Payload: Serialize + ?Sized;
fn new(base_url: &str, payload: Self::Payload) -> Self;
fn json_payload(&self) -> &Self::Payload;
}
@@ -0,0 +1,99 @@
// 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 super::{DirectoryPostRequest, DirectoryRequest};
use crate::presence::coconodes::CocoPresence;
const PATH: &str = "/api/presence/coconodes";
pub struct Request {
base_url: String,
path: String,
payload: CocoPresence,
}
impl DirectoryRequest for Request {
fn url(&self) -> String {
format!("{}{}", self.base_url, self.path)
}
}
impl DirectoryPostRequest for Request {
type Payload = CocoPresence;
fn json_payload(&self) -> &CocoPresence {
&self.payload
}
fn new(base_url: &str, payload: Self::Payload) -> Self {
Request {
base_url: base_url.to_string(),
path: PATH.to_string(),
payload,
}
}
}
#[cfg(test)]
mod presence_coconodes_post_request {
use super::*;
use crate::client_test_fixture;
use mockito::mock;
#[cfg(test)]
mod on_a_400_status {
use super::*;
#[tokio::test]
async fn it_returns_an_error() {
let _m = mock("POST", PATH).with_status(400).create();
let client = client_test_fixture(&mockito::server_url());
let presence = fixtures::new_presence();
let result = client.post_coconode_presence(presence).await;
assert_eq!(400, result.unwrap().status());
_m.assert();
}
}
#[cfg(test)]
mod on_a_200 {
use super::*;
#[tokio::test]
async fn it_returns_a_response_with_201() {
let json = r#"{
"ok": true
}"#;
let _m = mock("POST", PATH).with_status(201).with_body(json).create();
let client = client_test_fixture(&mockito::server_url());
let presence = fixtures::new_presence();
let result = client.post_coconode_presence(presence).await;
assert!(result.is_ok());
_m.assert();
}
}
#[cfg(test)]
mod fixtures {
use crate::presence::coconodes::CocoPresence;
pub fn new_presence() -> CocoPresence {
CocoPresence {
location: "foomp".to_string(),
host: "foo.com".to_string(),
pub_key: "abc".to_string(),
last_seen: 666,
version: "0.2.0".to_string(),
}
}
}
}
@@ -0,0 +1,100 @@
// 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 super::{DirectoryPostRequest, DirectoryRequest};
use crate::presence::gateways::GatewayPresence;
const PATH: &str = "/api/presence/gateways";
pub struct Request {
base_url: String,
path: String,
payload: GatewayPresence,
}
impl DirectoryRequest for Request {
fn url(&self) -> String {
format!("{}{}", self.base_url, self.path)
}
}
impl DirectoryPostRequest for Request {
type Payload = GatewayPresence;
fn json_payload(&self) -> &GatewayPresence {
&self.payload
}
fn new(base_url: &str, payload: Self::Payload) -> Self {
Request {
base_url: base_url.to_string(),
path: PATH.to_string(),
payload,
}
}
}
#[cfg(test)]
mod presence_gateways_post_request {
use super::*;
use crate::client_test_fixture;
use mockito::mock;
#[cfg(test)]
mod on_a_400_status {
use super::*;
#[tokio::test]
async fn it_returns_an_error() {
let _m = mock("POST", PATH).with_status(400).create();
let client = client_test_fixture(&mockito::server_url());
let presence = fixtures::new_presence();
let result = client.post_gateway_presence(presence).await;
assert_eq!(400, result.unwrap().status());
_m.assert();
}
}
#[cfg(test)]
mod on_a_200 {
use super::*;
#[tokio::test]
async fn it_returns_a_response_with_201() {
let json = r#"{
"ok": true
}"#;
let _m = mock("POST", PATH).with_status(201).with_body(json).create();
let client = client_test_fixture(&mockito::server_url());
let presence = fixtures::new_presence();
let result = client.post_gateway_presence(presence).await;
assert!(result.is_ok());
_m.assert();
}
}
#[cfg(test)]
mod fixtures {
use crate::presence::gateways::GatewayPresence;
pub fn new_presence() -> GatewayPresence {
GatewayPresence {
location: "foomp".to_string(),
client_listener: "foo.com".to_string(),
mixnet_listener: "foo.com".to_string(),
pub_key: "abc".to_string(),
registered_clients: vec![],
last_seen: 0,
version: "0.1.0".to_string(),
}
}
}
}
@@ -0,0 +1,100 @@
// 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 super::{DirectoryPostRequest, DirectoryRequest};
use crate::presence::mixnodes::MixNodePresence;
const PATH: &str = "/api/presence/mixnodes";
pub struct Request {
base_url: String,
path: String,
payload: MixNodePresence,
}
impl DirectoryRequest for Request {
fn url(&self) -> String {
format!("{}{}", self.base_url, self.path)
}
}
impl DirectoryPostRequest for Request {
type Payload = MixNodePresence;
fn json_payload(&self) -> &MixNodePresence {
&self.payload
}
fn new(base_url: &str, payload: Self::Payload) -> Self {
Request {
base_url: base_url.to_string(),
path: PATH.to_string(),
payload,
}
}
}
#[cfg(test)]
mod presence_mixnodes_post_request {
use super::*;
use crate::client_test_fixture;
use mockito::mock;
#[cfg(test)]
mod on_a_400_status {
use super::*;
#[tokio::test]
async fn it_returns_an_error() {
let _m = mock("POST", PATH).with_status(400).create();
let client = client_test_fixture(&mockito::server_url());
let presence = fixtures::new_presence();
let result = client.post_mixnode_presence(presence).await;
assert_eq!(400, result.unwrap().status());
_m.assert();
}
}
#[cfg(test)]
mod on_a_200 {
use super::*;
#[tokio::test]
async fn it_returns_a_response_with_201() {
let json = r#"{
"ok": true
}"#;
let _m = mock("POST", PATH).with_status(201).with_body(json).create();
let client = client_test_fixture(&mockito::server_url());
let presence = fixtures::new_presence();
let result = client.post_mixnode_presence(presence).await;
assert!(result.is_ok());
_m.assert();
}
}
#[cfg(test)]
mod fixtures {
use crate::presence::mixnodes::MixNodePresence;
pub fn new_presence() -> MixNodePresence {
MixNodePresence {
location: "foomp".to_string(),
host: "foo.com".to_string(),
pub_key: "abc".to_string(),
layer: 1,
last_seen: 0,
version: "0.1.0".to_string(),
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More