Compare commits

...

178 Commits

Author SHA1 Message Date
mfahampshire 7bc2c070e8 pick yana's edits: remove specified callout theming 2024-10-21 11:20:32 +02:00
mfahampshire edce7a5d3f first pass new ci 2024-10-18 18:40:19 +02:00
mfahampshire 04d09fba7b operator redirects 2024-10-18 17:17:36 +02:00
mfahampshire 3f4361cb8a minor themeing 2024-10-18 16:24:43 +02:00
mx b4157a67a2 links (#4990)
* links
* removed todos
* updated todo list
2024-10-18 13:36:14 +00:00
mfahampshire 33deb09da8 rename overview to more descriptive 2024-10-18 15:08:40 +02:00
mfahampshire 5bb59466ab Merge branch 'max/new-docs-framework' of github.com:nymtech/nym into max/new-docs-framework 2024-10-18 15:06:56 +02:00
mfahampshire da1d7874bb also moved matrix images to correct place 2024-10-18 15:06:41 +02:00
mx 9e692bfba4 Max/fix links new docs framework (#4989)
* tweak client links
* standardise images in public/
* old images move to public/archive
2024-10-18 13:05:48 +00:00
mfahampshire 38bc98ecc1 tweak client links 2024-10-18 14:05:43 +02:00
import this 937be101d2 [DOCs]: Operators rework to next.js (#4930)
* initialise operators guides v2

* new introduction page

* add variables csv and page

* add baseurl to allow short path

* add sandbox page

* added building from source page

* add binary pages

* add preliminary steps

* clean preliminary steps dir

* syntax edit

* syntax edit

* add configuration page

* create new proxy configuration page

* create new proxy configuration page

* create bonding.mdx page

* correct images path

* syntax edit

* add new validator setup page

* add api setup page

* add nyx configuration page

* add nym node and maintenance pages

* finish maintenance and add nymvisor conf page

* add manual upgrade page

* add nymvisor upgrade page

* add performance testing page and dir

* add node api check page

* add explore nym scripts page

* add testing pages

* fix menu issue by moving snippets to coomponents

* add all troubleshooting pages

* add general faq page

* add nym node faq page

* add nyx faq page

* revamp legal forum to community counsel and add all pages

* rewire relative paths to new structure

* simplify setup and remove lock file

* syntax fix

* rm package.json

* re add package.json, rm package-lock.json

* removed old books from commit

* address review comments

---------

Co-authored-by: mfahampshire <maxhampshire@pm.me>
Co-authored-by: mx <33262279+mfahampshire@users.noreply.github.com>
2024-10-18 11:58:48 +00:00
mfahampshire b514b0a747 updated todo list 2024-10-18 13:49:54 +02:00
mfahampshire 0d4979a2f1 changed theme of mermaid diagram to match everything else 2024-10-18 13:49:41 +02:00
mfahampshire f15a1d4a9a tweaked landing page component 2024-10-16 20:15:53 +02:00
Yana 7527deab1e cherry pick yana landingpage 2024-10-16 19:34:57 +02:00
mfahampshire b8eeaa9211 brought in archive + done rewrites for devportal 2024-10-16 19:18:56 +02:00
mfahampshire a6be529103 new pages + rest of redirects for old docs/ 2024-10-16 17:47:01 +02:00
mfahampshire 04fc39a544 tweaking 2024-10-16 17:24:32 +02:00
mfahampshire 6082e817b7 docs redirects first pass 2024-10-16 17:23:07 +02:00
mfahampshire 5fd0ab9325 changed erroneous note 2024-10-16 15:47:33 +02:00
mfahampshire 8ebfa810fa some more themeing 2024-10-15 22:13:51 +02:00
mfahampshire 5b3f986602 update theme: width of page and padding 2024-10-15 21:56:40 +02:00
mfahampshire 8c2255bc9c update readme 2024-10-15 21:56:25 +02:00
mfahampshire f5c262dd7c cherry pick yana commits + some extra config in theme 2024-10-15 19:06:30 +02:00
mfahampshire e5b10b3995 removed backups of root meta.json 2024-10-15 17:25:56 +02:00
mfahampshire 434518ca43 update readme 2024-10-15 16:51:50 +02:00
mfahampshire 1ff7969fed update readme 2024-10-15 16:45:10 +02:00
mfahampshire d43d01ee75 removed mdbook related scripts 2024-10-15 16:42:21 +02:00
mfahampshire 94ed32d493 make subcommand headers smaller 2024-10-15 16:23:46 +02:00
mfahampshire c4f5642c52 updated readme 2024-10-15 16:23:17 +02:00
mfahampshire de2dca7017 auto commit generated command files 2024-10-15 16:12:04 +02:00
mfahampshire 63f86f088c updated autodoc for committing changing else exit 2024-10-15 15:50:34 +02:00
mfahampshire a8f36f89ab add link to autodoc generated files 2024-10-15 15:49:40 +02:00
mfahampshire 2e0fa87129 auto commit generated command files 2024-10-15 15:49:02 +02:00
mfahampshire 4f45ff6690 temp 2024-10-15 15:23:51 +02:00
mfahampshire 54f3ded4e1 updated autogenerated docs 2024-10-15 13:50:13 +02:00
mfahampshire eeadec80fe made code blocks sh 2024-10-15 13:49:51 +02:00
mfahampshire c86f0a18cc make script own command instead of prebuild 2024-10-15 13:44:30 +02:00
mfahampshire 3e233b776e prebuild and predev script for autodoc commands 2024-10-15 13:28:46 +02:00
mfahampshire 9d0dddb024 remove tools dir moved to wrong palce 2024-10-15 13:11:03 +02:00
mfahampshire fc52c64ea7 recreated tools dir 2024-10-15 13:00:25 +02:00
mfahampshire 0f7ac8e694 remove test component 2024-10-15 12:59:59 +02:00
mfahampshire d4d0b71341 update deps 2024-10-15 12:59:36 +02:00
mfahampshire c47dbf2e11 hardcoded import version for the moment 2024-10-15 11:25:03 +02:00
mfahampshire 8ccd0d70e1 fixed link 2024-10-11 16:47:10 +02:00
mfahampshire 271000b0a5 replaced old diagram with mermaid 2024-10-11 16:47:02 +02:00
mfahampshire eb214a164e tweaks 2024-10-11 15:39:04 +02:00
mfahampshire e0e88d2b80 added note for standalone: can be accessed via sdk 2024-10-11 13:27:07 +02:00
mfahampshire f7d3599b58 change order in list 2024-10-11 12:51:22 +02:00
mfahampshire b55ad654f9 diagrams 2024-10-11 12:49:36 +02:00
mfahampshire 55edf9246a new sock5 diagram, minor client docs tweaks 2024-10-11 10:53:45 +02:00
mfahampshire fe47b76354 remove diagram title 2024-10-10 20:38:42 +02:00
mfahampshire efb9dd4e55 small correction re tcpproxy ffi 2024-10-10 20:35:46 +02:00
mfahampshire a2ca65447b diagram + concepts overview 2024-10-10 16:51:39 +02:00
mfahampshire d7ecdf71ba remove forced dark mode 2024-10-10 16:50:34 +02:00
mfahampshire b30465cbae removed todo 2024-10-10 15:24:56 +02:00
mfahampshire 1e58de0e93 added links for codecs + full flow diagram 2024-10-10 14:31:56 +02:00
mfahampshire 68b4d93f94 add mermaid flow diagram 2024-10-10 14:17:32 +02:00
mfahampshire 6219114ac2 redo acks diagram as mermaid 2024-10-10 14:17:21 +02:00
mfahampshire 6d927c6295 final linkchecks 2024-10-09 23:11:45 +02:00
mfahampshire 159314d325 ts sdk links 2024-10-09 22:55:58 +02:00
mfahampshire cc74172e7a rust sdk links 2024-10-09 22:40:31 +02:00
mfahampshire 1eb6fd8e2a added echo server to tools 2024-10-09 22:28:12 +02:00
mfahampshire c9b570b48e chain registry 2024-10-09 22:27:59 +02:00
mfahampshire a996fbe54d more links 2024-10-09 22:12:46 +02:00
mfahampshire ceb8322185 links 2024-10-09 22:09:36 +02:00
mfahampshire b45d45f917 new chain info, left todo links in 2024-10-09 20:22:21 +02:00
mfahampshire 13e8a9fca7 first pass new ws client 2024-10-09 20:15:18 +02:00
mfahampshire ebb9b37786 moved cli wallet out of tools 2024-10-09 20:04:51 +02:00
mfahampshire 9e29b71ff5 chain first pass 2024-10-09 20:04:30 +02:00
mfahampshire 32684ab456 started on client redo 2024-10-09 20:04:18 +02:00
mfahampshire 8e31cea97d moved images/ to correct place 2024-10-09 20:04:02 +02:00
mfahampshire 02a18fdb43 commit before moving image dir 2024-10-09 19:13:45 +02:00
mfahampshire 5551612c8b first pass tcpproxy 2024-10-09 19:02:16 +02:00
mfahampshire 2919d4cee5 updated faq 2024-10-09 18:45:49 +02:00
mfahampshire 000986eadc tweaks to ffi 2024-10-09 18:42:10 +02:00
mfahampshire 8ec308567c stripped unnecessary stuff from TS 2024-10-09 18:41:59 +02:00
mfahampshire 9dcebf69c3 added testnet example + note to custom topology example overview 2024-10-09 16:47:46 +02:00
mfahampshire aac1682414 tweaks 2024-10-09 16:35:23 +02:00
mfahampshire 50a5f8311c first pass ffi 2024-10-09 16:35:12 +02:00
mfahampshire fac373c1db first pass @ rest of rust sdk doc 2024-10-09 14:59:40 +02:00
mfahampshire 54282fa098 finished ffi overview page 2024-10-09 14:59:22 +02:00
mfahampshire 08f856bb5a added no scroll to inline code 2024-10-09 14:59:05 +02:00
mfahampshire f28f11ff5d reorg + added FFI table 2024-10-09 14:27:06 +02:00
mfahampshire 025573b1fc start reorg of rust sdk docs 2024-10-09 11:30:50 +02:00
mfahampshire 3c307ec2d3 first pass concepts done 2024-10-09 11:30:38 +02:00
mfahampshire 66b1927ace add credential stub 2024-10-09 11:30:19 +02:00
mfahampshire 1e7a3d7aca typo fix 2024-10-08 20:22:39 +02:00
mfahampshire 6ff608aafb crypto overview page 2024-10-08 17:24:32 +02:00
mfahampshire dca54b62d0 updated arch 2024-10-08 17:24:24 +02:00
mfahampshire a6acffc400 added to concepts in dev portal 2024-10-08 17:24:10 +02:00
mfahampshire f6fa071d9d more for networking pages 2024-10-08 14:56:46 +02:00
mfahampshire 67920ab1bc stub 2024-10-05 12:52:02 +02:00
mfahampshire ddadd3c2e9 concepts overview for devporta 2024-09-30 18:13:43 +02:00
mfahampshire bd31db24b5 integration overview work + tools 2024-09-30 13:26:35 +02:00
mfahampshire ca470ab757 sidebar autocollapse 2024-09-30 12:13:03 +02:00
mfahampshire 561147573b add echo serv to tools 2024-09-27 18:31:15 +02:00
mfahampshire 314336a386 rework intro 2024-09-27 18:29:32 +02:00
mfahampshire 92efad3116 initial pass at new clients overview for developers 2024-09-27 18:23:29 +02:00
mfahampshire 1907170e92 move sdks to developers 2024-09-27 18:10:23 +02:00
mfahampshire 044c537a88 updated todo list 2024-09-27 17:51:42 +02:00
mfahampshire 7b1a05acda added ffi stub files 2024-09-27 17:51:34 +02:00
mfahampshire 8c7e9501e4 todo for the tldr overview 2024-09-27 17:51:13 +02:00
mfahampshire c85be2b99b pass @ integration page 2024-09-27 17:50:57 +02:00
mfahampshire 2a4fdc83c4 started moving integrations docs over from ts sdk 2024-09-26 19:53:50 +02:00
mfahampshire 3445ec88a7 smart contracts done 2024-09-26 18:58:43 +02:00
mfahampshire c0fd0b7b47 note on where to find deployed info 2024-09-26 18:20:16 +02:00
mfahampshire fbe4931745 added zknym docs 2024-09-26 18:17:18 +02:00
mfahampshire 430928d75a added zknym docs 2024-09-26 18:17:12 +02:00
mfahampshire 4fa3bd4b72 updating nyx section 2024-09-26 18:16:57 +02:00
mfahampshire 393bbc188e update todo list 2024-09-26 14:28:41 +02:00
mfahampshire 66637be98e add links + tweaks 2024-09-26 14:28:01 +02:00
mfahampshire a6045b7956 overhaul arch 2024-09-26 14:27:40 +02:00
mfahampshire 93157f5308 overhaul arch 2024-09-26 14:27:30 +02:00
mfahampshire 24d714c642 hid root index 2024-09-26 14:27:19 +02:00
mfahampshire 6ac2d8939d misc 2024-09-25 18:57:50 +02:00
mfahampshire e58c53dd1a traffic 2nd pass 2024-09-25 18:57:37 +02:00
mfahampshire 1b1373fb2f structure change 2024-09-25 18:57:22 +02:00
mfahampshire fa0a681529 stub for not p2p 2024-09-25 18:57:09 +02:00
mfahampshire 5ae9510933 crypto first proper pass, sphinx 2024-09-25 18:56:50 +02:00
mfahampshire 927558be73 concepts 2nd pass 2024-09-25 18:56:34 +02:00
mfahampshire 28c3e3bb6e note to client 2024-09-25 15:44:16 +02:00
mfahampshire b485085a55 removed old reference to archive 2024-09-25 15:39:41 +02:00
mfahampshire 0e6b505d50 moved some chain files to the dev portal stubs 2024-09-25 15:38:26 +02:00
mfahampshire e0cdb5978f more network docs 2024-09-25 15:37:50 +02:00
mfahampshire ae69ecea54 first pass traffic 2024-09-25 15:37:29 +02:00
mfahampshire 3bf7ff0870 first pass concepts 2024-09-25 15:37:02 +02:00
mfahampshire 87bc27daa1 first pass new arch 2024-09-25 15:36:33 +02:00
mfahampshire cf8910bb72 tweak overview 2024-09-25 11:56:35 +02:00
mfahampshire d00fd92d9a mixnet node overview 2024-09-25 11:55:56 +02:00
mfahampshire 21d5ecd4b4 tweak to overview 2024-09-24 16:35:23 +02:00
mfahampshire 505ba9c83d new list 2024-09-24 14:16:18 +02:00
mfahampshire c55499df37 add new bits to todo list 2024-09-20 15:58:10 +02:00
mfahampshire cdc8840868 added arch and concepts stubs 2024-09-05 16:04:42 +02:00
mfahampshire 1e17041d8a rework of structure of developers 2024-09-05 16:04:11 +02:00
mfahampshire d46c51a966 quick first sketch of landing page 2024-09-05 16:03:46 +02:00
mx 2f4e74d180 Update rework_todo.md 2024-08-28 14:13:09 +00:00
mx 09feaf4fe1 new autodoc version (#4781) 2024-08-28 10:31:17 +00:00
mfahampshire 032e990c37 updated todo list 2024-08-28 12:29:50 +02:00
mfahampshire 4d7262e051 moving around new docs - think this is the final dir structure 2024-08-28 12:29:42 +02:00
mfahampshire 2a2ecab852 moved old docs -> old_docs dir for clarity when devving 2024-08-28 12:29:01 +02:00
mfahampshire f7c39397b3 add licensing 2024-08-27 18:10:48 +02:00
mfahampshire 2c47c932e8 structure 2024-08-27 18:01:42 +02:00
mfahampshire 21acab9857 first pass network structure 2024-08-27 18:01:33 +02:00
mfahampshire e18dd80b36 first pass developers structure 2024-08-27 18:01:21 +02:00
mfahampshire 712fa519e9 sdk in its own dir 2024-08-27 18:01:08 +02:00
mfahampshire cf2afc6adf gen updates 2024-08-27 18:00:52 +02:00
mfahampshire 8318c7ff61 first pass @ operator docs 2024-08-27 18:00:36 +02:00
mfahampshire e36d4f105d consolidating images folders in one place 2024-08-27 17:59:59 +02:00
mfahampshire 14f659337c updated todo list 2024-08-26 17:15:13 +02:00
mfahampshire cc2d4c3376 small shift typescript org 2024-08-26 17:15:01 +02:00
mfahampshire d8c3a3f738 first pass rust sdk 2024-08-26 17:14:41 +02:00
mfahampshire 7d561bff63 modified code component filepaths 2024-08-26 13:15:39 +02:00
mfahampshire 9daa2f6e98 rearranged code example dir structure 2024-08-26 13:15:10 +02:00
mfahampshire 74c3dbe169 started new docs draft 2024-08-26 11:53:21 +02:00
mfahampshire 8c4f2fde78 remove ts docs from ts sdk dir 2024-08-26 11:53:10 +02:00
mfahampshire e5efba2d45 startd long todo list 2024-08-26 11:52:26 +02:00
mfahampshire 02bfa9a7ab startd long todo list 2024-08-26 11:51:07 +02:00
mfahampshire cea6ac1d3e started todo list for rework 2024-08-23 15:55:16 +02:00
Drazen Urch 1ac262ec90 New Network Monitor (#4610)
* Initial commit

* Cherry pick from develop

* Keep track of fragments

* A bunch of data formats, graphs

* Use mix_id for display

* Proper API routes

* Add openapi + swagger ui

* Update locustfile

* Add node stats endpoint

* Add Swagger and locust to readme

* All node stats endpoint

* Update dependencies to use workspace

* Bunch of pedantic fixes

* More version updates, fmt

* More lints

* Add new_from_env for NymTopology

* Nym API endpoint to submit monitoring results (#4616)

* Nym API endpoint to submit monitoring results

* Add gateway monitoring results

* Cleanup, ergonomics

* Weaponize

* Finalize results submissions

* Monitor message signing and verification

* Update README

* Axum graceful shutdown

* More grtacefulness

* Restructure result submission

* Less fragile routes

* Remove gateway unique index on node_id
2024-08-22 11:29:36 +02:00
Bogdan-Ștefan Neacşu 7c1fca8ce4 Persist used wireguard private IPs (#4771)
* Persist used wireguard private IPs

* Fix imports

* Remove unnecessary type specification
2024-08-21 11:26:14 +02:00
import this f3ac17eb9d [DOCs/developers]: syntax fix (#4770)
* syntax-fix

* syntax-fix
2024-08-20 16:41:29 +02:00
import this 6296d09adf [DOCs/developers]: Update NymVPN CLI guide (#4769)
* creat guide to build nym-vpn-cli from source

* update nymvpn cli guide
2024-08-20 13:10:05 +00:00
Bogdan-Ștefan Neacşu 2ae81f6da0 Avoid race on ip and registration structures (#4766) 2024-08-20 14:51:59 +02:00
Tommy Verrall 1d5e8b62ac Merge pull request #4765 from nymtech/serinko-hotfix
docs/hotfix
2024-08-20 10:21:18 +02:00
import this 581cdd5bdf Update configuration.md 2024-08-18 11:56:56 +00:00
import this e2e49e7136 docs/hotfix 2024-08-18 11:55:28 +00:00
Jon Häggblad dff82f946f Make gateway latency check generic (#4759)
* Replace concrete gateway type with trait in latency check

* Rename to ConnectableGateway
2024-08-15 09:42:13 +02:00
Tommy Verrall ec61728654 Merge pull request #4762 from nymtech/serinko/wg_hotfix
[DOCs/operators]: serinko/hotfix
2024-08-13 17:48:36 +02:00
import this 61471e9058 add note about IPv6 2024-08-13 15:41:16 +00:00
import this ed4fd84503 serinko/hotfix 2024-08-13 15:39:31 +00:00
Jon Häggblad cb4b0403b5 Remove deprecated mark_as_success and use new disarm (#4751) 2024-08-13 15:09:48 +02:00
import this da8e513627 [DOCs/operators]: WireGuard guide & changelog update (#4760)
* wireguard documentation and changelog update

* add review comments

* add review comments
2024-08-13 13:05:52 +00:00
Jon Häggblad 3f6de8b10c Remove duplicate stat count for retransmissions (#4756) 2024-08-09 14:55:14 +02:00
import this 1e01a8e633 [DOCs/operators]: Release detailed changelog for v2024.9 topdeck (#4757)
* add changelog for new release

* add more URLs redirection for socks5 specific apps

* update exit policy page

* finish changelog - ready for review

* add tooling

* clarify tornul note comment
2024-08-07 13:20:17 +00:00
import this aaf3dca5b9 [DOCs]: Catching more broken URLs (#4755)
* urls edit

* finish PR - ready to merge
2024-08-06 18:49:46 +00:00
Bogdan-Ștefan Neacşu f939cae3d9 Update peer refresh value (#4754)
* Use a more proper timeout value

* Move const to wireguard types
2024-08-06 18:14:29 +02:00
import this 1db61f800c docs/hotfix (#4752) 2024-08-06 14:49:09 +00:00
782 changed files with 37115 additions and 1182 deletions
+7
View File
@@ -0,0 +1,7 @@
.git
.github
.gitignore
**/node_modules
**/target
dist
documentation
@@ -1,9 +1,10 @@
name: ci-sdk-docs-typescript
on:
workflow_dispatch:
pull_request:
paths:
- "sdk/typescript/**"
- "documentation/"
- "wasm/**"
jobs:
@@ -28,7 +29,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: "1.20"
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
@@ -36,7 +37,7 @@ jobs:
- name: Install wasm-opt
uses: ./.github/actions/install-wasm-opt
with:
version: '116'
version: "116"
- name: Build branch WASM packages
run: make sdk-wasm-build
+4 -1
View File
@@ -48,4 +48,7 @@ foxyfox.env
.next
ppa-private-key.b64
ppa-private-key.asc
ppa-private-key.asc
nym-network-monitor/topology.json
nym-network-monitor/__pycache__
nym-network-monitor/*.key
Generated
+89 -1
View File
@@ -347,6 +347,14 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "autodoc"
version = "0.1.0"
dependencies = [
"env_logger 0.11.5",
"log",
]
[[package]]
name = "axum"
version = "0.6.20"
@@ -1858,6 +1866,7 @@ dependencies = [
"lock_api",
"once_cell",
"parking_lot_core 0.9.10",
"serde",
]
[[package]]
@@ -2184,6 +2193,16 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "env_filter"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@@ -2207,6 +2226,19 @@ dependencies = [
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"humantime 2.1.0",
"log",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -2397,6 +2429,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
version = "1.0.30"
@@ -4253,6 +4291,7 @@ dependencies = [
"nym-sphinx",
"nym-task",
"nym-topology",
"nym-types",
"nym-validator-client",
"nym-vesting-contract-common",
"okapi",
@@ -4579,6 +4618,7 @@ dependencies = [
"nym-topology",
"nym-validator-client",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_json",
"sha2 0.10.8",
@@ -5410,6 +5450,36 @@ dependencies = [
"url",
]
[[package]]
name = "nym-network-monitor"
version = "0.1.0"
dependencies = [
"anyhow",
"axum 0.7.5",
"clap 4.5.7",
"dashmap",
"futures",
"log",
"nym-bin-common",
"nym-crypto",
"nym-network-defaults",
"nym-sdk",
"nym-sphinx",
"nym-topology",
"nym-types",
"nym-validator-client",
"petgraph",
"rand 0.8.5",
"rand_chacha 0.3.1",
"reqwest 0.12.4",
"serde",
"serde_json",
"tokio",
"tokio-util",
"utoipa",
"utoipa-swagger-ui",
]
[[package]]
name = "nym-network-requester"
version = "1.1.40"
@@ -5575,6 +5645,7 @@ dependencies = [
"nym-task",
"nym-topology",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_json",
"thiserror",
@@ -5858,6 +5929,7 @@ version = "0.1.0"
dependencies = [
"log",
"nym-crypto",
"nym-metrics",
"nym-mixnet-contract-common",
"nym-sphinx-acknowledgements",
"nym-sphinx-addressing",
@@ -5871,6 +5943,7 @@ dependencies = [
"nym-sphinx-types",
"nym-topology",
"rand 0.8.5",
"rand_chacha 0.3.1",
"rand_distr",
"thiserror",
"tokio",
@@ -5927,12 +6000,17 @@ dependencies = [
name = "nym-sphinx-chunking"
version = "0.1.0"
dependencies = [
"dashmap",
"log",
"nym-crypto",
"nym-metrics",
"nym-sphinx-addressing",
"nym-sphinx-params",
"nym-sphinx-types",
"rand 0.8.5",
"serde",
"thiserror",
"utoipa",
]
[[package]]
@@ -6046,6 +6124,7 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"rand 0.8.5",
"reqwest 0.12.4",
"semver 0.11.0",
"serde",
"serde_json",
@@ -6242,7 +6321,6 @@ name = "nym-wireguard-types"
version = "0.1.0"
dependencies = [
"base64 0.21.7",
"dashmap",
"hmac",
"log",
"nym-config",
@@ -6683,6 +6761,16 @@ dependencies = [
"sha2 0.10.8",
]
[[package]]
name = "petgraph"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
"indexmap 2.2.6",
]
[[package]]
name = "pin-project"
version = "1.1.5"
+3 -1
View File
@@ -14,7 +14,6 @@ panic = "abort"
opt-level = 3
[workspace]
resolver = "2"
members = [
"clients/native",
@@ -94,6 +93,7 @@ members = [
"common/wasm/utils",
"common/wireguard",
"common/wireguard-types",
"documentation/autodoc",
"explorer-api",
"explorer-api/explorer-api-requests",
"explorer-api/explorer-client",
@@ -106,6 +106,7 @@ members = [
"service-providers/common",
"service-providers/ip-packet-router",
"service-providers/network-requester",
"nym-network-monitor",
"nym-api",
"nym-browser-extension/storage",
"nym-api/nym-api-requests",
@@ -159,6 +160,7 @@ homepage = "https://nymtech.net"
documentation = "https://nymtech.net"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.80"
[workspace.dependencies]
addr = "0.15.6"
+1 -1
View File
@@ -422,7 +422,7 @@ impl Handler {
) {
// We don't want a crash in the connection handler to trigger a shutdown of the whole
// process.
task_client.mark_as_success();
task_client.disarm();
let ws_stream = match accept_async(socket).await {
Ok(ws_stream) => ws_stream,
+1
View File
@@ -19,6 +19,7 @@ futures = { workspace = true }
humantime-serde = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
rand_chacha = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = { workspace = true }
@@ -455,7 +455,7 @@ where
Err(ClientCoreError::CustomGatewaySelectionExpected)
} else {
// and make sure to invalidate the task client so we wouldn't cause premature shutdown
shutdown.mark_as_success();
shutdown.disarm();
custom_gateway_transceiver.set_packet_router(packet_router)?;
Ok(custom_gateway_transceiver)
};
@@ -562,7 +562,7 @@ where
if topology_config.disable_refreshing {
// if we're not spawning the refresher, don't cause shutdown immediately
info!("The topology refesher is not going to be started");
shutdown.mark_as_success();
shutdown.disarm();
} else {
// don't spawn the refresher if we don't want to be refreshing the topology.
// only use the initial values obtained
@@ -458,7 +458,7 @@ impl PacketStatisticsControl {
fn report_rates(&self) {
if let Some((_, rates)) = self.rates.back() {
log::info!("{}", rates.summary());
log::debug!("{}", rates.summary());
log::debug!("{}", rates.detailed_summary());
}
}
@@ -486,7 +486,7 @@ impl PacketStatisticsControl {
// Check what the number of retransmissions was during the recording window
if let Some((_, start_stats)) = self.history.front() {
let delta = self.stats.clone() - start_stats.clone();
log::info!(
log::debug!(
"mix packet retransmissions/real mix packets: {}/{}",
delta.retransmissions_queued,
delta.real_packets_queued,
@@ -453,6 +453,7 @@ where
let mut pending_acks = Vec::with_capacity(fragments.len());
let mut real_messages = Vec::with_capacity(fragments.len());
debug!("Splitting message into {} fragments", fragments.len());
for fragment in fragments {
// we need to clone it because we need to keep it in memory in case we had to retransmit
// it. And then we'd need to recreate entire ACK again.
@@ -474,13 +474,6 @@ where
Poll::Ready(Some((real_messages, conn_id))) => {
log::trace!("handling real_messages: size: {}", real_messages.len());
// This is the last step in the pipeline where we know the type of the message, so
// lets count the number of retransmissions here.
if conn_id == TransmissionLane::Retransmission {
self.stats_tx
.report(PacketStatisticsEvent::RetransmissionQueued);
}
// First store what we got for the given connection id
self.transmission_buffer.store(&conn_id, real_messages);
let real_next = self.pop_next_message().expect("we just added one");
+40 -18
View File
@@ -46,13 +46,34 @@ const MEASUREMENTS: usize = 3;
const CONN_TIMEOUT: Duration = Duration::from_millis(1500);
const PING_TIMEOUT: Duration = Duration::from_millis(1000);
struct GatewayWithLatency<'a> {
gateway: &'a gateway::Node,
// The abstraction that some of these helpers use
pub trait ConnectableGateway {
fn identity(&self) -> &identity::PublicKey;
fn clients_address(&self) -> String;
fn is_wss(&self) -> bool;
}
impl ConnectableGateway for gateway::Node {
fn identity(&self) -> &identity::PublicKey {
self.identity()
}
fn clients_address(&self) -> String {
self.clients_address()
}
fn is_wss(&self) -> bool {
self.clients_wss_port.is_some()
}
}
struct GatewayWithLatency<'a, G: ConnectableGateway> {
gateway: &'a G,
latency: Duration,
}
impl<'a> GatewayWithLatency<'a> {
fn new(gateway: &'a gateway::Node, latency: Duration) -> Self {
impl<'a, G: ConnectableGateway> GatewayWithLatency<'a, G> {
fn new(gateway: &'a G, latency: Duration) -> Self {
GatewayWithLatency { gateway, latency }
}
}
@@ -130,11 +151,14 @@ async fn connect(endpoint: &str) -> Result<WsConn, ClientCoreError> {
JSWebsocket::new(endpoint).map_err(|_| ClientCoreError::GatewayJsConnectionFailure)
}
async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency, ClientCoreError> {
async fn measure_latency<G>(gateway: &G) -> Result<GatewayWithLatency<G>, ClientCoreError>
where
G: ConnectableGateway,
{
let addr = gateway.clients_address();
trace!(
"establishing connection to {} ({addr})...",
gateway.identity_key,
gateway.identity(),
);
let mut stream = connect(&addr).await?;
@@ -177,7 +201,7 @@ async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency,
let count = results.len() as u64;
if count == 0 {
return Err(ClientCoreError::NoGatewayMeasurements {
identity: gateway.identity_key.to_base58_string(),
identity: gateway.identity().to_base58_string(),
});
}
@@ -187,11 +211,11 @@ async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency,
Ok(GatewayWithLatency::new(gateway, avg))
}
pub async fn choose_gateway_by_latency<R: Rng>(
pub async fn choose_gateway_by_latency<'a, R: Rng, G: ConnectableGateway + Clone>(
rng: &mut R,
gateways: &[gateway::Node],
gateways: &[G],
must_use_tls: bool,
) -> Result<gateway::Node, ClientCoreError> {
) -> Result<G, ClientCoreError> {
let gateways = filter_by_tls(gateways, must_use_tls)?;
info!(
@@ -223,21 +247,19 @@ pub async fn choose_gateway_by_latency<R: Rng>(
info!(
"chose gateway {} with average latency of {:?}",
chosen.gateway.identity_key, chosen.latency
chosen.gateway.identity(),
chosen.latency
);
Ok(chosen.gateway.clone())
}
fn filter_by_tls(
gateways: &[gateway::Node],
fn filter_by_tls<G: ConnectableGateway>(
gateways: &[G],
must_use_tls: bool,
) -> Result<Vec<&gateway::Node>, ClientCoreError> {
) -> Result<Vec<&G>, ClientCoreError> {
if must_use_tls {
let filtered = gateways
.iter()
.filter(|g| g.clients_wss_port.is_some())
.collect::<Vec<_>>();
let filtered = gateways.iter().filter(|g| g.is_wss()).collect::<Vec<_>>();
if filtered.is_empty() {
return Err(ClientCoreError::NoWssGateways);
@@ -70,8 +70,8 @@ impl PacketRouter {
Ok(())
}
pub fn mark_as_success(&mut self) {
self.shutdown.mark_as_success();
pub fn disarm(&mut self) {
self.shutdown.disarm();
}
}
@@ -113,8 +113,8 @@ impl PartiallyDelegatedRouter {
let return_res = match ret {
Err(err) => self.stream_return.send(Err(err)),
Ok(_) => {
self.packet_router.mark_as_success();
task_client.mark_as_success();
self.packet_router.disarm();
task_client.disarm();
self.stream_return.send(Ok(split_stream))
}
};
@@ -90,4 +90,6 @@ default = ["http-client"]
http-client = ["cosmrs/rpc"]
generate-ts = []
contract-testing = ["nym-mixnet-contract-common/contract-testing"]
# Features below are added to make clippy happy, it seems like they're unused we should remove them
tendermint-rpc-http-client = ["tendermint-rpc/http-client"]
tendermint-rpc-websocket-client = ["tendermint-rpc/websocket-client"]
@@ -49,5 +49,7 @@ pub const COMPUTE_REWARD_ESTIMATION: &str = "compute-reward-estimation";
pub const AVG_UPTIME: &str = "avg_uptime";
pub const STAKE_SATURATION: &str = "stake-saturation";
pub const INCLUSION_CHANCE: &str = "inclusion-probability";
pub const SUBMIT_GATEWAY: &str = "submit-gateway-monitoring-results";
pub const SUBMIT_NODE: &str = "submit-node-monitoring-results";
pub const SERVICE_PROVIDERS: &str = "services";
@@ -300,8 +300,8 @@ where
}
#[cfg(any(
feature = "tendermint-rpc/http-client",
feature = "tendermint-rpc/websocket-client"
feature = "tendermint-rpc-http-client",
feature = "tendermint-rpc-websocket-client"
))]
async fn wait_until_healthy<T>(&self, timeout: T) -> Result<(), Error>
where
@@ -820,8 +820,8 @@ where
}
#[cfg(any(
feature = "tendermint-rpc/http-client",
feature = "tendermint-rpc/websocket-client"
feature = "tendermint-rpc-http-client",
feature = "tendermint-rpc-websocket-client"
))]
async fn wait_until_healthy<T>(&self, timeout: T) -> Result<(), Error>
where
@@ -300,8 +300,8 @@ pub trait TendermintRpcClient {
}
#[cfg(any(
feature = "tendermint-rpc/http-client",
feature = "tendermint-rpc/websocket-client"
feature = "tendermint-rpc-http-client",
feature = "tendermint-rpc-websocket-client"
))]
/// Poll the `/health` endpoint until it returns a successful result or
/// the given `timeout` has elapsed.
@@ -518,8 +518,8 @@ mod non_wasm {
}
#[cfg(any(
feature = "tendermint-rpc/http-client",
feature = "tendermint-rpc/websocket-client"
feature = "tendermint-rpc-http-client",
feature = "tendermint-rpc-websocket-client"
))]
async fn wait_until_healthy<T>(&self, timeout: T) -> Result<(), Error>
where
+1 -1
View File
@@ -22,7 +22,7 @@ use tracing::{debug, error};
pub mod bandwidth;
pub mod error;
mod inboxes;
pub(crate) mod models;
pub mod models;
mod shared_keys;
mod tickets;
#[cfg(feature = "wireguard")]
+1 -1
View File
@@ -57,7 +57,7 @@ impl PacketListener {
// cloning the arc as each accepted socket is handled in separate task
let connection_handler = Arc::clone(&self.connection_handler);
let mut handler_shutdown_listener = self.shutdown.clone();
handler_shutdown_listener.mark_as_success();
handler_shutdown_listener.disarm();
tokio::select! {
socket = listener.accept() => {
+1 -1
View File
@@ -245,7 +245,7 @@ impl VerlocMeasurer {
}
let mut shutdown_listener = self.shutdown_listener.clone().named("VerlocMeasurement");
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
for chunk in nodes_to_test.chunks(self.config.tested_nodes_batch_size) {
let mut chunk_results = Vec::with_capacity(chunk.len());
+1 -1
View File
@@ -84,7 +84,7 @@ impl PacketSender {
tested_node: TestedNode,
) -> Result<VerlocMeasurement, RttError> {
let mut shutdown_listener = self.shutdown_listener.fork(tested_node.address.to_string());
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
let mut conn = match tokio::time::timeout(
self.connection_timeout,
+2 -1
View File
@@ -9,11 +9,12 @@ license.workspace = true
[dependencies]
futures = { workspace = true }
rand = { workspace = true }
rand_chacha = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["macros"]}
tokio = { workspace = true, features = ["macros"] }
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
nym-task = { path = "../task" }
+4
View File
@@ -294,4 +294,8 @@ impl<R: CryptoRng + Rng> FragmentPreparer for NodeTester<R> {
fn average_ack_delay(&self) -> Duration {
self.average_ack_delay
}
fn nonce(&self) -> i32 {
1
}
}
+15 -3
View File
@@ -11,6 +11,7 @@ repository = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
rand_distr = { workspace = true }
rand_chacha = { workspace = true }
thiserror = { workspace = true }
nym-sphinx-acknowledgements = { path = "acknowledgements" }
@@ -27,10 +28,13 @@ nym-sphinx-types = { path = "types" }
# to separate crate?
nym-crypto = { path = "../crypto", version = "0.4.0" }
nym-topology = { path = "../topology" }
nym-metrics = { path = "../nym-metrics" }
[dev-dependencies]
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
nym-crypto = { path = "../crypto", version = "0.4.0", features = ["asymmetric"] }
nym-crypto = { path = "../crypto", version = "0.4.0", features = [
"asymmetric",
] }
# do not include this when compiling into wasm as it somehow when combined together with reqwest, it will require
# net2 via tokio-util -> tokio -> mio -> net2
@@ -43,5 +47,13 @@ features = ["sync"]
[features]
default = ["sphinx"]
sphinx = ["nym-crypto/sphinx", "nym-sphinx-params/sphinx", "nym-sphinx-types/sphinx"]
outfox = ["nym-crypto/outfox", "nym-sphinx-params/outfox", "nym-sphinx-types/outfox"]
sphinx = [
"nym-crypto/sphinx",
"nym-sphinx-params/sphinx",
"nym-sphinx-types/sphinx",
]
outfox = [
"nym-crypto/outfox",
"nym-sphinx-params/outfox",
"nym-sphinx-types/outfox",
]
+7
View File
@@ -13,7 +13,14 @@ repository = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
thiserror = { workspace = true }
dashmap = { workspace = true, features = ["serde"] }
serde = { workspace = true, features = ["derive"] }
utoipa = { workspace = true }
nym-sphinx-addressing = { path = "../addressing" }
nym-sphinx-params = { path = "../params" }
nym-sphinx-types = { path = "../types" }
nym-metrics = { path = "../../nym-metrics" }
nym-crypto = { path = "../../crypto", version = "0.4.0", features = [
"asymmetric",
] }
+31 -3
View File
@@ -3,6 +3,8 @@
use crate::ChunkingError;
use nym_sphinx_params::{SerializedFragmentIdentifier, FRAG_ID_LEN};
use serde::Serialize;
use utoipa::ToSchema;
use std::fmt::{self, Debug, Formatter};
@@ -58,7 +60,7 @@ pub const COVER_FRAG_ID: FragmentIdentifier = FragmentIdentifier {
/// and u8 position of the `Fragment` in the set.
// TODO: this should really be redesigned, especially how cover and reply messages are really
// "abusing" this. They should work with it natively instead.
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize)]
pub struct FragmentIdentifier {
set_id: i32,
fragment_position: u8,
@@ -75,6 +77,10 @@ impl fmt::Display for FragmentIdentifier {
}
impl FragmentIdentifier {
pub fn set_id(&self) -> i32 {
self.set_id
}
pub fn to_bytes(self) -> SerializedFragmentIdentifier {
debug_assert_eq!(FRAG_ID_LEN, 5);
@@ -125,6 +131,10 @@ impl Debug for Fragment {
}
impl Fragment {
pub fn header(&self) -> FragmentHeader {
self.header.clone()
}
/// Tries to encapsulate provided payload slice and metadata into a `Fragment`.
/// It can fail if payload would not fully fit in a single `Fragment` or some of the metadata
/// is malformed or self-contradictory, for example if current_fragment > total_fragments.
@@ -216,6 +226,10 @@ impl Fragment {
}
}
pub fn seed(&self) -> i32 {
self.header().seed()
}
/// Gets the size of payload contained in this `Fragment`.
pub fn payload_size(&self) -> usize {
self.payload.len()
@@ -297,8 +311,8 @@ impl Fragment {
/// there is 7 bytes of overhead inside each sphinx packet sent
/// and for the longest messages, without upper bound, there is usually also only 7 bytes
/// of overhead apart from first and last fragments in each set that instead have 10 bytes of overhead.
#[derive(PartialEq, Clone, Debug)]
pub(crate) struct FragmentHeader {
#[derive(PartialEq, Clone, Debug, Serialize, ToSchema)]
pub struct FragmentHeader {
/// ID associated with `FragmentSet` to which this particular `Fragment` belongs.
/// Its value is restricted to (0, i32::MAX].
/// Note that it *excludes* 0, but *includes* i32::MAX.
@@ -324,6 +338,20 @@ pub(crate) struct FragmentHeader {
}
impl FragmentHeader {
pub fn seed(&self) -> i32 {
let mut seed = self.id;
seed = seed.wrapping_mul(self.total_fragments as i32);
seed = seed.wrapping_mul(self.current_fragment as i32);
seed
}
pub fn total_fragments(&self) -> u8 {
self.total_fragments
}
pub fn current_fragment(&self) -> u8 {
self.current_fragment
}
/// Tries to create a new `FragmentHeader` using provided metadata. Bunch of logical
/// checks are performed to see if the data is not self-contradictory,
/// for example if current_fragment > total_fragments.
+119
View File
@@ -1,9 +1,16 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::sync::LazyLock;
use crate::fragment::{linked_fragment_payload_max_len, unlinked_fragment_payload_max_len};
use dashmap::DashMap;
use fragment::{Fragment, FragmentHeader};
use nym_crypto::asymmetric::ed25519::PublicKey;
use serde::Serialize;
pub use set::split_into_sets;
use thiserror::Error;
use utoipa::ToSchema;
pub const MIN_PADDING_OVERHEAD: usize = 1;
@@ -22,6 +29,118 @@ pub mod fragment;
pub mod reconstruction;
pub mod set;
#[derive(Debug, Clone)]
pub struct FragmentMixParams {
destination: PublicKey,
hops: u8,
}
impl FragmentMixParams {
pub fn destination(&self) -> &PublicKey {
&self.destination
}
pub fn hops(&self) -> u8 {
self.hops
}
}
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct SentFragment {
header: FragmentHeader,
at: u64,
client_nonce: i32,
#[serde(skip)]
mixnet_params: FragmentMixParams,
}
impl SentFragment {
fn new(
header: FragmentHeader,
at: u64,
client_nonce: i32,
destination: PublicKey,
hops: u8,
) -> Self {
let mixnet_params = FragmentMixParams { destination, hops };
SentFragment {
header,
at,
client_nonce,
mixnet_params,
}
}
pub fn header(&self) -> FragmentHeader {
self.header.clone()
}
pub fn at(&self) -> u64 {
self.at
}
pub fn client_nonce(&self) -> i32 {
self.client_nonce
}
pub fn seed(&self) -> i32 {
self.header().seed().wrapping_mul(self.client_nonce())
}
pub fn mixnet_params(&self) -> FragmentMixParams {
self.mixnet_params.clone()
}
}
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct ReceivedFragment {
header: FragmentHeader,
at: u64,
}
impl ReceivedFragment {
fn new(header: FragmentHeader, at: u64) -> Self {
ReceivedFragment { header, at }
}
pub fn header(&self) -> FragmentHeader {
self.header.clone()
}
pub fn at(&self) -> u64 {
self.at
}
}
pub static FRAGMENTS_RECEIVED: LazyLock<DashMap<i32, Vec<ReceivedFragment>>> =
LazyLock::new(DashMap::new);
pub static FRAGMENTS_SENT: LazyLock<DashMap<i32, Vec<SentFragment>>> = LazyLock::new(DashMap::new);
#[macro_export]
macro_rules! now {
() => {
match std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH) {
Ok(n) => n.as_secs(),
Err(_) => 0,
}
};
}
pub fn fragment_received(fragment: &Fragment) {
let id = fragment.fragment_identifier().set_id();
let mut entry = FRAGMENTS_RECEIVED.entry(id).or_default();
let r = ReceivedFragment::new(fragment.header(), now!());
entry.push(r);
}
pub fn fragment_sent(fragment: &Fragment, client_nonce: i32, destination: PublicKey, hops: u8) {
let id = fragment.fragment_identifier().set_id();
let mut entry = FRAGMENTS_SENT.entry(id).or_default();
let s = SentFragment::new(fragment.header(), now!(), client_nonce, destination, hops);
entry.push(s);
}
/// The idea behind the process of chunking is to incur as little data overhead as possible due
/// to very computationally costly sphinx encapsulation procedure.
///
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::fragment::Fragment;
use crate::ChunkingError;
use crate::{fragment_received, ChunkingError};
use log::*;
use std::collections::HashMap;
@@ -66,6 +66,12 @@ impl ReconstructionBuffer {
// if the set is complete.
debug_assert!(self.is_complete);
debug!(
"Got {} fragments for set id {}",
self.fragments.len(),
self.fragments[0].as_ref().unwrap().id()
);
self.fragments
.into_iter()
.map(|fragment| fragment.unwrap().extract_payload())
@@ -104,6 +110,8 @@ impl ReconstructionBuffer {
}
});
fragment_received(&fragment);
let fragment_index = fragment.current_fragment() as usize - 1;
if self.fragments[fragment_index].is_some() {
// TODO: what to do in that case? give up on the message? overwrite it? panic?
+24 -4
View File
@@ -3,6 +3,7 @@
use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD};
use crate::NymPayloadBuilder;
use log::debug;
use nym_crypto::asymmetric::encryption;
use nym_crypto::Digest;
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
@@ -11,12 +12,14 @@ use nym_sphinx_addressing::clients::Recipient;
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
use nym_sphinx_anonymous_replies::reply_surb::ReplySurb;
use nym_sphinx_chunking::fragment::{Fragment, FragmentIdentifier};
use nym_sphinx_chunking::fragment_sent;
use nym_sphinx_forwarding::packet::MixPacket;
use nym_sphinx_params::packet_sizes::PacketSize;
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
use nym_sphinx_types::{Delay, NymPacket};
use nym_topology::{NymTopology, NymTopologyError};
use rand::{CryptoRng, Rng};
use rand::{CryptoRng, Rng, SeedableRng};
use rand_chacha::ChaCha20Rng;
use std::time::Duration;
@@ -49,6 +52,7 @@ pub trait FragmentPreparer {
type Rng: CryptoRng + Rng;
fn rng(&mut self) -> &mut Self::Rng;
fn nonce(&self) -> i32;
fn num_mix_hops(&self) -> u8;
fn average_packet_delay(&self) -> Duration;
fn average_ack_delay(&self) -> Duration;
@@ -192,9 +196,18 @@ pub trait FragmentPreparer {
packet_type: PacketType,
mix_hops: Option<u8>,
) -> Result<PreparedFragment, NymTopologyError> {
debug!("Preparing chunk for sending");
// each plain or repliable packet (i.e. not a reply) attaches an ephemeral public key so that the recipient
// could perform diffie-hellman with its own keys followed by a kdf to re-derive
// the packet encryption key
let seed = fragment.seed().wrapping_mul(self.nonce());
let mut rng = ChaCha20Rng::seed_from_u64(seed as u64);
let destination = packet_recipient.gateway();
let hops = mix_hops.unwrap_or(self.num_mix_hops());
fragment_sent(&fragment, self.nonce(), *destination, hops);
let non_reply_overhead = encryption::PUBLIC_KEY_SIZE;
let expected_plaintext = match packet_type {
PacketType::Outfox => {
@@ -228,10 +241,8 @@ pub trait FragmentPreparer {
};
// generate pseudorandom route for the packet
let hops = mix_hops.unwrap_or(self.num_mix_hops());
log::trace!("Preparing chunk for sending with {} mix hops", hops);
let route =
topology.random_route_to_gateway(self.rng(), hops, packet_recipient.gateway())?;
let route = topology.random_route_to_gateway(&mut rng, hops, destination)?;
let destination = packet_recipient.as_sphinx_destination();
// including set of delays
@@ -313,6 +324,8 @@ pub struct MessagePreparer<R> {
/// Number of mix hops each packet ('real' message, ack, reply) is expected to take.
/// Note that it does not include gateway hops.
num_mix_hops: u8,
nonce: i32,
}
impl<R> MessagePreparer<R>
@@ -325,12 +338,15 @@ where
average_packet_delay: Duration,
average_ack_delay: Duration,
) -> Self {
let mut rng = rng;
let nonce = rng.gen();
MessagePreparer {
rng,
sender_address,
average_packet_delay,
average_ack_delay,
num_mix_hops: DEFAULT_NUM_MIX_HOPS,
nonce,
}
}
@@ -454,6 +470,10 @@ impl<R: CryptoRng + Rng> FragmentPreparer for MessagePreparer<R> {
fn average_ack_delay(&self) -> Duration {
self.average_ack_delay
}
fn nonce(&self) -> i32 {
self.nonce
}
}
/*
@@ -218,7 +218,7 @@ impl SocksClient {
packet_type: Option<PacketType>,
) -> Self {
// If this task fails and exits, we don't want to send shutdown signal
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
let connection_id = Self::generate_random();
@@ -294,7 +294,7 @@ impl SocksClient {
.shutdown()
.await
.map_err(|source| SocksProxyError::SocketShutdownFailure { source })?;
self.shutdown_listener.mark_as_success();
self.shutdown_listener.disarm();
Ok(())
}
@@ -172,6 +172,6 @@ where
trace!("{} - inbound closed", connection_id);
shutdown_notify.notify_one();
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
reader
}
@@ -148,7 +148,7 @@ where
}
pub fn into_inner(mut self) -> (TcpStream, ConnectionReceiver) {
self.shutdown_listener.mark_as_success();
self.shutdown_listener.disarm();
(
self.socket.take().unwrap(),
self.mix_receiver.take().unwrap(),
@@ -60,7 +60,7 @@ pub(super) async fn run_outbound(
loop {
select! {
connection_message = &mut mix_receiver.next() => {
connection_message = mix_receiver.next() => {
if let Some(connection_message) = connection_message {
if deal_with_message(connection_message, &mut writer, &local_destination_address, &remote_source_address, connection_id).await {
break;
@@ -90,6 +90,6 @@ pub(super) async fn run_outbound(
trace!("{} - outbound closed", connection_id);
shutdown_notify.notify_one();
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
(writer, mix_receiver)
}
+1 -5
View File
@@ -470,12 +470,8 @@ impl TaskClient {
// This listener should to *not* notify the ShutdownNotifier to shutdown when dropped. For
// example when we clone the listener for a task handling connections, we often want to drop
// without signal failure.
pub fn mark_as_success(&mut self) {
self.mode.set_should_not_signal_on_drop();
}
pub fn disarm(&mut self) {
self.mark_as_success();
self.mode.set_should_not_signal_on_drop();
}
pub fn send_we_stopped(&mut self, err: SentError) {
+11 -8
View File
@@ -5,7 +5,6 @@ edition = { workspace = true }
authors = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
readme = { workspace = true }
homepage = { workspace = true }
documentation = { workspace = true }
@@ -15,9 +14,10 @@ documentation = { workspace = true }
bs58 = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
reqwest = { workspace = true, features = ["json"] }
thiserror = { workspace = true }
async-trait = { workspace = true, optional = true }
semver = "0.11"
semver = { version = "0.11" }
# 'serializable' feature
serde = { workspace = true, features = ["derive"], optional = true }
@@ -28,20 +28,22 @@ tsify = { workspace = true, features = ["js"], optional = true }
wasm-bindgen = { workspace = true, optional = true }
## internal
nym-bin-common = { path = "../bin-common" }
nym-config = { path = "../config" }
nym-crypto = { path = "../crypto", features = ["sphinx", "outfox"] }
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
nym-sphinx-addressing = { path = "../nymsphinx/addressing" }
nym-sphinx-types = { path = "../nymsphinx/types", features = ["sphinx", "outfox"] }
nym-sphinx-types = { path = "../nymsphinx/types", features = [
"sphinx",
"outfox",
] }
nym-sphinx-routing = { path = "../nymsphinx/routing" }
nym-bin-common = { path = "../bin-common" }
# I'm not sure how to feel about pulling in this dependency here...
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
# 'serializable' feature
nym-config = { path = "../config", optional = true }
# 'wasm-serde-types' feature
wasm-utils = { path = "../wasm/utils", default-features = false, optional = true }
@@ -49,4 +51,5 @@ wasm-utils = { path = "../wasm/utils", default-features = false, optional = true
default = ["provider-trait"]
provider-trait = ["async-trait"]
wasm-serde-types = ["tsify", "wasm-bindgen", "wasm-utils"]
serializable = ["serde", "nym-config", "serde_json"]
serializable = ["serde", "serde_json"]
outfox = []
+12
View File
@@ -51,4 +51,16 @@ pub enum NymTopologyError {
#[error("{0}")]
PacketError(#[from] NymPacketError),
#[error("{0}")]
ReqwestError(#[from] reqwest::Error),
#[error("{0}")]
MixnodeConversionError(#[from] crate::mix::MixnodeConversionError),
#[error("{0}")]
GatewayConversionError(#[from] crate::gateway::GatewayConversionError),
#[error("{0}")]
VarError(#[from] std::env::VarError),
}
+54 -4
View File
@@ -6,7 +6,9 @@
use crate::filter::VersionFilterable;
pub use error::NymTopologyError;
use log::{debug, warn};
use log::{debug, info, warn};
use mix::Node;
use nym_config::defaults::var_names::NYM_API;
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
use nym_sphinx_addressing::nodes::NodeIdentity;
@@ -116,13 +118,40 @@ impl Display for NetworkAddress {
pub type MixLayer = u8;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct NymTopology {
mixes: BTreeMap<MixLayer, Vec<mix::Node>>,
gateways: Vec<gateway::Node>,
}
impl NymTopology {
pub async fn new_from_env() -> Result<Self, NymTopologyError> {
let api_url = std::env::var(NYM_API)?;
info!("Generating topology from {}", api_url);
let mixnodes = reqwest::get(&format!("{}/v1/mixnodes", api_url))
.await?
.json::<Vec<MixNodeDetails>>()
.await?
.into_iter()
.map(|details| details.bond_information)
.map(mix::Node::try_from)
.filter(Result::is_ok)
.collect::<Result<Vec<_>, _>>()?;
let gateways = reqwest::get(&format!("{}/v1/gateways", api_url))
.await?
.json::<Vec<GatewayBond>>()
.await?
.into_iter()
.map(gateway::Node::try_from)
.filter(Result::is_ok)
.collect::<Result<Vec<_>, _>>()?;
let topology = NymTopology::new_unordered(mixnodes, gateways);
Ok(topology)
}
pub fn new(mixes: BTreeMap<MixLayer, Vec<mix::Node>>, gateways: Vec<gateway::Node>) -> Self {
NymTopology { mixes, gateways }
}
@@ -270,7 +299,7 @@ impl NymTopology {
&self,
rng: &mut R,
num_mix_hops: u8,
) -> Result<Vec<SphinxNode>, NymTopologyError>
) -> Result<Vec<Node>, NymTopologyError>
where
R: Rng + CryptoRng + ?Sized,
{
@@ -295,12 +324,32 @@ impl NymTopology {
let random_mix = layer_mixes
.choose(rng)
.ok_or(NymTopologyError::EmptyMixLayer { layer })?;
route.push(random_mix.into());
route.push(random_mix.clone());
}
Ok(route)
}
pub fn random_path_to_gateway<R>(
&self,
rng: &mut R,
num_mix_hops: u8,
gateway_identity: &NodeIdentity,
) -> Result<(Vec<mix::Node>, gateway::Node), NymTopologyError>
where
R: Rng + CryptoRng + ?Sized,
{
let gateway = self.get_gateway(gateway_identity).ok_or(
NymTopologyError::NonExistentGatewayError {
identity_key: gateway_identity.to_base58_string(),
},
)?;
let path = self.random_mix_route(rng, num_mix_hops)?;
Ok((path, gateway.clone()))
}
/// Tries to create a route to the specified gateway, such that it goes through mixnode on layer 1,
/// mixnode on layer2, .... mixnode on layer n and finally the target gateway
pub fn random_route_to_gateway<R>(
@@ -321,6 +370,7 @@ impl NymTopology {
Ok(self
.random_mix_route(rng, num_mix_hops)?
.into_iter()
.map(|node| SphinxNode::from(&node))
.chain(std::iter::once(gateway.into()))
.collect())
}
+1 -1
View File
@@ -4,7 +4,7 @@ version = "1.0.0"
description = "Nym common types"
authors.workspace = true
edition = "2021"
rust-version = "1.58"
rust-version.workspace = true
license.workspace = true
[dependencies]
+1
View File
@@ -11,6 +11,7 @@ pub mod gas;
pub mod gateway;
pub mod helpers;
pub mod mixnode;
pub mod monitoring;
pub mod pending_events;
pub mod transaction;
pub mod vesting;
+131
View File
@@ -0,0 +1,131 @@
use std::{collections::HashSet, sync::LazyLock, time::SystemTime};
use nym_crypto::asymmetric::identity::{PrivateKey, PublicKey, Signature};
use nym_mixnet_contract_common::MixId;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
static NETWORK_MONITORS: LazyLock<HashSet<String>> = LazyLock::new(|| {
let mut nm = HashSet::new();
nm.insert("5VsPyLbsBCq9PAMWmjKkToteVAKNabNqex6QwDf5fWzt".to_string());
nm
});
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
pub struct NodeResult {
pub node_id: MixId,
pub identity: String,
pub reliability: u8,
}
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
pub struct MixnodeResult {
pub mix_id: MixId,
pub identity: String,
pub owner: String,
pub reliability: u8,
}
impl MixnodeResult {
pub fn new(mix_id: MixId, identity: String, owner: String, reliability: u8) -> Self {
MixnodeResult {
mix_id,
identity,
owner,
reliability,
}
}
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
pub struct GatewayResult {
pub identity: String,
pub owner: String,
pub reliability: u8,
pub mix_id: MixId,
}
impl GatewayResult {
pub fn new(identity: String, owner: String, reliability: u8) -> Self {
GatewayResult {
identity,
owner,
reliability,
mix_id: 0,
}
}
}
#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum MonitorResults {
Mixnode(Vec<MixnodeResult>),
Gateway(Vec<GatewayResult>),
}
#[derive(Serialize, Deserialize, JsonSchema)]
pub struct MonitorMessage {
results: Vec<NodeResult>,
signature: String,
signer: String,
timestamp: i64,
}
impl MonitorMessage {
fn message_to_sign(results: &[NodeResult], timestamp: i64) -> Vec<u8> {
let mut msg = match serde_json::to_vec(results) {
Ok(msg) => msg,
Err(_) => Vec::new(),
};
msg.extend_from_slice(&timestamp.to_le_bytes());
msg
}
pub fn timely(&self) -> bool {
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Time went backwards")
.as_secs() as i64;
now - self.timestamp < 5
}
pub fn new(results: Vec<NodeResult>, private_key: &PrivateKey) -> Self {
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Time went backwards")
.as_secs() as i64;
let msg = Self::message_to_sign(&results, timestamp);
let signature = private_key.sign(&msg);
let public_key = private_key.public_key();
MonitorMessage {
results,
signature: signature.to_base58_string(),
signer: public_key.to_base58_string(),
timestamp,
}
}
pub fn from_allowed(&self) -> bool {
NETWORK_MONITORS.contains(&self.signer)
}
pub fn results(&self) -> &[NodeResult] {
&self.results
}
pub fn verify(&self) -> bool {
let msg = Self::message_to_sign(&self.results, self.timestamp);
let signature = match Signature::from_base58_string(&self.signature) {
Ok(sig) => sig,
Err(_) => return false,
};
PublicKey::from_base58_string(&self.signer)
.map(|pk| pk.verify(msg, &signature).is_ok())
.unwrap_or(false)
}
}
+2 -6
View File
@@ -30,13 +30,9 @@ workspace = true
optional = true
[features]
default = ["sleep", "console_error_panic_hook"]
default = ["sleep"]
sleep = ["web-sys", "web-sys/Window"]
websocket = [
"getrandom",
"tungstenite",
"gloo-net"
]
websocket = ["getrandom", "tungstenite", "gloo-net"]
crypto = [
"web-sys",
"web-sys/Crypto",
+1 -2
View File
@@ -12,7 +12,6 @@ license.workspace = true
[dependencies]
base64 = { workspace = true }
dashmap = { workspace = true }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
@@ -35,7 +34,7 @@ x25519-dalek = { workspace = true, features = ["static_secrets"] }
[dev-dependencies]
rand = "0.8.5"
nym-crypto = { path = "../crypto", features = ["rand"]}
nym-crypto = { path = "../crypto", features = ["rand"] }
[features]
+7
View File
@@ -6,10 +6,17 @@ pub mod error;
pub mod public_key;
pub mod registration;
use std::time::Duration;
pub use config::Config;
pub use error::Error;
pub use public_key::PeerPublicKey;
pub use registration::{ClientMac, ClientMessage, GatewayClient, InitMessage, Nonce};
// To avoid any problems, keep this stale check time bigger (>2x) then the bandwidth cap
// reset time (currently that one is 24h, at UTC midnight)
pub const DEFAULT_PEER_TIMEOUT: Duration = Duration::from_secs(60 * 60 * 24 * 3); // 3 days
pub const DEFAULT_PEER_TIMEOUT_CHECK: Duration = Duration::from_secs(5); // 5 seconds
#[cfg(feature = "verify")]
pub use registration::HmacSha256;
+3 -3
View File
@@ -4,8 +4,8 @@
use crate::error::Error;
use crate::PeerPublicKey;
use base64::{engine::general_purpose, Engine};
use dashmap::DashMap;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::IpAddr;
use std::time::SystemTime;
use std::{fmt, ops::Deref, str::FromStr};
@@ -17,8 +17,8 @@ use nym_crypto::asymmetric::encryption::PrivateKey;
#[cfg(feature = "verify")]
use sha2::Sha256;
pub type PendingRegistrations = DashMap<PeerPublicKey, RegistrationData>;
pub type PrivateIPs = DashMap<IpAddr, Taken>;
pub type PendingRegistrations = HashMap<PeerPublicKey, RegistrationData>;
pub type PrivateIPs = HashMap<IpAddr, Taken>;
#[cfg(feature = "verify")]
pub type HmacSha256 = Hmac<Sha256>;
+2 -1
View File
@@ -84,6 +84,7 @@ pub struct WireguardData {
#[cfg(target_os = "linux")]
pub async fn start_wireguard<St: nym_gateway_storage::Storage + 'static>(
storage: St,
all_peers: Vec<nym_gateway_storage::models::WireguardPeer>,
task_client: nym_task::TaskClient,
wireguard_data: WireguardData,
control_tx: UnboundedSender<peer_controller::PeerControlResponse>,
@@ -95,7 +96,7 @@ pub async fn start_wireguard<St: nym_gateway_storage::Storage + 'static>(
let mut peers = vec![];
let mut suspended_peers = vec![];
for storage_peer in storage.get_all_wireguard_peers().await? {
for storage_peer in all_peers {
let suspended = storage_peer.suspended;
let peer = Peer::try_from(storage_peer)?;
if suspended {
+13 -6
View File
@@ -5,19 +5,15 @@ use chrono::{Timelike, Utc};
use defguard_wireguard_rs::{host::Peer, key::Key, WireguardInterfaceApi};
use nym_gateway_storage::Storage;
use nym_wireguard_types::registration::{RemainingBandwidthData, BANDWIDTH_CAP_PER_DAY};
use nym_wireguard_types::{DEFAULT_PEER_TIMEOUT, DEFAULT_PEER_TIMEOUT_CHECK};
use std::time::SystemTime;
use std::{collections::HashMap, sync::Arc, time::Duration};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::mpsc;
use tokio_stream::{wrappers::IntervalStream, StreamExt};
use crate::error::Error;
use crate::WgApiWrapper;
// To avoid any problems, keep this stale check time bigger (>2x) then the bandwidth cap
// reset time (currently that one is 24h, at UTC midnight)
const DEFAULT_PEER_TIMEOUT: Duration = Duration::from_secs(60 * 60 * 24 * 3); // 3 days
const DEFAULT_PEER_TIMEOUT_CHECK: Duration = Duration::from_secs(60); // 1 minute
pub enum PeerControlRequest {
AddPeer(Peer),
RemovePeer(Key),
@@ -50,6 +46,7 @@ pub struct PeerController<St: Storage> {
active_peers: HashMap<Key, Peer>,
suspended_peers: HashMap<Key, Peer>,
last_seen_bandwidth: HashMap<Key, u64>,
timeout_count: u8,
}
impl<St: Storage> PeerController<St> {
@@ -82,6 +79,7 @@ impl<St: Storage> PeerController<St> {
active_peers,
suspended_peers,
last_seen_bandwidth: HashMap::new(),
timeout_count: 0,
}
}
@@ -144,6 +142,15 @@ impl<St: Storage> PeerController<St> {
.iter()
.map(|(key, peer)| (key.clone(), peer.rx_bytes + peer.tx_bytes))
.collect();
// Do in-memory updates of bandwidth every DEFAULT_PEER_TIMEOUT_CHECK
// and storage updates every 5 * DEFAULT_PEER_TIMEOUT_CHECK, because in-memory
// is more important for client query preciseness
self.timeout_count = self.timeout_count % 5 + 1;
if !reset && self.timeout_count < 5 {
return Ok(());
}
if reset {
self.active_peers = host.peers;
for peer in self.active_peers.values() {
+18 -22
View File
@@ -1,30 +1,27 @@
# Documentation
# Nym Docs v2
This is v2 of the nym docs, condensed from various mdbooks projects that we had previously.
These docs are hosted at [nymtech.net/docs](www.nymtech.net/docs).
## Doc projects
Each directory contains a readme with more information about running and contributing to the projects. Each is built with [`mdbook`](https://rust-lang.github.io/mdBook/index.html) - use `mdbook serve` to build and serve them (defaults to `localhost:3000`).
* `docs` contains technical documentation hosted at [https://nymtech.net/docs](https://nymtech.net/docs)
* `dev-portal` contains developer documentation hosted at [https://nymtech.net/developers](https://nymtech.net/developers)
* `operators` contains node setup and maintenance guides hosted at [https://nymtech.net/operators](https://nymtech.net/operators)
`docs/pages/` contains several subdirs, each hosting a subsection of the docs:
* `network` contains key concepts, cryptosystems, architecture.
* `developers` contains key concepts for developers, required architecture, and Rust/Typescript SDK docs.
* `operators` contains node setup and maintenance guides.
> If you are looking for the Typescript SDK documentation located at [sdk.nymtech.net](https://sdk.nymtech.net) this can be found in `../sdk/typescript/docs/`
## Contribution
* If you wish to add to the documentation please create a PR against this repo, with a `patch` against `develop`.
## Contribution
* If you wish to add to the documentation please create a PR against this repo.
* If you are **adding a plugin dependency** make sure to also **add that to the list of plugins in `install_mdbook_deps.sh` line 12**.
## Scripts
* There are several autogenerated command files for clients and binaries. These are generated with `generate:commands`, which runs the `autodoc` rust binary, moves the files to their required places, and then if there is an update, commits them to git. This is for remote deployments.
* TODO
## Scripts
* `bump_versions.sh` allows you to update the ~~`platform_release_version` and~~ `wallet_release_version` variable~~s~~ in the `book.toml` of each mdbook project at once. You can also optionally update the `minimum_rust_version` as well. Helpful for lazy-updating when cutting a new version of the docs.
### Autodoc
`autodoc` is a script that generates markdown files containing commands and their output (both command and `--help` output). For the moment the binaries and their commands are manually configured in the script.
* The following scripts are used by the `ci-dev.yml` and `cd-dev.yml` scripts (located in `../.github/workflows/`):
* `build_all_to_dist.sh` is used for building all mdbook projects and moving the rendered html to `../dist/` to be rsynced with various servers.
* `install_mdbook_deps.sh` checks for an existing install of mdbook (and plugins), uninstalls them, and then installs them on a clean slate. This is to avoid weird dependency clashes if relying on an existing mdbook version.
* `post_process.sh` is used to post process CSS/image/href links for serving several mdbooks from a subdirectory.
* `removed_existing_config.sh` is used to check for existing nym client/node config files on the CI/CD server and remove it if it exists. This is to mitigate issues with `mdbook-cmdrun` where e.g. a node is already initialised, and the command fails.
## CI/CD
Deployment of the docs is partially automated and partially manual.
* `ci-docs.yml` will run on pushes to all branches **apart from `master`**
* `cd-docs.yml` must be run manually. This pushes to a staging branch which then must be manually promoted to production.
## CI/CD
TODO
## Licensing and copyright information
This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files.
@@ -36,4 +33,3 @@ As a general approach, licensing is as follows this pattern:
* Nym applications and binaries are [GPL-3.0-only](https://www.gnu.org/licenses/)
* Used libraries and different components are [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.html) or [MIT](https://mit-license.org/)
+1
View File
@@ -0,0 +1 @@
/autodoc-generated-markdown/*
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "autodoc"
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
env_logger = "0.11.3"
log.workspace = true
+4
View File
@@ -0,0 +1,4 @@
# `autodoc`
Command output documentation generator WIP
+259
View File
@@ -0,0 +1,259 @@
use log::{debug, info};
use std::fs::File;
use std::io::{self, Write};
use std::process::{Command, Output};
use std::{fs, vec};
const WRITE_PATH: &str = "./autodoc-generated-markdown/";
fn main() -> io::Result<()> {
env_logger::init();
// TODO if this balloons write automated way of grabbing commands from crates.
let commands_with_subcommands = vec![
(
"../../target/release/nym-api",
vec!["init", "run", "build-info"],
),
(
"../../target/release/nym-client",
vec![
"init",
"run",
"import-credential",
"list-gateways",
"switch-gateway",
"build-info",
"completions",
"generate-fig-spec",
],
),
(
"../../target/release/nym-socks5-client",
vec![
"init",
"run",
"import-credential",
"list-gateways",
"add-gateway",
"build-info",
"completions",
"generate-fig-spec",
],
),
(
"../../target/release/nym-node",
vec![
"build-info",
"bonding-information",
"node-details",
"migrate",
"run",
"sign",
],
),
(
"../../target/release/nymvisor",
vec![
"init",
"run",
"build-info",
"daemon-build-info",
"add-upgrade",
"config",
],
),
];
let commands_with_subsubcommands = vec![(
"../../target/release/nym-cli",
vec![
(
"account",
vec!["create", "balance", "pub-key", "send", "send-multiple"],
),
("signature", vec!["sign", "verify"]),
(
"ecash",
vec![
"issue-ticket-book",
"recover-ticket-book",
"import-ticket-book",
],
),
(
"coconut",
vec![
"generate-freepass",
"issue-credentials",
"recover-credentials",
"import-credential",
],
),
("block", vec!["get", "time", "current-height"]),
(
"cosmwasm",
vec![
"upload",
"init",
"generate-init-message",
"migrate",
"execute",
],
),
("tx", vec!["get", "query"]),
(
"vesting-schedule",
vec!["create", "query", "vested-balance", "withdraw-vested"],
),
("mixnet", vec!["query", "delegators", "operators"]),
("generate-fig", vec![""]),
],
)];
for (main_command, subcommands) in commands_with_subcommands {
let last_word = get_last_word_from_filepath(main_command);
debug!("now running {last_word:#?}");
if !fs::metadata(WRITE_PATH)
.map(|metadata| metadata.is_dir())
.unwrap_or(false)
{
fs::create_dir_all(WRITE_PATH)?;
}
let mut file = File::create(format!("{}/{}-commands.md", WRITE_PATH, last_word.unwrap()))?;
writeln!(
file,
"# {} Binary Commands (Autogenerated)",
format!("`{}`", last_word.unwrap())
)?;
writeln!(
file,
"\nThese docs are autogenerated by the [`autodocs`](https://github.com/nymtech/nym/tree/max/new-docs-framework/documentation/autodoc) script."
)?;
let output = Command::new(main_command).arg("--help").output()?;
write_output_to_file(&mut file, output)?;
for subcommand in subcommands {
execute_command(&mut file, main_command, subcommand, None)?;
}
}
// nym-cli has subsubcommands so needs its own loop
for (main_command, subcommands) in &commands_with_subsubcommands {
let last_word = get_last_word_from_filepath(main_command);
debug!("now running {last_word:#?}");
let mut file = File::create(format!("{}/{}-commands.md", WRITE_PATH, last_word.unwrap()))?;
writeln!(
file,
"# {} Binary Commands (Autogenerated)",
format!("`{}`", last_word.unwrap())
)?;
writeln!(
file,
"\nThese docs are autogenerated by the [`autodocs`](https://github.com/nymtech/nym/tree/max/new-docs-framework/documentation/autodoc) script."
)?;
let output = Command::new(main_command).arg("--help").output()?;
write_output_to_file(&mut file, output)?;
for (subcommand, subsubcommands) in subcommands {
writeln!(file, "\n## `{}` ", subcommand)?;
let output = Command::new(main_command)
.arg(subcommand)
.arg("--help")
.output()?;
if !output.stdout.is_empty() {
write_output_to_file(&mut file, output)?;
} else {
debug!("empty stdout - nothing to write");
}
for subsubcommand in subsubcommands {
execute_command(&mut file, main_command, subcommand, Some(subsubcommand))?;
}
}
}
Ok(())
}
fn get_last_word_from_filepath(filepath: &str) -> Option<&str> {
let parts: Vec<&str> = filepath.split('/').collect();
parts.last().copied()
}
fn execute_command(
file: &mut File,
main_command: &str,
subcommand: &str,
subsubcommand: Option<&str>,
) -> io::Result<()> {
// checking for the nym-cli subsubcommands
if subsubcommand.is_some() {
writeln!(file, "\n### `{} {}`", subcommand, subsubcommand.unwrap())?;
info!("executing {} {} --help ", main_command, subcommand);
let output = Command::new(main_command)
.arg(subcommand)
.arg(subsubcommand.unwrap())
.arg("--help")
.output()?;
if !output.stdout.is_empty() {
write_output_to_file(file, output)?;
} else {
debug!("empty stdout - nothing to write");
}
// just subcommands
} else {
writeln!(file, "\n### `{}`", subcommand)?;
// execute help
let output = Command::new(main_command)
.arg(subcommand)
.arg("--help")
.output()?;
if !output.stdout.is_empty() {
write_output_to_file(file, output)?;
} else {
debug!("empty stdout - nothing to write");
}
// then execute w/out help: the majority of functions will fail since you're not passing
// required params but thats fine as we can just not render stderr into the final file.
//
// this check is basically checking for the rare commands (rn just one) that start a process with no params
// perhaps if this list grows we could just add a timeout and shunt the running and writing
// into a thread with a timeout or something but for right now its fine / thats overkill
if get_last_word_from_filepath(main_command).unwrap() == "nym-node"
|| get_last_word_from_filepath(main_command).unwrap() == "nym-api"
|| get_last_word_from_filepath(main_command).unwrap() == "nymvisor"
&& subcommand == "run"
{
info!("SKIPPING {} {}", main_command, subcommand);
} else {
info!("executing {} {}", main_command, subcommand);
let output = Command::new(main_command).arg(subcommand).output()?;
if !output.stdout.is_empty() {
writeln!(file, "Example output:")?;
write_output_to_file(file, output)?;
} else {
debug!("empty stdout - nothing to write");
if !&output.stderr.is_empty() {
debug!("stderr: {:#?}", String::from_utf8_lossy(&output.stderr));
}
}
}
}
Ok(())
}
fn write_output_to_file(file: &mut File, output: Output) -> io::Result<()> {
writeln!(file, "```sh")?;
file.write_all(&output.stdout)?;
writeln!(file, "```")?;
if !&output.stderr.is_empty() {
debug!("stderr: {:#?}", String::from_utf8_lossy(&output.stderr));
}
Ok(())
}
-51
View File
@@ -1,51 +0,0 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
# this is a script called by the github CI and CD workflows to build all 3 docs projects
# and move them to /dist/ in the root of the monorepo. They are rsynced to various servers
# from there by subsequent workflow tasks.
# array of project dirs
declare -a projects=("docs" "dev-portal" "operators")
# check you're calling from the right place
if [ $(pwd | awk -F/ '{print $NF}') != "documentation" ]
then
echo "failure: please run script from documentation/"
else
for i in "${projects[@]}"
do
# cd to project dir
cd "./$i" &&
# little sanity checks
echo $(pwd) && echo $(mdbook --version) &&
# clean old book
echo "cleaning old book"
rm -rf ./book/
# build book
# mdbook test || true
mdbook build
# check for destination, if ! then mkdir & check again else echo thumbs up
if [ ! -d ../../dist/docs/$i ]; then
echo "dest doesn't exist: creating dir"
mkdir -p ../../dist/docs/$i
fi
if [ -d ../../dist/docs/$i ]; then
echo "cp destination exists, all good"
fi
# clean old dist/$i
rm -rf ../../dist/docs/$i
# move newly rendered book/ to dist
rsync -r ./book/html/ ../../dist/docs/$i
# sanity check
ls -laF ../../dist/docs/
# cd back to ../documentation/
cd ../
done
# rename for server paths
rm -rf ../dist/docs/developers
mv ../dist/docs/dev-portal ../dist/docs/developers
fi
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
# takes one manadatory arg and one optional arg: wallet release and minimum rust versions
# it then uses sed to bump them in the three book.toml files.
#
# e.g if the upcoming wallet release version was 1.2.9 you'd run this as:
# `./bump_versions.sh "1.2.9"`
#
# you can also set the minumum rust version by passing an optional additional argument:
# `./bump_versions.sh "1.2.9" "1.67"`
# array of project dirs
declare -a projects=("docs" "dev-portal" "operators")
# check number of args passed
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ];
then
echo "failure: please pass at least 1 and at most 2 args: "
echo "./bump_version.sh <new wallet_release_version> [OPTIONAL]<new minimum_rust_version>"
exit 0
fi
# check you're calling from the right place
if [ $(pwd | awk -F/ '{print $NF}') != "documentation" ]
then
echo "failure: please run script from documentation/"
exit 0
else
## now loop through the above array sed-ing the variable values in the book.toml files
for i in "${projects[@]}"
do
# sed the vars in the book.toml file for each project
echo "setting wallet version in $i/"
sed -i 's/wallet_release_version =.*/wallet_release_version = "'$2'"/' "$i"/book.toml
if [ "$3" ]
then
echo "setting minimum rust version in $i/"
sed -i 's/minimum_rust_version = .*/minimum_rust_version = "'$3'"/' "$i"/book.toml
fi
done
fi
+5 -13
View File
@@ -1,14 +1,6 @@
# mdbook files
book/
# Compiled assets
.sass-cache
_site
# Developing
todo.md
.idea
# OSX
.DS_Store
.next
node_modules
out
# the lock file will break Vercel because it may get committed from a machine with a different build architecture
package-lock.json
+25 -27
View File
@@ -1,42 +1,40 @@
# Nym Documentation
Documentation for the Nym privacy platform built using the [mdBook](https://rust-lang.github.io/mdBook/) docs framework.
# Nym Docs v2
Documentation can be viewed at https://nymtech.net/docs
New consolidated version of the nym docs.
## Contributing
Contributions to our documentation are very welcome. Please work on your contribution in either a `feature/<feature-name>` or `chore/<chore-name>` branch from `master` and target your pull request at `master`.
## Local development
Since these docs autogenerate command output and import docs from binaries in `target/release` on `build` make sure you're branching off of `master` when making your branch.
```
npm i
npm run dev
```
Changes merged to `master` will be autodeployed to the production site.
Open `http://localhost:3000` to browse the output that will hot-reload when you make changes.
### Contributing a new translation
To contribute tranlsations in a new language, please get in touch via [Matrix](https://matrix.to/#/#general:nymtech.chat) or [Discord](https://nymtech.net/go/discord).
If you are cutting a new version with binaries that have updated commands (and you have updated the command list in `autodocs`) run:
### Variables
There are some variables that are shared across the entire docs site, such as the current latest software version.
```
npm generate:commands
```
Variables are denoted in the `.md` files wrapped in `{{}}` (e.g `{{wallet_release_version}}`), and are located in the `book.toml` file under the `[preprocessor.variables.variables]` heading. If you are changing something like the software release version, minimum code versions in prerequisites, etc, **check in here first!**
This will regenerate the md command files for the binaries, move them into position, and then commit them to the branch head.
### Diagrams
Most diagrams are simply ascii. Copies are kept in `/diagrams/` for ease of reproducability. Created using [textik](https://textik.com/#).
## Build
### Importing files and auto-generated command output
```
npm run build
```
Example files are inserted as per normal with mdbook.
The static output will be in `./out`;
Some binary command outputs are generated using the [`cmdrun`](https://docs.rs/mdbook-cmdrun/latest/mdbook_cmdrun/) mdbook plugin.
If you are cutting a new version with binaries that have updated commands (and you have updated the command list in `autodocs`) **run this first**:
## Building
When working locally, it is recommended that you use `mdbook serve` to have a local version of the docs served on `localhost:3000`, with hot reloading on any changes made to files in the `src/` directory.
```
npm generate:commands
```
You can find other commands in the [mdBook CLI tool docs](https://rust-lang.github.io/mdBook/cli/index.html).
This will regenerate the md command files for the binaries, move them into position, and then commit them to the branch head.
### I tried to edit files in `theme/` and they aren't taking effect / `mdbook serve` causes a looping reload on file changes after changing fields in `[preprocessor.theme]` config
## Template details
Looping reload is a known issue with the `mdbook-theme` preprocessor used for the table of contents and layout of these docs. As outlined in the `mdbook-theme` [readme](https://github.com/zjp-CN/mdbook-theme#avoid-repeating-call-on-this-tool-when-mdbook-watch) one way to mitigate this is to set `turn-off = true` under `[preprocessor.theme]`. This means that `mdbook serve` or `mdbook watch` ignores changes to the `theme/` directory, which is the source of the looping reload. If you have changed or commented out this line, reintroduce it to remove the looping reload. If you are trying to edit the theme of the docs and want to apply the change, see [here](https://github.com/zjp-CN/mdbook-theme#avoid-repeating-call-on-this-tool-when-mdbook-watch) for more info on how to remove the block, change the theme, and reintroduce the block.
### Checking the mdBook version
To check the version of mdBook installed on your system, you can use the `mdbook --version` command. This will print the version number of mdBook installed on your system in the terminal.
The latest release of the binary of the pre-compiled binaries can be found on [GitHub](https://github.com/rust-lang/mdBook/releases).
This documentation was made with [Nextra](https://nextra.site) using the template from here https://github.com/shuding/nextra-docs-template.
@@ -0,0 +1,5 @@
import { Tabs } from 'nextra/components';
export const MyTab = ({ name, children }) => (
<Tabs.Tab>{name} {children}</Tabs.Tab>
);
@@ -0,0 +1,158 @@
import React from "react";
import { Box, Grid, Typography } from "@mui/material";
import Image from "next/image";
import Link from "next/link";
import networkDocs from "../public/images/landing/network-docs.png";
import developerDocs from "../public/images/landing/developer-docs.png";
import sdkDocs from "../public/images/landing/sdk-docs.png";
import operatorGuide from "../public/images/landing/operator-guide.png";
export const LandingPage = () => {
const squares = [
{
text: "Network Docs",
description: "Architecture, crypto systems, and how the Mixnet works",
href: "/network",
icon: developerDocs,
},
{
text: "Operator Guides",
description:
"Guides and maintenance: if you want to run a node, start here",
href: "/operators/introduction",
icon: operatorGuide,
},
{
text: "Developer Portal",
description:
"Conceptual overview, clients, and tools for developers and integrations",
href: "/developers",
icon: networkDocs,
},
{
text: "SDKs",
description: "Rust and Typescript SDK docs",
href: "/developers/rust",
icon: sdkDocs,
},
];
return (
<Box maxWidth={1200} margin={"0 auto"}>
<Typography variant="h2" mb={6}>
Nym Docs
</Typography>
<Typography mb={10}>
Nym is a privacy platform. It provides strong network-level privacy
against sophisticated end-to-end attackers, and anonymous access control
using blinded, re-randomizable, decentralized credentials. Our goal is
to allow developers to build new applications, or upgrade existing apps,
with privacy features unavailable in other systems.
</Typography>
<Grid container border={"1px solid #262626"}>
{squares.map((square, index) => (
<Grid
item
key={index}
xs={12}
md={6}
padding={4}
width={"100%"}
sx={{
borderBottom: {
xs: index < 3 ? "1px solid #262626" : "none",
md: index === 0 || index === 1 ? "1px solid #262626" : "none",
},
borderRight: {
md: index === 0 || index === 2 ? "1px solid #262626" : "none",
},
}}
>
<Link href={square.href} target="_blank" rel="noopener noreferrer">
<Box display={"flex"} gap={4} height={"100%"}>
<Image
src={square.icon}
alt={square.text}
width={180}
height={134}
/>
<Box
display={"flex"}
flexDirection={"column"}
justifyContent={"space-between"}
flexGrow={1}
height={"100%"}
>
<Typography variant="h5" sx={{ fontWeight: 600 }}>
{square.text}
</Typography>
<Typography variant="body1" sx={{ color: "#909195" }}>
{square.description}
</Typography>
<Typography sx={{ color: "#ff6600", fontWeight: 600 }}>
Open
</Typography>
</Box>
</Box>
</Link>
</Grid>
))}
</Grid>
<style jsx>{`
.landing-page-container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
}
.landing-page-intro {
font-size: 1.125rem;
margin-bottom: 2rem;
}
.landing-page-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
max-width: 36rem;
margin: 0 auto;
}
.landing-page-square {
background-color: #000000;
color: white;
padding: 1rem;
border-radius: 0.5rem;
text-align: center;
cursor: pointer;
text-decoration: none;
transition: box-shadow 0.3s ease;
aspect-ratio: 1 / 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 3px solid #ff6600;
box-shadow: 0 0 10px #ff6600;
}
.landing-page-square:hover {
box-shadow: 0 0 20px #ff6600;
}
.landing-page-icon {
width: 12.5rem;
height: 12.5rem;
margin-bottom: 0.75rem;
color: #ff6600;
}
.landing-page-text {
font-size: 0.875rem;
font-weight: 600;
color: #ff6600;
}
`}</style>
</Box>
);
};
@@ -0,0 +1,15 @@
import { Box } from "@mui/material";
import Image from "next/image";
import Link from "next/link";
import matrixLogo from "../public/images/matrix-logo.png";
export const Matrix = () => {
return (
<Link
href={"https://matrix.to/#/#dev:nymtech.chat"}
target="_blank"
rel="noopener noreferrer"
>
<Image src={matrixLogo} alt={"Matrix Logo"} width={20} height={24} />
</Link>
);
};
@@ -1,26 +1,25 @@
import React, { useState } from 'react';
import CircularProgress from '@mui/material/CircularProgress';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import { mixFetch } from '@nymproject/mix-fetch-full-fat';
import Stack from '@mui/material/Stack';
import Paper from '@mui/material/Paper';
import type { SetupMixFetchOps } from '@nymproject/mix-fetch-full-fat';
import React, { useState } from "react";
import CircularProgress from "@mui/material/CircularProgress";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
import { mixFetch } from "@nymproject/mix-fetch-full-fat";
import Stack from "@mui/material/Stack";
import Paper from "@mui/material/Paper";
import type { SetupMixFetchOps } from "@nymproject/mix-fetch-full-fat";
const defaultUrl = 'https://nymtech.net/favicon.svg';
const args = { mode: 'unsafe-ignore-cors' };
const defaultUrl = "https://nymtech.net/favicon.svg";
const args = { mode: "unsafe-ignore-cors" };
const mixFetchOptions: SetupMixFetchOps = {
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
preferredGateway: "6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B", // with WSS
preferredNetworkRequester:
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
"8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B",
mixFetchOverride: {
requestTimeoutMs: 60_000,
},
forceTls: true, // force WSS
extra: {},
};
export const MixFetch = () => {
@@ -44,7 +43,7 @@ export const MixFetch = () => {
};
return (
<div style={{ marginTop: '1rem' }}>
<div style={{ marginTop: "1rem" }}>
<Stack direction="row">
<TextField
disabled={busy}
@@ -55,7 +54,12 @@ export const MixFetch = () => {
defaultValue={defaultUrl}
onChange={(e) => setUrl(e.target.value)}
/>
<Button variant="outlined" disabled={busy} sx={{ marginLeft: '1rem' }} onClick={handleFetch}>
<Button
variant="outlined"
disabled={busy}
sx={{ marginLeft: "1rem" }}
onClick={handleFetch}
>
Fetch
</Button>
</Stack>
@@ -0,0 +1,20 @@
import {Accordion, AccordionItem} from "@nextui-org/react";
export const App = () => {
const defaultContent =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.";
return (
<Accordion variant="shadow">
<AccordionItem key="1" aria-label="Accordion 1" title="Accordion 1">
{defaultContent}
</AccordionItem>
<AccordionItem key="2" aria-label="Accordion 2" title="Accordion 2">
{defaultContent}
</AccordionItem>
<AccordionItem key="3" aria-label="Accordion 3" title="Accordion 3">
{defaultContent}
</AccordionItem>
</Accordion>
);
}
@@ -0,0 +1,18 @@
import { Tabs } from 'nextra/components';
import Mixnodes from 'components/operators/snippets/mixnode-migrate-tab-snippet.mdx';
import Gateways from 'components/operators/snippets/gateway-migrate-tab-snippet.mdx'
export const MigrateTabs = () => {
return (
<div>
<Tabs items={[
<code>nym-mixnode</code>,
<code>nym-gateway</code>
]} defaultIndex="1">
<Tabs.Tab><Mixnodes/></Tabs.Tab>
<Tabs.Tab><Gateways/></Tabs.Tab>
</Tabs>
</div>
)
}
@@ -0,0 +1,21 @@
import { Tabs } from 'nextra/components';
import Mixnodes from 'components/operators/snippets/mixnode-run-tab-snippet.mdx';
import EntryGateway from 'components/operators/snippets/entry-gateway-run-tab-snippet.mdx';
import ExitGateway from 'components/operators/snippets/exit-gateway-run-tab-snippet.mdx';
export const RunTabs = () => {
return (
<div>
<Tabs items={[
<code>mixnode</code>,
<code>exit-gateway</code>,
<code>entry-gateway</code>
]} defaultIndex="1">
<Tabs.Tab><Mixnodes/></Tabs.Tab>
<Tabs.Tab><ExitGateway/></Tabs.Tab>
<Tabs.Tab><EntryGateway/></Tabs.Tab>
</Tabs>
</div>
)
}
@@ -0,0 +1,34 @@
<>
If you run a `nym-node` for the first time, you will need to specify a few parameters, please read the section [Essential Parameters & Variables](#essential-paramteters--varibles) before you start and make sure that your `nym-node` is up to date with the [latest version](https://github.com/nymtech/nym/releases/).
**Initialise and run:**
To initialise and test run with yur node with all needed options, use this command:
```sh
./nym-node run --id <ID> --mode entry-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<HOSTNAME>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <LOCATION> --accept-operator-terms-and-conditions --wireguard-enabled true
```
If you prefer to have a generic local identifier set to `default-nym-node`, skip `--id` option.
We highly recommend to setup [reverse proxy and WSS](proxy-configuration.md) for `nym-node`. If you haven't configured any of that, skip `--hostname` flag.
In any case `--public-ips` is a necessity for your node to bond to API and communicate with the internet.
**Initialise only** without running the node with `--init-only` command :
Adding `--init-only` option results in `nym-node` initialising a configuration file `config.toml` without running - a good option for an initial node setup. Remember that if you using this flag on a node which already has a config file, this will not over-write the values, unless used with a specified flag `--write-changes` (`-w`) - a good option for introducing changes to your `config.toml` file.
```sh
./nym-node run --id <ID> --init-only --mode entry-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<HOSTNAME>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <LOCATION> --wireguard-enabled true
```
In the example above we dropped `--accept-operator-terms-and-conditions` as the flag must be added to a running command explicitly and it is not stored in the config, `--init-only` will not run the node.
**Deny init**
`--deny-init` was introduced as an additional safety for migration from legacy binaries to `nym-node` to prevent operators initialise over existing nodes. For most of the operators, this flag is not needed.
In this example we run the node with custom `--id` without initialising, using `--deny-init` command:
```sh
./nym-node run --id <ID> --deny-init --mode entry-gateway --accept-operator-terms-and-conditions
```
</>
@@ -0,0 +1,35 @@
<>
If you run a `nym-node` for the first time, you will need to specify a few parameters, please read the section [Essential Parameters & Variables](#essential-paramteters--varibles) before you start and make sure that your `nym-node` is up to date with the [latest version](https://github.com/nymtech/nym/releases/).
**Initialise and Run**
To initialise and test run your node, use this command:
```sh
./nym-node run --id <ID> --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<HOSTNAME>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <LOCATION> --accept-operator-terms-and-conditions --wireguard-enabled true
```
If you prefer to have a generic local identifier set to `default-nym-node`, skip `--id` option.
We highly recommend to setup [reverse proxy and WSS](proxy-configuration.md) for `nym-node`. If you haven't configured any of that, skip `--hostname` flag.
In any case `--public-ips` is a necessity for your node to bond to API and communicate with the internet.
**Initialise only** without running the node with `--init-only` command:
Adding `--init-only` option results in `nym-node` initialising a configuration file `config.toml` without running - a good option for an initial node setup. Remember that if you using this flag on a node which already has a config file, this will not over-write the values, unless used with a specified flag `--write-changes` (`-w`) - a good option for introducing changes to your `config.toml` file.
```sh
./nym-node run --id <ID> --init-only --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<HOSTNAME>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <LOCATION> --wireguard-enabled true
```
In the example above we dropped `--accept-operator-terms-and-conditions` as the flag must be added to a running command explicitly and it is not stored in the config, `--init-only` will not run the node.
**Deny init**
`--deny-init` was introduced as an additional safety for migration from legacy binaries to `nym-node` to prevent operators initialise over existing nodes. For most of the operators, this flag is not needed.
In this example we run the node with custom `--id` without initialising, using `--deny-init` command:
```sh
./nym-node run --id <ID> --deny-init --mode exit-gateway --accept-operator-terms-and-conditions
```
</>
@@ -0,0 +1,23 @@
import { Steps } from 'nextra/components';
<>
Migrate your `nym-gateway` to `nym-node --mode entry-gateway` or `--mode exit-gateway` using these commands:
<Steps>
###### 1. Move relevant info from `config.toml`
```sh
./nym-node migrate --config-file ~/.nym/gateways/<GATEWAY_ID>/config/config.toml gateway
```
###### 2. Initialise with new `nym-node` config chosing one of the options below:
- as `entry-gateway`:
```sh
./nym-node run --id <ID> --mode entry-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname <HOSTNAME> --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <LOCATION> --accept-operator-terms-and-conditions --wireguard-enabled true
```
- or as `exit-gateway`:
```sh
./nym-node run --id <ID> --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname <HOSTNAME> --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <LOCATION> --accept-operator-terms-and-conditions --wireguard-enabled true
```
</Steps>
</>
@@ -0,0 +1,16 @@
import { Steps } from 'nextra/components';
<>
Migrate your `nym-mixnode` to `nym-node --mode mixnode` using these commands:
<Steps>
###### 1. Move relevant info from `config.toml`
```sh
./nym-node migrate --config-file ~/.nym/mixnodes/<ID>/config/config.toml mixnode
```
###### 2. Initialise with new `nym-node` config
```sh
./nym-node run --mode mixnode --id <ID> --location <LOCATION> --mixnet-bind-address 0.0.0.0:1789 --http-bind-address 0.0.0.0:8080 --accept-operator-terms-and-conditions
```
</Steps>
</>
@@ -0,0 +1,31 @@
<>
If you run a `nym-node` for the first time, you will need to specify a few parameters, please read the section [Essential Parameters & Variables](#essential-paramteters--varibles) before you start and make sure that your `nym-node` is up to date with the [latest version](https://github.com/nymtech/nym/releases/).
**Initialise and Run:**
To initialise and run your node, use this command:
```sh
./nym-node run --mode mixnode --mixnet-bind-address 0.0.0.0:1789 --verloc-bind-address 0.0.0.0:1790 --http-bind-address 0.0.0.0:8080 --public-ips "$(curl -4 https://ifconfig.me)" --accept-operator-terms-and-conditions
```
**Init only**
Adding `--init-only` option results in `nym-node` initialising a configuration file `config.toml` without running - a good option for an initial node setup. Remember that if you using this flag on a node which already has a config file, this will not over-write the values, unless used with a specified flag `--write-changes` (`-w`) - a good option for introducing changes to your `config.toml` file.
Initialise only with a custom `--id` and `--init-only` command:
```sh
./nym-node run --mode mixnode --id <ID> --init-only --mixnet-bind-address 0.0.0.0:1789 --verloc-bind-address 0.0.0.0:1790 --http-bind-address 0.0.0.0:8080 --public-ips "$(curl -4 https://ifconfig.me)" --accept-operator-terms-and-conditions
```
If you prefer to have a generic local identifier set to `default-nym-node`, skip `--id` option.
**Deny init**
`--deny-init` was introduced as an additional safety for migration from legacy binaries to `nym-node` to prevent operators initialise over existing nodes. For most of the operators, this flag is not needed.
In this example we run the node with custom `--id` without initialising, using `--deny-init` command:
```sh
./nym-node run --mode mixnode --id <ID> --deny-init --accept-operator-terms-and-conditions
```
</>
@@ -0,0 +1,13 @@
Open the needed ports for `nym-node` by running these commands:
```sh
ufw allow 22/tcp # SSH - you're in control of these ports
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow 1789/tcp # Nym specific
ufw allow 1790/tcp # Nym specific
ufw allow 8080/tcp # Nym specific - nym-node-api
ufw allow 9000/tcp # Nym Specific - clients port
ufw allow 9001/tcp # Nym specific - wss port
ufw allow 51822/udp # WireGuard
```
@@ -0,0 +1,10 @@
Open the needed ports for `validator` by running these commands:
```sh
ufw allow 1317 # REST API server endpoint
ufw allow 26656 # Listen for incoming peer connections
ufw allow 26660 # Listen for Prometheus connections
ufw allow 22 # SSH port
ufw allow 80 # http port
ufw allow 443/tcp # https port
```
@@ -0,0 +1,7 @@
import { Callout } from 'nextra/components';
If you want to bond or upgrade your `nym-node` via the CLI, then check out the [relevant section in the Nym CLI](https://nymtech.net/docs/tools/nym-cli.html#upgrade-a-mix-node) docs.
<Callout>
If you run in mode `--entry-gateway` or `--exit-gateway`, visit [Nym Harbour Master](https://harbourmaster.nymtech.net/) to get all the probe info about your node directly from API.
</Callout>
@@ -0,0 +1,9 @@
- Open your Desktop wallet
- Navigate to the `Bonding` page and click the `Node Settings` link in the top right corner
![](/images/operators/wallet-screenshots/bonding.png)
- Update the fields in the `Node Settings` page (usually the field `Version` is the only one to change) and click `Submit changes to the blockchain`.
![](/images/operators/wallet-screenshots/node_settings.png)
@@ -0,0 +1,6 @@
import { Callout } from 'nextra/components'
<Callout type="info" emoji="️">
Our documentation often refer to syntax annotated in `<>` brackets. We use this expression for variables that are unique to each user (like path, local moniker, versions etcetra).
Any syntax in `<>` brackets needs to be substituted with your correct name or version, without the `<>` brackets. If you are unsure, please check our table of essential [parameters and variables](https://nymtech.net/docs/operators/variables.html).
</Callout>
@@ -0,0 +1,10 @@
import VariableInfo from './snippets-general/varible-info-snippet.mdx';
export const VarInfo = () => {
return (
<div>
<VariableInfo/ >
</div>
)
}

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