Compare commits
516 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 846d1e54d0 | |||
| b195fb09bb | |||
| c4fee9ba4c | |||
| c495f35eff | |||
| c4324640e2 | |||
| 3a8b79e3e5 | |||
| 05bcdc073b | |||
| 7c48a198e3 | |||
| e7a8db432d | |||
| d20e675209 | |||
| 254ae1dc14 | |||
| 80894dc5c9 | |||
| 24c9843889 | |||
| 5fd0fb9bd8 | |||
| 3a7f850840 | |||
| e6e74855af | |||
| a56068e28a | |||
| d309b44ad7 | |||
| 22539c3e7d | |||
| edde411568 | |||
| 75f2fb7039 | |||
| f768c8e8e2 | |||
| 200efebc37 | |||
| a429d6528e | |||
| ebed210de2 | |||
| d062524d32 | |||
| f1d3c33391 | |||
| 89eea3100e | |||
| d893c806c2 | |||
| 7846058802 | |||
| 42fbb6684d | |||
| f705884a53 | |||
| 2f55c031da | |||
| a9eb6052ff | |||
| 3bc7ced2cf | |||
| 8abcc58055 | |||
| 76ff03b248 | |||
| ccf3420aab | |||
| 5df76ea2a9 | |||
| 33992542b1 | |||
| a95ee3f334 | |||
| 0a92f04048 | |||
| 368b105e27 | |||
| 813cbda891 | |||
| a8af641ec4 | |||
| f41a2d3a99 | |||
| a3b7cb52c9 | |||
| 60846b57f6 | |||
| 8ed09d74b3 | |||
| cd52bc577c | |||
| ed021ff467 | |||
| 4f67998127 | |||
| d06a8e0b21 | |||
| 3f05c0d4b9 | |||
| 1a37e60483 | |||
| 19775cf917 | |||
| 0abc07c96f | |||
| fbfeacf539 | |||
| e1583daaa3 | |||
| e904627513 | |||
| 04664c8ae1 | |||
| 4da68438c0 | |||
| 05c1554109 | |||
| 2b83442a6d | |||
| f982cb49c2 | |||
| 0c05727e58 | |||
| 3c432ac073 | |||
| 52ffd2e798 | |||
| be8c7b4953 | |||
| 8e4bc12b87 | |||
| 4895820985 | |||
| 8500618fe9 | |||
| a5b390b98f | |||
| ff66674f61 | |||
| a7cf34e812 | |||
| a85dad6bd7 | |||
| 5b8a14f74b | |||
| 730c2efea6 | |||
| c9d6a8cc25 | |||
| 230b2b1784 | |||
| e4e9615535 | |||
| a19ee8f2aa | |||
| abfc68108a | |||
| 7bf1adff28 | |||
| ed90e358fb | |||
| c7d0e26946 | |||
| 8d65c25986 | |||
| a143d5f4f6 | |||
| c041d11673 | |||
| 82e82943aa | |||
| e4fd87be2c | |||
| 19ffe217f1 | |||
| 079bfa52e7 | |||
| be9a2c26e7 | |||
| d6f3eb6411 | |||
| 144f3bed9c | |||
| c1174e64d4 | |||
| 312ecbe4dc | |||
| d2afa587e4 | |||
| 224c4c1870 | |||
| 3f8abdb74f | |||
| 0f6ec8610e | |||
| 3baac1292d | |||
| c3b8c4b2f7 | |||
| 271b9e545c | |||
| 9641f01670 | |||
| a7bb3e8d91 | |||
| dc88650d6d | |||
| 79ce611d21 | |||
| 960e817b8f | |||
| 8b03e66ba7 | |||
| 6a35581299 | |||
| ce124a29a7 | |||
| f62d8813e0 | |||
| a9cf016af2 | |||
| a8403b585b | |||
| e9a7b48da0 | |||
| 66792f57ed | |||
| f8d863249e | |||
| 7d59a2477a | |||
| eca88b0fa4 | |||
| b80a4c8614 | |||
| ec5d342e3a | |||
| 6565655861 | |||
| 5aba886f14 | |||
| 3ee73d541e | |||
| 4588a3036e | |||
| 6194ac07b8 | |||
| a7fcfef5a3 | |||
| fa927b82d8 | |||
| f724478763 | |||
| 040f4f2500 | |||
| 63002e784a | |||
| 4a0b683b70 | |||
| 9e84b1f0c1 | |||
| bf031ad6de | |||
| 933769401c | |||
| ddd85704bb | |||
| 17860c809f | |||
| 2d00fcd934 | |||
| c2c3df98cb | |||
| f429092e21 | |||
| d7ef68d8d1 | |||
| 1a334b575d | |||
| 2126736aff | |||
| a69aa23609 | |||
| 8a2d98e3ce | |||
| 9c4243914e | |||
| 143ede268d | |||
| 81bddb5f6d | |||
| 247ebb7c43 | |||
| 01c052e9a4 | |||
| 3880971e57 | |||
| 6bd31b9521 | |||
| 430c33eb04 | |||
| d45d1eb313 | |||
| 3cb3ebd79b | |||
| b42e5b063e | |||
| f6b30d0db6 | |||
| c33e4c0836 | |||
| be92ccf0da | |||
| 35bf49c48c | |||
| 7335a3dad4 | |||
| 698883c03f | |||
| 8ddef08c72 | |||
| 0d8b3abc6f | |||
| aa2f336904 | |||
| eacaf84430 | |||
| c284b1e8b1 | |||
| 7785d085cf | |||
| bb5b2eafcf | |||
| 09ea406c02 | |||
| 681c054890 | |||
| f623bbd57c | |||
| 8c6f84b3fe | |||
| 27dc9c8024 | |||
| 42d559bc69 | |||
| 41b9b0e5bd | |||
| 6c781a0064 | |||
| 080ec80722 | |||
| 9c17239831 | |||
| f6c19ec02b | |||
| 94ff8a79ee | |||
| 155c4d37ef | |||
| 7060fa6dad | |||
| 9be9c04f52 | |||
| 2a6fe6624d | |||
| 4f7124e661 | |||
| f52f07f6ec | |||
| b709d3ba0b | |||
| 128f69a5d6 | |||
| 40dd7dc95e | |||
| f13ce6bf2d | |||
| 856dbfe1ac | |||
| b2f6836756 | |||
| 87e429d78a | |||
| 4178809555 | |||
| e6f6e1342f | |||
| 65175fee09 | |||
| 69b2448500 | |||
| 8ba5322997 | |||
| 2cb3817b2c | |||
| 80b395cd8e | |||
| 8f5457e698 | |||
| 9de5d7213a | |||
| 94eb362a71 | |||
| 0f615f48f2 | |||
| d511611641 | |||
| 26f97d3c34 | |||
| 17d3ff2d77 | |||
| dd3dcfa7fe | |||
| 86ea2d23cb | |||
| 42a37442e8 | |||
| 6b24f081e1 | |||
| 6e5d0dac1b | |||
| d4d576f363 | |||
| 63a8f96ea5 | |||
| 5f2740bf66 | |||
| ecb15034d3 | |||
| bd49c222a3 | |||
| 50b044a100 | |||
| ba645694d4 | |||
| be44811a65 | |||
| 62e1d32e4f | |||
| 9a4bbe1d67 | |||
| 98090d18b4 | |||
| 79f8066c13 | |||
| d0209766a3 | |||
| 844030091f | |||
| a7a421b006 | |||
| 6680fbd61a | |||
| fe2d21cf88 | |||
| eeaca9fc10 | |||
| 7255f79b9c | |||
| 589069504a | |||
| 4da7bc7442 | |||
| 35be8de9f1 | |||
| 2b14a9e6f8 | |||
| e9269da897 | |||
| 7bceeadf16 | |||
| e72ce8fa92 | |||
| 1ccdd5d660 | |||
| c6d38d3c4f | |||
| e8e2bf107f | |||
| efe4e5c1c1 | |||
| 2230609a72 | |||
| 6d80c37b21 | |||
| cb8b4c56af | |||
| 4d486abfef | |||
| b694845e4c | |||
| 5cb2800d15 | |||
| fd14394958 | |||
| 134883522d | |||
| 0d397ab5cc | |||
| 221e01e9b8 | |||
| dcc48db301 | |||
| 7528109693 | |||
| 203d682f2c | |||
| 589575eed8 | |||
| 35bf1cc717 | |||
| f5e02d5652 | |||
| 2fc641a7ff | |||
| 0ccca19cc2 | |||
| a07e567eb2 | |||
| f3400a0aa5 | |||
| bf8614a545 | |||
| b7e3687757 | |||
| b9b969b7d3 | |||
| 47303e5b3b | |||
| 6b38ffd4f3 | |||
| 169c313404 | |||
| a3e19b4563 | |||
| ccf430ea62 | |||
| cf13b79e93 | |||
| 134a0196f8 | |||
| 54aef7c242 | |||
| 6c45c9f0b0 | |||
| b5afae0916 | |||
| 988eca857f | |||
| 3c05db2874 | |||
| a8e268f84a | |||
| ac22533ecd | |||
| bdc0b875a4 | |||
| d7b67c1408 | |||
| 606e29ebb0 | |||
| 21e3c1538d | |||
| 0fc7cc657d | |||
| 23a7f01c05 | |||
| 3a21cfa1ab | |||
| 1d2e6d916c | |||
| 4c2bf3642e | |||
| 70e2e32385 | |||
| 68a192daa3 | |||
| d6aacae14e | |||
| 6f00023d09 | |||
| 982ec56874 | |||
| 5dcc1ed6dc | |||
| d62bc0a10b | |||
| d1fb926a2a | |||
| dea69acd49 | |||
| ada2d2247a | |||
| 0159d7c27a | |||
| 882003c08c | |||
| b71a491872 | |||
| 8f48ae08c4 | |||
| 31b9623407 | |||
| 6d90ffdd2c | |||
| 28997c7f97 | |||
| 9550934d1f | |||
| a6c586a33b | |||
| 7c85c1a271 | |||
| 92c8d1b73f | |||
| 554e9ca490 | |||
| ff91d4619e | |||
| 9d01474277 | |||
| 8d10552d7c | |||
| 04fd197f5a | |||
| 4eadaf8292 | |||
| 32e39ebc6b | |||
| 117eb83a0b | |||
| c964c137f4 | |||
| 35b43d5b20 | |||
| bf88b34898 | |||
| 93140a1aa7 | |||
| f594bfc9ab | |||
| 4327e2945a | |||
| 6e6675f7bf | |||
| 8670693952 | |||
| a7f7ebfbae | |||
| 57c38ef222 | |||
| 1aec8be85e | |||
| 4b474dd8ff | |||
| 8e05386a0b | |||
| 13cfa55e6c | |||
| 18e628acde | |||
| b163dba2d4 | |||
| e67b2b020a | |||
| 9b627dd70f | |||
| 9a0b769425 | |||
| 8e14f5f884 | |||
| 1b64cb42b0 | |||
| 03c4895f2b | |||
| dcfb092758 | |||
| 9305ad5364 | |||
| ea5aef6c2f | |||
| 61a4433cd9 | |||
| 5c89d36140 | |||
| 5ab164d229 | |||
| 26538c5884 | |||
| a0daabab03 | |||
| b0a5b60945 | |||
| adb248dbcc | |||
| fffec65cab | |||
| bb24004d46 | |||
| c487eff7ca | |||
| 5fa21c9aae | |||
| fd18aae0d6 | |||
| c202e2d598 | |||
| 62d23cff9f | |||
| e454d71b78 | |||
| a7874add88 | |||
| 0a47d5dcf8 | |||
| 3d84be22e2 | |||
| 6ccbb30491 | |||
| 91c205f83a | |||
| 4a704e992a | |||
| 6c88c7df42 | |||
| 2a748fc968 | |||
| 25766dc0ec | |||
| 07544d939e | |||
| 102cd1033c | |||
| 676e93a372 | |||
| 5a6770e5e2 | |||
| 529e8d49ee | |||
| 01c7ea72dd | |||
| dfd1df5706 | |||
| 11d6ee2fdb | |||
| d704c428fc | |||
| bca070c1bd | |||
| a94c035c0a | |||
| 24480418f0 | |||
| 226c040a13 | |||
| a46245ffe3 | |||
| 7c1c13e139 | |||
| 836a93cd96 | |||
| 3d2914b3e5 | |||
| 9b02de3e75 | |||
| b47a742dd0 | |||
| 6e14882246 | |||
| f3d8aba82c | |||
| aa83501ed0 | |||
| a7466a0e02 | |||
| 78f45012db | |||
| f6a2f62ea9 | |||
| 3efeededc5 | |||
| c482350ec6 | |||
| 72a4a26c40 | |||
| 5d9b5a0d70 | |||
| c070e4bfee | |||
| 4d3d60b78e | |||
| 5f06414a12 | |||
| 656838811a | |||
| 7b8458630a | |||
| cf2ab08b4d | |||
| 2466112829 | |||
| e5306908e4 | |||
| 41fb17a31b | |||
| 7d5e3ef7d3 | |||
| 4f283f565c | |||
| 2fab3f11b6 | |||
| d0722e5f63 | |||
| 64373548e4 | |||
| bad85abff3 | |||
| 6e66cc2467 | |||
| c805aa79a4 | |||
| f5ca1ee20a | |||
| 4f07343efd | |||
| 94ab78606a | |||
| 7b92e471c8 | |||
| a507ffe371 | |||
| c02e93004f | |||
| 1113e0c599 | |||
| 06c7394861 | |||
| e20bea9d32 | |||
| eeea32fdca | |||
| b06349efd0 | |||
| 98a4cb4ae8 | |||
| be185824b4 | |||
| 60e8e53f3b | |||
| 1890367bfc | |||
| 2b26a88d6c | |||
| a6f4f017c7 | |||
| d8a6ca48c1 | |||
| 541d46e899 | |||
| 39f525e88e | |||
| 156e892baa | |||
| 5b6ae39dab | |||
| df004f834f | |||
| 235165171b | |||
| 572875058d | |||
| cf6f437187 | |||
| 6010de978d | |||
| d951ea9548 | |||
| 868d7439ec | |||
| a884aee1e9 | |||
| 80f965a104 | |||
| c99a240ed4 | |||
| 67976b1b30 | |||
| a2322d6cdf | |||
| ae346bb75b | |||
| 53c28af847 | |||
| 3521f36374 | |||
| f7a7a8072f | |||
| 3695332036 | |||
| acd068e5ab | |||
| d03302c391 | |||
| cd86110b2c | |||
| 8d5a41a790 | |||
| caa17d933c | |||
| ad0c135d4c | |||
| 039b05cf7e | |||
| 37b10b59aa | |||
| a9ede22bbd | |||
| b656003306 | |||
| 61e872f033 | |||
| b4f51baf94 | |||
| a3f3d83c1b | |||
| 84d7004cb2 | |||
| be063a36eb | |||
| 0a712b9fce | |||
| 88d6fb4e22 | |||
| 04c2045d94 | |||
| c0b4e8dd70 | |||
| e7702a1e7a | |||
| 07435ce3b2 | |||
| b628a5f814 | |||
| 9690c73c91 | |||
| 684d7ac1a2 | |||
| b813044360 | |||
| c26d4f24fc | |||
| ee7b3f1415 | |||
| ccd66f8a51 | |||
| c31d1f63e6 | |||
| 2ab172146a | |||
| 9b5e14c78e | |||
| d9e5c62b5c | |||
| a336893116 | |||
| 1d0d62f798 | |||
| daa680d6b8 | |||
| a491e6a71a | |||
| fd47768b75 | |||
| 4e2aa2c0b3 | |||
| 96f99bb9e4 | |||
| 10933ff8f1 | |||
| 5454b36022 | |||
| 675e5a0305 | |||
| 210cc5286e | |||
| d07e293cb5 | |||
| 4b055a9bf0 | |||
| 80d1a24164 | |||
| b481da9c55 | |||
| 585d752c83 | |||
| 6eddc913f4 | |||
| 15c3012199 | |||
| 78bf413e6a | |||
| 29ea4623c8 | |||
| 60c21a8d1d | |||
| feefde9022 | |||
| 645be5fa22 | |||
| ac56717b23 | |||
| 62045d76b3 | |||
| f8317f5a03 | |||
| c3ec970a37 | |||
| 5a573bc278 | |||
| 3d200db722 | |||
| e4139713cb |
@@ -4,4 +4,3 @@
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
**/target
|
**/target
|
||||||
dist
|
dist
|
||||||
documentation
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
nym-validator-rewarder/.sqlx/** diff=nodiff
|
||||||
|
nym-node-status-api/nym-node-status-api/.sqlx/** diff=nodiff
|
||||||
+149
-265
@@ -9,7 +9,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.1",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^5.1.1",
|
"@actions/github": "^6.0.0",
|
||||||
"@octokit/auth-action": "^4.0.1",
|
"@octokit/auth-action": "^4.0.1",
|
||||||
"@octokit/rest": "^20.0.2",
|
"@octokit/rest": "^20.0.2",
|
||||||
"hasha": "^5.2.0",
|
"hasha": "^5.2.0",
|
||||||
@@ -29,22 +29,34 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/github": {
|
"node_modules/@actions/github": {
|
||||||
"version": "5.1.1",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.0.tgz",
|
||||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
"integrity": "sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/http-client": "^2.0.1",
|
"@actions/http-client": "^2.2.0",
|
||||||
"@octokit/core": "^3.6.0",
|
"@octokit/core": "^5.0.1",
|
||||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
"@octokit/plugin-paginate-rest": "^9.0.0",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
"@octokit/plugin-rest-endpoint-methods": "^10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/http-client": {
|
"node_modules/@actions/http-client": {
|
||||||
"version": "2.1.1",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||||
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==",
|
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tunnel": "^0.0.6"
|
"tunnel": "^0.0.6",
|
||||||
|
"undici": "^5.25.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@fastify/busboy": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/auth-action": {
|
"node_modules/@octokit/auth-action": {
|
||||||
@@ -59,14 +71,6 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/auth-action/node_modules/@octokit/auth-token": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/auth-action/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/auth-action/node_modules/@octokit/openapi-types": {
|
||||||
"version": "20.0.0",
|
"version": "20.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||||
@@ -81,115 +85,152 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/auth-token": {
|
"node_modules/@octokit/auth-token": {
|
||||||
"version": "2.5.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"@octokit/types": "^6.0.3"
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/core": {
|
"node_modules/@octokit/core": {
|
||||||
"version": "3.6.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz",
|
||||||
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
|
"integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-token": "^2.4.4",
|
"@octokit/auth-token": "^4.0.0",
|
||||||
"@octokit/graphql": "^4.5.8",
|
"@octokit/graphql": "^7.1.0",
|
||||||
"@octokit/request": "^5.6.3",
|
"@octokit/request": "^8.3.1",
|
||||||
"@octokit/request-error": "^2.0.5",
|
"@octokit/request-error": "^5.1.0",
|
||||||
"@octokit/types": "^6.0.3",
|
"@octokit/types": "^13.0.0",
|
||||||
"before-after-hook": "^2.2.0",
|
"before-after-hook": "^2.2.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/endpoint": {
|
"node_modules/@octokit/endpoint": {
|
||||||
"version": "6.0.12",
|
"version": "9.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
||||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^6.0.3",
|
"@octokit/types": "^13.1.0",
|
||||||
"is-plain-object": "^5.0.0",
|
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/graphql": {
|
"node_modules/@octokit/graphql": {
|
||||||
"version": "4.8.0",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz",
|
||||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
"integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/request": "^5.6.0",
|
"@octokit/request": "^8.3.0",
|
||||||
"@octokit/types": "^6.0.3",
|
"@octokit/types": "^13.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/openapi-types": {
|
||||||
"version": "12.11.0",
|
"version": "23.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||||
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
|
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-paginate-rest": {
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
"version": "2.21.3",
|
"version": "9.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
||||||
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
|
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^6.40.0"
|
"@octokit/types": "^12.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@octokit/core": ">=2"
|
"@octokit/core": "5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "20.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||||
|
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
||||||
|
"version": "12.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||||
|
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||||
"version": "5.16.2",
|
"version": "10.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
|
||||||
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
|
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^6.39.0",
|
"@octokit/types": "^12.6.0"
|
||||||
"deprecation": "^2.3.1"
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@octokit/core": ">=3"
|
"@octokit/core": "5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "20.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||||
|
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||||
|
"version": "12.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||||
|
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request": {
|
"node_modules/@octokit/request": {
|
||||||
"version": "5.6.3",
|
"version": "8.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
||||||
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
|
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/endpoint": "^6.0.1",
|
"@octokit/endpoint": "^9.0.6",
|
||||||
"@octokit/request-error": "^2.1.0",
|
"@octokit/request-error": "^5.1.1",
|
||||||
"@octokit/types": "^6.16.1",
|
"@octokit/types": "^13.1.0",
|
||||||
"is-plain-object": "^5.0.0",
|
|
||||||
"node-fetch": "^2.6.7",
|
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request-error": {
|
"node_modules/@octokit/request-error": {
|
||||||
"version": "2.1.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
||||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^6.0.3",
|
"@octokit/types": "^13.1.0",
|
||||||
"deprecation": "^2.0.0",
|
"deprecation": "^2.0.0",
|
||||||
"once": "^1.4.0"
|
"once": "^1.4.0"
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/request/node_modules/node-fetch": {
|
|
||||||
"version": "2.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
|
||||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
|
||||||
"dependencies": {
|
|
||||||
"whatwg-url": "^5.0.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "4.x || >=6.0.0"
|
"node": ">= 18"
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"encoding": "^0.1.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"encoding": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/rest": {
|
"node_modules/@octokit/rest": {
|
||||||
@@ -206,89 +247,6 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/core": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-YbAtMWIrbZ9FCXbLwT9wWB8TyLjq9mxpKdgB3dUNxQcIVTf9hJ70gRPwAcqGZdY6WdJPZ0I7jLaaNDCiloGN2A==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/auth-token": "^4.0.0",
|
|
||||||
"@octokit/graphql": "^7.0.0",
|
|
||||||
"@octokit/request": "^8.0.2",
|
|
||||||
"@octokit/request-error": "^5.0.0",
|
|
||||||
"@octokit/types": "^11.0.0",
|
|
||||||
"before-after-hook": "^2.2.0",
|
|
||||||
"universal-user-agent": "^6.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
|
|
||||||
"version": "9.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.0.tgz",
|
|
||||||
"integrity": "sha512-szrQhiqJ88gghWY2Htt8MqUDO6++E/EIXqJ2ZEp5ma3uGS46o7LZAzSLt49myB7rT+Hfw5Y6gO3LmOxGzHijAQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/types": "^11.0.0",
|
|
||||||
"is-plain-object": "^5.0.0",
|
|
||||||
"universal-user-agent": "^6.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-T5S3oZ1JOE58gom6MIcrgwZXzTaxRnxBso58xhozxHpOqSTgDS6YNeEUvZ/kRvXgPrRz/KHnZhtb7jUMRi9E6w==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/request": "^8.0.1",
|
|
||||||
"@octokit/types": "^11.0.0",
|
|
||||||
"universal-user-agent": "^6.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
|
|
||||||
"version": "18.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
|
||||||
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
|
|
||||||
"version": "9.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz",
|
|
||||||
"integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/types": "^12.6.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@octokit/core": "5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
|
||||||
"version": "20.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
|
||||||
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
|
||||||
"version": "12.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
|
||||||
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/openapi-types": "^20.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
|
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz",
|
||||||
@@ -300,75 +258,13 @@
|
|||||||
"@octokit/core": ">=5"
|
"@octokit/core": ">=5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
|
|
||||||
"version": "10.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
|
|
||||||
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/types": "^12.6.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@octokit/core": "5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
|
||||||
"version": "20.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
|
||||||
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
|
||||||
"version": "12.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
|
||||||
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/openapi-types": "^20.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/request": {
|
|
||||||
"version": "8.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
|
|
||||||
"integrity": "sha512-8N+tdUz4aCqQmXl8FpHYfKG9GelDFd7XGVzyN8rc6WxVlYcfpHECnuRkgquzz+WzvHTK62co5di8gSXnzASZPQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/endpoint": "^9.0.0",
|
|
||||||
"@octokit/request-error": "^5.0.0",
|
|
||||||
"@octokit/types": "^11.1.0",
|
|
||||||
"is-plain-object": "^5.0.0",
|
|
||||||
"universal-user-agent": "^6.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/types": "^11.0.0",
|
|
||||||
"deprecation": "^2.0.0",
|
|
||||||
"once": "^1.4.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest/node_modules/@octokit/types": {
|
|
||||||
"version": "11.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
|
|
||||||
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/openapi-types": "^18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/types": {
|
"node_modules/@octokit/types": {
|
||||||
"version": "6.41.0",
|
"version": "13.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||||
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
|
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/openapi-types": "^12.11.0"
|
"@octokit/openapi-types": "^23.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vercel/ncc": {
|
"node_modules/@vercel/ncc": {
|
||||||
@@ -396,7 +292,8 @@
|
|||||||
"node_modules/deprecation": {
|
"node_modules/deprecation": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/fetch-blob": {
|
"node_modules/fetch-blob": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
@@ -446,14 +343,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-plain-object": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-stream": {
|
"node_modules/is-stream": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
@@ -504,15 +393,11 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tr46": {
|
|
||||||
"version": "0.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
|
||||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
|
||||||
},
|
|
||||||
"node_modules/tunnel": {
|
"node_modules/tunnel": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||||
@@ -529,6 +414,18 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/undici": {
|
||||||
|
"version": "5.28.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
|
||||||
|
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@fastify/busboy": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/universal-user-agent": {
|
"node_modules/universal-user-agent": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||||
@@ -550,24 +447,11 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webidl-conversions": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
|
||||||
},
|
|
||||||
"node_modules/whatwg-url": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
|
||||||
"dependencies": {
|
|
||||||
"tr46": "~0.0.3",
|
|
||||||
"webidl-conversions": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/wrappy": {
|
"node_modules/wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
|
"license": "ISC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.1",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^5.1.1",
|
"@actions/github": "^6.0.0",
|
||||||
"@octokit/auth-action": "^4.0.1",
|
"@octokit/auth-action": "^4.0.1",
|
||||||
"@octokit/rest": "^20.0.2",
|
"@octokit/rest": "^20.0.2",
|
||||||
"hasha": "^5.2.0",
|
"hasha": "^5.2.0",
|
||||||
|
|||||||
@@ -31,3 +31,5 @@ updates:
|
|||||||
update-types:
|
update-types:
|
||||||
- "patch"
|
- "patch"
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
|
assignees:
|
||||||
|
- "octol"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -79,7 +80,6 @@ jobs:
|
|||||||
target/release/nym-socks5-client
|
target/release/nym-socks5-client
|
||||||
target/release/nym-api
|
target/release/nym-api
|
||||||
target/release/nym-network-requester
|
target/release/nym-network-requester
|
||||||
target/release/nym-data-observatory
|
|
||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
target/release/nymvisor
|
target/release/nymvisor
|
||||||
target/release/nym-node
|
target/release/nym-node
|
||||||
@@ -97,11 +97,9 @@ jobs:
|
|||||||
cp target/release/nym-socks5-client $OUTPUT_DIR
|
cp target/release/nym-socks5-client $OUTPUT_DIR
|
||||||
cp target/release/nym-api $OUTPUT_DIR
|
cp target/release/nym-api $OUTPUT_DIR
|
||||||
cp target/release/nym-network-requester $OUTPUT_DIR
|
cp target/release/nym-network-requester $OUTPUT_DIR
|
||||||
cp target/release/nym-data-observatory $OUTPUT_DIR
|
|
||||||
cp target/release/nymvisor $OUTPUT_DIR
|
cp target/release/nymvisor $OUTPUT_DIR
|
||||||
cp target/release/nym-node $OUTPUT_DIR
|
cp target/release/nym-node $OUTPUT_DIR
|
||||||
cp target/release/nym-cli $OUTPUT_DIR
|
cp target/release/nym-cli $OUTPUT_DIR
|
||||||
cp target/release/explorer-api $OUTPUT_DIR
|
|
||||||
if [ ${{ github.event_name == 'workflow_dispatch' && inputs.enable_deb == true }} = true ]; then
|
if [ ${{ github.event_name == 'workflow_dispatch' && inputs.enable_deb == true }} = true ]; then
|
||||||
cp target/debian/*.deb $OUTPUT_DIR
|
cp target/debian/*.deb $OUTPUT_DIR
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ jobs:
|
|||||||
runs-on: arc-ubuntu-22.04
|
runs-on: arc-ubuntu-22.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|||||||
@@ -8,16 +8,18 @@ on:
|
|||||||
- 'explorer-api/**'
|
- 'explorer-api/**'
|
||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
- 'mixnode/**'
|
|
||||||
- 'sdk/rust/**'
|
|
||||||
- 'sdk/lib/**'
|
|
||||||
- 'service-providers/**'
|
|
||||||
- 'nym-network-monitor/**'
|
|
||||||
- 'nym-api/**'
|
- 'nym-api/**'
|
||||||
|
- 'nym-credential-proxy/**'
|
||||||
|
- 'nym-network-monitor/**'
|
||||||
- 'nym-node/**'
|
- 'nym-node/**'
|
||||||
|
- 'nym-node-status-api/**'
|
||||||
- 'nym-outfox/**'
|
- 'nym-outfox/**'
|
||||||
- 'nym-data-observatory/**'
|
|
||||||
- 'nym-validator-rewarder/**'
|
- 'nym-validator-rewarder/**'
|
||||||
|
- 'nyx-chain-watcher/**'
|
||||||
|
- 'sdk/ffi/**'
|
||||||
|
- 'sdk/rust/**'
|
||||||
|
- 'service-providers/**'
|
||||||
|
- 'nym-browser-extension/storage/**'
|
||||||
- 'tools/**'
|
- 'tools/**'
|
||||||
- 'wasm/**'
|
- 'wasm/**'
|
||||||
- 'Cargo.toml'
|
- 'Cargo.toml'
|
||||||
@@ -25,16 +27,23 @@ on:
|
|||||||
- '.github/workflows/ci-build.yml'
|
- '.github/workflows/ci-build.yml'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
# only 1 concurrent `ci-build` allowed per branch
|
||||||
|
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#example-using-concurrency-and-the-default-behavior
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ arc-ubuntu-20.04, custom-runner-mac-m1 ]
|
os: [ arc-ubuntu-20.04, custom-windows-11, custom-runner-mac-m1 ]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
IPINFO_API_TOKEN: ${{ secrets.IPINFO_API_TOKEN }}
|
IPINFO_API_TOKEN: ${{ secrets.IPINFO_API_TOKEN }}
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
@@ -52,6 +61,20 @@ jobs:
|
|||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
# To avoid running out of disk space, skip generating debug symbols
|
||||||
|
- name: Set debug to false (unix)
|
||||||
|
if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'mac')
|
||||||
|
run: |
|
||||||
|
sed -i.bak 's/\[profile.dev\]/\[profile.dev\]\ndebug = false/' Cargo.toml
|
||||||
|
git diff
|
||||||
|
|
||||||
|
- name: Set debug to false (win)
|
||||||
|
if: contains(matrix.os, 'windows')
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
(Get-Content Cargo.toml) -replace '\[profile.dev\]', "`$&`ndebug = false" | Set-Content Cargo.toml
|
||||||
|
git diff
|
||||||
|
|
||||||
- name: Check formatting
|
- name: Check formatting
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
name: ci-check-ns-api-version
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "nym-node-status-api/**"
|
||||||
|
|
||||||
|
env:
|
||||||
|
WORKING_DIRECTORY: "nym-node-status-api/nym-node-status-api"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-if-tag-exists:
|
||||||
|
runs-on: arc-ubuntu-22.04-dind
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get version from cargo.toml
|
||||||
|
uses: mikefarah/yq@v4.45.1
|
||||||
|
id: get_version
|
||||||
|
with:
|
||||||
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|
||||||
|
- name: Check if git tag exists
|
||||||
|
run: |
|
||||||
|
TAG=${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
|
||||||
|
if [[ -z "$TAG" ]]; then
|
||||||
|
echo "Tag is empty"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
git ls-remote --tags origin | awk '{print $2}'
|
||||||
|
if git ls-remote --tags origin | awk '{print $2}' | grep -q "refs/tags/$TAG$" ; then
|
||||||
|
echo "Tag '$TAG' ALREADY EXISTS on the remote"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Tag '$TAG' does not exist on the remote"
|
||||||
|
fi
|
||||||
|
- name: Check if harbor tag exists
|
||||||
|
run: |
|
||||||
|
TAG=${{ steps.get_version.outputs.result }}
|
||||||
|
registry=https://harbor.nymte.ch
|
||||||
|
repo_name=nym/node-status-api
|
||||||
|
if [[ -z $TAG ]]; then
|
||||||
|
echo "Tag is empty"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq
|
||||||
|
exists=$(curl -su ${{ secrets.HARBOR_ROBOT_USERNAME }}:${{ secrets.HARBOR_ROBOT_SECRET }} "$registry/v2/$repo_name/tags/list" | jq --arg tag $TAG '.tags | contains([$tag])' )
|
||||||
|
if [[ $exists = "true" ]]; then
|
||||||
|
echo "Version '$TAG' defined in Cargo.toml ALREADY EXISTS as tag in harbor repo"
|
||||||
|
exit 1
|
||||||
|
elif [[ $exists = "false" ]]; then
|
||||||
|
echo "Version '$TAG' doesn't exist on the remote"
|
||||||
|
else
|
||||||
|
echo "Unknown output '$exists'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"rust":"stable",
|
|
||||||
"runOnEvent":"always"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -31,7 +31,6 @@ jobs:
|
|||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.77
|
|
||||||
target: wasm32-unknown-unknown
|
target: wasm32-unknown-unknown
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
@@ -40,6 +39,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
version: '114'
|
version: '114'
|
||||||
|
|
||||||
|
- name: Install cosmwasm-check
|
||||||
|
run: cargo install cosmwasm-check
|
||||||
|
|
||||||
- name: Build release contracts
|
- name: Build release contracts
|
||||||
run: make contracts
|
run: make contracts
|
||||||
|
|
||||||
@@ -50,7 +52,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_bandwidth.wasm $OUTPUT_DIR
|
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
|
||||||
|
|||||||
@@ -9,31 +9,17 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- 'contracts/**'
|
- 'contracts/**'
|
||||||
- 'common/**'
|
- 'common/**'
|
||||||
|
- 'Cargo.lock'
|
||||||
|
- 'Cargo.toml'
|
||||||
- '.github/workflows/ci-contracts.yml'
|
- '.github/workflows/ci-contracts.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
matrix_prep:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
outputs:
|
|
||||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
||||||
steps:
|
|
||||||
# creates the matrix strategy from ci-contracts-matrix-includes.json
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- id: set-matrix
|
|
||||||
uses: JoshuaTheMiller/conditional-build-matrix@main
|
|
||||||
with:
|
|
||||||
inputFile: '.github/workflows/ci-contracts-matrix-includes.json'
|
|
||||||
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
|
||||||
build:
|
build:
|
||||||
# since it's going to be compiled into wasm, there's absolutely
|
# since it's going to be compiled into wasm, there's absolutely
|
||||||
# no point in running CI on different OS-es
|
# no point in running CI on different OS-es
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
needs: matrix_prep
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -41,11 +27,19 @@ jobs:
|
|||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
profile: minimal
|
profile: minimal
|
||||||
toolchain: ${{ matrix.rust }}
|
toolchain: stable
|
||||||
target: wasm32-unknown-unknown
|
target: wasm32-unknown-unknown
|
||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
- name: Install cosmwasm-check
|
||||||
|
run: cargo install cosmwasm-check
|
||||||
|
|
||||||
|
- name: Install wasm-opt
|
||||||
|
uses: ./.github/actions/install-wasm-opt
|
||||||
|
with:
|
||||||
|
version: '114'
|
||||||
|
|
||||||
- name: Build contracts
|
- name: Build contracts
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
env:
|
env:
|
||||||
@@ -71,3 +65,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
command: clippy
|
command: clippy
|
||||||
args: --lib --manifest-path contracts/Cargo.toml --workspace --all-targets -- -D warnings
|
args: --lib --manifest-path contracts/Cargo.toml --workspace --all-targets -- -D warnings
|
||||||
|
|
||||||
|
- name: Check chain compatibility against release build
|
||||||
|
# this will build contracts in release mode, run wasm-opt and finally cosmwasm-check
|
||||||
|
run: make contracts
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
|
env:
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: documentation/docs
|
working-directory: documentation/docs
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
|
env:
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
@@ -42,7 +44,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: "1.23.7"
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ jobs:
|
|||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
|
||||||
@@ -30,6 +31,12 @@ jobs:
|
|||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
- name: Set debug to false
|
||||||
|
working-directory: nym-wallet
|
||||||
|
run: |
|
||||||
|
sed -i.bak '1s/^/\[profile.dev\]\ndebug = false\n\n/' Cargo.toml
|
||||||
|
git diff
|
||||||
|
|
||||||
- name: Build all binaries
|
- name: Build all binaries
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -10,66 +10,66 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: custom-linux
|
runs-on: custom-linux
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install rsync
|
- name: Install rsync
|
||||||
run: sudo apt-get install rsync
|
run: sudo apt-get install rsync
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
|
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
|
||||||
- name: Install wasm-pack
|
- name: Install wasm-pack
|
||||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
- name: Build dependencies
|
- name: Build dependencies
|
||||||
run: yarn && yarn build
|
run: yarn && yarn build
|
||||||
|
|
||||||
- name: Build storybook
|
- name: Build storybook
|
||||||
run: yarn storybook:build
|
run: yarn storybook:build
|
||||||
working-directory: ./nym-wallet
|
working-directory: ./nym-wallet
|
||||||
|
|
||||||
- name: Deploy branch to CI www (storybook)
|
- name: Deploy branch to CI www (storybook)
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: easingthemes/ssh-deploy@main
|
uses: easingthemes/ssh-deploy@main
|
||||||
env:
|
env:
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
||||||
ARGS: "-rltgoDzvO --delete"
|
ARGS: "-rltgoDzvO --delete"
|
||||||
SOURCE: "nym-wallet/storybook-static/"
|
SOURCE: "nym-wallet/storybook-static/"
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }}
|
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }}
|
||||||
EXCLUDE: "/dist/, /node_modules/"
|
EXCLUDE: "/dist/, /node_modules/"
|
||||||
|
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
run: npm install
|
run: npm install
|
||||||
working-directory: .github/workflows/support-files
|
working-directory: .github/workflows/support-files
|
||||||
|
|
||||||
- name: Matrix - Send Notification
|
- name: Matrix - Send Notification
|
||||||
env:
|
env:
|
||||||
NYM_NOTIFICATION_KIND: nym-wallet
|
NYM_NOTIFICATION_KIND: nym-wallet
|
||||||
NYM_PROJECT_NAME: "nym-wallet"
|
NYM_PROJECT_NAME: "nym-wallet"
|
||||||
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
|
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
|
||||||
NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}"
|
NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}"
|
||||||
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||||
GIT_BRANCH: "${GITHUB_REF##*/}"
|
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||||
IS_SUCCESS: "${{ job.status == 'success' }}"
|
IS_SUCCESS: "${{ job.status == 'success' }}"
|
||||||
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
||||||
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
|
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
|
||||||
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
||||||
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
||||||
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
||||||
uses: docker://keybaseio/client:stable-node
|
uses: docker://keybaseio/client:stable-node
|
||||||
with:
|
with:
|
||||||
args: .github/workflows/support-files/notifications/entry_point.sh
|
args: .github/workflows/support-files/notifications/entry_point.sh
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
name: ci-sdk-wasm
|
name: ci-sdk-wasm
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'wasm/**'
|
- 'wasm/**'
|
||||||
@@ -13,6 +14,7 @@ jobs:
|
|||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: "1.23.7"
|
||||||
|
|
||||||
- name: Install wasm-pack
|
- name: Install wasm-pack
|
||||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
@@ -44,6 +46,11 @@ jobs:
|
|||||||
- name: Install wasm-bindgen-cli
|
- name: Install wasm-bindgen-cli
|
||||||
run: cargo install wasm-bindgen-cli
|
run: cargo install wasm-bindgen-cli
|
||||||
|
|
||||||
|
- name: Set debug to false
|
||||||
|
run: |
|
||||||
|
sed -i.bak 's/\[profile.dev\]/\[profile.dev\]\ndebug = false/' Cargo.toml
|
||||||
|
git diff
|
||||||
|
|
||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: make sdk-wasm-build
|
run: make sdk-wasm-build
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
IPINFO_API_TOKEN: ${{ secrets.IPINFO_API_TOKEN }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
|
|||||||
@@ -2,19 +2,18 @@ name: publish-nym-contracts
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [ created ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
runs-on: [self-hosted, custom-ubuntu-20.04]
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.77
|
|
||||||
target: wasm32-unknown-unknown
|
target: wasm32-unknown-unknown
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [macos-12-large]
|
platform: [macos-15]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
- name: Node
|
- name: Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 21
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -64,11 +64,25 @@ jobs:
|
|||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- name: Add Rust target for x86_64-apple-darwin
|
||||||
|
run: rustup target add x86_64-apple-darwin
|
||||||
|
|
||||||
|
- name: Set Cargo build target to x86_64
|
||||||
|
run: echo "CARGO_BUILD_TARGET=x86_64-apple-darwin" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: yarn cache clean
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn cache clean
|
||||||
|
|
||||||
- name: Install project dependencies
|
- name: Install project dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cd .. && yarn --network-timeout 100000
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Install app dependencies and build it
|
- name: yarn build
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn build
|
||||||
|
|
||||||
|
- name: Install dependencies and build it
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
@@ -80,13 +94,14 @@ jobs:
|
|||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
run: yarn && yarn build
|
run: |
|
||||||
|
yarn build-macx86
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: nym-wallet.app.tar.gz
|
name: nym-wallet.app.tar.gz
|
||||||
path: nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz
|
path: nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/nym-wallet.app.tar.gz
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
|
|
||||||
- name: Clean up keychain
|
- name: Clean up keychain
|
||||||
@@ -99,8 +114,8 @@ jobs:
|
|||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/dmg/*.dmg
|
nym-wallet/target/x86_64-apple-darwin/release/bundle/dmg/*.dmg
|
||||||
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
|
nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/*.app.tar.gz*
|
||||||
|
|
||||||
- name: Deploy artifacts to CI www
|
- name: Deploy artifacts to CI www
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -108,7 +123,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
||||||
ARGS: "-avzr"
|
ARGS: "-avzr"
|
||||||
SOURCE: "nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz"
|
SOURCE: "nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/nym-wallet.app.tar.gz"
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
|
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ jobs:
|
|||||||
- name: Node
|
- name: Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 21
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
- name: Node
|
- name: Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 21
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|||||||
@@ -49,21 +49,13 @@ jobs:
|
|||||||
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: dtolnay/rust-toolchain@1.90.0
|
uses: dtolnay/rust-toolchain@1.100.0
|
||||||
|
|
||||||
- name: Install rust android targets
|
- name: Install rust android targets
|
||||||
run: |
|
run: |
|
||||||
rustup target add aarch64-linux-android \
|
rustup target add aarch64-linux-android \
|
||||||
x86_64-linux-android
|
x86_64-linux-android
|
||||||
|
|
||||||
- name: Build lib nym-socks5-listener
|
|
||||||
working-directory: sdk/lib/socks5-listener/
|
|
||||||
env:
|
|
||||||
RELEASE: true
|
|
||||||
RUSTFLAGS: "-C link-args=-Wl,--hash-style=gnu"
|
|
||||||
# build for arm64 and x86_64
|
|
||||||
run: ./build-android.sh aarch64 x86_64
|
|
||||||
|
|
||||||
- name: Build APKs (unsigned)
|
- name: Build APKs (unsigned)
|
||||||
working-directory: nym-connect/native/android
|
working-directory: nym-connect/native/android
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -31,12 +31,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "1.20"
|
go-version: "1.23.7"
|
||||||
|
|
||||||
- name: Install TinyGo
|
|
||||||
uses: acifani/setup-tinygo@v2
|
|
||||||
with:
|
|
||||||
tinygo-version: "0.27.0"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-credential-proxy/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-credential-proxy/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-network-monitor/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-network-monitor/Cargo.toml
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.44.6
|
uses: mikefarah/yq@v4.45.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
+8
-1
@@ -51,4 +51,11 @@ ppa-private-key.b64
|
|||||||
ppa-private-key.asc
|
ppa-private-key.asc
|
||||||
nym-network-monitor/topology.json
|
nym-network-monitor/topology.json
|
||||||
nym-network-monitor/__pycache__
|
nym-network-monitor/__pycache__
|
||||||
nym-network-monitor/*.key
|
nym-network-monitor/*.key
|
||||||
|
nym-network-monitor/.envrc
|
||||||
|
nym-network-monitor/.envrc
|
||||||
|
nym-api/redocly/formatted-openapi.json
|
||||||
|
|
||||||
|
|
||||||
|
*.sqlite
|
||||||
|
.build
|
||||||
|
|||||||
+634
-5
@@ -4,6 +4,635 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2025.6-chuckles] (2025-03-31)
|
||||||
|
|
||||||
|
- Remove Google public DNS ([#5660])
|
||||||
|
- Revert using AsyncWrite sink in IPR ([#5656])
|
||||||
|
- Add fd callback for initial authentication ([#5654])
|
||||||
|
- Add concurrency limit to CI ([#5651])
|
||||||
|
- Remove UNIQUE constraint on node pubkey ([#5649])
|
||||||
|
- Add RUSTUP_PERMIT_COPY_RENAME in two workflows that we forgot about ([#5646])
|
||||||
|
- Upgrade sha2 to workspace version for validator-client ([#5644])
|
||||||
|
- Add max_retransmissions flag on each message ([#5642])
|
||||||
|
- build(deps): bump zip from 2.2.2 to 2.4.1 ([#5639])
|
||||||
|
- build(deps): bump dtolnay/rust-toolchain from 1.90.0 to 1.100.0 ([#5638])
|
||||||
|
- / regenerated yarn.lock ([#5636])
|
||||||
|
- Rework IPR codec to extract out timer and implement AsyncWrite ([#5632])
|
||||||
|
- build(deps): bump tempfile from 3.18.0 to 3.19.0 ([#5631])
|
||||||
|
- build(deps): bump zeroize from 1.6.0 to 1.8.1 ([#5630])
|
||||||
|
- build(deps): bump once_cell from 1.20.3 to 1.21.1 ([#5629])
|
||||||
|
- build(deps): bump uuid from 1.15.1 to 1.16.0 ([#5628])
|
||||||
|
- build(deps): bump celes from 2.5.0 to 2.6.0 ([#5627])
|
||||||
|
- build(deps): bump http from 1.2.0 to 1.3.1 ([#5626])
|
||||||
|
- build(deps): bump humantime from 2.1.0 to 2.2.0 ([#5625])
|
||||||
|
- build(deps): bump the patch-updates group with 8 updates ([#5624])
|
||||||
|
- build(deps): bump @babel/runtime from 7.16.3 to 7.26.10 in /testnet-faucet ([#5621])
|
||||||
|
- Feature/paginated ticketbooks challenge ([#5619])
|
||||||
|
- build(deps-dev): bump webpack from 5.77.0 to 5.98.0 in /wasm/client/internal-dev ([#5615])
|
||||||
|
- build(deps-dev): bump ws from 8.13.0 to 8.18.1 in /wasm/client/internal-dev ([#5614])
|
||||||
|
- build(deps): bump golang.org/x/net from 0.23.0 to 0.36.0 in /wasm/mix-fetch/go-mix-conn ([#5613])
|
||||||
|
- build(deps): bump braces from 3.0.2 to 3.0.3 in /sdk/typescript/packages/mix-fetch-node ([#5612])
|
||||||
|
- Wireguard exit policies (and tests) ([#5557])
|
||||||
|
- Explorer V2 ([#5548])
|
||||||
|
- Clean stale partially received buffers ([#5536])
|
||||||
|
- Corrected typos ([#5497])
|
||||||
|
- build(deps): bump @octokit/plugin-paginate-rest and @actions/github in /.github/actions/nym-hash-releases/src ([#5488])
|
||||||
|
- feature: upgrade cosmwasm to 2.2 ([#5479])
|
||||||
|
- build(deps): bump store2 from 2.14.3 to 2.14.4 ([#5391])
|
||||||
|
- build(deps): bump nanoid from 3.3.7 to 3.3.8 in /documentation/docs ([#5335])
|
||||||
|
- build(deps): bump next from 13.5.7 to 14.2.15 in /documentation/docs ([#5281])
|
||||||
|
- Bump http-proxy-middleware from 2.0.6 to 2.0.7 ([#5019])
|
||||||
|
|
||||||
|
[#5660]: https://github.com/nymtech/nym/pull/5660
|
||||||
|
[#5656]: https://github.com/nymtech/nym/pull/5656
|
||||||
|
[#5654]: https://github.com/nymtech/nym/pull/5654
|
||||||
|
[#5651]: https://github.com/nymtech/nym/pull/5651
|
||||||
|
[#5649]: https://github.com/nymtech/nym/pull/5649
|
||||||
|
[#5646]: https://github.com/nymtech/nym/pull/5646
|
||||||
|
[#5644]: https://github.com/nymtech/nym/pull/5644
|
||||||
|
[#5642]: https://github.com/nymtech/nym/pull/5642
|
||||||
|
[#5639]: https://github.com/nymtech/nym/pull/5639
|
||||||
|
[#5638]: https://github.com/nymtech/nym/pull/5638
|
||||||
|
[#5636]: https://github.com/nymtech/nym/pull/5636
|
||||||
|
[#5632]: https://github.com/nymtech/nym/pull/5632
|
||||||
|
[#5631]: https://github.com/nymtech/nym/pull/5631
|
||||||
|
[#5630]: https://github.com/nymtech/nym/pull/5630
|
||||||
|
[#5629]: https://github.com/nymtech/nym/pull/5629
|
||||||
|
[#5628]: https://github.com/nymtech/nym/pull/5628
|
||||||
|
[#5627]: https://github.com/nymtech/nym/pull/5627
|
||||||
|
[#5626]: https://github.com/nymtech/nym/pull/5626
|
||||||
|
[#5625]: https://github.com/nymtech/nym/pull/5625
|
||||||
|
[#5624]: https://github.com/nymtech/nym/pull/5624
|
||||||
|
[#5621]: https://github.com/nymtech/nym/pull/5621
|
||||||
|
[#5619]: https://github.com/nymtech/nym/pull/5619
|
||||||
|
[#5615]: https://github.com/nymtech/nym/pull/5615
|
||||||
|
[#5614]: https://github.com/nymtech/nym/pull/5614
|
||||||
|
[#5613]: https://github.com/nymtech/nym/pull/5613
|
||||||
|
[#5612]: https://github.com/nymtech/nym/pull/5612
|
||||||
|
[#5557]: https://github.com/nymtech/nym/pull/5557
|
||||||
|
[#5548]: https://github.com/nymtech/nym/pull/5548
|
||||||
|
[#5536]: https://github.com/nymtech/nym/pull/5536
|
||||||
|
[#5497]: https://github.com/nymtech/nym/pull/5497
|
||||||
|
[#5488]: https://github.com/nymtech/nym/pull/5488
|
||||||
|
[#5479]: https://github.com/nymtech/nym/pull/5479
|
||||||
|
[#5391]: https://github.com/nymtech/nym/pull/5391
|
||||||
|
[#5335]: https://github.com/nymtech/nym/pull/5335
|
||||||
|
[#5281]: https://github.com/nymtech/nym/pull/5281
|
||||||
|
[#5019]: https://github.com/nymtech/nym/pull/5019
|
||||||
|
|
||||||
|
## [2025.5-chokito] (2025-03-18)
|
||||||
|
|
||||||
|
- build(deps): bump braces from 3.0.2 to 3.0.3 in /sdk/typescript/packages/nodejs-client ([#5611])
|
||||||
|
- build(deps-dev): bump webpack-dev-middleware from 5.3.3 to 5.3.4 in /wasm/client/internal-dev ([#5610])
|
||||||
|
- Export lane queue lengths in sdk ([#5609])
|
||||||
|
- Chore/more payment watcher debug endpoints ([#5608])
|
||||||
|
- build(deps): bump @babel/helpers from 7.24.4 to 7.26.10 ([#5606])
|
||||||
|
- Chore/update bls12 381 fork ([#5605])
|
||||||
|
- chore: change auth v2 timestamp skew and allow values from the future ([#5604])
|
||||||
|
- Chore/payment watcher debug endpoints ([#5601])
|
||||||
|
- Allow resetting all SURB sender tags ([#5600])
|
||||||
|
- introduce internal tool for checking signer status ([#5598])
|
||||||
|
- build(deps-dev): bump webpack from 5.77.0 to 5.98.0 in /wasm/mix-fetch/internal-dev ([#5597])
|
||||||
|
- build(deps): bump body-parser and express in /wasm/mix-fetch/internal-dev ([#5596])
|
||||||
|
- build(deps): bump serve-static and express in /wasm/mix-fetch/internal-dev ([#5594])
|
||||||
|
- build(deps-dev): bump ws from 8.13.0 to 8.18.1 in /wasm/mix-fetch/internal-dev ([#5593])
|
||||||
|
- build(deps): bump cookie and express in /wasm/client/internal-dev ([#5592])
|
||||||
|
- build(deps): bump cookie and express in /wasm/mix-fetch/internal-dev ([#5591])
|
||||||
|
- build(deps): bump braces from 3.0.2 to 3.0.3 in /wasm/zknym-lib/internal-dev ([#5590])
|
||||||
|
- build(deps): bump webpack-dev-middleware from 5.3.3 to 5.3.4 in /wasm/zknym-lib/internal-dev ([#5589])
|
||||||
|
- build(deps): bump tempfile from 3.17.1 to 3.18.0 ([#5588])
|
||||||
|
- build(deps): bump tokio from 1.43.0 to 1.44.0 ([#5587])
|
||||||
|
- build(deps): bump the patch-updates group with 8 updates ([#5585])
|
||||||
|
- build(deps): bump ring from 0.17.9 to 0.17.13 ([#5583])
|
||||||
|
- delete double memo field in send modal ([#5578])
|
||||||
|
- Server Side internal DoT/DoH opt out ([#5577])
|
||||||
|
- Rust SDK SURB example: change hardcoded file to tempdir ([#5576])
|
||||||
|
- Add /v3/nym-nodes ([#5569])
|
||||||
|
- chore: start sending v2 sphinx packets ([#5554])
|
||||||
|
- build(deps): bump the patch-updates group across 1 directory with 14 updates ([#5549])
|
||||||
|
- build(deps): bump uuid from 1.13.2 to 1.15.1 ([#5542])
|
||||||
|
- build(deps): bump rs_merkle from 1.4.2 to 1.5.0 ([#5541])
|
||||||
|
- feature: v2 authentication request ([#5537])
|
||||||
|
- Set RUSTUP_PERMIT_COPY_RENAME ([#5533])
|
||||||
|
- feature: disallow routing mix packets to nodes not present in the topology ([#5526])
|
||||||
|
- Make "Memo" visible per default on send NYM ([#5524])
|
||||||
|
- feat: make sure any terminated task kills the watcher and write run info to db ([#5517])
|
||||||
|
- Another total_stake SQL fix ([#5516])
|
||||||
|
- Fix total_stake on SQL update ([#5514])
|
||||||
|
- build(deps): bump flate2 from 1.0.35 to 1.1.0 ([#5510])
|
||||||
|
- build(deps): bump itertools from 0.13.0 to 0.14.0 ([#5509])
|
||||||
|
- build(deps): bump the patch-updates group with 2 updates ([#5505])
|
||||||
|
- Treat gateways as Nym Nodes ([#5504])
|
||||||
|
- Update version in Cargo.toml ([#5503])
|
||||||
|
- feat: use ct_eq for checking bearer token ([#5501])
|
||||||
|
- Add extra args for the probe ([#5499])
|
||||||
|
- Fix stats bug & remove HM caching ([#5495])
|
||||||
|
- fix: Cargo.lock for contracts ([#5489])
|
||||||
|
- Display error messages if IPv4 or IPv6 address not found on nymtun0 ([#5465])
|
||||||
|
|
||||||
|
[#5611]: https://github.com/nymtech/nym/pull/5611
|
||||||
|
[#5610]: https://github.com/nymtech/nym/pull/5610
|
||||||
|
[#5609]: https://github.com/nymtech/nym/pull/5609
|
||||||
|
[#5608]: https://github.com/nymtech/nym/pull/5608
|
||||||
|
[#5606]: https://github.com/nymtech/nym/pull/5606
|
||||||
|
[#5605]: https://github.com/nymtech/nym/pull/5605
|
||||||
|
[#5604]: https://github.com/nymtech/nym/pull/5604
|
||||||
|
[#5601]: https://github.com/nymtech/nym/pull/5601
|
||||||
|
[#5600]: https://github.com/nymtech/nym/pull/5600
|
||||||
|
[#5598]: https://github.com/nymtech/nym/pull/5598
|
||||||
|
[#5597]: https://github.com/nymtech/nym/pull/5597
|
||||||
|
[#5596]: https://github.com/nymtech/nym/pull/5596
|
||||||
|
[#5594]: https://github.com/nymtech/nym/pull/5594
|
||||||
|
[#5593]: https://github.com/nymtech/nym/pull/5593
|
||||||
|
[#5592]: https://github.com/nymtech/nym/pull/5592
|
||||||
|
[#5591]: https://github.com/nymtech/nym/pull/5591
|
||||||
|
[#5590]: https://github.com/nymtech/nym/pull/5590
|
||||||
|
[#5589]: https://github.com/nymtech/nym/pull/5589
|
||||||
|
[#5588]: https://github.com/nymtech/nym/pull/5588
|
||||||
|
[#5587]: https://github.com/nymtech/nym/pull/5587
|
||||||
|
[#5585]: https://github.com/nymtech/nym/pull/5585
|
||||||
|
[#5583]: https://github.com/nymtech/nym/pull/5583
|
||||||
|
[#5578]: https://github.com/nymtech/nym/pull/5578
|
||||||
|
[#5577]: https://github.com/nymtech/nym/pull/5577
|
||||||
|
[#5576]: https://github.com/nymtech/nym/pull/5576
|
||||||
|
[#5569]: https://github.com/nymtech/nym/pull/5569
|
||||||
|
[#5554]: https://github.com/nymtech/nym/pull/5554
|
||||||
|
[#5549]: https://github.com/nymtech/nym/pull/5549
|
||||||
|
[#5542]: https://github.com/nymtech/nym/pull/5542
|
||||||
|
[#5541]: https://github.com/nymtech/nym/pull/5541
|
||||||
|
[#5537]: https://github.com/nymtech/nym/pull/5537
|
||||||
|
[#5533]: https://github.com/nymtech/nym/pull/5533
|
||||||
|
[#5526]: https://github.com/nymtech/nym/pull/5526
|
||||||
|
[#5524]: https://github.com/nymtech/nym/pull/5524
|
||||||
|
[#5517]: https://github.com/nymtech/nym/pull/5517
|
||||||
|
[#5516]: https://github.com/nymtech/nym/pull/5516
|
||||||
|
[#5514]: https://github.com/nymtech/nym/pull/5514
|
||||||
|
[#5510]: https://github.com/nymtech/nym/pull/5510
|
||||||
|
[#5509]: https://github.com/nymtech/nym/pull/5509
|
||||||
|
[#5505]: https://github.com/nymtech/nym/pull/5505
|
||||||
|
[#5504]: https://github.com/nymtech/nym/pull/5504
|
||||||
|
[#5503]: https://github.com/nymtech/nym/pull/5503
|
||||||
|
[#5501]: https://github.com/nymtech/nym/pull/5501
|
||||||
|
[#5499]: https://github.com/nymtech/nym/pull/5499
|
||||||
|
[#5495]: https://github.com/nymtech/nym/pull/5495
|
||||||
|
[#5489]: https://github.com/nymtech/nym/pull/5489
|
||||||
|
[#5465]: https://github.com/nymtech/nym/pull/5465
|
||||||
|
|
||||||
|
## [2025.4-dorina-patched] (2025-03-06)
|
||||||
|
|
||||||
|
- use legacy crypto for constructing SURB headers ([#5579])
|
||||||
|
- bugfix: make sure to correctly decode response content when putting it into error message ([#5571])
|
||||||
|
- Tweak surb management to be more conservative ([#5570])
|
||||||
|
- Deserialize v5 authenticator requests ([#5568])
|
||||||
|
- chore: additional logs when attempting to load ecash keys ([#5567])
|
||||||
|
- add full response body to error message upon decoding failure ([#5566])
|
||||||
|
- hotfix: ensure we bail on merkle leaves insertion upon missing data ([#5565])
|
||||||
|
- feature: v2 authentication request (#5537) ([#5563])
|
||||||
|
- Create authenticator v5 request/response types ([#5561])
|
||||||
|
|
||||||
|
[#5579]: https://github.com/nymtech/nym/pull/5579
|
||||||
|
[#5571]: https://github.com/nymtech/nym/pull/5571
|
||||||
|
[#5570]: https://github.com/nymtech/nym/pull/5570
|
||||||
|
[#5568]: https://github.com/nymtech/nym/pull/5568
|
||||||
|
[#5567]: https://github.com/nymtech/nym/pull/5567
|
||||||
|
[#5566]: https://github.com/nymtech/nym/pull/5566
|
||||||
|
[#5565]: https://github.com/nymtech/nym/pull/5565
|
||||||
|
[#5563]: https://github.com/nymtech/nym/pull/5563
|
||||||
|
[#5561]: https://github.com/nymtech/nym/pull/5561
|
||||||
|
|
||||||
|
## [2025.4-dorina] (2025-03-04)
|
||||||
|
|
||||||
|
- fixed sphinx version metrics registration ([#5546])
|
||||||
|
- Feature/chain status api ([#5539])
|
||||||
|
- Add SURBs soft threshold ([#5535])
|
||||||
|
- Simplify IPR v8 ([#5532])
|
||||||
|
- Shared instance for DNS AsyncResolver ([#5523])
|
||||||
|
- merge #5512 again after reverting due to incorrect rebase ([#5520])
|
||||||
|
- cherry-pick 17d3ff2d775f61aee381d90a304ed416c08f33fc onto dorina ([#5519])
|
||||||
|
- cherry-pick 6e5d0dac1b75413c5f09122b0d953f8ec6ef48df onto dorina ([#5518])
|
||||||
|
- chore: workspace global panic preventing lints ([#5512])
|
||||||
|
- bugfix: dont query for ecash apis unless necessary when spending ticketbooks ([#5508])
|
||||||
|
- bugfix: bound check when recovering a reply SURB ([#5502])
|
||||||
|
- chore: removed all old coconut code ([#5500])
|
||||||
|
- IPR request types v8 ([#5498])
|
||||||
|
- Support static routes for HTTP requests ([#5487])
|
||||||
|
- build(deps): bump the patch-updates group across 1 directory with 3 updates ([#5482])
|
||||||
|
- added missing import to doctest ([#5480])
|
||||||
|
- adjusted TestSetup::new_complex to ensure bonded node's existence ([#5478])
|
||||||
|
- Trigger contracts CI on main workspace Cargo changes ([#5477])
|
||||||
|
- build(deps): bump http from 1.1.0 to 1.2.0 ([#5472])
|
||||||
|
- build(deps): bump utoipa-swagger-ui from 8.0.3 to 8.1.0 ([#5471])
|
||||||
|
- build(deps): bump colored from 2.1.0 to 2.2.0 ([#5470])
|
||||||
|
- build(deps): bump celes from 2.4.0 to 2.5.0 ([#5469])
|
||||||
|
- build(deps): bump the patch-updates group with 2 updates ([#5467])
|
||||||
|
- build(deps): bump elliptic from 6.5.4 to 6.6.1 in /docker/typescript_client/upload_contract ([#5463])
|
||||||
|
- Run cargo autoinherit ([#5460])
|
||||||
|
- Fix clippy::precedence ([#5457])
|
||||||
|
- Provide Interval context with node descriptor endpoints ([#5456])
|
||||||
|
- fix: update fx average rate calcs to ignore 0 values ([#5454])
|
||||||
|
- Feature/add gbp currency ([#5453])
|
||||||
|
- Add helper to extract a list of sqlite files with journal files wal/shm ([#5452])
|
||||||
|
- Add a middleware layer to the nym api allowing for data compression ([#5451])
|
||||||
|
- Condense core API functionalities and enable gzip decompression for reqwest payloads ([#5450])
|
||||||
|
- build(deps): bump uniffi_build from 0.25.3 to 0.29.0 ([#5448])
|
||||||
|
- Upgrade tower to 0.5.2 ([#5446])
|
||||||
|
- build(deps): bump hickory-proto from 0.24.2 to 0.24.3 ([#5444])
|
||||||
|
- Seedable clients ([#5440])
|
||||||
|
- build(deps): bump the patch-updates group across 1 directory with 10 updates ([#5439])
|
||||||
|
- Remove all recv_with_delay and add shutdown condition to loops in client-core ([#5435])
|
||||||
|
- Disable the test for checking the remaining bandwidth in nym-node-status-api ([#5425])
|
||||||
|
- Dz nym node stats ([#5418])
|
||||||
|
- build(deps): bump hyper from 1.4.1 to 1.6.0 ([#5416])
|
||||||
|
- build(deps): bump publicsuffix from 2.2.3 to 2.3.0 ([#5367])
|
||||||
|
- Nymnode entrypoint docker ([#5300])
|
||||||
|
|
||||||
|
[#5546]: https://github.com/nymtech/nym/pull/5546
|
||||||
|
[#5539]: https://github.com/nymtech/nym/pull/5539
|
||||||
|
[#5535]: https://github.com/nymtech/nym/pull/5535
|
||||||
|
[#5532]: https://github.com/nymtech/nym/pull/5532
|
||||||
|
[#5523]: https://github.com/nymtech/nym/pull/5523
|
||||||
|
[#5520]: https://github.com/nymtech/nym/pull/5520
|
||||||
|
[#5519]: https://github.com/nymtech/nym/pull/5519
|
||||||
|
[#5518]: https://github.com/nymtech/nym/pull/5518
|
||||||
|
[#5512]: https://github.com/nymtech/nym/pull/5512
|
||||||
|
[#5508]: https://github.com/nymtech/nym/pull/5508
|
||||||
|
[#5502]: https://github.com/nymtech/nym/pull/5502
|
||||||
|
[#5500]: https://github.com/nymtech/nym/pull/5500
|
||||||
|
[#5498]: https://github.com/nymtech/nym/pull/5498
|
||||||
|
[#5487]: https://github.com/nymtech/nym/pull/5487
|
||||||
|
[#5482]: https://github.com/nymtech/nym/pull/5482
|
||||||
|
[#5480]: https://github.com/nymtech/nym/pull/5480
|
||||||
|
[#5478]: https://github.com/nymtech/nym/pull/5478
|
||||||
|
[#5477]: https://github.com/nymtech/nym/pull/5477
|
||||||
|
[#5472]: https://github.com/nymtech/nym/pull/5472
|
||||||
|
[#5471]: https://github.com/nymtech/nym/pull/5471
|
||||||
|
[#5470]: https://github.com/nymtech/nym/pull/5470
|
||||||
|
[#5469]: https://github.com/nymtech/nym/pull/5469
|
||||||
|
[#5467]: https://github.com/nymtech/nym/pull/5467
|
||||||
|
[#5463]: https://github.com/nymtech/nym/pull/5463
|
||||||
|
[#5460]: https://github.com/nymtech/nym/pull/5460
|
||||||
|
[#5457]: https://github.com/nymtech/nym/pull/5457
|
||||||
|
[#5456]: https://github.com/nymtech/nym/pull/5456
|
||||||
|
[#5454]: https://github.com/nymtech/nym/pull/5454
|
||||||
|
[#5453]: https://github.com/nymtech/nym/pull/5453
|
||||||
|
[#5452]: https://github.com/nymtech/nym/pull/5452
|
||||||
|
[#5451]: https://github.com/nymtech/nym/pull/5451
|
||||||
|
[#5450]: https://github.com/nymtech/nym/pull/5450
|
||||||
|
[#5448]: https://github.com/nymtech/nym/pull/5448
|
||||||
|
[#5446]: https://github.com/nymtech/nym/pull/5446
|
||||||
|
[#5444]: https://github.com/nymtech/nym/pull/5444
|
||||||
|
[#5440]: https://github.com/nymtech/nym/pull/5440
|
||||||
|
[#5439]: https://github.com/nymtech/nym/pull/5439
|
||||||
|
[#5435]: https://github.com/nymtech/nym/pull/5435
|
||||||
|
[#5425]: https://github.com/nymtech/nym/pull/5425
|
||||||
|
[#5418]: https://github.com/nymtech/nym/pull/5418
|
||||||
|
[#5416]: https://github.com/nymtech/nym/pull/5416
|
||||||
|
[#5367]: https://github.com/nymtech/nym/pull/5367
|
||||||
|
[#5300]: https://github.com/nymtech/nym/pull/5300
|
||||||
|
|
||||||
|
## [2025.3-ruta] (2025-02-10)
|
||||||
|
|
||||||
|
- Push down forget me to client configs ([#5431])
|
||||||
|
- Fix statistics shutdown ([#5426])
|
||||||
|
- Make wait_for_graceful_shutdown to be pub ([#5424])
|
||||||
|
- Upgrade to thiserror 2.0 ([#5414])
|
||||||
|
- build(deps): bump the patch-updates group across 1 directory with 9 updates ([#5406])
|
||||||
|
- Relocate a validator api function ([#5401])
|
||||||
|
- Send shutdown instead of panic when reaching max fail ([#5398])
|
||||||
|
- Change Explorer URL to new smooshed nodes ([#5396])
|
||||||
|
- reduce log severity for checking topology validity ([#5395])
|
||||||
|
- MixnetClient can send ClientRequests ([#5381])
|
||||||
|
- Fix missing path triggers for CI ([#5380])
|
||||||
|
- Uncouple storage reference for bandwidth client ([#5372])
|
||||||
|
- build(deps): bump tokio from 1.40.0 to 1.43.0 ([#5370])
|
||||||
|
- DNS resolver configuration for internal HTTP client lookups ([#5355])
|
||||||
|
- Update README.md ([#5328])
|
||||||
|
- Update README.md ([#5327])
|
||||||
|
|
||||||
|
[#5431]: https://github.com/nymtech/nym/pull/5431
|
||||||
|
[#5426]: https://github.com/nymtech/nym/pull/5426
|
||||||
|
[#5424]: https://github.com/nymtech/nym/pull/5424
|
||||||
|
[#5414]: https://github.com/nymtech/nym/pull/5414
|
||||||
|
[#5406]: https://github.com/nymtech/nym/pull/5406
|
||||||
|
[#5401]: https://github.com/nymtech/nym/pull/5401
|
||||||
|
[#5398]: https://github.com/nymtech/nym/pull/5398
|
||||||
|
[#5396]: https://github.com/nymtech/nym/pull/5396
|
||||||
|
[#5395]: https://github.com/nymtech/nym/pull/5395
|
||||||
|
[#5381]: https://github.com/nymtech/nym/pull/5381
|
||||||
|
[#5380]: https://github.com/nymtech/nym/pull/5380
|
||||||
|
[#5372]: https://github.com/nymtech/nym/pull/5372
|
||||||
|
[#5370]: https://github.com/nymtech/nym/pull/5370
|
||||||
|
[#5355]: https://github.com/nymtech/nym/pull/5355
|
||||||
|
[#5328]: https://github.com/nymtech/nym/pull/5328
|
||||||
|
[#5327]: https://github.com/nymtech/nym/pull/5327
|
||||||
|
|
||||||
|
## [2025.2-hu] (2025-02-04)
|
||||||
|
|
||||||
|
- Feature/remove double spending bloomfilter ([#5417])
|
||||||
|
- HU - Downgrade harmless log message from info to debug ([#5405])
|
||||||
|
- lower default ticket verification quorum to 0.7 ([#5404])
|
||||||
|
- Downgrade harmless log message from info to debug ([#5403])
|
||||||
|
- Redirect from mixnode page to nodes page ([#5397])
|
||||||
|
- chore :update version of chain watcher and validator rewarder ([#5394])
|
||||||
|
- bugfix: correctly handle ignore epoch roles flag ([#5390])
|
||||||
|
- bugfix: terminate mixnet socket listener on shutdown ([#5389])
|
||||||
|
- feat: make client ignore dual mode nodes by default ([#5388])
|
||||||
|
- Handle ecash network errors differently ([#5378])
|
||||||
|
- Remove empty ephemeral keys ([#5376])
|
||||||
|
- fixed sql migration for adding default message timestamp ([#5374])
|
||||||
|
- Bind to [::] on nym-node for both IP versions ([#5361])
|
||||||
|
- exposed NymApiClient method for obtaining node performance history ([#5360])
|
||||||
|
- Client gateway selection ([#5358])
|
||||||
|
- chore: refresh wasm sdk ([#5353])
|
||||||
|
- chore: update indexed_db_futures ([#5347])
|
||||||
|
- build(deps): bump mikefarah/yq from 4.44.6 to 4.45.1 ([#5342])
|
||||||
|
- updated cosmrs and tendermint-rpc to their most recent versions ([#5339])
|
||||||
|
- build(deps): bump ts-rs from 10.0.0 to 10.1.0 ([#5338])
|
||||||
|
- build(deps): bump tempfile from 3.14.0 to 3.15.0 ([#5337])
|
||||||
|
- build(deps): bump the patch-updates group with 8 updates ([#5336])
|
||||||
|
- feature: introduce /load endpoint for self-reported quantised NymNode load ([#5326])
|
||||||
|
- feature: `CancellationToken`-based shutdowns ([#5325])
|
||||||
|
- Use expect in geodata test to give error message on failure ([#5314])
|
||||||
|
- feature: periodically remove stale gateway messages ([#5312])
|
||||||
|
- build(deps): bump the patch-updates group across 1 directory with 35 updates ([#5310])
|
||||||
|
- Add dependabot assigns for the root cargo ecosystem ([#5297])
|
||||||
|
- Move tun constants to network defaults ([#5286])
|
||||||
|
- Include IPINFO_API_TOKEN in nightly CI ([#5285])
|
||||||
|
- Nyx Chain Watcher ([#5274])
|
||||||
|
- bugfix: remove unnecessary arguments for nym-api swagger endpoints ([#5272])
|
||||||
|
- feature: nym topology revamp ([#5271])
|
||||||
|
- Add windows to CI builds ([#5269])
|
||||||
|
- http-api-client: deduplicate code ([#5267])
|
||||||
|
- build(deps): bump http from 1.1.0 to 1.2.0 ([#5228])
|
||||||
|
- NS API: add mixnet scraper ([#5200])
|
||||||
|
- build(deps): bump criterion from 0.4.0 to 0.5.1 ([#4911])
|
||||||
|
|
||||||
|
[#5417]: https://github.com/nymtech/nym/pull/5417
|
||||||
|
[#5405]: https://github.com/nymtech/nym/pull/5405
|
||||||
|
[#5404]: https://github.com/nymtech/nym/pull/5404
|
||||||
|
[#5403]: https://github.com/nymtech/nym/pull/5403
|
||||||
|
[#5397]: https://github.com/nymtech/nym/pull/5397
|
||||||
|
[#5394]: https://github.com/nymtech/nym/pull/5394
|
||||||
|
[#5390]: https://github.com/nymtech/nym/pull/5390
|
||||||
|
[#5389]: https://github.com/nymtech/nym/pull/5389
|
||||||
|
[#5388]: https://github.com/nymtech/nym/pull/5388
|
||||||
|
[#5378]: https://github.com/nymtech/nym/pull/5378
|
||||||
|
[#5376]: https://github.com/nymtech/nym/pull/5376
|
||||||
|
[#5374]: https://github.com/nymtech/nym/pull/5374
|
||||||
|
[#5361]: https://github.com/nymtech/nym/pull/5361
|
||||||
|
[#5360]: https://github.com/nymtech/nym/pull/5360
|
||||||
|
[#5358]: https://github.com/nymtech/nym/pull/5358
|
||||||
|
[#5353]: https://github.com/nymtech/nym/pull/5353
|
||||||
|
[#5347]: https://github.com/nymtech/nym/pull/5347
|
||||||
|
[#5342]: https://github.com/nymtech/nym/pull/5342
|
||||||
|
[#5339]: https://github.com/nymtech/nym/pull/5339
|
||||||
|
[#5338]: https://github.com/nymtech/nym/pull/5338
|
||||||
|
[#5337]: https://github.com/nymtech/nym/pull/5337
|
||||||
|
[#5336]: https://github.com/nymtech/nym/pull/5336
|
||||||
|
[#5326]: https://github.com/nymtech/nym/pull/5326
|
||||||
|
[#5325]: https://github.com/nymtech/nym/pull/5325
|
||||||
|
[#5314]: https://github.com/nymtech/nym/pull/5314
|
||||||
|
[#5312]: https://github.com/nymtech/nym/pull/5312
|
||||||
|
[#5310]: https://github.com/nymtech/nym/pull/5310
|
||||||
|
[#5297]: https://github.com/nymtech/nym/pull/5297
|
||||||
|
[#5286]: https://github.com/nymtech/nym/pull/5286
|
||||||
|
[#5285]: https://github.com/nymtech/nym/pull/5285
|
||||||
|
[#5274]: https://github.com/nymtech/nym/pull/5274
|
||||||
|
[#5272]: https://github.com/nymtech/nym/pull/5272
|
||||||
|
[#5271]: https://github.com/nymtech/nym/pull/5271
|
||||||
|
[#5269]: https://github.com/nymtech/nym/pull/5269
|
||||||
|
[#5267]: https://github.com/nymtech/nym/pull/5267
|
||||||
|
[#5228]: https://github.com/nymtech/nym/pull/5228
|
||||||
|
[#5200]: https://github.com/nymtech/nym/pull/5200
|
||||||
|
[#4911]: https://github.com/nymtech/nym/pull/4911
|
||||||
|
|
||||||
|
## [2025.1-reeses] (2025-01-15)
|
||||||
|
|
||||||
|
- Feature, Future/legacy alert ([#5346])
|
||||||
|
- chore: readjusted --mode behaviour to fix the regression ([#5331])
|
||||||
|
- chore: apply 1.84 linter suggestions ([#5330])
|
||||||
|
- bugfix: make sure refresh data key matches bond info ([#5329])
|
||||||
|
- reduce log severity for number of packets being delayed ([#5321])
|
||||||
|
- feat: warn users if node is run in exit mode only ([#5320])
|
||||||
|
- Bugfix/contract version assignment ([#5318])
|
||||||
|
- fixed client session histogram buckets ([#5316])
|
||||||
|
- amend 250gb limit ([#5313])
|
||||||
|
- feature: expand nym-node prometheus metrics ([#5298])
|
||||||
|
- Cherry picked #5286 ([#5287])
|
||||||
|
- Add close to credential storage ([#5283])
|
||||||
|
- feature: wireguard metrics ([#5278])
|
||||||
|
- Add PATCH support to nym-http-api-client ([#5260])
|
||||||
|
- chore: removed legacy socks5 listener ([#5259])
|
||||||
|
- bugfix: make sure to apply gateway score filtering when choosing initial node ([#5256])
|
||||||
|
- Update TS bindings ([#5255])
|
||||||
|
- Add conversion unit tests for auth msg ([#5251])
|
||||||
|
- Add control messages to GatewayTransciver ([#5247])
|
||||||
|
- Remove unneeded async function annotation ([#5246])
|
||||||
|
- bugfix: make sure to update timestamp of last batch verification to prevent double redemption ([#5239])
|
||||||
|
- Add FromStr impl for UserAgent ([#5236])
|
||||||
|
- Extend swagger docs ([#5235])
|
||||||
|
- TicketType derive Hash and Eq ([#5233])
|
||||||
|
- Add fd callback to client core ([#5230])
|
||||||
|
- Extend raw ws fd for gateway client ([#5218])
|
||||||
|
- Shipping raw metrics to PG ([#5216])
|
||||||
|
- Change sqlite journal mode to WAL ([#5213])
|
||||||
|
- Derive serialize for UserAgent ([#5210])
|
||||||
|
- Restore Location fields ([#5208])
|
||||||
|
- better date serialization ([#5207])
|
||||||
|
- Fix overflow ([#5204])
|
||||||
|
- feature: hopefully final steps of the smoosh™️ ([#5201])
|
||||||
|
- Fix overflow ([#5184])
|
||||||
|
- NS API - Gateway stats scraping ([#5180])
|
||||||
|
- introduced initial internal commands for nym-cli: ecash key and request generation ([#5174])
|
||||||
|
- Move NS client to separate package under NS API ([#5171])
|
||||||
|
- build(deps): bump micromatch from 4.0.4 to 4.0.8 in /testnet-faucet ([#4813])
|
||||||
|
|
||||||
|
[#5346]: https://github.com/nymtech/nym/pull/5346
|
||||||
|
[#5331]: https://github.com/nymtech/nym/pull/5331
|
||||||
|
[#5330]: https://github.com/nymtech/nym/pull/5330
|
||||||
|
[#5329]: https://github.com/nymtech/nym/pull/5329
|
||||||
|
[#5321]: https://github.com/nymtech/nym/pull/5321
|
||||||
|
[#5320]: https://github.com/nymtech/nym/pull/5320
|
||||||
|
[#5318]: https://github.com/nymtech/nym/pull/5318
|
||||||
|
[#5316]: https://github.com/nymtech/nym/pull/5316
|
||||||
|
[#5313]: https://github.com/nymtech/nym/pull/5313
|
||||||
|
[#5298]: https://github.com/nymtech/nym/pull/5298
|
||||||
|
[#5287]: https://github.com/nymtech/nym/pull/5287
|
||||||
|
[#5283]: https://github.com/nymtech/nym/pull/5283
|
||||||
|
[#5278]: https://github.com/nymtech/nym/pull/5278
|
||||||
|
[#5260]: https://github.com/nymtech/nym/pull/5260
|
||||||
|
[#5259]: https://github.com/nymtech/nym/pull/5259
|
||||||
|
[#5256]: https://github.com/nymtech/nym/pull/5256
|
||||||
|
[#5255]: https://github.com/nymtech/nym/pull/5255
|
||||||
|
[#5251]: https://github.com/nymtech/nym/pull/5251
|
||||||
|
[#5247]: https://github.com/nymtech/nym/pull/5247
|
||||||
|
[#5246]: https://github.com/nymtech/nym/pull/5246
|
||||||
|
[#5239]: https://github.com/nymtech/nym/pull/5239
|
||||||
|
[#5236]: https://github.com/nymtech/nym/pull/5236
|
||||||
|
[#5235]: https://github.com/nymtech/nym/pull/5235
|
||||||
|
[#5233]: https://github.com/nymtech/nym/pull/5233
|
||||||
|
[#5230]: https://github.com/nymtech/nym/pull/5230
|
||||||
|
[#5218]: https://github.com/nymtech/nym/pull/5218
|
||||||
|
[#5216]: https://github.com/nymtech/nym/pull/5216
|
||||||
|
[#5213]: https://github.com/nymtech/nym/pull/5213
|
||||||
|
[#5210]: https://github.com/nymtech/nym/pull/5210
|
||||||
|
[#5208]: https://github.com/nymtech/nym/pull/5208
|
||||||
|
[#5207]: https://github.com/nymtech/nym/pull/5207
|
||||||
|
[#5204]: https://github.com/nymtech/nym/pull/5204
|
||||||
|
[#5201]: https://github.com/nymtech/nym/pull/5201
|
||||||
|
[#5184]: https://github.com/nymtech/nym/pull/5184
|
||||||
|
[#5180]: https://github.com/nymtech/nym/pull/5180
|
||||||
|
[#5174]: https://github.com/nymtech/nym/pull/5174
|
||||||
|
[#5171]: https://github.com/nymtech/nym/pull/5171
|
||||||
|
[#4813]: https://github.com/nymtech/nym/pull/4813
|
||||||
|
|
||||||
|
## [2024.14-crunch-patched] (2024-12-17)
|
||||||
|
|
||||||
|
- Fixes an issue to allow previously registered clients to connect to latest nym-nodes
|
||||||
|
- Fixes compatibility issues between nym-nodes and older clients
|
||||||
|
|
||||||
|
## [2024.14-crunch] (2024-12-11)
|
||||||
|
|
||||||
|
- Merge/release/2024.14-crunch ([#5242])
|
||||||
|
- bugfix: added explicit openapi servers to account for route prefixes ([#5237])
|
||||||
|
- Further config score adjustments ([#5225])
|
||||||
|
- feature: remove any filtering on node semver ([#5224])
|
||||||
|
- Backport #5218 ([#5220])
|
||||||
|
- Derive serialize for UserAgent (#5210) ([#5217])
|
||||||
|
- dont consider legacy nodes for rewarded set selection ([#5215])
|
||||||
|
- introduce UNSTABLE endpoints for returning network monitor run details ([#5214])
|
||||||
|
- Nmv2 add debug config ([#5212])
|
||||||
|
- nym-api NMv1 adjustments ([#5209])
|
||||||
|
- adjusted config score penalty calculation ([#5206])
|
||||||
|
- Fix backwards compat mac generation ([#5202])
|
||||||
|
- merge crunch into develop ([#5199])
|
||||||
|
- Update Security disclosure email, public key and policy ([#5195])
|
||||||
|
- Guard storage access with cache ([#5193])
|
||||||
|
- chore: apply 1.84 linter suggestions ([#5192])
|
||||||
|
- improvement: make internal gateway clients use the same topology cache ([#5191])
|
||||||
|
- Bugfix/credential proxy sequencing ([#5187])
|
||||||
|
- Add monitor_run and testing_route indexes ([#5182])
|
||||||
|
- Add indexes to monitor run and testing route ([#5181])
|
||||||
|
- bugfix: fixed nym-node config migrations (again) ([#5179])
|
||||||
|
- bugfix: use default value for verloc config when deserialising missing values ([#5177])
|
||||||
|
- Remove peers with no allowed ip from storage ([#5175])
|
||||||
|
- Move two minor jobs to free tier github hosted runners ([#5169])
|
||||||
|
- Add support for DELETE to nym-http-api-client ([#5166])
|
||||||
|
- Fix env var name ([#5165])
|
||||||
|
- Add strum::EnumIter for TicketType ([#5164])
|
||||||
|
- Add export_to_env to NymNetworkDetails ([#5162])
|
||||||
|
- bugfix: correctly expose ecash-related data on nym-api ([#5155])
|
||||||
|
- fix: validator-rewarder GH job ([#5151])
|
||||||
|
- build(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /testnet-faucet ([#5150])
|
||||||
|
- build(deps): bump mikefarah/yq from 4.44.3 to 4.44.5 ([#5149])
|
||||||
|
- start session collection for exit gateways ([#5148])
|
||||||
|
- add version to clientStatsReport ([#5147])
|
||||||
|
- update serde_json_path due to compilation issue ([#5144])
|
||||||
|
- chore: remove standalone legacy mixnode/gateway binaries ([#5135])
|
||||||
|
- [Product Data] Set up country reporting from vpn-client ([#5134])
|
||||||
|
- removed ci-nym-api-tests.yml which was running outdated (and broken) tests ([#5133])
|
||||||
|
- CI: reduce jobs running on cluster ([#5132])
|
||||||
|
- [DOCS/operators]: Release changes v2024.13-magura & Tokenomics pages v1.0 ([#5128])
|
||||||
|
- NS Agent auth with NS API ([#5127])
|
||||||
|
- [Product Data] Config deserialization bug fix ([#5126])
|
||||||
|
- bugfix: don't send empty BankMsg in ecash contract ([#5121])
|
||||||
|
- [Product data] Data consumption with ecash ticket ([#5120])
|
||||||
|
- feat: add GH workflow for nym-validator-rewarder ([#5119])
|
||||||
|
- feat: add Dockerfile and add env vars for clap arguments ([#5118])
|
||||||
|
- feature: config score ([#5117])
|
||||||
|
- [Product Data] Add stats reporting configuration in client config ([#5115])
|
||||||
|
- Correct IPv6 address generation ([#5113])
|
||||||
|
- feature: rewarding for ticketbook issuance ([#5112])
|
||||||
|
- Add granular log on nym-node ([#5111])
|
||||||
|
- Send mixnet packet stats using task client ([#5109])
|
||||||
|
- Expose time range ([#5108])
|
||||||
|
- [Product Data] Client-side stats collection ([#5107])
|
||||||
|
- chore: ecash contract migration to remove unused 'redemption_gateway_share' ([#5104])
|
||||||
|
- [Product Data] Better unique user count on gateways ([#5084])
|
||||||
|
- feat: add nym node GH workflow ([#5080])
|
||||||
|
- IPv6 support for wireguard ([#5059])
|
||||||
|
- Node Status API ([#5050])
|
||||||
|
- Authenticator CLI client mode ([#5044])
|
||||||
|
- Integrate nym-credential-proxy into workspace ([#5027])
|
||||||
|
- [Product Data] Introduce data persistence on gateways ([#5022])
|
||||||
|
- Bump the patch-updates group across 1 directory with 10 updates ([#5011])
|
||||||
|
- build(deps): bump once_cell from 1.19.0 to 1.20.2 ([#4952])
|
||||||
|
- Create TaskStatusEvent trait instead of piggybacking on Error ([#4919])
|
||||||
|
- build(deps): bump lazy_static from 1.4.0 to 1.5.0 ([#4913])
|
||||||
|
- Sync code with .env in build.rs ([#4876])
|
||||||
|
- build(deps): bump axios from 1.6.0 to 1.7.5 in /nym-api/tests ([#4790])
|
||||||
|
- Bump elliptic from 6.5.4 to 6.5.7 in /testnet-faucet ([#4768])
|
||||||
|
|
||||||
|
[#5242]: https://github.com/nymtech/nym/pull/5242
|
||||||
|
[#5237]: https://github.com/nymtech/nym/pull/5237
|
||||||
|
[#5225]: https://github.com/nymtech/nym/pull/5225
|
||||||
|
[#5224]: https://github.com/nymtech/nym/pull/5224
|
||||||
|
[#5220]: https://github.com/nymtech/nym/pull/5220
|
||||||
|
[#5217]: https://github.com/nymtech/nym/pull/5217
|
||||||
|
[#5215]: https://github.com/nymtech/nym/pull/5215
|
||||||
|
[#5214]: https://github.com/nymtech/nym/pull/5214
|
||||||
|
[#5212]: https://github.com/nymtech/nym/pull/5212
|
||||||
|
[#5209]: https://github.com/nymtech/nym/pull/5209
|
||||||
|
[#5206]: https://github.com/nymtech/nym/pull/5206
|
||||||
|
[#5202]: https://github.com/nymtech/nym/pull/5202
|
||||||
|
[#5199]: https://github.com/nymtech/nym/pull/5199
|
||||||
|
[#5195]: https://github.com/nymtech/nym/pull/5195
|
||||||
|
[#5193]: https://github.com/nymtech/nym/pull/5193
|
||||||
|
[#5192]: https://github.com/nymtech/nym/pull/5192
|
||||||
|
[#5191]: https://github.com/nymtech/nym/pull/5191
|
||||||
|
[#5187]: https://github.com/nymtech/nym/pull/5187
|
||||||
|
[#5182]: https://github.com/nymtech/nym/pull/5182
|
||||||
|
[#5181]: https://github.com/nymtech/nym/pull/5181
|
||||||
|
[#5179]: https://github.com/nymtech/nym/pull/5179
|
||||||
|
[#5177]: https://github.com/nymtech/nym/pull/5177
|
||||||
|
[#5175]: https://github.com/nymtech/nym/pull/5175
|
||||||
|
[#5169]: https://github.com/nymtech/nym/pull/5169
|
||||||
|
[#5166]: https://github.com/nymtech/nym/pull/5166
|
||||||
|
[#5165]: https://github.com/nymtech/nym/pull/5165
|
||||||
|
[#5164]: https://github.com/nymtech/nym/pull/5164
|
||||||
|
[#5162]: https://github.com/nymtech/nym/pull/5162
|
||||||
|
[#5155]: https://github.com/nymtech/nym/pull/5155
|
||||||
|
[#5151]: https://github.com/nymtech/nym/pull/5151
|
||||||
|
[#5150]: https://github.com/nymtech/nym/pull/5150
|
||||||
|
[#5149]: https://github.com/nymtech/nym/pull/5149
|
||||||
|
[#5148]: https://github.com/nymtech/nym/pull/5148
|
||||||
|
[#5147]: https://github.com/nymtech/nym/pull/5147
|
||||||
|
[#5144]: https://github.com/nymtech/nym/pull/5144
|
||||||
|
[#5135]: https://github.com/nymtech/nym/pull/5135
|
||||||
|
[#5134]: https://github.com/nymtech/nym/pull/5134
|
||||||
|
[#5133]: https://github.com/nymtech/nym/pull/5133
|
||||||
|
[#5132]: https://github.com/nymtech/nym/pull/5132
|
||||||
|
[#5128]: https://github.com/nymtech/nym/pull/5128
|
||||||
|
[#5127]: https://github.com/nymtech/nym/pull/5127
|
||||||
|
[#5126]: https://github.com/nymtech/nym/pull/5126
|
||||||
|
[#5121]: https://github.com/nymtech/nym/pull/5121
|
||||||
|
[#5120]: https://github.com/nymtech/nym/pull/5120
|
||||||
|
[#5119]: https://github.com/nymtech/nym/pull/5119
|
||||||
|
[#5118]: https://github.com/nymtech/nym/pull/5118
|
||||||
|
[#5117]: https://github.com/nymtech/nym/pull/5117
|
||||||
|
[#5115]: https://github.com/nymtech/nym/pull/5115
|
||||||
|
[#5113]: https://github.com/nymtech/nym/pull/5113
|
||||||
|
[#5112]: https://github.com/nymtech/nym/pull/5112
|
||||||
|
[#5111]: https://github.com/nymtech/nym/pull/5111
|
||||||
|
[#5109]: https://github.com/nymtech/nym/pull/5109
|
||||||
|
[#5108]: https://github.com/nymtech/nym/pull/5108
|
||||||
|
[#5107]: https://github.com/nymtech/nym/pull/5107
|
||||||
|
[#5104]: https://github.com/nymtech/nym/pull/5104
|
||||||
|
[#5084]: https://github.com/nymtech/nym/pull/5084
|
||||||
|
[#5080]: https://github.com/nymtech/nym/pull/5080
|
||||||
|
[#5059]: https://github.com/nymtech/nym/pull/5059
|
||||||
|
[#5050]: https://github.com/nymtech/nym/pull/5050
|
||||||
|
[#5044]: https://github.com/nymtech/nym/pull/5044
|
||||||
|
[#5027]: https://github.com/nymtech/nym/pull/5027
|
||||||
|
[#5022]: https://github.com/nymtech/nym/pull/5022
|
||||||
|
[#5011]: https://github.com/nymtech/nym/pull/5011
|
||||||
|
[#4952]: https://github.com/nymtech/nym/pull/4952
|
||||||
|
[#4919]: https://github.com/nymtech/nym/pull/4919
|
||||||
|
[#4913]: https://github.com/nymtech/nym/pull/4913
|
||||||
|
[#4876]: https://github.com/nymtech/nym/pull/4876
|
||||||
|
[#4790]: https://github.com/nymtech/nym/pull/4790
|
||||||
|
[#4768]: https://github.com/nymtech/nym/pull/4768
|
||||||
|
|
||||||
## [2024.13-magura-drift] (2024-11-29)
|
## [2024.13-magura-drift] (2024-11-29)
|
||||||
|
|
||||||
- Optimised syncing bandwidth information to storage
|
- Optimised syncing bandwidth information to storage
|
||||||
@@ -46,7 +675,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
- bugfix/feature: added NymApiClient method to get all skimmed nodes ([#5062])
|
- bugfix/feature: added NymApiClient method to get all skimmed nodes ([#5062])
|
||||||
- Merge1/release/2024.13 magura ([#5061])
|
- Merge1/release/2024.13 magura ([#5061])
|
||||||
- added hacky routes to return nymnodes alongside legacy nodes ([#5051])
|
- added hacky routes to return nymnodes alongside legacy nodes ([#5051])
|
||||||
- bugfix: mark migrated gateways as rewarded in the previous epoch in case theyre in the rewarded set ([#5049])
|
- bugfix: mark migrated gateways as rewarded in the previous epoch in case they're, their, there in the rewarded set ([#5049])
|
||||||
- bugfix: adjust runtime storage migration ([#5047])
|
- bugfix: adjust runtime storage migration ([#5047])
|
||||||
- bugfix: supersede 'cb13be27f8f61d9ae74d924e85d2e6787895eb14' by using… ([#5046])
|
- bugfix: supersede 'cb13be27f8f61d9ae74d924e85d2e6787895eb14' by using… ([#5046])
|
||||||
- bugfix: restore default http port for nym-api ([#5045])
|
- bugfix: restore default http port for nym-api ([#5045])
|
||||||
@@ -107,7 +736,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
- Fix broken build after merge ([#4937])
|
- Fix broken build after merge ([#4937])
|
||||||
- bugfix: correctly paginate through 'search_tx' endpoint ([#4936])
|
- bugfix: correctly paginate through 'search_tx' endpoint ([#4936])
|
||||||
- Add more conversions for responses of authenticator messages ([#4929])
|
- Add more conversions for responses of authenticator messages ([#4929])
|
||||||
- Directory Sevices v2.1 ([#4903])
|
- Directory Services, Devices v2.1 ([#4903])
|
||||||
- Migrate Legacy Node (Frontend) ([#4826])
|
- Migrate Legacy Node (Frontend) ([#4826])
|
||||||
- Fix critical issues SI84 and SI85 from Cure53 ([#4758])
|
- Fix critical issues SI84 and SI85 from Cure53 ([#4758])
|
||||||
|
|
||||||
@@ -491,7 +1120,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
- Remove stale peers ([#4640])
|
- Remove stale peers ([#4640])
|
||||||
- Add generic wg private network routing ([#4636])
|
- Add generic wg private network routing ([#4636])
|
||||||
- Feature/new node endpoints ([#4635])
|
- Feature/new node endpoints ([#4635])
|
||||||
- standarised ContractBuildInformation and added it to all contracts ([#4631])
|
- standardised ContractBuildInformation and added it to all contracts ([#4631])
|
||||||
- validate nym-node public ips on startup ([#4630])
|
- validate nym-node public ips on startup ([#4630])
|
||||||
- Bump defguard wg ([#4625])
|
- Bump defguard wg ([#4625])
|
||||||
- Fix cargo warnings ([#4624])
|
- Fix cargo warnings ([#4624])
|
||||||
@@ -1112,7 +1741,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
- clean-up nym-api startup arguments/flags to use clap 3 and its macro-derived arguments ([#2772])
|
- clean-up nym-api startup arguments/flags to use clap 3 and its macro-derived arguments ([#2772])
|
||||||
- renamed all references to validator_api to nym_api
|
- renamed all references to validator_api to nym_api
|
||||||
- renamed all references to nymd to nyxd ([#2696])
|
- renamed all references to nymd to nyxd ([#2696])
|
||||||
- all-binaries: standarised argument names (note: old names should still be accepted) ([#2762]
|
- all-binaries: standardised argument names (note: old names should still be accepted) ([#2762]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@@ -1617,7 +2246,7 @@ The release also include some additional work for distributed key generation in
|
|||||||
- Explorer UI tests missing data-testid [\#903](https://github.com/nymtech/nym/pull/903) ([tommyv1987](https://github.com/tommyv1987))
|
- Explorer UI tests missing data-testid [\#903](https://github.com/nymtech/nym/pull/903) ([tommyv1987](https://github.com/tommyv1987))
|
||||||
- Fix up Nym-Wallet README.md [\#899](https://github.com/nymtech/nym/pull/899) ([tommyv1987](https://github.com/tommyv1987))
|
- Fix up Nym-Wallet README.md [\#899](https://github.com/nymtech/nym/pull/899) ([tommyv1987](https://github.com/tommyv1987))
|
||||||
- Feature/batch delegator rewarding [\#898](https://github.com/nymtech/nym/pull/898) ([jstuczyn](https://github.com/jstuczyn))
|
- Feature/batch delegator rewarding [\#898](https://github.com/nymtech/nym/pull/898) ([jstuczyn](https://github.com/jstuczyn))
|
||||||
- Bug mapp nodemap [\#897](https://github.com/nymtech/nym/pull/897) ([Aid19801](https://github.com/Aid19801))
|
- Bug map nodemap [\#897](https://github.com/nymtech/nym/pull/897) ([Aid19801](https://github.com/Aid19801))
|
||||||
- Bug fix/macos keyboard shortcuts [\#896](https://github.com/nymtech/nym/pull/896) ([fmtabbara](https://github.com/fmtabbara))
|
- Bug fix/macos keyboard shortcuts [\#896](https://github.com/nymtech/nym/pull/896) ([fmtabbara](https://github.com/fmtabbara))
|
||||||
- Add a Mobile Nav to the Network Explorer [\#895](https://github.com/nymtech/nym/pull/895) ([Aid19801](https://github.com/Aid19801))
|
- Add a Mobile Nav to the Network Explorer [\#895](https://github.com/nymtech/nym/pull/895) ([Aid19801](https://github.com/Aid19801))
|
||||||
- Only use ts-rs in tests [\#894](https://github.com/nymtech/nym/pull/894) ([durch](https://github.com/durch))
|
- Only use ts-rs in tests [\#894](https://github.com/nymtech/nym/pull/894) ([durch](https://github.com/durch))
|
||||||
|
|||||||
Generated
+2987
-2420
File diff suppressed because it is too large
Load Diff
+128
-121
@@ -32,9 +32,8 @@ members = [
|
|||||||
"common/client-libs/validator-client",
|
"common/client-libs/validator-client",
|
||||||
"common/commands",
|
"common/commands",
|
||||||
"common/config",
|
"common/config",
|
||||||
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
|
|
||||||
"common/cosmwasm-smart-contracts/coconut-dkg",
|
"common/cosmwasm-smart-contracts/coconut-dkg",
|
||||||
"common/cosmwasm-smart-contracts/contracts-common",
|
"common/cosmwasm-smart-contracts/contracts-common", "common/cosmwasm-smart-contracts/easy_addr",
|
||||||
"common/cosmwasm-smart-contracts/ecash-contract",
|
"common/cosmwasm-smart-contracts/ecash-contract",
|
||||||
"common/cosmwasm-smart-contracts/group-contract",
|
"common/cosmwasm-smart-contracts/group-contract",
|
||||||
"common/cosmwasm-smart-contracts/mixnet-contract",
|
"common/cosmwasm-smart-contracts/mixnet-contract",
|
||||||
@@ -48,13 +47,12 @@ members = [
|
|||||||
"common/credentials-interface",
|
"common/credentials-interface",
|
||||||
"common/crypto",
|
"common/crypto",
|
||||||
"common/dkg",
|
"common/dkg",
|
||||||
"common/ecash-double-spending",
|
|
||||||
"common/ecash-time",
|
"common/ecash-time",
|
||||||
"common/execute",
|
"common/execute",
|
||||||
"common/exit-policy",
|
"common/exit-policy",
|
||||||
"common/gateway-requests",
|
"common/gateway-requests",
|
||||||
"common/gateway-storage",
|
|
||||||
"common/gateway-stats-storage",
|
"common/gateway-stats-storage",
|
||||||
|
"common/gateway-storage",
|
||||||
"common/http-api-client",
|
"common/http-api-client",
|
||||||
"common/http-api-common",
|
"common/http-api-common",
|
||||||
"common/inclusion-probability",
|
"common/inclusion-probability",
|
||||||
@@ -67,7 +65,6 @@ members = [
|
|||||||
"common/nym-id",
|
"common/nym-id",
|
||||||
"common/nym-metrics",
|
"common/nym-metrics",
|
||||||
"common/nym_offline_compact_ecash",
|
"common/nym_offline_compact_ecash",
|
||||||
"common/nymcoconut",
|
|
||||||
"common/nymsphinx",
|
"common/nymsphinx",
|
||||||
"common/nymsphinx/acknowledgements",
|
"common/nymsphinx/acknowledgements",
|
||||||
"common/nymsphinx/addressing",
|
"common/nymsphinx/addressing",
|
||||||
@@ -93,47 +90,53 @@ members = [
|
|||||||
"common/topology",
|
"common/topology",
|
||||||
"common/tun",
|
"common/tun",
|
||||||
"common/types",
|
"common/types",
|
||||||
|
"common/verloc",
|
||||||
"common/wasm/client-core",
|
"common/wasm/client-core",
|
||||||
"common/wasm/storage",
|
"common/wasm/storage",
|
||||||
"common/wasm/utils",
|
"common/wasm/utils",
|
||||||
"common/wireguard",
|
"common/wireguard",
|
||||||
"common/wireguard-types",
|
"common/wireguard-types",
|
||||||
# "documentation/autodoc",
|
"documentation/autodoc",
|
||||||
"explorer-api",
|
# "explorer-api",
|
||||||
"explorer-api/explorer-api-requests",
|
# "explorer-api/explorer-api-requests",
|
||||||
"explorer-api/explorer-client",
|
# "explorer-api/explorer-client",
|
||||||
"gateway",
|
"gateway",
|
||||||
"integrations/bity",
|
"integrations/bity",
|
||||||
"sdk/ffi/cpp",
|
|
||||||
"sdk/ffi/go",
|
|
||||||
"sdk/ffi/shared",
|
|
||||||
"sdk/lib/socks5-listener",
|
|
||||||
"sdk/rust/nym-sdk",
|
|
||||||
"service-providers/authenticator",
|
|
||||||
"service-providers/common",
|
|
||||||
"service-providers/ip-packet-router",
|
|
||||||
"service-providers/network-requester",
|
|
||||||
"nym-api",
|
"nym-api",
|
||||||
"nym-api/nym-api-requests",
|
"nym-api/nym-api-requests",
|
||||||
"nym-browser-extension/storage",
|
"nym-browser-extension/storage",
|
||||||
"nym-credential-proxy/nym-credential-proxy",
|
"nym-credential-proxy/nym-credential-proxy",
|
||||||
"nym-credential-proxy/nym-credential-proxy-requests",
|
"nym-credential-proxy/nym-credential-proxy-requests",
|
||||||
"nym-credential-proxy/vpn-api-lib-wasm",
|
"nym-credential-proxy/vpn-api-lib-wasm",
|
||||||
"nym-data-observatory",
|
|
||||||
"nym-network-monitor",
|
"nym-network-monitor",
|
||||||
"nym-node",
|
"nym-node",
|
||||||
"nym-node/nym-node-requests",
|
|
||||||
"nym-node/nym-node-metrics",
|
|
||||||
"nym-node-status-api/nym-node-status-agent",
|
"nym-node-status-api/nym-node-status-agent",
|
||||||
"nym-node-status-api/nym-node-status-api",
|
"nym-node-status-api/nym-node-status-api",
|
||||||
"nym-node-status-api/nym-node-status-client",
|
"nym-node-status-api/nym-node-status-client",
|
||||||
|
"nym-node/nym-node-metrics",
|
||||||
|
"nym-node/nym-node-requests",
|
||||||
"nym-outfox",
|
"nym-outfox",
|
||||||
"nym-validator-rewarder",
|
"nym-validator-rewarder",
|
||||||
|
"nyx-chain-watcher",
|
||||||
|
"sdk/ffi/cpp",
|
||||||
|
"sdk/ffi/go",
|
||||||
|
"sdk/ffi/shared",
|
||||||
|
"sdk/rust/nym-sdk",
|
||||||
|
"service-providers/authenticator",
|
||||||
|
"service-providers/common",
|
||||||
|
"service-providers/ip-packet-router",
|
||||||
|
"service-providers/network-requester",
|
||||||
"tools/echo-server",
|
"tools/echo-server",
|
||||||
"tools/internal/ssl-inject",
|
"tools/echo-server",
|
||||||
|
"tools/internal/contract-state-importer/importer-cli",
|
||||||
|
"tools/internal/contract-state-importer/importer-contract",
|
||||||
|
"tools/internal/mixnet-connectivity-check",
|
||||||
# "tools/internal/sdk-version-bump",
|
# "tools/internal/sdk-version-bump",
|
||||||
|
"tools/internal/ssl-inject",
|
||||||
|
"tools/internal/testnet-manager",
|
||||||
"tools/internal/testnet-manager",
|
"tools/internal/testnet-manager",
|
||||||
"tools/internal/testnet-manager/dkg-bypass-contract",
|
"tools/internal/testnet-manager/dkg-bypass-contract",
|
||||||
|
"tools/internal/testnet-manager/dkg-bypass-contract", "tools/internal/validator-status-check",
|
||||||
"tools/nym-cli",
|
"tools/nym-cli",
|
||||||
"tools/nym-id-cli",
|
"tools/nym-id-cli",
|
||||||
"tools/nym-nr-query",
|
"tools/nym-nr-query",
|
||||||
@@ -144,24 +147,18 @@ members = [
|
|||||||
"wasm/mix-fetch",
|
"wasm/mix-fetch",
|
||||||
"wasm/node-tester",
|
"wasm/node-tester",
|
||||||
"wasm/zknym-lib",
|
"wasm/zknym-lib",
|
||||||
"tools/echo-server",
|
|
||||||
"tools/internal/contract-state-importer/importer-cli",
|
|
||||||
"tools/internal/contract-state-importer/importer-contract",
|
|
||||||
"tools/internal/testnet-manager",
|
|
||||||
"tools/internal/testnet-manager/dkg-bypass-contract", "common/verloc", "tools/internal/mixnet-connectivity-check",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
default-members = [
|
default-members = [
|
||||||
"clients/native",
|
"clients/native",
|
||||||
"clients/socks5",
|
"clients/socks5",
|
||||||
"explorer-api",
|
|
||||||
"nym-api",
|
"nym-api",
|
||||||
"nym-credential-proxy/nym-credential-proxy",
|
"nym-credential-proxy/nym-credential-proxy",
|
||||||
"nym-data-observatory",
|
|
||||||
"nym-node",
|
"nym-node",
|
||||||
"nym-node-status-api/nym-node-status-agent",
|
"nym-node-status-api/nym-node-status-agent",
|
||||||
"nym-node-status-api/nym-node-status-api",
|
"nym-node-status-api/nym-node-status-api",
|
||||||
"nym-validator-rewarder",
|
"nym-validator-rewarder",
|
||||||
|
"nyx-chain-watcher",
|
||||||
"service-providers/authenticator",
|
"service-providers/authenticator",
|
||||||
"service-providers/ip-packet-router",
|
"service-providers/ip-packet-router",
|
||||||
"service-providers/network-requester",
|
"service-providers/network-requester",
|
||||||
@@ -172,7 +169,6 @@ exclude = [
|
|||||||
"explorer",
|
"explorer",
|
||||||
"contracts",
|
"contracts",
|
||||||
"nym-wallet",
|
"nym-wallet",
|
||||||
"nym-vpn/ui/src-tauri",
|
|
||||||
"cpu-cycles",
|
"cpu-cycles",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -188,45 +184,49 @@ readme = "README.md"
|
|||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
addr = "0.15.6"
|
addr = "0.15.6"
|
||||||
|
aead = "0.5.2"
|
||||||
aes = "0.8.1"
|
aes = "0.8.1"
|
||||||
aes-gcm = "0.10.1"
|
aes-gcm = "0.10.1"
|
||||||
aes-gcm-siv = "0.11.1"
|
aes-gcm-siv = "0.11.1"
|
||||||
aead = "0.5.2"
|
ammonia = "4"
|
||||||
anyhow = "1.0.90"
|
anyhow = "1.0.97"
|
||||||
|
arc-swap = "1.7.1"
|
||||||
argon2 = "0.5.0"
|
argon2 = "0.5.0"
|
||||||
async-trait = "0.1.83"
|
async-trait = "0.1.88"
|
||||||
axum-client-ip = "0.6.1"
|
|
||||||
axum = "0.7.5"
|
axum = "0.7.5"
|
||||||
|
axum-client-ip = "0.6.1"
|
||||||
axum-extra = "0.9.4"
|
axum-extra = "0.9.4"
|
||||||
|
axum-test = "16.2.0"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
|
base85rs = "0.1.3"
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||||
bit-vec = "0.7.0" # can we unify those?
|
bit-vec = "0.7.0" # can we unify those?
|
||||||
bitvec = "1.0.0"
|
bitvec = "1.0.0"
|
||||||
blake3 = "1.5.4"
|
blake3 = "1.7.0"
|
||||||
bloomfilter = "1.0.14"
|
bloomfilter = "1.0.14"
|
||||||
bs58 = "0.5.1"
|
bs58 = "0.5.1"
|
||||||
bytecodec = "0.4.15"
|
bytecodec = "0.4.15"
|
||||||
bytes = "1.7.2"
|
bytes = "1.10.1"
|
||||||
cargo_metadata = "0.18.1"
|
cargo_metadata = "0.18.1"
|
||||||
celes = "2.4.0"
|
celes = "2.6.0"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
chacha20 = "0.9.0"
|
chacha20 = "0.9.0"
|
||||||
chacha20poly1305 = "0.10.1"
|
chacha20poly1305 = "0.10.1"
|
||||||
chrono = "0.4.31"
|
chrono = "0.4.40"
|
||||||
cipher = "0.4.3"
|
cipher = "0.4.3"
|
||||||
clap = "4.5.20"
|
clap = "4.5.34"
|
||||||
clap_complete = "4.5"
|
clap_complete = "4.5"
|
||||||
clap_complete_fig = "4.5"
|
clap_complete_fig = "4.5"
|
||||||
colored = "2.0"
|
colored = "2.2"
|
||||||
comfy-table = "7.1.1"
|
comfy-table = "7.1.4"
|
||||||
console = "0.15.8"
|
console = "0.15.11"
|
||||||
console-subscriber = "0.1.1"
|
console-subscriber = "0.1.1"
|
||||||
console_error_panic_hook = "0.1"
|
console_error_panic_hook = "0.1"
|
||||||
const-str = "0.5.6"
|
const-str = "0.5.6"
|
||||||
const_format = "0.2.33"
|
const_format = "0.2.34"
|
||||||
criterion = "0.4"
|
criterion = "0.5"
|
||||||
csv = "1.3.0"
|
csv = "1.3.1"
|
||||||
ctr = "0.9.1"
|
ctr = "0.9.1"
|
||||||
cupid = "0.6.1"
|
cupid = "0.6.1"
|
||||||
curve25519-dalek = "4.1"
|
curve25519-dalek = "4.1"
|
||||||
@@ -239,58 +239,60 @@ doc-comment = "0.3"
|
|||||||
dotenvy = "0.15.6"
|
dotenvy = "0.15.6"
|
||||||
ecdsa = "0.16"
|
ecdsa = "0.16"
|
||||||
ed25519-dalek = "2.1"
|
ed25519-dalek = "2.1"
|
||||||
etherparse = "0.13.0"
|
encoding_rs = "0.8.35"
|
||||||
|
env_logger = "0.11.7"
|
||||||
envy = "0.4"
|
envy = "0.4"
|
||||||
|
etherparse = "0.13.0"
|
||||||
eyre = "0.6.9"
|
eyre = "0.6.9"
|
||||||
fastrand = "2.1.1"
|
fastrand = "2.1.1"
|
||||||
flate2 = "1.0.34"
|
flate2 = "1.1.0"
|
||||||
futures = "0.3.28"
|
futures = "0.3.31"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
generic-array = "0.14.7"
|
generic-array = "0.14.7"
|
||||||
getrandom = "0.2.10"
|
getrandom = "0.2.10"
|
||||||
getset = "0.1.3"
|
getset = "0.1.5"
|
||||||
handlebars = "3.5.5"
|
handlebars = "3.5.5"
|
||||||
headers = "0.4.0"
|
headers = "0.4.0"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
hex-literal = "0.3.3"
|
hex-literal = "0.3.3"
|
||||||
|
hickory-resolver = "0.24.4"
|
||||||
hkdf = "0.12.3"
|
hkdf = "0.12.3"
|
||||||
hmac = "0.12.1"
|
hmac = "0.12.1"
|
||||||
http = "1"
|
http = "1"
|
||||||
http-body-util = "0.1"
|
http-body-util = "0.1"
|
||||||
httpcodec = "0.2.3"
|
httpcodec = "0.2.3"
|
||||||
humantime = "2.1.0"
|
|
||||||
humantime-serde = "1.1.1"
|
|
||||||
human-repr = "1.1.0"
|
human-repr = "1.1.0"
|
||||||
hyper = "1.4.1"
|
humantime = "2.2.0"
|
||||||
|
humantime-serde = "1.1.1"
|
||||||
|
hyper = "1.6.0"
|
||||||
hyper-util = "0.1"
|
hyper-util = "0.1"
|
||||||
indicatif = "0.17.8"
|
indicatif = "0.17.11"
|
||||||
inquire = "0.6.2"
|
inquire = "0.6.2"
|
||||||
ip_network = "0.4.1"
|
ip_network = "0.4.1"
|
||||||
ipnetwork = "0.20"
|
ipnetwork = "0.20"
|
||||||
isocountry = "0.3.2"
|
isocountry = "0.3.2"
|
||||||
itertools = "0.13.0"
|
itertools = "0.14.0"
|
||||||
k256 = "0.13"
|
k256 = "0.13"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
ledger-transport = "0.10.0"
|
ledger-transport = "0.10.0"
|
||||||
ledger-transport-hid = "0.10.0"
|
ledger-transport-hid = "0.10.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
maxminddb = "0.23.0"
|
maxminddb = "0.23.0"
|
||||||
rs_merkle = "1.4.2"
|
|
||||||
mime = "0.3.17"
|
mime = "0.3.17"
|
||||||
moka = { version = "0.12", features = ["future"] }
|
moka = { version = "0.12", features = ["future"] }
|
||||||
nix = "0.27.1"
|
nix = "0.27.1"
|
||||||
notify = "5.1.0"
|
notify = "5.1.0"
|
||||||
okapi = "0.7.0"
|
okapi = "0.7.0"
|
||||||
once_cell = "1.20.2"
|
once_cell = "1.21.3"
|
||||||
opentelemetry = "0.19.0"
|
opentelemetry = "0.19.0"
|
||||||
opentelemetry-jaeger = "0.18.0"
|
opentelemetry-jaeger = "0.18.0"
|
||||||
parking_lot = "0.12.3"
|
parking_lot = "0.12.3"
|
||||||
pem = "0.8"
|
pem = "0.8"
|
||||||
petgraph = "0.6.5"
|
petgraph = "0.6.5"
|
||||||
pin-project = "1.1"
|
pin-project = "1.1"
|
||||||
pin-project-lite = "0.2.14"
|
pin-project-lite = "0.2.16"
|
||||||
pretty_env_logger = "0.4.0"
|
pretty_env_logger = "0.4.0"
|
||||||
publicsuffix = "2.2.3"
|
publicsuffix = "2.3.0"
|
||||||
quote = "1"
|
quote = "1"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rand_chacha = "0.3"
|
rand_chacha = "0.3"
|
||||||
@@ -300,61 +302,66 @@ rand_pcg = "0.3.1"
|
|||||||
rand_seeder = "0.2.3"
|
rand_seeder = "0.2.3"
|
||||||
rayon = "1.5.1"
|
rayon = "1.5.1"
|
||||||
regex = "1.10.6"
|
regex = "1.10.6"
|
||||||
reqwest = { version = "0.12.4", default-features = false }
|
reqwest = { version = "0.12.15", default-features = false }
|
||||||
rocket = "0.5.0"
|
rocket = "0.5.0"
|
||||||
rocket_cors = "0.6.0"
|
rocket_cors = "0.6.0"
|
||||||
rocket_okapi = "0.8.0"
|
rocket_okapi = "0.8.0"
|
||||||
|
rs_merkle = "1.5.0"
|
||||||
safer-ffi = "0.1.13"
|
safer-ffi = "0.1.13"
|
||||||
schemars = "0.8.21"
|
schemars = "0.8.22"
|
||||||
semver = "1.0.23"
|
semver = "1.0.26"
|
||||||
serde = "1.0.211"
|
serde = "1.0.219"
|
||||||
serde_bytes = "0.11.15"
|
serde_bytes = "0.11.17"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0.132"
|
serde_json = "1.0.140"
|
||||||
serde_json_path = "0.7.1"
|
serde_json_path = "0.7.2"
|
||||||
serde_repr = "0.1"
|
serde_repr = "0.1"
|
||||||
serde_with = "3.9.0"
|
serde_with = "3.9.0"
|
||||||
serde_yaml = "0.9.25"
|
serde_yaml = "0.9.25"
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
si-scale = "0.2.3"
|
si-scale = "0.2.3"
|
||||||
sphinx-packet = "0.1.1"
|
sphinx-packet = "=0.3.2"
|
||||||
sqlx = "0.7.4"
|
sqlx = "0.7.4"
|
||||||
strum = "0.26"
|
strum = "0.26"
|
||||||
strum_macros = "0.26"
|
strum_macros = "0.26"
|
||||||
subtle-encoding = "0.5"
|
subtle-encoding = "0.5"
|
||||||
syn = "1"
|
syn = "1"
|
||||||
sysinfo = "0.30.13"
|
sysinfo = "0.33.0"
|
||||||
tap = "1.0.1"
|
tap = "1.0.1"
|
||||||
tar = "0.4.42"
|
tar = "0.4.44"
|
||||||
tempfile = "3.14"
|
tempfile = "3.19"
|
||||||
thiserror = "1.0.64"
|
thiserror = "2.0"
|
||||||
time = "0.3.30"
|
time = "0.3.41"
|
||||||
tokio = "1.39"
|
tokio = "1.44"
|
||||||
tokio-stream = "0.1.16"
|
tokio-postgres = "0.7"
|
||||||
|
tokio-stream = "0.1.17"
|
||||||
tokio-test = "0.4.4"
|
tokio-test = "0.4.4"
|
||||||
tokio-tun = "0.11.5"
|
tokio-tun = "0.11.5"
|
||||||
tokio-tungstenite = { version = "0.20.1" }
|
tokio-tungstenite = { version = "0.20.1" }
|
||||||
tokio-util = "0.7.12"
|
tokio-util = "0.7.14"
|
||||||
toml = "0.8.14"
|
toml = "0.8.20"
|
||||||
tower = "0.4.13"
|
tower = "0.5.2"
|
||||||
tower-http = "0.5.2"
|
tower-http = "0.5.2"
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.41"
|
||||||
tracing-opentelemetry = "0.19.0"
|
|
||||||
tracing-subscriber = "0.3.16"
|
|
||||||
tracing-tree = "0.2.2"
|
|
||||||
tracing-log = "0.2"
|
tracing-log = "0.2"
|
||||||
ts-rs = "10.0.0"
|
tracing-opentelemetry = "0.19.0"
|
||||||
|
tracing-subscriber = "0.3.19"
|
||||||
|
tracing-tree = "0.2.2"
|
||||||
|
tracing-indicatif = "0.3.9"
|
||||||
|
ts-rs = "10.1.0"
|
||||||
tungstenite = { version = "0.20.1", default-features = false }
|
tungstenite = { version = "0.20.1", default-features = false }
|
||||||
|
uniffi = "0.29.1"
|
||||||
|
uniffi_build = "0.29.0"
|
||||||
url = "2.5"
|
url = "2.5"
|
||||||
utoipa = "4.2"
|
utoipa = "5.2"
|
||||||
utoipa-swagger-ui = "7.1"
|
utoipa-swagger-ui = "8.1"
|
||||||
utoipauto = "0.1"
|
utoipauto = "0.2"
|
||||||
uuid = "*"
|
uuid = "*"
|
||||||
vergen = { version = "=8.3.1", default-features = false }
|
vergen = { version = "=8.3.1", default-features = false }
|
||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
wasm-bindgen-test = "0.3.43"
|
wasm-bindgen-test = "0.3.49"
|
||||||
x25519-dalek = "2.0.0"
|
x25519-dalek = "2.0.0"
|
||||||
zeroize = "1.6.0"
|
zeroize = "1.7.0"
|
||||||
|
|
||||||
prometheus = { version = "0.13.0" }
|
prometheus = { version = "0.13.0" }
|
||||||
|
|
||||||
@@ -362,52 +369,46 @@ prometheus = { version = "0.13.0" }
|
|||||||
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
|
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
|
||||||
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
|
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
|
||||||
# plus to make our live easier we need serde support from https://github.com/zkcrypto/bls12_381/pull/125
|
# plus to make our live easier we need serde support from https://github.com/zkcrypto/bls12_381/pull/125
|
||||||
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", default-features = false, branch = "temp/experimental-serdect" }
|
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", default-features = false, branch = "temp/experimental-serdect-updated" }
|
||||||
group = { version = "0.13.0", default-features = false }
|
group = { version = "0.13.0", default-features = false }
|
||||||
ff = { version = "0.13.0", default-features = false }
|
ff = { version = "0.13.1", default-features = false }
|
||||||
subtle = "2.5.0"
|
subtle = "2.5.0"
|
||||||
|
|
||||||
# cosmwasm-related
|
# cosmwasm-related
|
||||||
cosmwasm-schema = "=1.4.3"
|
cosmwasm-schema = "=2.2.2"
|
||||||
cosmwasm-std = "=1.4.3"
|
cosmwasm-std = "=2.2.2"
|
||||||
# use 0.5.0 as that's the version used by cosmwasm-std 1.4.3
|
# use 1.0.1 as that's the version used by cosmwasm-std 2.2.1
|
||||||
# (and ideally we don't want to pull the same dependency twice)
|
# (and ideally we don't want to pull the same dependency twice)
|
||||||
serde-json-wasm = "=0.5.0"
|
serde-json-wasm = "=1.0.1"
|
||||||
cosmwasm-storage = "=1.4.3"
|
|
||||||
# same version as used by cosmwasm
|
# same version as used by cosmwasm
|
||||||
cw-utils = "=1.0.1"
|
cw-utils = "=2.0.0"
|
||||||
cw-storage-plus = "=1.2.0"
|
cw-storage-plus = "=2.0.0"
|
||||||
cw2 = { version = "=1.1.2" }
|
cw2 = { version = "=2.0.0" }
|
||||||
cw3 = { version = "=1.1.2" }
|
cw3 = { version = "=2.0.0" }
|
||||||
cw4 = { version = "=1.1.2" }
|
cw4 = { version = "=2.0.0" }
|
||||||
cw-controllers = { version = "=1.1.0" }
|
cw-controllers = { version = "=2.0.0" }
|
||||||
|
|
||||||
# cosmrs-related
|
# cosmrs-related
|
||||||
bip32 = { version = "0.5.2", default-features = false }
|
bip32 = { version = "0.5.3", default-features = false }
|
||||||
|
|
||||||
# temporarily using a fork again (yay.) because we need staking and slashing support (which are already on main but not released)
|
|
||||||
# plus response message parsing (which is, as of the time of writing this message, waiting to get merged)
|
cosmrs = { version = "0.21.1" }
|
||||||
#cosmrs = { path = "../cosmos-rust-fork/cosmos-rust/cosmrs" }
|
tendermint = "0.40.0"
|
||||||
cosmrs = { git = "https://github.com/cosmos/cosmos-rust", rev = "4b1332e6d8258ac845cef71589c8d362a669675a" } # unfortuntely we need a fork by yours truly to get the staking support
|
tendermint-rpc = "0.40.0"
|
||||||
tendermint = "0.37.0" # same version as used by cosmrs
|
prost = { version = "0.13", default-features = false }
|
||||||
tendermint-rpc = "0.37.0" # same version as used by cosmrs
|
|
||||||
prost = { version = "0.12", default-features = false }
|
|
||||||
|
|
||||||
# wasm-related dependencies
|
# wasm-related dependencies
|
||||||
gloo-utils = "0.2.0"
|
gloo-utils = "0.2.0"
|
||||||
gloo-net = "0.5.0"
|
gloo-net = "0.6.0"
|
||||||
|
|
||||||
# use a separate branch due to feature unification failures
|
indexed_db_futures = "0.6.1"
|
||||||
# this is blocked until the upstream removes outdates `wasm_bindgen` feature usage
|
js-sys = "0.3.76"
|
||||||
# indexed_db_futures = "0.4.1"
|
|
||||||
indexed_db_futures = { git = "https://github.com/TiemenSch/rust-indexed-db", branch = "update-uuid" }
|
|
||||||
js-sys = "0.3.70"
|
|
||||||
serde-wasm-bindgen = "0.6.5"
|
serde-wasm-bindgen = "0.6.5"
|
||||||
tsify = "0.4.5"
|
tsify = "0.4.5"
|
||||||
wasm-bindgen = "0.2.95"
|
wasm-bindgen = "0.2.99"
|
||||||
wasm-bindgen-futures = "0.4.45"
|
wasm-bindgen-futures = "0.4.49"
|
||||||
wasmtimer = "0.2.0"
|
wasmtimer = "0.4.1"
|
||||||
web-sys = "0.3.72"
|
web-sys = "0.3.76"
|
||||||
|
|
||||||
# Profile settings for individual crates
|
# Profile settings for individual crates
|
||||||
|
|
||||||
@@ -417,10 +418,6 @@ web-sys = "0.3.72"
|
|||||||
[profile.dev.package.sqlx-macros]
|
[profile.dev.package.sqlx-macros]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
[profile.release.package.nym-socks5-listener]
|
|
||||||
strip = true
|
|
||||||
codegen-units = 1
|
|
||||||
|
|
||||||
[profile.release.package.nym-client-wasm]
|
[profile.release.package.nym-client-wasm]
|
||||||
# lto = true
|
# lto = true
|
||||||
opt-level = 'z'
|
opt-level = 'z'
|
||||||
@@ -439,3 +436,13 @@ opt-level = 'z'
|
|||||||
[profile.release.package.mix-fetch-wasm]
|
[profile.release.package.mix-fetch-wasm]
|
||||||
# lto = true
|
# lto = true
|
||||||
opt-level = 'z'
|
opt-level = 'z'
|
||||||
|
|
||||||
|
[workspace.lints.clippy]
|
||||||
|
unwrap_used = "deny"
|
||||||
|
expect_used = "deny"
|
||||||
|
todo = "deny"
|
||||||
|
dbg_macro = "deny"
|
||||||
|
exit = "deny"
|
||||||
|
panic = "deny"
|
||||||
|
unimplemented = "deny"
|
||||||
|
unreachable = "deny"
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
@@ -133,17 +133,22 @@ clippy: sdk-wasm-lint
|
|||||||
# Build contracts ready for deploy
|
# Build contracts ready for deploy
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
CONTRACTS=vesting_contract mixnet_contract nym_ecash
|
CONTRACTS=vesting_contract mixnet_contract nym_ecash cw3_flex_multisig cw4_group nym_coconut_dkg
|
||||||
CONTRACTS_WASM=$(addsuffix .wasm, $(CONTRACTS))
|
CONTRACTS_WASM=$(addsuffix .wasm, $(CONTRACTS))
|
||||||
CONTRACTS_OUT_DIR=contracts/target/wasm32-unknown-unknown/release
|
CONTRACTS_OUT_DIR=contracts/target/wasm32-unknown-unknown/release
|
||||||
|
|
||||||
contracts: build-release-contracts wasm-opt-contracts
|
contracts: build-release-contracts wasm-opt-contracts cosmwasm-check-contracts
|
||||||
|
|
||||||
wasm-opt-contracts:
|
wasm-opt-contracts:
|
||||||
for contract in $(CONTRACTS_WASM); do \
|
for contract in $(CONTRACTS_WASM); do \
|
||||||
wasm-opt --signext-lowering -Os $(CONTRACTS_OUT_DIR)/$$contract -o $(CONTRACTS_OUT_DIR)/$$contract; \
|
wasm-opt --signext-lowering -Os $(CONTRACTS_OUT_DIR)/$$contract -o $(CONTRACTS_OUT_DIR)/$$contract; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
cosmwasm-check-contracts:
|
||||||
|
for contract in $(CONTRACTS_WASM); do \
|
||||||
|
cosmwasm-check $(CONTRACTS_OUT_DIR)/$$contract; \
|
||||||
|
done
|
||||||
|
|
||||||
# Consider adding 's' to make plural consistent (beware: used in github workflow)
|
# Consider adding 's' to make plural consistent (beware: used in github workflow)
|
||||||
contract-schema:
|
contract-schema:
|
||||||
$(MAKE) -C contracts schema
|
$(MAKE) -C contracts schema
|
||||||
@@ -152,18 +157,9 @@ contract-schema:
|
|||||||
# Convenience targets for crates that are already part of the main workspace
|
# Convenience targets for crates that are already part of the main workspace
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
build-explorer-api:
|
|
||||||
cargo build -p explorer-api
|
|
||||||
|
|
||||||
build-nym-cli:
|
build-nym-cli:
|
||||||
cargo build -p nym-cli --release
|
cargo build -p nym-cli --release
|
||||||
|
|
||||||
build-nym-gateway:
|
|
||||||
cargo build -p nym-gateway --release
|
|
||||||
|
|
||||||
build-nym-mixnode:
|
|
||||||
cargo build -p nym-mixnode --release
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Misc
|
# Misc
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@@ -176,13 +172,7 @@ run-api-tests:
|
|||||||
cd nym-api/tests/functional_test && yarn test:qa
|
cd nym-api/tests/functional_test && yarn test:qa
|
||||||
|
|
||||||
# Build debian package, and update PPA
|
# Build debian package, and update PPA
|
||||||
deb-mixnode: build-nym-mixnode
|
|
||||||
cargo deb -p nym-mixnode
|
|
||||||
|
|
||||||
deb-gateway: build-nym-gateway
|
|
||||||
cargo deb -p nym-gateway
|
|
||||||
|
|
||||||
deb-cli: build-nym-cli
|
deb-cli: build-nym-cli
|
||||||
cargo deb -p nym-cli
|
cargo deb -p nym-cli
|
||||||
|
|
||||||
deb: deb-mixnode deb-gateway deb-cli
|
deb: deb-cli
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
|
|||||||
* `nym-client` - an executable which you can build into your own applications. Use it for interacting with Nym nodes.
|
* `nym-client` - an executable which you can build into your own applications. Use it for interacting with Nym nodes.
|
||||||
* `nym-socks5-client` - a Socks5 proxy you can run on your machine and use with existing applications.
|
* `nym-socks5-client` - a Socks5 proxy you can run on your machine and use with existing applications.
|
||||||
* `nym-explorer` - a (projected) block explorer and (existing) mixnet viewer.
|
* `nym-explorer` - a (projected) block explorer and (existing) mixnet viewer.
|
||||||
* `nym-wallet` - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
|
* `nym-wallet` - a desktop wallet implemented using the [Tauri](https://tauri.app)) framework.
|
||||||
|
* `nym-cli` - a tool for interacting with the network from the CLI.
|
||||||
<!-- coming soon
|
<!-- coming soon
|
||||||
* `nym-network-monitor` - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
|
* `nym-network-monitor` - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
|
||||||
-->
|
-->
|
||||||
@@ -35,24 +36,20 @@ client ───► Gateway ──┘ mix │ mix ┌─►mix ───►
|
|||||||
### Building
|
### Building
|
||||||
|
|
||||||
* Platform build instructions are available on Nym [Operators Guide documentation](https://nymtech.net/operators/binaries/building-nym.html).
|
* Platform build instructions are available on Nym [Operators Guide documentation](https://nymtech.net/operators/binaries/building-nym.html).
|
||||||
* Wallet build instructions are available on Nym [Technical docs](https://nymtech.net/docs/wallet/desktop-wallet.html).
|
* Wallet build instructions are available [here](https://github.com/nymtech/nym/tree/master/nym-wallet#installation-prerequisites---linux--mac).
|
||||||
|
|
||||||
### Developing
|
### Developing
|
||||||
|
|
||||||
There's a [`sandbox.env`](https://github.com/nymtech/nym/envs/sandbox.env) file provided which you can rename to `.env` if you want convenient testing environment. Read more about sandbox environment in our [Operators Guide page](https://nymtech.net/operators/sandbox.html).
|
|
||||||
|
|
||||||
References for developers:
|
References for developers:
|
||||||
|
|
||||||
* [Developers Portal](https://nymtech.net/developers)
|
* [Dev Docs](https://nym.com/docs/developers)
|
||||||
* [Typescript SDKs](https://sdk.nymtech.net/)
|
* [SDKs](https://nym.com/docs/developers/rust)
|
||||||
* [Technical Documentation - Nym network overview](https://nymtech.net/docs/)
|
* [Network Docs](https://nym.com/docs/network)
|
||||||
* [Release Cycle - git flow](https://nymtech.net/operators/release-cycle.html)
|
* [Release Cycle - git flow](https://nym.com/docs/operators/release-cycle)
|
||||||
|
|
||||||
### Developer chat
|
### Developer chat
|
||||||
|
|
||||||
You can chat to us in two places:
|
You can chat to us in the #dev channel on [Matrix](https://matrix.to/#/#dev:nymtech.chat) or on the [Nym Forum](https://forum.nymtech.net).
|
||||||
* The #dev channel on [Matrix](https://matrix.to/#/#dev:nymtech.chat)
|
|
||||||
* The various developer channels on [Discord](https://nymtech.net/go/discord)
|
|
||||||
|
|
||||||
### Tokenomics & Rewards
|
### Tokenomics & Rewards
|
||||||
|
|
||||||
@@ -69,4 +66,14 @@ As a general approach, licensing is as follows this pattern:
|
|||||||
- libraries and components are Apache 2.0 or MIT
|
- libraries and components are Apache 2.0 or MIT
|
||||||
- documentation is Apache 2.0 or CC0-1.0
|
- documentation is Apache 2.0 or CC0-1.0
|
||||||
|
|
||||||
Nym Node Operators and Validators Temrs and Conditions can be found [here](https://nymtech.net/terms-and-conditions/operators/v1.0.0).
|
Nym Node Operators and Validators Terms and Conditions can be found [here](https://nym.com/operators-validators-terms).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.45"
|
version = "1.1.52"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||||
description = "Implementation of the Nym Client"
|
description = "Implementation of the Nym Client"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ pub fn default_data_directory<P: AsRef<Path>>(id: P) -> PathBuf {
|
|||||||
.join(DEFAULT_DATA_DIR)
|
.join(DEFAULT_DATA_DIR)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Deserialize, PartialEq, Serialize, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: BaseClientConfig,
|
pub base: BaseClientConfig,
|
||||||
@@ -94,6 +94,10 @@ impl CliClientConfig for Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
pub fn base(&self) -> BaseClientConfig {
|
||||||
|
self.base.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new<S: AsRef<str>>(id: S) -> Self {
|
pub fn new<S: AsRef<str>>(id: S) -> Self {
|
||||||
Config {
|
Config {
|
||||||
base: BaseClientConfig::new(id.as_ref(), env!("CARGO_PKG_VERSION")),
|
base: BaseClientConfig::new(id.as_ref(), env!("CARGO_PKG_VERSION")),
|
||||||
@@ -209,7 +213,7 @@ impl SocketType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct Socket {
|
pub struct Socket {
|
||||||
pub socket_type: SocketType,
|
pub socket_type: SocketType,
|
||||||
|
|||||||
@@ -107,5 +107,8 @@ enabled = {{ debug.stats_reporting.enabled }}
|
|||||||
provider_address = '{{ debug.stats_reporting.provider_address }}'
|
provider_address = '{{ debug.stats_reporting.provider_address }}'
|
||||||
reporting_interval = '{{ debug.stats_reporting.reporting_interval }}'
|
reporting_interval = '{{ debug.stats_reporting.reporting_interval }}'
|
||||||
|
|
||||||
|
[debug.forget_me]
|
||||||
|
client = {{ debug.forget_me.client }}
|
||||||
|
stats = {{ debug.forget_me.stats }}
|
||||||
|
|
||||||
"#;
|
"#;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub use nym_sphinx::addressing::clients::Recipient;
|
|||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
||||||
type NativeClientBuilder<'a> = BaseClientBuilder<'a, QueryHttpRpcNyxdClient, OnDiskPersistent>;
|
type NativeClientBuilder = BaseClientBuilder<QueryHttpRpcNyxdClient, OnDiskPersistent>;
|
||||||
|
|
||||||
pub struct SocketClient {
|
pub struct SocketClient {
|
||||||
/// Client configuration options, including, among other things, packet sending rates,
|
/// Client configuration options, including, among other things, packet sending rates,
|
||||||
@@ -32,6 +32,10 @@ pub struct SocketClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SocketClient {
|
impl SocketClient {
|
||||||
|
pub fn config(&self) -> Config {
|
||||||
|
self.config.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(config: Config, custom_mixnet: Option<PathBuf>) -> Self {
|
pub fn new(config: Config, custom_mixnet: Option<PathBuf>) -> Self {
|
||||||
SocketClient {
|
SocketClient {
|
||||||
config,
|
config,
|
||||||
@@ -45,7 +49,7 @@ impl SocketClient {
|
|||||||
client_output: ClientOutput,
|
client_output: ClientOutput,
|
||||||
client_state: ClientState,
|
client_state: ClientState,
|
||||||
self_address: &Recipient,
|
self_address: &Recipient,
|
||||||
shutdown: nym_task::TaskClient,
|
task_client: nym_task::TaskClient,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
) {
|
) {
|
||||||
info!("Starting websocket listener...");
|
info!("Starting websocket listener...");
|
||||||
@@ -73,10 +77,15 @@ impl SocketClient {
|
|||||||
shared_lane_queue_lengths,
|
shared_lane_queue_lengths,
|
||||||
reply_controller_sender,
|
reply_controller_sender,
|
||||||
Some(packet_type),
|
Some(packet_type),
|
||||||
|
task_client.fork("websocket_handler"),
|
||||||
);
|
);
|
||||||
|
|
||||||
websocket::Listener::new(config.socket.host, config.socket.listening_port)
|
websocket::Listener::new(
|
||||||
.start(websocket_handler, shutdown);
|
config.socket.host,
|
||||||
|
config.socket.listening_port,
|
||||||
|
task_client.with_suffix("websocket_listener"),
|
||||||
|
)
|
||||||
|
.start(websocket_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// blocking version of `start_socket` method. Will run forever (or until SIGINT is sent)
|
/// blocking version of `start_socket` method. Will run forever (or until SIGINT is sent)
|
||||||
@@ -108,8 +117,9 @@ impl SocketClient {
|
|||||||
let storage = self.initialise_storage().await?;
|
let storage = self.initialise_storage().await?;
|
||||||
let user_agent = nym_bin_common::bin_info!().into();
|
let user_agent = nym_bin_common::bin_info!().into();
|
||||||
|
|
||||||
let mut base_client = BaseClientBuilder::new(&self.config.base, storage, dkg_query_client)
|
let mut base_client =
|
||||||
.with_user_agent(user_agent);
|
BaseClientBuilder::new(self.config().base(), storage, dkg_query_client)
|
||||||
|
.with_user_agent(user_agent);
|
||||||
|
|
||||||
if let Some(custom_mixnet) = &self.custom_mixnet {
|
if let Some(custom_mixnet) = &self.custom_mixnet {
|
||||||
base_client = base_client.with_stored_topology(custom_mixnet)?;
|
base_client = base_client.with_stored_topology(custom_mixnet)?;
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ impl From<Init> for OverrideConfig {
|
|||||||
nyxd_urls: init_config.common_args.nyxd_urls,
|
nyxd_urls: init_config.common_args.nyxd_urls,
|
||||||
enabled_credentials_mode: init_config.common_args.enabled_credentials_mode,
|
enabled_credentials_mode: init_config.common_args.enabled_credentials_mode,
|
||||||
stats_reporting_address: init_config.common_args.stats_reporting_address,
|
stats_reporting_address: init_config.common_args.stats_reporting_address,
|
||||||
|
forget_me: init_config.common_args.forget_me.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use nym_bin_common::completions::{fig_generate, ArgShell};
|
|||||||
use nym_client::client::Recipient;
|
use nym_client::client::Recipient;
|
||||||
use nym_client_core::cli_helpers::CliClient;
|
use nym_client_core::cli_helpers::CliClient;
|
||||||
use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33;
|
use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33;
|
||||||
|
use nym_client_core::config::ForgetMe;
|
||||||
use nym_config::OptionalSet;
|
use nym_config::OptionalSet;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
@@ -106,6 +107,7 @@ pub(crate) struct OverrideConfig {
|
|||||||
nyxd_urls: Option<Vec<url::Url>>,
|
nyxd_urls: Option<Vec<url::Url>>,
|
||||||
enabled_credentials_mode: Option<bool>,
|
enabled_credentials_mode: Option<bool>,
|
||||||
stats_reporting_address: Option<Recipient>,
|
stats_reporting_address: Option<Recipient>,
|
||||||
|
forget_me: ForgetMe,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||||
@@ -133,6 +135,7 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
|||||||
args.fastmode,
|
args.fastmode,
|
||||||
)
|
)
|
||||||
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
|
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
|
||||||
|
.with_base(BaseClientConfig::with_forget_me, args.forget_me)
|
||||||
.with_optional(Config::with_port, args.port)
|
.with_optional(Config::with_port, args.port)
|
||||||
.with_optional(Config::with_host, args.host)
|
.with_optional(Config::with_host, args.host)
|
||||||
.with_optional_custom_env_ext(
|
.with_optional_custom_env_ext(
|
||||||
|
|||||||
@@ -3,13 +3,10 @@
|
|||||||
|
|
||||||
use crate::commands::try_load_current_config;
|
use crate::commands::try_load_current_config;
|
||||||
use crate::{
|
use crate::{
|
||||||
client::{config::Config, SocketClient},
|
client::SocketClient,
|
||||||
commands::{override_config, OverrideConfig},
|
commands::{override_config, OverrideConfig},
|
||||||
error::ClientError,
|
|
||||||
};
|
};
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use log::*;
|
|
||||||
use nym_bin_common::version_checker::is_minor_version_compatible;
|
|
||||||
use nym_client_core::cli_helpers::client_run::CommonClientRunArgs;
|
use nym_client_core::cli_helpers::client_run::CommonClientRunArgs;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
@@ -44,25 +41,7 @@ impl From<Run> for OverrideConfig {
|
|||||||
nyxd_urls: run_config.common_args.nyxd_urls,
|
nyxd_urls: run_config.common_args.nyxd_urls,
|
||||||
enabled_credentials_mode: run_config.common_args.enabled_credentials_mode,
|
enabled_credentials_mode: run_config.common_args.enabled_credentials_mode,
|
||||||
stats_reporting_address: run_config.common_args.stats_reporting_address,
|
stats_reporting_address: run_config.common_args.stats_reporting_address,
|
||||||
}
|
forget_me: run_config.common_args.forget_me.into(),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this only checks compatibility between config the binary. It does not take into consideration
|
|
||||||
// network version. It might do so in the future.
|
|
||||||
fn version_check(cfg: &Config) -> bool {
|
|
||||||
let binary_version = env!("CARGO_PKG_VERSION");
|
|
||||||
let config_version = &cfg.base.client.version;
|
|
||||||
if binary_version == config_version {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
warn!("The native-client binary has different version than what is specified in config file! {} and {}", binary_version, config_version);
|
|
||||||
if is_minor_version_compatible(binary_version, config_version) {
|
|
||||||
info!("but they are still semver compatible. However, consider running the `upgrade` command");
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
error!("and they are semver incompatible! - please run the `upgrade` command before attempting `run` again");
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,11 +52,6 @@ pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn Error + Send + Sync
|
|||||||
let mut config = try_load_current_config(&args.common_args.id).await?;
|
let mut config = try_load_current_config(&args.common_args.id).await?;
|
||||||
config = override_config(config, OverrideConfig::from(args.clone()));
|
config = override_config(config, OverrideConfig::from(args.clone()));
|
||||||
|
|
||||||
if !version_check(&config) {
|
|
||||||
error!("failed the local version check");
|
|
||||||
return Err(Box::new(ClientError::FailedLocalVersionCheck));
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketClient::new(config, args.common_args.custom_mixnet)
|
SocketClient::new(config, args.common_args.custom_mixnet)
|
||||||
.run_socket_forever()
|
.run_socket_forever()
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ pub enum ClientError {
|
|||||||
#[error("Failed to validate the loaded config")]
|
#[error("Failed to validate the loaded config")]
|
||||||
ConfigValidationFailure,
|
ConfigValidationFailure,
|
||||||
|
|
||||||
#[error("Failed local version check, client and config mismatch")]
|
|
||||||
FailedLocalVersionCheck,
|
|
||||||
|
|
||||||
#[error("Attempted to start the client in invalid socket mode")]
|
#[error("Attempted to start the client in invalid socket mode")]
|
||||||
InvalidSocketMode,
|
InvalidSocketMode,
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use nym_sphinx::receiver::ReconstructedMessage;
|
|||||||
use nym_task::connections::{
|
use nym_task::connections::{
|
||||||
ConnectionCommand, ConnectionCommandSender, ConnectionId, LaneQueueLengths, TransmissionLane,
|
ConnectionCommand, ConnectionCommandSender, ConnectionId, LaneQueueLengths, TransmissionLane,
|
||||||
};
|
};
|
||||||
|
use nym_task::TaskClient;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio::time::Instant;
|
use tokio::time::Instant;
|
||||||
@@ -43,9 +44,11 @@ pub(crate) struct HandlerBuilder {
|
|||||||
lane_queue_lengths: LaneQueueLengths,
|
lane_queue_lengths: LaneQueueLengths,
|
||||||
reply_controller_sender: ReplyControllerSender,
|
reply_controller_sender: ReplyControllerSender,
|
||||||
packet_type: Option<PacketType>,
|
packet_type: Option<PacketType>,
|
||||||
|
task_client: TaskClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HandlerBuilder {
|
impl HandlerBuilder {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
msg_input: InputMessageSender,
|
msg_input: InputMessageSender,
|
||||||
client_connection_tx: ConnectionCommandSender,
|
client_connection_tx: ConnectionCommandSender,
|
||||||
@@ -54,6 +57,7 @@ impl HandlerBuilder {
|
|||||||
lane_queue_lengths: LaneQueueLengths,
|
lane_queue_lengths: LaneQueueLengths,
|
||||||
reply_controller_sender: ReplyControllerSender,
|
reply_controller_sender: ReplyControllerSender,
|
||||||
packet_type: Option<PacketType>,
|
packet_type: Option<PacketType>,
|
||||||
|
task_client: TaskClient,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
msg_input,
|
msg_input,
|
||||||
@@ -63,11 +67,14 @@ impl HandlerBuilder {
|
|||||||
lane_queue_lengths,
|
lane_queue_lengths,
|
||||||
reply_controller_sender,
|
reply_controller_sender,
|
||||||
packet_type,
|
packet_type,
|
||||||
|
task_client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make sure we only ever have one active handler
|
// TODO: make sure we only ever have one active handler
|
||||||
pub fn create_active_handler(&self) -> Handler {
|
pub fn create_active_handler(&self) -> Handler {
|
||||||
|
let mut task_client = self.task_client.fork("active_handler");
|
||||||
|
task_client.disarm();
|
||||||
Handler {
|
Handler {
|
||||||
msg_input: self.msg_input.clone(),
|
msg_input: self.msg_input.clone(),
|
||||||
client_connection_tx: self.client_connection_tx.clone(),
|
client_connection_tx: self.client_connection_tx.clone(),
|
||||||
@@ -78,6 +85,7 @@ impl HandlerBuilder {
|
|||||||
lane_queue_lengths: self.lane_queue_lengths.clone(),
|
lane_queue_lengths: self.lane_queue_lengths.clone(),
|
||||||
reply_controller_sender: self.reply_controller_sender.clone(),
|
reply_controller_sender: self.reply_controller_sender.clone(),
|
||||||
packet_type: self.packet_type,
|
packet_type: self.packet_type,
|
||||||
|
task_client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,16 +100,18 @@ pub(crate) struct Handler {
|
|||||||
lane_queue_lengths: LaneQueueLengths,
|
lane_queue_lengths: LaneQueueLengths,
|
||||||
reply_controller_sender: ReplyControllerSender,
|
reply_controller_sender: ReplyControllerSender,
|
||||||
packet_type: Option<PacketType>,
|
packet_type: Option<PacketType>,
|
||||||
|
task_client: TaskClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Handler {
|
impl Drop for Handler {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self
|
if let Err(err) = self
|
||||||
.buffer_requester
|
.buffer_requester
|
||||||
.unbounded_send(ReceivedBufferMessage::ReceiverDisconnect)
|
.unbounded_send(ReceivedBufferMessage::ReceiverDisconnect)
|
||||||
.is_err()
|
|
||||||
{
|
{
|
||||||
error!("we failed to disconnect the receiver from the buffer! presumably the shutdown procedure has been initiated!")
|
if !self.task_client.is_shutdown_poll() {
|
||||||
|
error!("failed to disconnect the receiver from the buffer: {err}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,10 +135,23 @@ impl Handler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// get the number of pending replies waiting for reply surbs
|
// get the number of pending replies waiting for reply surbs
|
||||||
let reply_queue_length = self
|
let reply_queue_length = match self
|
||||||
.reply_controller_sender
|
.reply_controller_sender
|
||||||
.get_lane_queue_length(connection_id)
|
.get_lane_queue_length(connection_id)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
|
Ok(length) => length,
|
||||||
|
Err(err) => {
|
||||||
|
if !self.task_client.is_shutdown_poll() {
|
||||||
|
error!(
|
||||||
|
"Failed to get reply queue length for connection {connection_id}: {err}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// We're just going to assume that the queue is empty, and I think that's okay
|
||||||
|
// during shutdown.
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let queue_length = base_length + reply_queue_length;
|
let queue_length = base_length + reply_queue_length;
|
||||||
|
|
||||||
@@ -168,10 +191,11 @@ impl Handler {
|
|||||||
|
|
||||||
// the ack control is now responsible for chunking, etc.
|
// the ack control is now responsible for chunking, etc.
|
||||||
let input_msg = InputMessage::new_regular(recipient, message, lane, self.packet_type);
|
let input_msg = InputMessage::new_regular(recipient, message, lane, self.packet_type);
|
||||||
self.msg_input
|
if let Err(err) = self.msg_input.send(input_msg).await {
|
||||||
.send(input_msg)
|
if !self.task_client.is_shutdown_poll() {
|
||||||
.await
|
error!("Failed to send message to the input buffer: {err}");
|
||||||
.expect("InputMessageReceiver has stopped receiving!");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
|
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
|
||||||
let TransmissionLane::ConnectionId(connection_id) = lane else {
|
let TransmissionLane::ConnectionId(connection_id) = lane else {
|
||||||
@@ -200,10 +224,11 @@ impl Handler {
|
|||||||
|
|
||||||
let input_msg =
|
let input_msg =
|
||||||
InputMessage::new_anonymous(recipient, message, reply_surbs, lane, self.packet_type);
|
InputMessage::new_anonymous(recipient, message, reply_surbs, lane, self.packet_type);
|
||||||
self.msg_input
|
if let Err(err) = self.msg_input.send(input_msg).await {
|
||||||
.send(input_msg)
|
if !self.task_client.is_shutdown_poll() {
|
||||||
.await
|
error!("Failed to send anonymous message to the input buffer: {err}");
|
||||||
.expect("InputMessageReceiver has stopped receiving!");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
|
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
|
||||||
let TransmissionLane::ConnectionId(connection_id) = lane else {
|
let TransmissionLane::ConnectionId(connection_id) = lane else {
|
||||||
@@ -227,10 +252,11 @@ impl Handler {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let input_msg = InputMessage::new_reply(recipient_tag, message, lane, self.packet_type);
|
let input_msg = InputMessage::new_reply(recipient_tag, message, lane, self.packet_type);
|
||||||
self.msg_input
|
if let Err(err) = self.msg_input.send(input_msg).await {
|
||||||
.send(input_msg)
|
if !self.task_client.is_shutdown_poll() {
|
||||||
.await
|
error!("Failed to send reply message to the input buffer: {err}");
|
||||||
.expect("InputMessageReceiver has stopped receiving!");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
|
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
|
||||||
let TransmissionLane::ConnectionId(connection_id) = lane else {
|
let TransmissionLane::ConnectionId(connection_id) = lane else {
|
||||||
@@ -245,9 +271,14 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_closed_connection(&self, connection_id: u64) -> Option<ServerResponse> {
|
fn handle_closed_connection(&self, connection_id: u64) -> Option<ServerResponse> {
|
||||||
self.client_connection_tx
|
if let Err(err) = self
|
||||||
|
.client_connection_tx
|
||||||
.unbounded_send(ConnectionCommand::Close(connection_id))
|
.unbounded_send(ConnectionCommand::Close(connection_id))
|
||||||
.unwrap();
|
{
|
||||||
|
if !self.task_client.is_shutdown_poll() {
|
||||||
|
error!("Failed to send close connection command: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,11 +393,10 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn listen_for_requests(
|
async fn listen_for_requests(&mut self, mut msg_receiver: ReconstructedMessagesReceiver) {
|
||||||
&mut self,
|
let mut task_client = self.task_client.fork("select");
|
||||||
mut msg_receiver: ReconstructedMessagesReceiver,
|
task_client.disarm();
|
||||||
mut task_client: nym_task::TaskClient,
|
|
||||||
) {
|
|
||||||
while !task_client.is_shutdown() {
|
while !task_client.is_shutdown() {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
// we can either get a client request from the websocket
|
// we can either get a client request from the websocket
|
||||||
@@ -415,15 +445,7 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// consume self to make sure `drop` is called after this is done
|
// consume self to make sure `drop` is called after this is done
|
||||||
pub(crate) async fn handle_connection(
|
pub(crate) async fn handle_connection(mut self, socket: TcpStream) {
|
||||||
mut self,
|
|
||||||
socket: TcpStream,
|
|
||||||
mut task_client: nym_task::TaskClient,
|
|
||||||
) {
|
|
||||||
// We don't want a crash in the connection handler to trigger a shutdown of the whole
|
|
||||||
// process.
|
|
||||||
task_client.disarm();
|
|
||||||
|
|
||||||
let ws_stream = match accept_async(socket).await {
|
let ws_stream = match accept_async(socket).await {
|
||||||
Ok(ws_stream) => ws_stream,
|
Ok(ws_stream) => ws_stream,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -436,14 +458,18 @@ impl Handler {
|
|||||||
let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded();
|
let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded();
|
||||||
|
|
||||||
// tell the buffer to start sending stuff to us
|
// tell the buffer to start sending stuff to us
|
||||||
self.buffer_requester
|
if let Err(err) =
|
||||||
.unbounded_send(ReceivedBufferMessage::ReceiverAnnounce(
|
self.buffer_requester
|
||||||
reconstructed_sender,
|
.unbounded_send(ReceivedBufferMessage::ReceiverAnnounce(
|
||||||
))
|
reconstructed_sender,
|
||||||
.expect("the buffer request failed!");
|
))
|
||||||
|
{
|
||||||
|
if !self.task_client.is_shutdown_poll() {
|
||||||
|
error!("failed to announce the receiver to the buffer: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.listen_for_requests(reconstructed_receiver, task_client)
|
self.listen_for_requests(reconstructed_receiver).await;
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
use super::handler::HandlerBuilder;
|
use super::handler::HandlerBuilder;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use nym_task::TaskClient;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::{net::SocketAddr, process, sync::Arc};
|
use std::{net::SocketAddr, process, sync::Arc};
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
@@ -22,21 +23,19 @@ impl State {
|
|||||||
pub(crate) struct Listener {
|
pub(crate) struct Listener {
|
||||||
address: SocketAddr,
|
address: SocketAddr,
|
||||||
state: State,
|
state: State,
|
||||||
|
task_client: TaskClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Listener {
|
impl Listener {
|
||||||
pub(crate) fn new(host: IpAddr, port: u16) -> Self {
|
pub(crate) fn new(host: IpAddr, port: u16, task_client: TaskClient) -> Self {
|
||||||
Listener {
|
Listener {
|
||||||
address: SocketAddr::new(host, port),
|
address: SocketAddr::new(host, port),
|
||||||
state: State::AwaitingConnection,
|
state: State::AwaitingConnection,
|
||||||
|
task_client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn run(
|
pub(crate) async fn run(&mut self, handler: HandlerBuilder) {
|
||||||
&mut self,
|
|
||||||
handler: HandlerBuilder,
|
|
||||||
mut task_client: nym_task::TaskClient,
|
|
||||||
) {
|
|
||||||
let tcp_listener = match tokio::net::TcpListener::bind(self.address).await {
|
let tcp_listener = match tokio::net::TcpListener::bind(self.address).await {
|
||||||
Ok(listener) => listener,
|
Ok(listener) => listener,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -47,11 +46,11 @@ impl Listener {
|
|||||||
|
|
||||||
let notify = Arc::new(Notify::new());
|
let notify = Arc::new(Notify::new());
|
||||||
|
|
||||||
loop {
|
while !self.task_client.is_shutdown() {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
// When the handler finishes we check if shutdown is signalled
|
// When the handler finishes we check if shutdown is signalled
|
||||||
_ = notify.notified() => {
|
_ = notify.notified() => {
|
||||||
if task_client.is_shutdown() {
|
if self.task_client.is_shutdown() {
|
||||||
log::trace!("Websocket listener: detected shutdown after connection closed");
|
log::trace!("Websocket listener: detected shutdown after connection closed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -60,7 +59,7 @@ impl Listener {
|
|||||||
}
|
}
|
||||||
// ... but when there is no connected client at the time of shutdown being
|
// ... but when there is no connected client at the time of shutdown being
|
||||||
// signalled, we handle it here.
|
// signalled, we handle it here.
|
||||||
_ = task_client.recv() => {
|
_ = self.task_client.recv() => {
|
||||||
if !self.state.is_connected() {
|
if !self.state.is_connected() {
|
||||||
log::trace!("Not connected: shutting down");
|
log::trace!("Not connected: shutting down");
|
||||||
break;
|
break;
|
||||||
@@ -88,9 +87,8 @@ impl Listener {
|
|||||||
// hanging because the executor doesn't come back here
|
// hanging because the executor doesn't come back here
|
||||||
let notify_clone = Arc::clone(¬ify);
|
let notify_clone = Arc::clone(¬ify);
|
||||||
let fresh_handler = handler.create_active_handler();
|
let fresh_handler = handler.create_active_handler();
|
||||||
let task_client_handler = task_client.clone();
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
fresh_handler.handle_connection(socket, task_client_handler).await;
|
fresh_handler.handle_connection(socket).await;
|
||||||
notify_clone.notify_one();
|
notify_clone.notify_one();
|
||||||
});
|
});
|
||||||
self.state = State::Connected;
|
self.state = State::Connected;
|
||||||
@@ -104,13 +102,9 @@ impl Listener {
|
|||||||
log::debug!("Websocket listener: Exiting");
|
log::debug!("Websocket listener: Exiting");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn start(
|
pub(crate) fn start(mut self, handler: HandlerBuilder) -> JoinHandle<()> {
|
||||||
mut self,
|
|
||||||
handler: HandlerBuilder,
|
|
||||||
shutdown: nym_task::TaskClient,
|
|
||||||
) -> JoinHandle<()> {
|
|
||||||
info!("Running websocket on {:?}", self.address.to_string());
|
info!("Running websocket on {:?}", self.address.to_string());
|
||||||
|
|
||||||
tokio::spawn(async move { self.run(handler, shutdown).await })
|
tokio::spawn(async move { self.run(handler).await })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.45"
|
version = "1.1.52"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ impl From<Init> for OverrideConfig {
|
|||||||
enabled_credentials_mode: init_config.common_args.enabled_credentials_mode,
|
enabled_credentials_mode: init_config.common_args.enabled_credentials_mode,
|
||||||
outfox: false,
|
outfox: false,
|
||||||
stats_reporting_address: init_config.common_args.stats_reporting_address,
|
stats_reporting_address: init_config.common_args.stats_reporting_address,
|
||||||
|
forget_me: init_config.common_args.forget_me.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use nym_bin_common::completions::{fig_generate, ArgShell};
|
|||||||
use nym_client_core::cli_helpers::CliClient;
|
use nym_client_core::cli_helpers::CliClient;
|
||||||
use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33;
|
use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33;
|
||||||
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
|
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
|
||||||
use nym_client_core::config::{GroupBy, TopologyStructure};
|
use nym_client_core::config::{ForgetMe, GroupBy, TopologyStructure};
|
||||||
use nym_config::OptionalSet;
|
use nym_config::OptionalSet;
|
||||||
use nym_sphinx::addressing::Recipient;
|
use nym_sphinx::addressing::Recipient;
|
||||||
use nym_sphinx::params::{PacketSize, PacketType};
|
use nym_sphinx::params::{PacketSize, PacketType};
|
||||||
@@ -113,6 +113,7 @@ pub(crate) struct OverrideConfig {
|
|||||||
enabled_credentials_mode: Option<bool>,
|
enabled_credentials_mode: Option<bool>,
|
||||||
outfox: bool,
|
outfox: bool,
|
||||||
stats_reporting_address: Option<Recipient>,
|
stats_reporting_address: Option<Recipient>,
|
||||||
|
forget_me: ForgetMe,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||||
@@ -179,6 +180,7 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
|||||||
BaseClientConfig::with_topology_structure,
|
BaseClientConfig::with_topology_structure,
|
||||||
topology_structure,
|
topology_structure,
|
||||||
)
|
)
|
||||||
|
.with_base(BaseClientConfig::with_forget_me, args.forget_me)
|
||||||
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
|
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
|
||||||
.with_optional(Config::with_port, args.port)
|
.with_optional(Config::with_port, args.port)
|
||||||
.with_optional(Config::with_ip, args.ip)
|
.with_optional(Config::with_ip, args.ip)
|
||||||
|
|||||||
@@ -2,14 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::commands::try_load_current_config;
|
use crate::commands::try_load_current_config;
|
||||||
use crate::config::Config;
|
use crate::commands::{override_config, OverrideConfig};
|
||||||
use crate::{
|
|
||||||
commands::{override_config, OverrideConfig},
|
|
||||||
error::Socks5ClientError,
|
|
||||||
};
|
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use log::*;
|
|
||||||
use nym_bin_common::version_checker::is_minor_version_compatible;
|
|
||||||
use nym_client_core::cli_helpers::client_run::CommonClientRunArgs;
|
use nym_client_core::cli_helpers::client_run::CommonClientRunArgs;
|
||||||
use nym_client_core::client::base_client::storage::OnDiskPersistent;
|
use nym_client_core::client::base_client::storage::OnDiskPersistent;
|
||||||
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
|
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
|
||||||
@@ -71,6 +65,7 @@ impl From<Run> for OverrideConfig {
|
|||||||
enabled_credentials_mode: run_config.common_args.enabled_credentials_mode,
|
enabled_credentials_mode: run_config.common_args.enabled_credentials_mode,
|
||||||
outfox: run_config.outfox,
|
outfox: run_config.outfox,
|
||||||
stats_reporting_address: run_config.common_args.stats_reporting_address,
|
stats_reporting_address: run_config.common_args.stats_reporting_address,
|
||||||
|
forget_me: run_config.common_args.forget_me.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,38 +77,12 @@ fn validate_country_group(s: &str) -> Result<CountryGroup, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this only checks compatibility between config the binary. It does not take into consideration
|
|
||||||
// network version. It might do so in the future.
|
|
||||||
fn version_check(cfg: &Config) -> bool {
|
|
||||||
let binary_version = env!("CARGO_PKG_VERSION");
|
|
||||||
let config_version = &cfg.core.base.client.version;
|
|
||||||
if binary_version == config_version {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
warn!(
|
|
||||||
"The socks5-client binary has different version than what is specified in config file! {binary_version} and {config_version}",
|
|
||||||
);
|
|
||||||
if is_minor_version_compatible(binary_version, config_version) {
|
|
||||||
info!("but they are still semver compatible. However, consider running the `upgrade` command");
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
error!("and they are semver incompatible! - please run the `upgrade` command before attempting `run` again");
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
eprintln!("Starting client {}...", args.common_args.id);
|
eprintln!("Starting client {}...", args.common_args.id);
|
||||||
|
|
||||||
let mut config = try_load_current_config(&args.common_args.id).await?;
|
let mut config = try_load_current_config(&args.common_args.id).await?;
|
||||||
config = override_config(config, OverrideConfig::from(args.clone()));
|
config = override_config(config, OverrideConfig::from(args.clone()));
|
||||||
|
|
||||||
if !version_check(&config) {
|
|
||||||
error!("failed the local version check");
|
|
||||||
return Err(Box::new(Socks5ClientError::FailedLocalVersionCheck));
|
|
||||||
}
|
|
||||||
|
|
||||||
let storage =
|
let storage =
|
||||||
OnDiskPersistent::from_paths(config.storage_paths.common_paths, &config.core.base.debug)
|
OnDiskPersistent::from_paths(config.storage_paths.common_paths, &config.core.base.debug)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -113,4 +113,8 @@ enabled = {{ core.debug.stats_reporting.enabled }}
|
|||||||
provider_address = '{{ core.debug.stats_reporting.provider_address }}'
|
provider_address = '{{ core.debug.stats_reporting.provider_address }}'
|
||||||
reporting_interval = '{{ core.debug.stats_reporting.reporting_interval }}'
|
reporting_interval = '{{ core.debug.stats_reporting.reporting_interval }}'
|
||||||
|
|
||||||
|
[core.debug.forget_me]
|
||||||
|
client = {{ core.debug.forget_me.client }}
|
||||||
|
stats = {{ core.debug.forget_me.stats }}
|
||||||
|
|
||||||
"#;
|
"#;
|
||||||
|
|||||||
@@ -14,9 +14,6 @@ pub enum Socks5ClientError {
|
|||||||
#[error("Failed to validate the loaded config")]
|
#[error("Failed to validate the loaded config")]
|
||||||
ConfigValidationFailure,
|
ConfigValidationFailure,
|
||||||
|
|
||||||
#[error("Failed local version check, client and config mismatch")]
|
|
||||||
FailedLocalVersionCheck,
|
|
||||||
|
|
||||||
#[error("Fail to bind address")]
|
#[error("Fail to bind address")]
|
||||||
FailToBindAddress,
|
FailToBindAddress,
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
allow-unwrap-in-tests = true
|
allow-unwrap-in-tests = true
|
||||||
allow-expect-in-tests = true
|
allow-expect-in-tests = true
|
||||||
|
allow-panic-in-tests = true
|
||||||
@@ -6,13 +6,15 @@ pub mod v1;
|
|||||||
pub mod v2;
|
pub mod v2;
|
||||||
pub mod v3;
|
pub mod v3;
|
||||||
pub mod v4;
|
pub mod v4;
|
||||||
|
pub mod v5;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
|
mod util;
|
||||||
|
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use v4 as latest;
|
pub use v5 as latest;
|
||||||
|
|
||||||
pub const CURRENT_VERSION: u8 = 4;
|
pub const CURRENT_VERSION: u8 = 5;
|
||||||
|
|
||||||
fn make_bincode_serializer() -> impl bincode::Options {
|
fn make_bincode_serializer() -> impl bincode::Options {
|
||||||
use bincode::Options;
|
use bincode::Options;
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ use nym_sphinx::addressing::clients::Recipient;
|
|||||||
use nym_wireguard_types::PeerPublicKey;
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
v1, v2, v3,
|
v1, v2, v3, v4,
|
||||||
v4::{self, registration::IpPair},
|
v5::{self, registration::IpPair},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ pub enum AuthenticatorVersion {
|
|||||||
V2,
|
V2,
|
||||||
V3,
|
V3,
|
||||||
V4,
|
V4,
|
||||||
|
V5,
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +35,8 @@ impl From<Protocol> for AuthenticatorVersion {
|
|||||||
AuthenticatorVersion::V3
|
AuthenticatorVersion::V3
|
||||||
} else if value.version == v4::VERSION {
|
} else if value.version == v4::VERSION {
|
||||||
AuthenticatorVersion::V4
|
AuthenticatorVersion::V4
|
||||||
|
} else if value.version == v5::VERSION {
|
||||||
|
AuthenticatorVersion::V5
|
||||||
} else {
|
} else {
|
||||||
AuthenticatorVersion::UNKNOWN
|
AuthenticatorVersion::UNKNOWN
|
||||||
}
|
}
|
||||||
@@ -68,6 +71,12 @@ impl InitMessage for v4::registration::InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InitMessage for v5::registration::InitMessage {
|
||||||
|
fn pub_key(&self) -> PeerPublicKey {
|
||||||
|
self.pub_key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait FinalMessage {
|
pub trait FinalMessage {
|
||||||
fn pub_key(&self) -> PeerPublicKey;
|
fn pub_key(&self) -> PeerPublicKey;
|
||||||
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error>;
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error>;
|
||||||
@@ -138,6 +147,24 @@ impl FinalMessage for v4::registration::FinalMessage {
|
|||||||
self.gateway_client.verify(private_key, nonce)
|
self.gateway_client.verify(private_key, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn private_ips(&self) -> IpPair {
|
||||||
|
self.gateway_client.private_ips.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn credential(&self) -> Option<CredentialSpendingData> {
|
||||||
|
self.credential.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FinalMessage for v5::registration::FinalMessage {
|
||||||
|
fn pub_key(&self) -> PeerPublicKey {
|
||||||
|
self.gateway_client.pub_key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
|
self.gateway_client.verify(private_key, nonce)
|
||||||
|
}
|
||||||
|
|
||||||
fn private_ips(&self) -> IpPair {
|
fn private_ips(&self) -> IpPair {
|
||||||
self.gateway_client.private_ips
|
self.gateway_client.private_ips
|
||||||
}
|
}
|
||||||
@@ -182,29 +209,39 @@ impl TopUpMessage for v4::topup::TopUpMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TopUpMessage for v5::topup::TopUpMessage {
|
||||||
|
fn pub_key(&self) -> PeerPublicKey {
|
||||||
|
self.pub_key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn credential(&self) -> CredentialSpendingData {
|
||||||
|
self.credential.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum AuthenticatorRequest {
|
pub enum AuthenticatorRequest {
|
||||||
Initial {
|
Initial {
|
||||||
msg: Box<dyn InitMessage + Send + Sync + 'static>,
|
msg: Box<dyn InitMessage + Send + Sync + 'static>,
|
||||||
protocol: Protocol,
|
protocol: Protocol,
|
||||||
reply_to: Recipient,
|
reply_to: Option<Recipient>,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
},
|
},
|
||||||
Final {
|
Final {
|
||||||
msg: Box<dyn FinalMessage + Send + Sync + 'static>,
|
msg: Box<dyn FinalMessage + Send + Sync + 'static>,
|
||||||
protocol: Protocol,
|
protocol: Protocol,
|
||||||
reply_to: Recipient,
|
reply_to: Option<Recipient>,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
},
|
},
|
||||||
QueryBandwidth {
|
QueryBandwidth {
|
||||||
msg: Box<dyn QueryBandwidthMessage + Send + Sync + 'static>,
|
msg: Box<dyn QueryBandwidthMessage + Send + Sync + 'static>,
|
||||||
protocol: Protocol,
|
protocol: Protocol,
|
||||||
reply_to: Recipient,
|
reply_to: Option<Recipient>,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
},
|
},
|
||||||
TopUpBandwidth {
|
TopUpBandwidth {
|
||||||
msg: Box<dyn TopUpMessage + Send + Sync + 'static>,
|
msg: Box<dyn TopUpMessage + Send + Sync + 'static>,
|
||||||
protocol: Protocol,
|
protocol: Protocol,
|
||||||
reply_to: Recipient,
|
reply_to: Option<Recipient>,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -218,7 +255,7 @@ impl From<v1::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
version: value.version,
|
version: value.version,
|
||||||
service_provider_type: ServiceProviderType::Authenticator,
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
},
|
},
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v1::request::AuthenticatorRequestData::Final(gateway_client) => Self::Final {
|
v1::request::AuthenticatorRequestData::Final(gateway_client) => Self::Final {
|
||||||
@@ -227,7 +264,7 @@ impl From<v1::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
version: value.version,
|
version: value.version,
|
||||||
service_provider_type: ServiceProviderType::Authenticator,
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
},
|
},
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v1::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
v1::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
||||||
@@ -237,7 +274,7 @@ impl From<v1::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
version: value.version,
|
version: value.version,
|
||||||
service_provider_type: ServiceProviderType::Authenticator,
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
},
|
},
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,20 +288,20 @@ impl From<v2::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
v2::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
v2::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
||||||
msg: Box::new(init_message),
|
msg: Box::new(init_message),
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v2::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
v2::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
||||||
msg: final_message,
|
msg: final_message,
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v2::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
v2::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
||||||
Self::QueryBandwidth {
|
Self::QueryBandwidth {
|
||||||
msg: Box::new(peer_public_key),
|
msg: Box::new(peer_public_key),
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,20 +315,20 @@ impl From<v3::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
v3::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
v3::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
||||||
msg: Box::new(init_message),
|
msg: Box::new(init_message),
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v3::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
v3::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
||||||
msg: final_message,
|
msg: final_message,
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v3::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
v3::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
||||||
Self::QueryBandwidth {
|
Self::QueryBandwidth {
|
||||||
msg: Box::new(peer_public_key),
|
msg: Box::new(peer_public_key),
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,7 +336,7 @@ impl From<v3::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
Self::TopUpBandwidth {
|
Self::TopUpBandwidth {
|
||||||
msg: top_up_message,
|
msg: top_up_message,
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,20 +350,20 @@ impl From<v4::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
v4::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
v4::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
||||||
msg: Box::new(init_message),
|
msg: Box::new(init_message),
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v4::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
v4::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
||||||
msg: final_message,
|
msg: final_message,
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
},
|
},
|
||||||
v4::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
v4::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
||||||
Self::QueryBandwidth {
|
Self::QueryBandwidth {
|
||||||
msg: Box::new(peer_public_key),
|
msg: Box::new(peer_public_key),
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,7 +371,42 @@ impl From<v4::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
Self::TopUpBandwidth {
|
Self::TopUpBandwidth {
|
||||||
msg: top_up_message,
|
msg: top_up_message,
|
||||||
protocol: value.protocol,
|
protocol: value.protocol,
|
||||||
reply_to: value.reply_to,
|
reply_to: Some(value.reply_to),
|
||||||
|
request_id: value.request_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v5::request::AuthenticatorRequest> for AuthenticatorRequest {
|
||||||
|
fn from(value: v5::request::AuthenticatorRequest) -> Self {
|
||||||
|
match value.data {
|
||||||
|
v5::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
||||||
|
msg: Box::new(init_message),
|
||||||
|
protocol: value.protocol,
|
||||||
|
reply_to: None,
|
||||||
|
request_id: value.request_id,
|
||||||
|
},
|
||||||
|
v5::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
||||||
|
msg: final_message,
|
||||||
|
protocol: value.protocol,
|
||||||
|
reply_to: None,
|
||||||
|
request_id: value.request_id,
|
||||||
|
},
|
||||||
|
v5::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
||||||
|
Self::QueryBandwidth {
|
||||||
|
msg: Box::new(peer_public_key),
|
||||||
|
protocol: value.protocol,
|
||||||
|
reply_to: None,
|
||||||
|
request_id: value.request_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v5::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message) => {
|
||||||
|
Self::TopUpBandwidth {
|
||||||
|
msg: top_up_message,
|
||||||
|
protocol: value.protocol,
|
||||||
|
reply_to: None,
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) mod tests {
|
||||||
|
pub(crate) const CREDENTIAL_BYTES: [u8; 1245] = [
|
||||||
|
0, 0, 4, 133, 96, 179, 223, 185, 136, 23, 213, 166, 59, 203, 66, 69, 209, 181, 227, 254,
|
||||||
|
16, 102, 98, 237, 59, 119, 170, 111, 31, 194, 51, 59, 120, 17, 115, 229, 79, 91, 11, 139,
|
||||||
|
154, 2, 212, 23, 68, 70, 167, 3, 240, 54, 224, 171, 221, 1, 69, 48, 60, 118, 119, 249, 123,
|
||||||
|
35, 172, 227, 131, 96, 232, 209, 187, 123, 4, 197, 102, 90, 96, 45, 125, 135, 140, 99, 1,
|
||||||
|
151, 17, 131, 143, 157, 97, 107, 139, 232, 212, 87, 14, 115, 253, 255, 166, 167, 186, 43,
|
||||||
|
90, 96, 173, 105, 120, 40, 10, 163, 250, 224, 214, 200, 178, 4, 160, 16, 130, 59, 76, 193,
|
||||||
|
39, 240, 3, 101, 141, 209, 183, 226, 186, 207, 56, 210, 187, 7, 164, 240, 164, 205, 37, 81,
|
||||||
|
184, 214, 193, 195, 90, 205, 238, 225, 195, 104, 12, 123, 203, 57, 233, 243, 215, 145, 195,
|
||||||
|
196, 57, 38, 125, 172, 18, 47, 63, 165, 110, 219, 180, 40, 58, 116, 92, 254, 160, 98, 48,
|
||||||
|
92, 254, 232, 107, 184, 80, 234, 60, 160, 235, 249, 76, 41, 38, 165, 28, 40, 136, 74, 48,
|
||||||
|
166, 50, 245, 23, 201, 140, 101, 79, 93, 235, 128, 186, 146, 126, 180, 134, 43, 13, 186,
|
||||||
|
19, 195, 48, 168, 201, 29, 216, 95, 176, 198, 132, 188, 64, 39, 212, 150, 32, 52, 53, 38,
|
||||||
|
228, 199, 122, 226, 217, 75, 40, 191, 151, 48, 164, 242, 177, 79, 14, 122, 105, 151, 85,
|
||||||
|
88, 199, 162, 17, 96, 103, 83, 178, 128, 9, 24, 30, 74, 108, 241, 85, 240, 166, 97, 241,
|
||||||
|
85, 199, 11, 198, 226, 234, 70, 107, 145, 28, 208, 114, 51, 12, 234, 108, 101, 202, 112,
|
||||||
|
48, 185, 22, 159, 67, 109, 49, 27, 149, 90, 109, 32, 226, 112, 7, 201, 208, 209, 104, 31,
|
||||||
|
97, 134, 204, 145, 27, 181, 206, 181, 106, 32, 110, 136, 115, 249, 201, 111, 5, 245, 203,
|
||||||
|
71, 121, 169, 126, 151, 178, 236, 59, 221, 195, 48, 135, 115, 6, 50, 227, 74, 97, 107, 107,
|
||||||
|
213, 90, 2, 203, 154, 138, 47, 128, 52, 134, 128, 224, 51, 65, 240, 90, 8, 55, 175, 180,
|
||||||
|
178, 204, 206, 168, 110, 51, 57, 189, 169, 48, 169, 136, 121, 99, 51, 170, 178, 214, 74, 1,
|
||||||
|
96, 151, 167, 25, 173, 180, 171, 155, 10, 55, 142, 234, 190, 113, 90, 79, 80, 244, 71, 166,
|
||||||
|
30, 235, 113, 150, 133, 1, 218, 17, 109, 111, 223, 24, 216, 177, 41, 2, 204, 65, 221, 212,
|
||||||
|
207, 236, 144, 6, 65, 224, 55, 42, 1, 1, 161, 134, 118, 127, 111, 220, 110, 127, 240, 71,
|
||||||
|
223, 129, 12, 93, 20, 220, 60, 56, 71, 146, 184, 95, 132, 69, 28, 56, 53, 192, 213, 22,
|
||||||
|
119, 230, 152, 225, 182, 188, 163, 219, 37, 175, 247, 73, 14, 247, 38, 72, 243, 1, 48, 131,
|
||||||
|
59, 8, 13, 96, 143, 185, 127, 241, 161, 217, 24, 149, 193, 40, 16, 30, 202, 151, 28, 119,
|
||||||
|
240, 153, 101, 156, 61, 193, 72, 245, 199, 181, 12, 231, 65, 166, 67, 142, 121, 207, 202,
|
||||||
|
58, 197, 113, 188, 248, 42, 124, 105, 48, 161, 241, 55, 209, 36, 194, 27, 63, 233, 144,
|
||||||
|
189, 85, 117, 234, 9, 139, 46, 31, 206, 114, 95, 131, 29, 240, 13, 81, 142, 140, 133, 33,
|
||||||
|
30, 41, 141, 37, 80, 217, 95, 221, 76, 115, 86, 201, 165, 51, 252, 9, 28, 209, 1, 48, 150,
|
||||||
|
74, 248, 212, 187, 222, 66, 210, 3, 200, 19, 217, 171, 184, 42, 148, 53, 150, 57, 50, 6,
|
||||||
|
227, 227, 62, 49, 42, 148, 148, 157, 82, 191, 58, 24, 34, 56, 98, 120, 89, 105, 176, 85,
|
||||||
|
15, 253, 241, 41, 153, 195, 136, 1, 48, 142, 126, 213, 101, 223, 79, 133, 230, 105, 38,
|
||||||
|
161, 149, 2, 21, 136, 150, 42, 72, 218, 85, 146, 63, 223, 58, 108, 186, 183, 248, 62, 20,
|
||||||
|
47, 34, 113, 160, 177, 204, 181, 16, 24, 212, 224, 35, 84, 51, 168, 56, 136, 11, 1, 48,
|
||||||
|
135, 242, 62, 149, 230, 178, 32, 224, 119, 26, 234, 163, 237, 224, 114, 95, 112, 140, 170,
|
||||||
|
150, 96, 125, 136, 221, 180, 78, 18, 11, 12, 184, 2, 198, 217, 119, 43, 69, 4, 172, 109,
|
||||||
|
55, 183, 40, 131, 172, 161, 88, 183, 101, 1, 48, 173, 216, 22, 73, 42, 255, 211, 93, 249,
|
||||||
|
87, 159, 115, 61, 91, 55, 130, 17, 216, 60, 34, 122, 55, 8, 244, 244, 153, 151, 57, 5, 144,
|
||||||
|
178, 55, 249, 64, 211, 168, 34, 148, 56, 89, 92, 203, 70, 124, 219, 152, 253, 165, 0, 32,
|
||||||
|
203, 116, 63, 7, 240, 222, 82, 86, 11, 149, 167, 72, 224, 55, 190, 66, 201, 65, 168, 184,
|
||||||
|
96, 47, 194, 241, 168, 124, 7, 74, 214, 250, 37, 76, 32, 218, 69, 122, 103, 215, 145, 169,
|
||||||
|
24, 212, 229, 168, 106, 10, 144, 31, 13, 25, 178, 242, 250, 106, 159, 40, 48, 163, 165, 61,
|
||||||
|
130, 57, 146, 4, 73, 32, 254, 233, 125, 135, 212, 29, 111, 4, 177, 114, 15, 210, 170, 82,
|
||||||
|
108, 110, 62, 166, 81, 209, 106, 176, 156, 14, 133, 242, 60, 127, 120, 242, 28, 97, 0, 1,
|
||||||
|
32, 103, 93, 109, 89, 240, 91, 1, 84, 150, 50, 206, 157, 203, 49, 220, 120, 234, 175, 234,
|
||||||
|
150, 126, 225, 94, 163, 164, 199, 138, 114, 62, 99, 106, 112, 1, 32, 171, 40, 220, 82, 241,
|
||||||
|
203, 76, 146, 111, 139, 182, 179, 237, 182, 115, 75, 128, 201, 107, 43, 214, 0, 135, 217,
|
||||||
|
160, 68, 150, 232, 144, 114, 237, 98, 32, 30, 134, 232, 59, 93, 163, 253, 244, 13, 202, 52,
|
||||||
|
147, 168, 83, 121, 123, 95, 21, 210, 209, 225, 223, 143, 49, 10, 205, 238, 1, 22, 83, 81,
|
||||||
|
70, 1, 32, 26, 76, 6, 234, 160, 50, 139, 102, 161, 232, 155, 106, 130, 171, 226, 210, 233,
|
||||||
|
178, 85, 247, 71, 123, 55, 53, 46, 67, 148, 137, 156, 207, 208, 107, 1, 32, 102, 31, 4, 98,
|
||||||
|
110, 156, 144, 61, 229, 140, 198, 84, 196, 238, 128, 35, 131, 182, 137, 125, 241, 95, 69,
|
||||||
|
131, 170, 27, 2, 144, 75, 72, 242, 102, 3, 32, 121, 80, 45, 173, 56, 65, 218, 27, 40, 251,
|
||||||
|
197, 32, 169, 104, 123, 110, 90, 78, 153, 166, 38, 9, 129, 228, 99, 8, 1, 116, 142, 233,
|
||||||
|
162, 69, 32, 216, 169, 159, 116, 95, 12, 63, 176, 195, 6, 183, 123, 135, 75, 61, 112, 106,
|
||||||
|
83, 235, 176, 41, 27, 248, 48, 71, 165, 170, 12, 92, 103, 103, 81, 32, 58, 74, 75, 145,
|
||||||
|
192, 94, 153, 69, 80, 128, 241, 3, 16, 117, 192, 86, 161, 103, 44, 174, 211, 196, 182, 124,
|
||||||
|
55, 11, 107, 142, 49, 88, 6, 41, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 37, 139, 240, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 1,
|
||||||
|
];
|
||||||
|
pub(crate) const RECIPIENT: &str = "CytBseW6yFXUMzz4SGAKdNLGR7q3sJLLYxyBGvutNEQV.4QXYyEVc5fUDjmmi8PrHN9tdUFV4PCvSJE1278cHyvoe@4sBbL1ngf1vtNqykydQKTFh26sQCw888GpUqvPvyNB4f";
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ use std::{fmt, ops::Deref, str::FromStr};
|
|||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use nym_crypto::asymmetric::encryption::PrivateKey;
|
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
@@ -82,16 +82,14 @@ impl GatewayClient {
|
|||||||
private_ip: IpAddr,
|
private_ip: IpAddr,
|
||||||
nonce: u64,
|
nonce: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
let local_public = PublicKey::from(local_secret);
|
||||||
#[allow(clippy::expect_used)]
|
let remote_public = PublicKey::from(remote_public);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
|
|
||||||
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&remote_public);
|
let dh = local_secret.diffie_hellman(&remote_public);
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
let mut mac = HmacSha256::new_from_slice(dh.as_bytes())
|
let mut mac = HmacSha256::new_from_slice(&dh[..])
|
||||||
.expect("x25519 shared secret is always 32 bytes long");
|
.expect("x25519 shared secret is always 32 bytes long");
|
||||||
|
|
||||||
mac.update(local_public.as_bytes());
|
mac.update(local_public.as_bytes());
|
||||||
@@ -99,7 +97,7 @@ impl GatewayClient {
|
|||||||
mac.update(&nonce.to_le_bytes());
|
mac.update(&nonce.to_le_bytes());
|
||||||
|
|
||||||
GatewayClient {
|
GatewayClient {
|
||||||
pub_key: PeerPublicKey::new(local_public),
|
pub_key: PeerPublicKey::new(local_public.into()),
|
||||||
private_ip,
|
private_ip,
|
||||||
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
||||||
}
|
}
|
||||||
@@ -109,11 +107,8 @@ impl GatewayClient {
|
|||||||
// Client should perform this step when generating its payload, using its own WG PK
|
// Client should perform this step when generating its payload, using its own WG PK
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
// use gateways key as a ref to an x25519_dalek key
|
||||||
#[allow(clippy::expect_used)]
|
let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&self.pub_key);
|
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use std::{fmt, ops::Deref, str::FromStr};
|
|||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use nym_crypto::asymmetric::encryption::PrivateKey;
|
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ pub type Taken = Option<SystemTime>;
|
|||||||
|
|
||||||
pub const BANDWIDTH_CAP_PER_DAY: u64 = 1024 * 1024 * 1024; // 1 GB
|
pub const BANDWIDTH_CAP_PER_DAY: u64 = 1024 * 1024 * 1024; // 1 GB
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct InitMessage {
|
pub struct InitMessage {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
@@ -41,7 +41,7 @@ impl InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct FinalMessage {
|
pub struct FinalMessage {
|
||||||
/// Gateway client data
|
/// Gateway client data
|
||||||
pub gateway_client: GatewayClient,
|
pub gateway_client: GatewayClient,
|
||||||
@@ -50,28 +50,28 @@ pub struct FinalMessage {
|
|||||||
pub credential: Option<CredentialSpendingData>,
|
pub credential: Option<CredentialSpendingData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegistrationData {
|
pub struct RegistrationData {
|
||||||
pub nonce: u64,
|
pub nonce: u64,
|
||||||
pub gateway_data: GatewayClient,
|
pub gateway_data: GatewayClient,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegistredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ip: IpAddr,
|
pub private_ip: IpAddr,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RemainingBandwidthData {
|
pub struct RemainingBandwidthData {
|
||||||
pub available_bandwidth: i64,
|
pub available_bandwidth: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
||||||
/// Gateway/Nym node can then verify pub_key payload using the same process
|
/// Gateway/Nym node can then verify pub_key payload using the same process
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct GatewayClient {
|
pub struct GatewayClient {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
@@ -91,16 +91,14 @@ impl GatewayClient {
|
|||||||
private_ip: IpAddr,
|
private_ip: IpAddr,
|
||||||
nonce: u64,
|
nonce: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
let local_public = PublicKey::from(local_secret);
|
||||||
#[allow(clippy::expect_used)]
|
let remote_public = PublicKey::from(remote_public);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
|
|
||||||
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&remote_public);
|
let dh = local_secret.diffie_hellman(&remote_public);
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
let mut mac = HmacSha256::new_from_slice(dh.as_bytes())
|
let mut mac = HmacSha256::new_from_slice(&dh[..])
|
||||||
.expect("x25519 shared secret is always 32 bytes long");
|
.expect("x25519 shared secret is always 32 bytes long");
|
||||||
|
|
||||||
mac.update(local_public.as_bytes());
|
mac.update(local_public.as_bytes());
|
||||||
@@ -108,7 +106,7 @@ impl GatewayClient {
|
|||||||
mac.update(&nonce.to_le_bytes());
|
mac.update(&nonce.to_le_bytes());
|
||||||
|
|
||||||
GatewayClient {
|
GatewayClient {
|
||||||
pub_key: PeerPublicKey::new(local_public),
|
pub_key: PeerPublicKey::new(local_public.into()),
|
||||||
private_ip,
|
private_ip,
|
||||||
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
||||||
}
|
}
|
||||||
@@ -118,11 +116,8 @@ impl GatewayClient {
|
|||||||
// Client should perform this step when generating its payload, using its own WG PK
|
// Client should perform this step when generating its payload, using its own WG PK
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
// use gateways key as a ref to an x25519_dalek key
|
||||||
#[allow(clippy::expect_used)]
|
let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&self.pub_key);
|
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
@@ -147,7 +142,7 @@ impl GatewayClient {
|
|||||||
|
|
||||||
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
||||||
// TODO2: rely on our internal crypto/hmac
|
// TODO2: rely on our internal crypto/hmac
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ClientMac(Vec<u8>);
|
pub struct ClientMac(Vec<u8>);
|
||||||
|
|
||||||
impl fmt::Display for ClientMac {
|
impl fmt::Display for ClientMac {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl AuthenticatorRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum AuthenticatorRequestData {
|
pub enum AuthenticatorRequestData {
|
||||||
Initial(InitMessage),
|
Initial(InitMessage),
|
||||||
Final(Box<FinalMessage>),
|
Final(Box<FinalMessage>),
|
||||||
|
|||||||
@@ -100,28 +100,28 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum AuthenticatorResponseData {
|
pub enum AuthenticatorResponseData {
|
||||||
PendingRegistration(PendingRegistrationResponse),
|
PendingRegistration(PendingRegistrationResponse),
|
||||||
Registered(RegisteredResponse),
|
Registered(RegisteredResponse),
|
||||||
RemainingBandwidth(RemainingBandwidthResponse),
|
RemainingBandwidth(RemainingBandwidthResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct PendingRegistrationResponse {
|
pub struct PendingRegistrationResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegistrationData,
|
pub reply: RegistrationData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegistredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct RemainingBandwidthResponse {
|
pub struct RemainingBandwidthResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
|
|||||||
@@ -19,6 +19,24 @@ impl From<v2::request::AuthenticatorRequest> for v3::request::AuthenticatorReque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<v3::request::AuthenticatorRequest> for v2::request::AuthenticatorRequest {
|
||||||
|
type Error = crate::Error;
|
||||||
|
|
||||||
|
fn try_from(
|
||||||
|
authenticator_request: v3::request::AuthenticatorRequest,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
},
|
||||||
|
data: authenticator_request.data.try_into()?,
|
||||||
|
reply_to: authenticator_request.reply_to,
|
||||||
|
request_id: authenticator_request.request_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<v2::request::AuthenticatorRequestData> for v3::request::AuthenticatorRequestData {
|
impl From<v2::request::AuthenticatorRequestData> for v3::request::AuthenticatorRequestData {
|
||||||
fn from(authenticator_request_data: v2::request::AuthenticatorRequestData) -> Self {
|
fn from(authenticator_request_data: v2::request::AuthenticatorRequestData) -> Self {
|
||||||
match authenticator_request_data {
|
match authenticator_request_data {
|
||||||
@@ -35,6 +53,29 @@ impl From<v2::request::AuthenticatorRequestData> for v3::request::AuthenticatorR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<v3::request::AuthenticatorRequestData> for v2::request::AuthenticatorRequestData {
|
||||||
|
type Error = crate::Error;
|
||||||
|
|
||||||
|
fn try_from(
|
||||||
|
authenticator_request_data: v3::request::AuthenticatorRequestData,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
match authenticator_request_data {
|
||||||
|
v3::request::AuthenticatorRequestData::Initial(init_msg) => Ok(
|
||||||
|
v2::request::AuthenticatorRequestData::Initial(init_msg.into()),
|
||||||
|
),
|
||||||
|
v3::request::AuthenticatorRequestData::Final(gw_client) => Ok(
|
||||||
|
v2::request::AuthenticatorRequestData::Final(gw_client.into()),
|
||||||
|
),
|
||||||
|
v3::request::AuthenticatorRequestData::QueryBandwidth(pub_key) => Ok(
|
||||||
|
v2::request::AuthenticatorRequestData::QueryBandwidth(pub_key),
|
||||||
|
),
|
||||||
|
v3::request::AuthenticatorRequestData::TopUpBandwidth(_) => Err(
|
||||||
|
Self::Error::Conversion("no top up bandwidth variant in v2".to_string()),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<v2::registration::InitMessage> for v3::registration::InitMessage {
|
impl From<v2::registration::InitMessage> for v3::registration::InitMessage {
|
||||||
fn from(init_msg: v2::registration::InitMessage) -> Self {
|
fn from(init_msg: v2::registration::InitMessage) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -43,6 +84,14 @@ impl From<v2::registration::InitMessage> for v3::registration::InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<v3::registration::InitMessage> for v2::registration::InitMessage {
|
||||||
|
fn from(init_msg: v3::registration::InitMessage) -> Self {
|
||||||
|
Self {
|
||||||
|
pub_key: init_msg.pub_key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Box<v2::registration::FinalMessage>> for Box<v3::registration::FinalMessage> {
|
impl From<Box<v2::registration::FinalMessage>> for Box<v3::registration::FinalMessage> {
|
||||||
fn from(gw_client: Box<v2::registration::FinalMessage>) -> Self {
|
fn from(gw_client: Box<v2::registration::FinalMessage>) -> Self {
|
||||||
Box::new(v3::registration::FinalMessage {
|
Box::new(v3::registration::FinalMessage {
|
||||||
@@ -52,6 +101,15 @@ impl From<Box<v2::registration::FinalMessage>> for Box<v3::registration::FinalMe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Box<v3::registration::FinalMessage>> for Box<v2::registration::FinalMessage> {
|
||||||
|
fn from(gw_client: Box<v3::registration::FinalMessage>) -> Self {
|
||||||
|
Box::new(v2::registration::FinalMessage {
|
||||||
|
gateway_client: gw_client.gateway_client.into(),
|
||||||
|
credential: gw_client.credential,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<v2::registration::GatewayClient> for v3::registration::GatewayClient {
|
impl From<v2::registration::GatewayClient> for v3::registration::GatewayClient {
|
||||||
fn from(gw_client: v2::registration::GatewayClient) -> Self {
|
fn from(gw_client: v2::registration::GatewayClient) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -93,7 +151,10 @@ impl TryFrom<v3::response::AuthenticatorResponse> for v2::response::Authenticato
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
data: authenticator_response.data.try_into()?,
|
data: authenticator_response.data.try_into()?,
|
||||||
reply_to: authenticator_response.reply_to,
|
reply_to: authenticator_response.reply_to,
|
||||||
protocol: authenticator_response.protocol,
|
protocol: Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: authenticator_response.protocol.service_provider_type,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +162,10 @@ impl TryFrom<v3::response::AuthenticatorResponse> for v2::response::Authenticato
|
|||||||
impl From<v2::response::AuthenticatorResponse> for v3::response::AuthenticatorResponse {
|
impl From<v2::response::AuthenticatorResponse> for v3::response::AuthenticatorResponse {
|
||||||
fn from(value: v2::response::AuthenticatorResponse) -> Self {
|
fn from(value: v2::response::AuthenticatorResponse) -> Self {
|
||||||
Self {
|
Self {
|
||||||
protocol: value.protocol,
|
protocol: Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: value.protocol.service_provider_type,
|
||||||
|
},
|
||||||
data: value.data.into(),
|
data: value.data.into(),
|
||||||
reply_to: value.reply_to,
|
reply_to: value.reply_to,
|
||||||
}
|
}
|
||||||
@@ -270,3 +334,511 @@ impl From<v2::registration::RemainingBandwidthData> for v3::registration::Remain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{net::IpAddr, str::FromStr};
|
||||||
|
|
||||||
|
use nym_credentials_interface::CredentialSpendingData;
|
||||||
|
use nym_crypto::asymmetric::encryption::PrivateKey;
|
||||||
|
use nym_sphinx::addressing::Recipient;
|
||||||
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use crate::util::tests::{CREDENTIAL_BYTES, RECIPIENT};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_initial_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v2::request::AuthenticatorRequest::new_initial_request(
|
||||||
|
v2::registration::InitMessage::new(pub_key),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v3::request::AuthenticatorRequest::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v3::request::AuthenticatorRequestData::Initial(v3::registration::InitMessage {
|
||||||
|
pub_key
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_initial_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v3::request::AuthenticatorRequest::new_initial_request(
|
||||||
|
v3::registration::InitMessage::new(pub_key),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let downgraded_msg = v2::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v2::request::AuthenticatorRequestData::Initial(v2::registration::InitMessage {
|
||||||
|
pub_key
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_final_req() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
|
let nonce = 42;
|
||||||
|
let gateway_client = v2::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let credential = Some(CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap());
|
||||||
|
let final_message = v2::registration::FinalMessage {
|
||||||
|
gateway_client,
|
||||||
|
credential: credential.clone(),
|
||||||
|
};
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) =
|
||||||
|
v2::request::AuthenticatorRequest::new_final_request(final_message, reply_to);
|
||||||
|
let upgraded_msg = v3::request::AuthenticatorRequest::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v3::request::AuthenticatorRequestData::Final(Box::new(
|
||||||
|
v3::registration::FinalMessage {
|
||||||
|
gateway_client: v3::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
),
|
||||||
|
credential
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_final_req() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
|
let nonce = 42;
|
||||||
|
let gateway_client = v3::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let credential = Some(CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap());
|
||||||
|
let final_message = v3::registration::FinalMessage {
|
||||||
|
gateway_client,
|
||||||
|
credential: credential.clone(),
|
||||||
|
};
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) =
|
||||||
|
v3::request::AuthenticatorRequest::new_final_request(final_message, reply_to);
|
||||||
|
let upgraded_msg = v2::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v2::request::AuthenticatorRequestData::Final(Box::new(
|
||||||
|
v2::registration::FinalMessage {
|
||||||
|
gateway_client: v2::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
),
|
||||||
|
credential
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_query_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v2::request::AuthenticatorRequest::new_query_request(pub_key, reply_to);
|
||||||
|
let upgraded_msg = v3::request::AuthenticatorRequest::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v3::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_query_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v3::request::AuthenticatorRequest::new_query_request(pub_key, reply_to);
|
||||||
|
let downgraded_msg = v2::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v2::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_topup_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let credential = CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap();
|
||||||
|
let top_up_message = v3::topup::TopUpMessage {
|
||||||
|
pub_key,
|
||||||
|
credential,
|
||||||
|
};
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) =
|
||||||
|
v3::request::AuthenticatorRequest::new_topup_request(top_up_message, reply_to);
|
||||||
|
assert!(v2::request::AuthenticatorRequest::try_from(msg).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_pending_reg_resp() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
|
let nonce = 42;
|
||||||
|
let wg_port = 51822;
|
||||||
|
let gateway_data = v2::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let registration_data = v2::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v2::response::AuthenticatorResponse::new_pending_registration_success(
|
||||||
|
registration_data,
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v3::response::AuthenticatorResponse::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v3::response::AuthenticatorResponseData::PendingRegistration(
|
||||||
|
v3::response::PendingRegistrationResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: v3::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data: v3::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
),
|
||||||
|
wg_port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_pending_reg_resp() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
|
let nonce = 42;
|
||||||
|
let wg_port = 51822;
|
||||||
|
let gateway_data = v3::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let registration_data = v3::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v3::response::AuthenticatorResponse::new_pending_registration_success(
|
||||||
|
registration_data,
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let downgraded_msg = v2::response::AuthenticatorResponse::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v2::response::AuthenticatorResponseData::PendingRegistration(
|
||||||
|
v2::response::PendingRegistrationResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: v2::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data: v2::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ip,
|
||||||
|
nonce,
|
||||||
|
),
|
||||||
|
wg_port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_registered_resp() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
|
let wg_port = 51822;
|
||||||
|
let registred_data = v2::registration::RegistredData {
|
||||||
|
pub_key,
|
||||||
|
private_ip,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v2::response::AuthenticatorResponse::new_registered(
|
||||||
|
registred_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v3::response::AuthenticatorResponse::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v3::response::AuthenticatorResponseData::Registered(v3::response::RegisteredResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: v3::registration::RegistredData {
|
||||||
|
wg_port,
|
||||||
|
pub_key,
|
||||||
|
private_ip
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_registered_resp() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
|
let wg_port = 51822;
|
||||||
|
let registred_data = v3::registration::RegistredData {
|
||||||
|
pub_key,
|
||||||
|
private_ip,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v3::response::AuthenticatorResponse::new_registered(
|
||||||
|
registred_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let downgraded_msg = v2::response::AuthenticatorResponse::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v2::response::AuthenticatorResponseData::Registered(v2::response::RegisteredResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: v2::registration::RegistredData {
|
||||||
|
wg_port,
|
||||||
|
pub_key,
|
||||||
|
private_ip
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_remaining_bandwidth_resp() {
|
||||||
|
let available_bandwidth = 42;
|
||||||
|
let remaining_bandwidth_data = Some(v2::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
});
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v2::response::AuthenticatorResponse::new_remaining_bandwidth(
|
||||||
|
remaining_bandwidth_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v3::response::AuthenticatorResponse::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v3::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
v3::response::RemainingBandwidthResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: Some(v3::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_remaining_bandwidth_resp() {
|
||||||
|
let available_bandwidth = 42;
|
||||||
|
let remaining_bandwidth_data = Some(v3::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
});
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v3::response::AuthenticatorResponse::new_remaining_bandwidth(
|
||||||
|
remaining_bandwidth_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let downgraded_msg = v2::response::AuthenticatorResponse::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 2,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v2::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
v2::response::RemainingBandwidthResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: Some(v2::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_topup_resp() {
|
||||||
|
let available_bandwidth = 42;
|
||||||
|
let remaining_bandwidth_data = v3::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v3::response::AuthenticatorResponse::new_topup_bandwidth(
|
||||||
|
remaining_bandwidth_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
assert!(v2::response::AuthenticatorResponse::try_from(msg).is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use std::{fmt, ops::Deref, str::FromStr};
|
|||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use nym_crypto::asymmetric::encryption::PrivateKey;
|
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ pub type Taken = Option<SystemTime>;
|
|||||||
|
|
||||||
pub const BANDWIDTH_CAP_PER_DAY: u64 = 250 * 1024 * 1024 * 1024; // 250 GB
|
pub const BANDWIDTH_CAP_PER_DAY: u64 = 250 * 1024 * 1024 * 1024; // 250 GB
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct InitMessage {
|
pub struct InitMessage {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
@@ -41,7 +41,7 @@ impl InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct FinalMessage {
|
pub struct FinalMessage {
|
||||||
/// Gateway client data
|
/// Gateway client data
|
||||||
pub gateway_client: GatewayClient,
|
pub gateway_client: GatewayClient,
|
||||||
@@ -50,28 +50,28 @@ pub struct FinalMessage {
|
|||||||
pub credential: Option<CredentialSpendingData>,
|
pub credential: Option<CredentialSpendingData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegistrationData {
|
pub struct RegistrationData {
|
||||||
pub nonce: u64,
|
pub nonce: u64,
|
||||||
pub gateway_data: GatewayClient,
|
pub gateway_data: GatewayClient,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegistredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ip: IpAddr,
|
pub private_ip: IpAddr,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RemainingBandwidthData {
|
pub struct RemainingBandwidthData {
|
||||||
pub available_bandwidth: i64,
|
pub available_bandwidth: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
||||||
/// Gateway/Nym node can then verify pub_key payload using the same process
|
/// Gateway/Nym node can then verify pub_key payload using the same process
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct GatewayClient {
|
pub struct GatewayClient {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
@@ -91,16 +91,14 @@ impl GatewayClient {
|
|||||||
private_ip: IpAddr,
|
private_ip: IpAddr,
|
||||||
nonce: u64,
|
nonce: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
let local_public = PublicKey::from(local_secret);
|
||||||
#[allow(clippy::expect_used)]
|
let remote_public = PublicKey::from(remote_public);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
|
|
||||||
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&remote_public);
|
let dh = local_secret.diffie_hellman(&remote_public);
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
let mut mac = HmacSha256::new_from_slice(dh.as_bytes())
|
let mut mac = HmacSha256::new_from_slice(&dh[..])
|
||||||
.expect("x25519 shared secret is always 32 bytes long");
|
.expect("x25519 shared secret is always 32 bytes long");
|
||||||
|
|
||||||
mac.update(local_public.as_bytes());
|
mac.update(local_public.as_bytes());
|
||||||
@@ -108,7 +106,7 @@ impl GatewayClient {
|
|||||||
mac.update(&nonce.to_le_bytes());
|
mac.update(&nonce.to_le_bytes());
|
||||||
|
|
||||||
GatewayClient {
|
GatewayClient {
|
||||||
pub_key: PeerPublicKey::new(local_public),
|
pub_key: PeerPublicKey::new(local_public.into()),
|
||||||
private_ip,
|
private_ip,
|
||||||
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
||||||
}
|
}
|
||||||
@@ -118,11 +116,8 @@ impl GatewayClient {
|
|||||||
// Client should perform this step when generating its payload, using its own WG PK
|
// Client should perform this step when generating its payload, using its own WG PK
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
// use gateways key as a ref to an x25519_dalek key
|
||||||
#[allow(clippy::expect_used)]
|
let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&self.pub_key);
|
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
@@ -147,7 +142,7 @@ impl GatewayClient {
|
|||||||
|
|
||||||
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
||||||
// TODO2: rely on our internal crypto/hmac
|
// TODO2: rely on our internal crypto/hmac
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ClientMac(Vec<u8>);
|
pub struct ClientMac(Vec<u8>);
|
||||||
|
|
||||||
impl fmt::Display for ClientMac {
|
impl fmt::Display for ClientMac {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ impl AuthenticatorRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum AuthenticatorRequestData {
|
pub enum AuthenticatorRequestData {
|
||||||
Initial(InitMessage),
|
Initial(InitMessage),
|
||||||
Final(Box<FinalMessage>),
|
Final(Box<FinalMessage>),
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum AuthenticatorResponseData {
|
pub enum AuthenticatorResponseData {
|
||||||
PendingRegistration(PendingRegistrationResponse),
|
PendingRegistration(PendingRegistrationResponse),
|
||||||
Registered(RegisteredResponse),
|
Registered(RegisteredResponse),
|
||||||
@@ -128,28 +128,28 @@ pub enum AuthenticatorResponseData {
|
|||||||
TopUpBandwidth(TopUpBandwidthResponse),
|
TopUpBandwidth(TopUpBandwidthResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct PendingRegistrationResponse {
|
pub struct PendingRegistrationResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegistrationData,
|
pub reply: RegistrationData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegistredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct RemainingBandwidthResponse {
|
pub struct RemainingBandwidthResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: Option<RemainingBandwidthData>,
|
pub reply: Option<RemainingBandwidthData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct TopUpBandwidthResponse {
|
pub struct TopUpBandwidthResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use nym_credentials_interface::CredentialSpendingData;
|
|||||||
use nym_wireguard_types::PeerPublicKey;
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct TopUpMessage {
|
pub struct TopUpMessage {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
|
|||||||
@@ -3,37 +3,82 @@
|
|||||||
|
|
||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
|
|
||||||
use crate::{v2, v3, v4};
|
use crate::{v3, v4};
|
||||||
|
|
||||||
impl From<v3::request::AuthenticatorRequest> for v4::request::AuthenticatorRequest {
|
impl TryFrom<v3::request::AuthenticatorRequest> for v4::request::AuthenticatorRequest {
|
||||||
fn from(authenticator_request: v3::request::AuthenticatorRequest) -> Self {
|
type Error = crate::Error;
|
||||||
Self {
|
fn try_from(
|
||||||
|
authenticator_request: v3::request::AuthenticatorRequest,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Self {
|
||||||
protocol: Protocol {
|
protocol: Protocol {
|
||||||
version: 4,
|
version: 4,
|
||||||
service_provider_type: ServiceProviderType::Authenticator,
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
},
|
},
|
||||||
data: authenticator_request.data.into(),
|
data: authenticator_request.data.try_into()?,
|
||||||
reply_to: authenticator_request.reply_to,
|
reply_to: authenticator_request.reply_to,
|
||||||
request_id: authenticator_request.request_id,
|
request_id: authenticator_request.request_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<v4::request::AuthenticatorRequest> for v3::request::AuthenticatorRequest {
|
||||||
|
type Error = crate::Error;
|
||||||
|
fn try_from(
|
||||||
|
authenticator_request: v4::request::AuthenticatorRequest,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
},
|
||||||
|
data: authenticator_request.data.try_into()?,
|
||||||
|
reply_to: authenticator_request.reply_to,
|
||||||
|
request_id: authenticator_request.request_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<v3::request::AuthenticatorRequestData> for v4::request::AuthenticatorRequestData {
|
||||||
|
type Error = crate::Error;
|
||||||
|
fn try_from(
|
||||||
|
authenticator_request_data: v3::request::AuthenticatorRequestData,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
match authenticator_request_data {
|
||||||
|
v3::request::AuthenticatorRequestData::Initial(init_msg) => Ok(
|
||||||
|
v4::request::AuthenticatorRequestData::Initial(init_msg.into()),
|
||||||
|
),
|
||||||
|
v3::request::AuthenticatorRequestData::Final(_) => Err(Self::Error::Conversion(
|
||||||
|
"mac hash breaking change".to_string(),
|
||||||
|
)),
|
||||||
|
v3::request::AuthenticatorRequestData::QueryBandwidth(pub_key) => Ok(
|
||||||
|
v4::request::AuthenticatorRequestData::QueryBandwidth(pub_key),
|
||||||
|
),
|
||||||
|
v3::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message) => Ok(
|
||||||
|
v4::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message.into()),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v3::request::AuthenticatorRequestData> for v4::request::AuthenticatorRequestData {
|
impl TryFrom<v4::request::AuthenticatorRequestData> for v3::request::AuthenticatorRequestData {
|
||||||
fn from(authenticator_request_data: v3::request::AuthenticatorRequestData) -> Self {
|
type Error = crate::Error;
|
||||||
|
fn try_from(
|
||||||
|
authenticator_request_data: v4::request::AuthenticatorRequestData,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
match authenticator_request_data {
|
match authenticator_request_data {
|
||||||
v3::request::AuthenticatorRequestData::Initial(init_msg) => {
|
v4::request::AuthenticatorRequestData::Initial(init_msg) => Ok(
|
||||||
v4::request::AuthenticatorRequestData::Initial(init_msg.into())
|
v3::request::AuthenticatorRequestData::Initial(init_msg.into()),
|
||||||
}
|
),
|
||||||
v3::request::AuthenticatorRequestData::Final(gw_client) => {
|
v4::request::AuthenticatorRequestData::Final(_) => Err(Self::Error::Conversion(
|
||||||
v4::request::AuthenticatorRequestData::Final(gw_client.into())
|
"mac hash breaking change".to_string(),
|
||||||
}
|
)),
|
||||||
v3::request::AuthenticatorRequestData::QueryBandwidth(pub_key) => {
|
v4::request::AuthenticatorRequestData::QueryBandwidth(pub_key) => Ok(
|
||||||
v4::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
v3::request::AuthenticatorRequestData::QueryBandwidth(pub_key),
|
||||||
}
|
),
|
||||||
v3::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message) => {
|
v4::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message) => Ok(
|
||||||
v4::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message.into())
|
v3::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message.into()),
|
||||||
}
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,12 +91,11 @@ impl From<v3::registration::InitMessage> for v4::registration::InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Box<v3::registration::FinalMessage>> for Box<v4::registration::FinalMessage> {
|
impl From<v4::registration::InitMessage> for v3::registration::InitMessage {
|
||||||
fn from(gw_client: Box<v3::registration::FinalMessage>) -> Self {
|
fn from(init_msg: v4::registration::InitMessage) -> Self {
|
||||||
Box::new(v4::registration::FinalMessage {
|
Self {
|
||||||
gateway_client: gw_client.gateway_client.into(),
|
pub_key: init_msg.pub_key,
|
||||||
credential: gw_client.credential,
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,67 +108,26 @@ impl From<Box<v3::topup::TopUpMessage>> for Box<v4::topup::TopUpMessage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v2::registration::GatewayClient> for v4::registration::GatewayClient {
|
impl From<Box<v4::topup::TopUpMessage>> for Box<v3::topup::TopUpMessage> {
|
||||||
fn from(gw_client: v2::registration::GatewayClient) -> Self {
|
fn from(top_up_message: Box<v4::topup::TopUpMessage>) -> Self {
|
||||||
Self {
|
Box::new(v3::topup::TopUpMessage {
|
||||||
pub_key: gw_client.pub_key,
|
pub_key: top_up_message.pub_key,
|
||||||
private_ips: gw_client.private_ip.into(),
|
credential: top_up_message.credential,
|
||||||
mac: gw_client.mac.into(),
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v3::registration::GatewayClient> for v4::registration::GatewayClient {
|
impl TryFrom<v3::response::AuthenticatorResponse> for v4::response::AuthenticatorResponse {
|
||||||
fn from(gw_client: v3::registration::GatewayClient) -> Self {
|
type Error = crate::Error;
|
||||||
Self {
|
fn try_from(value: v3::response::AuthenticatorResponse) -> Result<Self, Self::Error> {
|
||||||
pub_key: gw_client.pub_key,
|
Ok(Self {
|
||||||
private_ips: gw_client.private_ip.into(),
|
protocol: Protocol {
|
||||||
mac: gw_client.mac.into(),
|
version: 4,
|
||||||
}
|
service_provider_type: value.protocol.service_provider_type,
|
||||||
}
|
},
|
||||||
}
|
data: value.data.try_into()?,
|
||||||
|
reply_to: value.reply_to,
|
||||||
impl From<v4::registration::GatewayClient> for v3::registration::GatewayClient {
|
})
|
||||||
fn from(gw_client: v4::registration::GatewayClient) -> Self {
|
|
||||||
Self {
|
|
||||||
pub_key: gw_client.pub_key,
|
|
||||||
private_ip: gw_client.private_ips.ipv4.into(),
|
|
||||||
mac: gw_client.mac.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v4::registration::GatewayClient> for v2::registration::GatewayClient {
|
|
||||||
fn from(gw_client: v4::registration::GatewayClient) -> Self {
|
|
||||||
Self {
|
|
||||||
pub_key: gw_client.pub_key,
|
|
||||||
private_ip: gw_client.private_ips.ipv4.into(),
|
|
||||||
mac: gw_client.mac.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v2::registration::ClientMac> for v4::registration::ClientMac {
|
|
||||||
fn from(mac: v2::registration::ClientMac) -> Self {
|
|
||||||
Self::new(mac.to_vec())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v3::registration::ClientMac> for v4::registration::ClientMac {
|
|
||||||
fn from(mac: v3::registration::ClientMac) -> Self {
|
|
||||||
Self::new(mac.to_vec())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v4::registration::ClientMac> for v3::registration::ClientMac {
|
|
||||||
fn from(mac: v4::registration::ClientMac) -> Self {
|
|
||||||
Self::new(mac.to_vec())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v4::registration::ClientMac> for v2::registration::ClientMac {
|
|
||||||
fn from(mac: v4::registration::ClientMac) -> Self {
|
|
||||||
Self::new(mac.to_vec())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,11 +140,40 @@ impl TryFrom<v4::response::AuthenticatorResponse> for v3::response::Authenticato
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
data: authenticator_response.data.try_into()?,
|
data: authenticator_response.data.try_into()?,
|
||||||
reply_to: authenticator_response.reply_to,
|
reply_to: authenticator_response.reply_to,
|
||||||
protocol: authenticator_response.protocol,
|
protocol: Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: authenticator_response.protocol.service_provider_type,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<v3::response::AuthenticatorResponseData> for v4::response::AuthenticatorResponseData {
|
||||||
|
type Error = crate::Error;
|
||||||
|
fn try_from(
|
||||||
|
authenticator_response_data: v3::response::AuthenticatorResponseData,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
match authenticator_response_data {
|
||||||
|
v3::response::AuthenticatorResponseData::PendingRegistration(_) => Err(
|
||||||
|
Self::Error::Conversion("mac hash breaking change".to_string()),
|
||||||
|
),
|
||||||
|
|
||||||
|
v3::response::AuthenticatorResponseData::Registered(registered_response) => Ok(
|
||||||
|
v4::response::AuthenticatorResponseData::Registered(registered_response.into()),
|
||||||
|
),
|
||||||
|
|
||||||
|
v3::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
remaining_bandwidth_response,
|
||||||
|
) => Ok(v4::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
remaining_bandwidth_response.into(),
|
||||||
|
)),
|
||||||
|
v3::response::AuthenticatorResponseData::TopUpBandwidth(top_up_response) => Ok(
|
||||||
|
v4::response::AuthenticatorResponseData::TopUpBandwidth(top_up_response.into()),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<v4::response::AuthenticatorResponseData> for v3::response::AuthenticatorResponseData {
|
impl TryFrom<v4::response::AuthenticatorResponseData> for v3::response::AuthenticatorResponseData {
|
||||||
type Error = crate::Error;
|
type Error = crate::Error;
|
||||||
|
|
||||||
@@ -149,13 +181,10 @@ impl TryFrom<v4::response::AuthenticatorResponseData> for v3::response::Authenti
|
|||||||
authenticator_response_data: v4::response::AuthenticatorResponseData,
|
authenticator_response_data: v4::response::AuthenticatorResponseData,
|
||||||
) -> Result<Self, Self::Error> {
|
) -> Result<Self, Self::Error> {
|
||||||
match authenticator_response_data {
|
match authenticator_response_data {
|
||||||
v4::response::AuthenticatorResponseData::PendingRegistration(
|
v4::response::AuthenticatorResponseData::PendingRegistration(_) => Err(
|
||||||
pending_registration_response,
|
Self::Error::Conversion("mac hash breaking change".to_string()),
|
||||||
) => Ok(
|
|
||||||
v3::response::AuthenticatorResponseData::PendingRegistration(
|
|
||||||
pending_registration_response.into(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
v4::response::AuthenticatorResponseData::Registered(registered_response) => Ok(
|
v4::response::AuthenticatorResponseData::Registered(registered_response) => Ok(
|
||||||
v3::response::AuthenticatorResponseData::Registered(registered_response.into()),
|
v3::response::AuthenticatorResponseData::Registered(registered_response.into()),
|
||||||
),
|
),
|
||||||
@@ -173,8 +202,8 @@ impl TryFrom<v4::response::AuthenticatorResponseData> for v3::response::Authenti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v4::response::PendingRegistrationResponse> for v3::response::PendingRegistrationResponse {
|
impl From<v4::response::RegisteredResponse> for v3::response::RegisteredResponse {
|
||||||
fn from(value: v4::response::PendingRegistrationResponse) -> Self {
|
fn from(value: v4::response::RegisteredResponse) -> Self {
|
||||||
Self {
|
Self {
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
reply_to: value.reply_to,
|
reply_to: value.reply_to,
|
||||||
@@ -183,8 +212,8 @@ impl From<v4::response::PendingRegistrationResponse> for v3::response::PendingRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v4::response::RegisteredResponse> for v3::response::RegisteredResponse {
|
impl From<v3::response::RegisteredResponse> for v4::response::RegisteredResponse {
|
||||||
fn from(value: v4::response::RegisteredResponse) -> Self {
|
fn from(value: v3::response::RegisteredResponse) -> Self {
|
||||||
Self {
|
Self {
|
||||||
request_id: value.request_id,
|
request_id: value.request_id,
|
||||||
reply_to: value.reply_to,
|
reply_to: value.reply_to,
|
||||||
@@ -193,6 +222,16 @@ impl From<v4::response::RegisteredResponse> for v3::response::RegisteredResponse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<v3::response::RemainingBandwidthResponse> for v4::response::RemainingBandwidthResponse {
|
||||||
|
fn from(value: v3::response::RemainingBandwidthResponse) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: value.request_id,
|
||||||
|
reply_to: value.reply_to,
|
||||||
|
reply: value.reply.map(Into::into),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<v4::response::RemainingBandwidthResponse> for v3::response::RemainingBandwidthResponse {
|
impl From<v4::response::RemainingBandwidthResponse> for v3::response::RemainingBandwidthResponse {
|
||||||
fn from(value: v4::response::RemainingBandwidthResponse) -> Self {
|
fn from(value: v4::response::RemainingBandwidthResponse) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -203,11 +242,31 @@ impl From<v4::response::RemainingBandwidthResponse> for v3::response::RemainingB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v4::registration::RegistrationData> for v3::registration::RegistrationData {
|
impl From<v3::response::TopUpBandwidthResponse> for v4::response::TopUpBandwidthResponse {
|
||||||
fn from(value: v4::registration::RegistrationData) -> Self {
|
fn from(value: v3::response::TopUpBandwidthResponse) -> Self {
|
||||||
Self {
|
Self {
|
||||||
nonce: value.nonce,
|
request_id: value.request_id,
|
||||||
gateway_data: value.gateway_data.into(),
|
reply_to: value.reply_to,
|
||||||
|
reply: value.reply.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::response::TopUpBandwidthResponse> for v3::response::TopUpBandwidthResponse {
|
||||||
|
fn from(value: v4::response::TopUpBandwidthResponse) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: value.request_id,
|
||||||
|
reply_to: value.reply_to,
|
||||||
|
reply: value.reply.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v3::registration::RegistredData> for v4::registration::RegistredData {
|
||||||
|
fn from(value: v3::registration::RegistredData) -> Self {
|
||||||
|
Self {
|
||||||
|
pub_key: value.pub_key,
|
||||||
|
private_ips: value.private_ip.into(),
|
||||||
wg_port: value.wg_port,
|
wg_port: value.wg_port,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,6 +282,14 @@ impl From<v4::registration::RegistredData> for v3::registration::RegistredData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<v3::registration::RemainingBandwidthData> for v4::registration::RemainingBandwidthData {
|
||||||
|
fn from(value: v3::registration::RemainingBandwidthData) -> Self {
|
||||||
|
Self {
|
||||||
|
available_bandwidth: value.available_bandwidth,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<v4::registration::RemainingBandwidthData> for v3::registration::RemainingBandwidthData {
|
impl From<v4::registration::RemainingBandwidthData> for v3::registration::RemainingBandwidthData {
|
||||||
fn from(value: v4::registration::RemainingBandwidthData) -> Self {
|
fn from(value: v4::registration::RemainingBandwidthData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -230,3 +297,441 @@ impl From<v4::registration::RemainingBandwidthData> for v3::registration::Remain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{
|
||||||
|
net::{Ipv4Addr, Ipv6Addr},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
use nym_credentials_interface::CredentialSpendingData;
|
||||||
|
use nym_crypto::asymmetric::encryption::PrivateKey;
|
||||||
|
use nym_sphinx::addressing::Recipient;
|
||||||
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use crate::util::tests::{CREDENTIAL_BYTES, RECIPIENT};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_initial_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v3::request::AuthenticatorRequest::new_initial_request(
|
||||||
|
v3::registration::InitMessage::new(pub_key),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v4::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 4,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v4::request::AuthenticatorRequestData::Initial(v4::registration::InitMessage {
|
||||||
|
pub_key
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_initial_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v4::request::AuthenticatorRequest::new_initial_request(
|
||||||
|
v4::registration::InitMessage::new(pub_key),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let downgraded_msg = v3::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v3::request::AuthenticatorRequestData::Initial(v3::registration::InitMessage {
|
||||||
|
pub_key
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_final_req() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
||||||
|
let nonce = 42;
|
||||||
|
let gateway_client = v3::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
ipv4.into(),
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let credential = Some(CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap());
|
||||||
|
let final_message = v3::registration::FinalMessage {
|
||||||
|
gateway_client,
|
||||||
|
credential: credential.clone(),
|
||||||
|
};
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) =
|
||||||
|
v3::request::AuthenticatorRequest::new_final_request(final_message, reply_to);
|
||||||
|
assert!(v4::request::AuthenticatorRequest::try_from(msg).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_final_req() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
||||||
|
let private_ips =
|
||||||
|
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::10").unwrap());
|
||||||
|
let nonce = 42;
|
||||||
|
let gateway_client = v4::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ips,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let credential = Some(CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap());
|
||||||
|
let final_message = v4::registration::FinalMessage {
|
||||||
|
gateway_client,
|
||||||
|
credential: credential.clone(),
|
||||||
|
};
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) =
|
||||||
|
v4::request::AuthenticatorRequest::new_final_request(final_message, reply_to);
|
||||||
|
assert!(v3::request::AuthenticatorRequest::try_from(msg).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_query_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v3::request::AuthenticatorRequest::new_query_request(pub_key, reply_to);
|
||||||
|
let upgraded_msg = v4::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 4,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v4::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_query_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v4::request::AuthenticatorRequest::new_query_request(pub_key, reply_to);
|
||||||
|
let downgraded_msg = v3::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v3::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_topup_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let credential = CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap();
|
||||||
|
let top_up_message = v4::topup::TopUpMessage {
|
||||||
|
pub_key,
|
||||||
|
credential: credential.clone(),
|
||||||
|
};
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) =
|
||||||
|
v4::request::AuthenticatorRequest::new_topup_request(top_up_message, reply_to);
|
||||||
|
let downgraded_msg = v3::request::AuthenticatorRequest::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v3::request::AuthenticatorRequestData::TopUpBandwidth(Box::new(
|
||||||
|
v3::topup::TopUpMessage {
|
||||||
|
pub_key,
|
||||||
|
credential
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_pending_reg_resp() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
||||||
|
let nonce = 42;
|
||||||
|
let wg_port = 51822;
|
||||||
|
let gateway_data = v3::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
ipv4.into(),
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let registration_data = v3::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v3::response::AuthenticatorResponse::new_pending_registration_success(
|
||||||
|
registration_data,
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
assert!(v4::response::AuthenticatorResponse::try_from(msg).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_pending_reg_resp() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
||||||
|
let private_ips =
|
||||||
|
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::10").unwrap());
|
||||||
|
let nonce = 42;
|
||||||
|
let wg_port = 51822;
|
||||||
|
let gateway_data = v4::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
private_ips,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let registration_data = v4::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v4::response::AuthenticatorResponse::new_pending_registration_success(
|
||||||
|
registration_data,
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
assert!(v3::response::AuthenticatorResponse::try_from(msg).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_registered_resp() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.1.10.10").unwrap();
|
||||||
|
let private_ips =
|
||||||
|
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::a0a").unwrap());
|
||||||
|
let wg_port = 51822;
|
||||||
|
let registred_data = v3::registration::RegistredData {
|
||||||
|
pub_key,
|
||||||
|
private_ip: ipv4.into(),
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v3::response::AuthenticatorResponse::new_registered(
|
||||||
|
registred_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v4::response::AuthenticatorResponse::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 4,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v4::response::AuthenticatorResponseData::Registered(v4::response::RegisteredResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: v4::registration::RegistredData {
|
||||||
|
wg_port,
|
||||||
|
pub_key,
|
||||||
|
private_ips
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_registered_resp() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
||||||
|
let private_ips =
|
||||||
|
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::10").unwrap());
|
||||||
|
let wg_port = 51822;
|
||||||
|
let registred_data = v4::registration::RegistredData {
|
||||||
|
pub_key,
|
||||||
|
private_ips,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v4::response::AuthenticatorResponse::new_registered(
|
||||||
|
registred_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let downgraded_msg = v3::response::AuthenticatorResponse::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v3::response::AuthenticatorResponseData::Registered(v3::response::RegisteredResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: v3::registration::RegistredData {
|
||||||
|
wg_port,
|
||||||
|
pub_key,
|
||||||
|
private_ip: ipv4.into()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_remaining_bandwidth_resp() {
|
||||||
|
let available_bandwidth = 42;
|
||||||
|
let remaining_bandwidth_data = Some(v3::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
});
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v3::response::AuthenticatorResponse::new_remaining_bandwidth(
|
||||||
|
remaining_bandwidth_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v4::response::AuthenticatorResponse::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 4,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v4::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
v4::response::RemainingBandwidthResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: Some(v4::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_remaining_bandwidth_resp() {
|
||||||
|
let available_bandwidth = 42;
|
||||||
|
let remaining_bandwidth_data = Some(v4::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
});
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v4::response::AuthenticatorResponse::new_remaining_bandwidth(
|
||||||
|
remaining_bandwidth_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let downgraded_msg = v3::response::AuthenticatorResponse::try_from(msg).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 3,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
downgraded_msg.data,
|
||||||
|
v3::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
v3::response::RemainingBandwidthResponse {
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
reply: Some(v3::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downgrade_topup_resp() {
|
||||||
|
let available_bandwidth = 42;
|
||||||
|
let remaining_bandwidth_data = v4::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v4::response::AuthenticatorResponse::new_topup_bandwidth(
|
||||||
|
remaining_bandwidth_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
assert!(v3::response::AuthenticatorResponse::try_from(msg).is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use std::{fmt, ops::Deref, str::FromStr};
|
|||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use nym_crypto::asymmetric::encryption::PrivateKey;
|
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ pub type HmacSha256 = Hmac<Sha256>;
|
|||||||
pub type Nonce = u64;
|
pub type Nonce = u64;
|
||||||
pub type Taken = Option<SystemTime>;
|
pub type Taken = Option<SystemTime>;
|
||||||
|
|
||||||
pub const BANDWIDTH_CAP_PER_DAY: u64 = 1024 * 1024 * 1024; // 1 GB
|
pub const BANDWIDTH_CAP_PER_DAY: u64 = 250 * 1024 * 1024 * 1024; // 250 GB
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub struct IpPair {
|
pub struct IpPair {
|
||||||
@@ -60,7 +60,7 @@ impl From<IpAddr> for IpPair {
|
|||||||
std::net::IpAddr::V4(ipv4_addr) => (ipv4_addr.octets()[2], ipv4_addr.octets()[3]),
|
std::net::IpAddr::V4(ipv4_addr) => (ipv4_addr.octets()[2], ipv4_addr.octets()[3]),
|
||||||
std::net::IpAddr::V6(ipv6_addr) => (ipv6_addr.octets()[14], ipv6_addr.octets()[15]),
|
std::net::IpAddr::V6(ipv6_addr) => (ipv6_addr.octets()[14], ipv6_addr.octets()[15]),
|
||||||
};
|
};
|
||||||
let last_bytes = (before_last_byte as u16) << 8 | last_byte as u16;
|
let last_bytes = ((before_last_byte as u16) << 8) | last_byte as u16;
|
||||||
let ipv4 = Ipv4Addr::new(
|
let ipv4 = Ipv4Addr::new(
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[0],
|
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[0],
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[1],
|
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[1],
|
||||||
@@ -81,7 +81,7 @@ impl From<IpAddr> for IpPair {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct InitMessage {
|
pub struct InitMessage {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
@@ -93,7 +93,7 @@ impl InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct FinalMessage {
|
pub struct FinalMessage {
|
||||||
/// Gateway client data
|
/// Gateway client data
|
||||||
pub gateway_client: GatewayClient,
|
pub gateway_client: GatewayClient,
|
||||||
@@ -102,28 +102,28 @@ pub struct FinalMessage {
|
|||||||
pub credential: Option<CredentialSpendingData>,
|
pub credential: Option<CredentialSpendingData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegistrationData {
|
pub struct RegistrationData {
|
||||||
pub nonce: u64,
|
pub nonce: u64,
|
||||||
pub gateway_data: GatewayClient,
|
pub gateway_data: GatewayClient,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegistredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ips: IpPair,
|
pub private_ips: IpPair,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RemainingBandwidthData {
|
pub struct RemainingBandwidthData {
|
||||||
pub available_bandwidth: i64,
|
pub available_bandwidth: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
||||||
/// Gateway/Nym node can then verify pub_key payload using the same process
|
/// Gateway/Nym node can then verify pub_key payload using the same process
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct GatewayClient {
|
pub struct GatewayClient {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
@@ -143,16 +143,14 @@ impl GatewayClient {
|
|||||||
private_ips: IpPair,
|
private_ips: IpPair,
|
||||||
nonce: u64,
|
nonce: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
let local_public = PublicKey::from(local_secret);
|
||||||
#[allow(clippy::expect_used)]
|
let remote_public = PublicKey::from(remote_public);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
|
|
||||||
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&remote_public);
|
let dh = local_secret.diffie_hellman(&remote_public);
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
let mut mac = HmacSha256::new_from_slice(dh.as_bytes())
|
let mut mac = HmacSha256::new_from_slice(&dh[..])
|
||||||
.expect("x25519 shared secret is always 32 bytes long");
|
.expect("x25519 shared secret is always 32 bytes long");
|
||||||
|
|
||||||
mac.update(local_public.as_bytes());
|
mac.update(local_public.as_bytes());
|
||||||
@@ -160,7 +158,7 @@ impl GatewayClient {
|
|||||||
mac.update(&nonce.to_le_bytes());
|
mac.update(&nonce.to_le_bytes());
|
||||||
|
|
||||||
GatewayClient {
|
GatewayClient {
|
||||||
pub_key: PeerPublicKey::new(local_public),
|
pub_key: PeerPublicKey::new(local_public.into()),
|
||||||
private_ips,
|
private_ips,
|
||||||
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
||||||
}
|
}
|
||||||
@@ -170,11 +168,8 @@ impl GatewayClient {
|
|||||||
// Client should perform this step when generating its payload, using its own WG PK
|
// Client should perform this step when generating its payload, using its own WG PK
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek
|
// use gateways key as a ref to an x25519_dalek key
|
||||||
#[allow(clippy::expect_used)]
|
let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
|
||||||
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
|
|
||||||
|
|
||||||
let dh = static_secret.diffie_hellman(&self.pub_key);
|
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
@@ -199,7 +194,7 @@ impl GatewayClient {
|
|||||||
|
|
||||||
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
||||||
// TODO2: rely on our internal crypto/hmac
|
// TODO2: rely on our internal crypto/hmac
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ClientMac(Vec<u8>);
|
pub struct ClientMac(Vec<u8>);
|
||||||
|
|
||||||
impl fmt::Display for ClientMac {
|
impl fmt::Display for ClientMac {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fn generate_random() -> u64 {
|
|||||||
rng.next_u64()
|
rng.next_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct AuthenticatorRequest {
|
pub struct AuthenticatorRequest {
|
||||||
pub protocol: Protocol,
|
pub protocol: Protocol,
|
||||||
pub data: AuthenticatorRequestData,
|
pub data: AuthenticatorRequestData,
|
||||||
@@ -106,7 +106,7 @@ impl AuthenticatorRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum AuthenticatorRequestData {
|
pub enum AuthenticatorRequestData {
|
||||||
Initial(InitMessage),
|
Initial(InitMessage),
|
||||||
Final(Box<FinalMessage>),
|
Final(Box<FinalMessage>),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::make_bincode_serializer;
|
|||||||
|
|
||||||
use super::VERSION;
|
use super::VERSION;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct AuthenticatorResponse {
|
pub struct AuthenticatorResponse {
|
||||||
pub protocol: Protocol,
|
pub protocol: Protocol,
|
||||||
pub data: AuthenticatorResponseData,
|
pub data: AuthenticatorResponseData,
|
||||||
@@ -120,7 +120,7 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum AuthenticatorResponseData {
|
pub enum AuthenticatorResponseData {
|
||||||
PendingRegistration(PendingRegistrationResponse),
|
PendingRegistration(PendingRegistrationResponse),
|
||||||
Registered(RegisteredResponse),
|
Registered(RegisteredResponse),
|
||||||
@@ -128,28 +128,28 @@ pub enum AuthenticatorResponseData {
|
|||||||
TopUpBandwidth(TopUpBandwidthResponse),
|
TopUpBandwidth(TopUpBandwidthResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct PendingRegistrationResponse {
|
pub struct PendingRegistrationResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegistrationData,
|
pub reply: RegistrationData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegistredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct RemainingBandwidthResponse {
|
pub struct RemainingBandwidthResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: Option<RemainingBandwidthData>,
|
pub reply: Option<RemainingBandwidthData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct TopUpBandwidthResponse {
|
pub struct TopUpBandwidthResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use nym_credentials_interface::CredentialSpendingData;
|
|||||||
use nym_wireguard_types::PeerPublicKey;
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct TopUpMessage {
|
pub struct TopUpMessage {
|
||||||
/// Base64 encoded x25519 public key
|
/// Base64 encoded x25519 public key
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
|
|||||||
@@ -0,0 +1,478 @@
|
|||||||
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
|
|
||||||
|
use crate::{v4, v5};
|
||||||
|
|
||||||
|
impl From<v4::request::AuthenticatorRequest> for v5::request::AuthenticatorRequest {
|
||||||
|
fn from(authenticator_request: v4::request::AuthenticatorRequest) -> Self {
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
},
|
||||||
|
data: authenticator_request.data.into(),
|
||||||
|
request_id: authenticator_request.request_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::request::AuthenticatorRequestData> for v5::request::AuthenticatorRequestData {
|
||||||
|
fn from(authenticator_request_data: v4::request::AuthenticatorRequestData) -> Self {
|
||||||
|
match authenticator_request_data {
|
||||||
|
v4::request::AuthenticatorRequestData::Initial(init_msg) => {
|
||||||
|
v5::request::AuthenticatorRequestData::Initial(init_msg.into())
|
||||||
|
}
|
||||||
|
v4::request::AuthenticatorRequestData::Final(final_msg) => {
|
||||||
|
v5::request::AuthenticatorRequestData::Final(Box::new((*final_msg).into()))
|
||||||
|
}
|
||||||
|
v4::request::AuthenticatorRequestData::QueryBandwidth(pub_key) => {
|
||||||
|
v5::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
||||||
|
}
|
||||||
|
v4::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message) => {
|
||||||
|
v5::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::InitMessage> for v5::registration::InitMessage {
|
||||||
|
fn from(init_msg: v4::registration::InitMessage) -> Self {
|
||||||
|
Self {
|
||||||
|
pub_key: init_msg.pub_key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::FinalMessage> for v5::registration::FinalMessage {
|
||||||
|
fn from(final_msg: v4::registration::FinalMessage) -> Self {
|
||||||
|
Self {
|
||||||
|
gateway_client: final_msg.gateway_client.into(),
|
||||||
|
credential: final_msg.credential,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::GatewayClient> for v5::registration::GatewayClient {
|
||||||
|
fn from(gateway_client: v4::registration::GatewayClient) -> Self {
|
||||||
|
Self {
|
||||||
|
pub_key: gateway_client.pub_key,
|
||||||
|
private_ips: gateway_client.private_ips.into(),
|
||||||
|
mac: gateway_client.mac.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v5::registration::GatewayClient> for v4::registration::GatewayClient {
|
||||||
|
fn from(gateway_client: v5::registration::GatewayClient) -> Self {
|
||||||
|
Self {
|
||||||
|
pub_key: gateway_client.pub_key,
|
||||||
|
private_ips: gateway_client.private_ips.into(),
|
||||||
|
mac: gateway_client.mac.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::ClientMac> for v5::registration::ClientMac {
|
||||||
|
fn from(client_mac: v4::registration::ClientMac) -> Self {
|
||||||
|
Self::new((*client_mac).clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v5::registration::ClientMac> for v4::registration::ClientMac {
|
||||||
|
fn from(client_mac: v5::registration::ClientMac) -> Self {
|
||||||
|
Self::new((*client_mac).clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Box<v4::topup::TopUpMessage>> for Box<v5::topup::TopUpMessage> {
|
||||||
|
fn from(top_up_message: Box<v4::topup::TopUpMessage>) -> Self {
|
||||||
|
Box::new(v5::topup::TopUpMessage {
|
||||||
|
pub_key: top_up_message.pub_key,
|
||||||
|
credential: top_up_message.credential,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::response::AuthenticatorResponse> for v5::response::AuthenticatorResponse {
|
||||||
|
fn from(value: v4::response::AuthenticatorResponse) -> Self {
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: value.protocol.service_provider_type,
|
||||||
|
},
|
||||||
|
data: value.data.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::response::AuthenticatorResponseData> for v5::response::AuthenticatorResponseData {
|
||||||
|
fn from(authenticator_response_data: v4::response::AuthenticatorResponseData) -> Self {
|
||||||
|
match authenticator_response_data {
|
||||||
|
v4::response::AuthenticatorResponseData::PendingRegistration(pending_response) => {
|
||||||
|
v5::response::AuthenticatorResponseData::PendingRegistration(
|
||||||
|
pending_response.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
v4::response::AuthenticatorResponseData::Registered(registered_response) => {
|
||||||
|
v5::response::AuthenticatorResponseData::Registered(registered_response.into())
|
||||||
|
}
|
||||||
|
v4::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
remaining_bandwidth_response,
|
||||||
|
) => v5::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
remaining_bandwidth_response.into(),
|
||||||
|
),
|
||||||
|
v4::response::AuthenticatorResponseData::TopUpBandwidth(top_up_response) => {
|
||||||
|
v5::response::AuthenticatorResponseData::TopUpBandwidth(top_up_response.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::response::RegisteredResponse> for v5::response::RegisteredResponse {
|
||||||
|
fn from(value: v4::response::RegisteredResponse) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: value.request_id,
|
||||||
|
reply: value.reply.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::response::PendingRegistrationResponse> for v5::response::PendingRegistrationResponse {
|
||||||
|
fn from(value: v4::response::PendingRegistrationResponse) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: value.request_id,
|
||||||
|
reply: value.reply.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::RegistrationData> for v5::registration::RegistrationData {
|
||||||
|
fn from(value: v4::registration::RegistrationData) -> Self {
|
||||||
|
Self {
|
||||||
|
nonce: value.nonce,
|
||||||
|
gateway_data: value.gateway_data.into(),
|
||||||
|
wg_port: value.wg_port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v5::registration::RegistrationData> for v4::registration::RegistrationData {
|
||||||
|
fn from(value: v5::registration::RegistrationData) -> Self {
|
||||||
|
Self {
|
||||||
|
nonce: value.nonce,
|
||||||
|
gateway_data: value.gateway_data.into(),
|
||||||
|
wg_port: value.wg_port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::response::RemainingBandwidthResponse> for v5::response::RemainingBandwidthResponse {
|
||||||
|
fn from(value: v4::response::RemainingBandwidthResponse) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: value.request_id,
|
||||||
|
reply: value.reply.map(Into::into),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::response::TopUpBandwidthResponse> for v5::response::TopUpBandwidthResponse {
|
||||||
|
fn from(value: v4::response::TopUpBandwidthResponse) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: value.request_id,
|
||||||
|
reply: value.reply.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::RegistredData> for v5::registration::RegistredData {
|
||||||
|
fn from(value: v4::registration::RegistredData) -> Self {
|
||||||
|
Self {
|
||||||
|
pub_key: value.pub_key,
|
||||||
|
private_ips: value.private_ips.into(),
|
||||||
|
wg_port: value.wg_port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::RemainingBandwidthData> for v5::registration::RemainingBandwidthData {
|
||||||
|
fn from(value: v4::registration::RemainingBandwidthData) -> Self {
|
||||||
|
Self {
|
||||||
|
available_bandwidth: value.available_bandwidth,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v4::registration::IpPair> for v5::registration::IpPair {
|
||||||
|
fn from(value: v4::registration::IpPair) -> Self {
|
||||||
|
Self {
|
||||||
|
ipv4: value.ipv4,
|
||||||
|
ipv6: value.ipv6,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v5::registration::IpPair> for v4::registration::IpPair {
|
||||||
|
fn from(value: v5::registration::IpPair) -> Self {
|
||||||
|
Self {
|
||||||
|
ipv4: value.ipv4,
|
||||||
|
ipv6: value.ipv6,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{
|
||||||
|
net::{Ipv4Addr, Ipv6Addr},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
use nym_credentials_interface::CredentialSpendingData;
|
||||||
|
use nym_crypto::asymmetric::encryption::PrivateKey;
|
||||||
|
use nym_sphinx::addressing::Recipient;
|
||||||
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use crate::{
|
||||||
|
util::tests::{CREDENTIAL_BYTES, RECIPIENT},
|
||||||
|
v4,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_initial_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v4::request::AuthenticatorRequest::new_initial_request(
|
||||||
|
v4::registration::InitMessage::new(pub_key),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v5::request::AuthenticatorRequest::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v5::request::AuthenticatorRequestData::Initial(v5::registration::InitMessage {
|
||||||
|
pub_key
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_final_req() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
||||||
|
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
||||||
|
let ips = v4::registration::IpPair::new(ipv4, ipv6);
|
||||||
|
let nonce = 42;
|
||||||
|
let gateway_client = v4::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
ips,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let credential = Some(CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap());
|
||||||
|
let final_message = v4::registration::FinalMessage {
|
||||||
|
gateway_client: gateway_client.clone(),
|
||||||
|
credential: credential.clone(),
|
||||||
|
};
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) =
|
||||||
|
v4::request::AuthenticatorRequest::new_final_request(final_message, reply_to);
|
||||||
|
let upgraded_msg = v5::request::AuthenticatorRequest::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v5::request::AuthenticatorRequestData::Final(Box::new(
|
||||||
|
v5::registration::FinalMessage {
|
||||||
|
gateway_client: v5::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
v5::registration::IpPair::new(ipv4, ipv6),
|
||||||
|
nonce
|
||||||
|
),
|
||||||
|
credential
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_query_req() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let (msg, _) = v4::request::AuthenticatorRequest::new_query_request(pub_key, reply_to);
|
||||||
|
let upgraded_msg = v5::request::AuthenticatorRequest::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v5::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_pending_reg_resp() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let local_secret = PrivateKey::new(&mut rng);
|
||||||
|
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
||||||
|
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
||||||
|
let ips = v4::registration::IpPair::new(ipv4, ipv6);
|
||||||
|
let nonce = 42;
|
||||||
|
let wg_port = 51822;
|
||||||
|
let gateway_data = v4::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
ips,
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
let registration_data = v4::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v4::response::AuthenticatorResponse::new_pending_registration_success(
|
||||||
|
registration_data,
|
||||||
|
request_id,
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v5::response::AuthenticatorResponse::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v5::response::AuthenticatorResponseData::PendingRegistration(
|
||||||
|
v5::response::PendingRegistrationResponse {
|
||||||
|
request_id,
|
||||||
|
reply: v5::registration::RegistrationData {
|
||||||
|
nonce,
|
||||||
|
gateway_data: v5::registration::GatewayClient::new(
|
||||||
|
&local_secret,
|
||||||
|
(&remote_secret).into(),
|
||||||
|
v5::registration::IpPair::new(ipv4, ipv6),
|
||||||
|
nonce
|
||||||
|
),
|
||||||
|
wg_port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_registered_resp() {
|
||||||
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
|
let ipv4 = Ipv4Addr::from_str("10.1.10.10").unwrap();
|
||||||
|
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
||||||
|
let private_ips = v4::registration::IpPair::new(ipv4, ipv6);
|
||||||
|
let wg_port = 51822;
|
||||||
|
let registred_data = v4::registration::RegistredData {
|
||||||
|
pub_key,
|
||||||
|
private_ips,
|
||||||
|
wg_port,
|
||||||
|
};
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v4::response::AuthenticatorResponse::new_registered(
|
||||||
|
registred_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v5::response::AuthenticatorResponse::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v5::response::AuthenticatorResponseData::Registered(v5::response::RegisteredResponse {
|
||||||
|
request_id,
|
||||||
|
reply: v5::registration::RegistredData {
|
||||||
|
wg_port,
|
||||||
|
pub_key,
|
||||||
|
private_ips: v5::registration::IpPair::new(ipv4, ipv6)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_remaining_bandwidth_resp() {
|
||||||
|
let available_bandwidth = 42;
|
||||||
|
let remaining_bandwidth_data = Some(v4::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
});
|
||||||
|
let request_id = 123;
|
||||||
|
let reply_to = Recipient::try_from_base58_string(RECIPIENT).unwrap();
|
||||||
|
|
||||||
|
let msg = v4::response::AuthenticatorResponse::new_remaining_bandwidth(
|
||||||
|
remaining_bandwidth_data,
|
||||||
|
reply_to,
|
||||||
|
request_id,
|
||||||
|
);
|
||||||
|
let upgraded_msg = v5::response::AuthenticatorResponse::from(msg);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.protocol,
|
||||||
|
Protocol {
|
||||||
|
version: 5,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
upgraded_msg.data,
|
||||||
|
v5::response::AuthenticatorResponseData::RemainingBandwidth(
|
||||||
|
v5::response::RemainingBandwidthResponse {
|
||||||
|
request_id,
|
||||||
|
reply: Some(v5::registration::RemainingBandwidthData {
|
||||||
|
available_bandwidth,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
pub mod conversion;
|
||||||
|
pub mod registration;
|
||||||
|
pub mod request;
|
||||||
|
pub mod response;
|
||||||
|
pub mod topup;
|
||||||
|
|
||||||
|
pub const VERSION: u8 = 5;
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
// -2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
|
use base64::{engine::general_purpose, Engine};
|
||||||
|
use nym_credentials_interface::CredentialSpendingData;
|
||||||
|
use nym_network_defaults::constants::{WG_TUN_DEVICE_IP_ADDRESS_V4, WG_TUN_DEVICE_IP_ADDRESS_V6};
|
||||||
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
|
use std::time::SystemTime;
|
||||||
|
use std::{fmt, ops::Deref, str::FromStr};
|
||||||
|
|
||||||
|
#[cfg(feature = "verify")]
|
||||||
|
use hmac::{Hmac, Mac};
|
||||||
|
#[cfg(feature = "verify")]
|
||||||
|
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
|
||||||
|
#[cfg(feature = "verify")]
|
||||||
|
use sha2::Sha256;
|
||||||
|
|
||||||
|
pub type PendingRegistrations = HashMap<PeerPublicKey, RegistrationData>;
|
||||||
|
pub type PrivateIPs = HashMap<IpPair, Taken>;
|
||||||
|
|
||||||
|
#[cfg(feature = "verify")]
|
||||||
|
pub type HmacSha256 = Hmac<Sha256>;
|
||||||
|
|
||||||
|
pub type Nonce = u64;
|
||||||
|
pub type Taken = Option<SystemTime>;
|
||||||
|
|
||||||
|
pub const BANDWIDTH_CAP_PER_DAY: u64 = 250 * 1024 * 1024 * 1024; // 250 GB
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct IpPair {
|
||||||
|
pub ipv4: Ipv4Addr,
|
||||||
|
pub ipv6: Ipv6Addr,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IpPair {
|
||||||
|
pub fn new(ipv4: Ipv4Addr, ipv6: Ipv6Addr) -> Self {
|
||||||
|
IpPair { ipv4, ipv6 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Ipv4Addr, Ipv6Addr)> for IpPair {
|
||||||
|
fn from((ipv4, ipv6): (Ipv4Addr, Ipv6Addr)) -> Self {
|
||||||
|
IpPair { ipv4, ipv6 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for IpPair {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "({}, {})", self.ipv4, self.ipv6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IpAddr> for IpPair {
|
||||||
|
fn from(value: IpAddr) -> Self {
|
||||||
|
let (before_last_byte, last_byte) = match value {
|
||||||
|
std::net::IpAddr::V4(ipv4_addr) => (ipv4_addr.octets()[2], ipv4_addr.octets()[3]),
|
||||||
|
std::net::IpAddr::V6(ipv6_addr) => (ipv6_addr.octets()[14], ipv6_addr.octets()[15]),
|
||||||
|
};
|
||||||
|
let last_bytes = ((before_last_byte as u16) << 8) | last_byte as u16;
|
||||||
|
let ipv4 = Ipv4Addr::new(
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[0],
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[1],
|
||||||
|
before_last_byte,
|
||||||
|
last_byte,
|
||||||
|
);
|
||||||
|
let ipv6 = Ipv6Addr::new(
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[0],
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[1],
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[2],
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[3],
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[4],
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[5],
|
||||||
|
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[6],
|
||||||
|
last_bytes,
|
||||||
|
);
|
||||||
|
IpPair::new(ipv4, ipv6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
pub struct InitMessage {
|
||||||
|
/// Base64 encoded x25519 public key
|
||||||
|
pub pub_key: PeerPublicKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InitMessage {
|
||||||
|
pub fn new(pub_key: PeerPublicKey) -> Self {
|
||||||
|
InitMessage { pub_key }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
pub struct FinalMessage {
|
||||||
|
/// Gateway client data
|
||||||
|
pub gateway_client: GatewayClient,
|
||||||
|
|
||||||
|
/// Ecash credential
|
||||||
|
pub credential: Option<CredentialSpendingData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
pub struct RegistrationData {
|
||||||
|
pub nonce: u64,
|
||||||
|
pub gateway_data: GatewayClient,
|
||||||
|
pub wg_port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
pub struct RegistredData {
|
||||||
|
pub pub_key: PeerPublicKey,
|
||||||
|
pub private_ips: IpPair,
|
||||||
|
pub wg_port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
pub struct RemainingBandwidthData {
|
||||||
|
pub available_bandwidth: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
||||||
|
/// Gateway/Nym node can then verify pub_key payload using the same process
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
pub struct GatewayClient {
|
||||||
|
/// Base64 encoded x25519 public key
|
||||||
|
pub pub_key: PeerPublicKey,
|
||||||
|
|
||||||
|
/// Assigned private IPs (v4 and v6)
|
||||||
|
pub private_ips: IpPair,
|
||||||
|
|
||||||
|
/// Sha256 hmac on the data (alongside the prior nonce)
|
||||||
|
pub mac: ClientMac,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GatewayClient {
|
||||||
|
#[cfg(feature = "verify")]
|
||||||
|
pub fn new(
|
||||||
|
local_secret: &PrivateKey,
|
||||||
|
remote_public: x25519_dalek::PublicKey,
|
||||||
|
private_ips: IpPair,
|
||||||
|
nonce: u64,
|
||||||
|
) -> Self {
|
||||||
|
let local_public = PublicKey::from(local_secret);
|
||||||
|
let remote_public = PublicKey::from(remote_public);
|
||||||
|
|
||||||
|
let dh = local_secret.diffie_hellman(&remote_public);
|
||||||
|
|
||||||
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
|
#[allow(clippy::expect_used)]
|
||||||
|
let mut mac = HmacSha256::new_from_slice(&dh[..])
|
||||||
|
.expect("x25519 shared secret is always 32 bytes long");
|
||||||
|
|
||||||
|
mac.update(local_public.as_bytes());
|
||||||
|
mac.update(private_ips.to_string().as_bytes());
|
||||||
|
mac.update(&nonce.to_le_bytes());
|
||||||
|
|
||||||
|
GatewayClient {
|
||||||
|
pub_key: PeerPublicKey::new(local_public.into()),
|
||||||
|
private_ips,
|
||||||
|
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reusable secret should be gateways Wireguard PK
|
||||||
|
// Client should perform this step when generating its payload, using its own WG PK
|
||||||
|
#[cfg(feature = "verify")]
|
||||||
|
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
|
// use gateways key as a ref to an x25519_dalek key
|
||||||
|
let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
|
||||||
|
|
||||||
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
|
#[allow(clippy::expect_used)]
|
||||||
|
let mut mac = HmacSha256::new_from_slice(dh.as_bytes())
|
||||||
|
.expect("x25519 shared secret is always 32 bytes long");
|
||||||
|
|
||||||
|
mac.update(self.pub_key.as_bytes());
|
||||||
|
mac.update(self.private_ips.to_string().as_bytes());
|
||||||
|
mac.update(&nonce.to_le_bytes());
|
||||||
|
|
||||||
|
mac.verify_slice(&self.mac)
|
||||||
|
.map_err(|source| Error::FailedClientMacVerification {
|
||||||
|
client: self.pub_key.to_string(),
|
||||||
|
source,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pub_key(&self) -> PeerPublicKey {
|
||||||
|
self.pub_key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
||||||
|
// TODO2: rely on our internal crypto/hmac
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct ClientMac(Vec<u8>);
|
||||||
|
|
||||||
|
impl fmt::Display for ClientMac {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", general_purpose::STANDARD.encode(&self.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientMac {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn new(mac: Vec<u8>) -> Self {
|
||||||
|
ClientMac(mac)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for ClientMac {
|
||||||
|
type Target = Vec<u8>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ClientMac {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mac_bytes: Vec<u8> =
|
||||||
|
general_purpose::STANDARD
|
||||||
|
.decode(s)
|
||||||
|
.map_err(|source| Error::MalformedClientMac {
|
||||||
|
mac: s.to_string(),
|
||||||
|
source,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(ClientMac(mac_bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for ClientMac {
|
||||||
|
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
|
let encoded_key = general_purpose::STANDARD.encode(self.0.clone());
|
||||||
|
serializer.serialize_str(&encoded_key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for ClientMac {
|
||||||
|
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
|
let encoded_key = String::deserialize(deserializer)?;
|
||||||
|
ClientMac::from_str(&encoded_key).map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use nym_crypto::asymmetric::encryption;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_ip_pair() {
|
||||||
|
let ipv4: IpAddr = Ipv4Addr::from_str("10.1.10.50").unwrap().into();
|
||||||
|
let ipv6: IpAddr = Ipv6Addr::from_str("fc01::0a32").unwrap().into();
|
||||||
|
|
||||||
|
assert_eq!(IpPair::from(ipv4), IpPair::from(ipv6));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "verify")]
|
||||||
|
fn client_request_roundtrip() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let gateway_key_pair = encryption::KeyPair::new(&mut rng);
|
||||||
|
let client_key_pair = encryption::KeyPair::new(&mut rng);
|
||||||
|
|
||||||
|
let nonce = 1234567890;
|
||||||
|
|
||||||
|
let client = GatewayClient::new(
|
||||||
|
client_key_pair.private_key(),
|
||||||
|
x25519_dalek::PublicKey::from(gateway_key_pair.public_key().to_bytes()),
|
||||||
|
IpPair::new("10.0.0.42".parse().unwrap(), "fc00::42".parse().unwrap()),
|
||||||
|
nonce,
|
||||||
|
);
|
||||||
|
assert!(client.verify(gateway_key_pair.private_key(), nonce).is_ok())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
registration::{FinalMessage, InitMessage},
|
||||||
|
topup::TopUpMessage,
|
||||||
|
};
|
||||||
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::make_bincode_serializer;
|
||||||
|
|
||||||
|
use super::VERSION;
|
||||||
|
|
||||||
|
fn generate_random() -> u64 {
|
||||||
|
use rand::RngCore;
|
||||||
|
let mut rng = rand::rngs::OsRng;
|
||||||
|
rng.next_u64()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct AuthenticatorRequest {
|
||||||
|
pub protocol: Protocol,
|
||||||
|
pub data: AuthenticatorRequestData,
|
||||||
|
pub request_id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthenticatorRequest {
|
||||||
|
pub fn from_reconstructed_message(
|
||||||
|
message: &nym_sphinx::receiver::ReconstructedMessage,
|
||||||
|
) -> Result<Self, bincode::Error> {
|
||||||
|
use bincode::Options;
|
||||||
|
make_bincode_serializer().deserialize(&message.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_initial_request(init_message: InitMessage) -> (Self, u64) {
|
||||||
|
let request_id = generate_random();
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorRequestData::Initial(init_message),
|
||||||
|
request_id,
|
||||||
|
},
|
||||||
|
request_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_final_request(final_message: FinalMessage) -> (Self, u64) {
|
||||||
|
let request_id = generate_random();
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorRequestData::Final(Box::new(final_message)),
|
||||||
|
request_id,
|
||||||
|
},
|
||||||
|
request_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_query_request(peer_public_key: PeerPublicKey) -> (Self, u64) {
|
||||||
|
let request_id = generate_random();
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorRequestData::QueryBandwidth(peer_public_key),
|
||||||
|
request_id,
|
||||||
|
},
|
||||||
|
request_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_topup_request(top_up_message: TopUpMessage) -> (Self, u64) {
|
||||||
|
let request_id = generate_random();
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorRequestData::TopUpBandwidth(Box::new(top_up_message)),
|
||||||
|
request_id,
|
||||||
|
},
|
||||||
|
request_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
||||||
|
use bincode::Options;
|
||||||
|
make_bincode_serializer().serialize(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum AuthenticatorRequestData {
|
||||||
|
Initial(InitMessage),
|
||||||
|
Final(Box<FinalMessage>),
|
||||||
|
QueryBandwidth(PeerPublicKey),
|
||||||
|
TopUpBandwidth(Box<TopUpMessage>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_first_bytes_protocol() {
|
||||||
|
let version = 5;
|
||||||
|
let data = AuthenticatorRequest {
|
||||||
|
protocol: Protocol {
|
||||||
|
version,
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
},
|
||||||
|
data: AuthenticatorRequestData::Initial(InitMessage::new(
|
||||||
|
PeerPublicKey::from_str("yvNUDpT5l7W/xDhiu6HkqTHDQwbs/B3J5UrLmORl1EQ=").unwrap(),
|
||||||
|
)),
|
||||||
|
request_id: 1,
|
||||||
|
};
|
||||||
|
let bytes = *data.to_bytes().unwrap().first_chunk::<2>().unwrap();
|
||||||
|
assert_eq!(bytes, [version, ServiceProviderType::Authenticator as u8]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData};
|
||||||
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::make_bincode_serializer;
|
||||||
|
|
||||||
|
use super::VERSION;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct AuthenticatorResponse {
|
||||||
|
pub protocol: Protocol,
|
||||||
|
pub data: AuthenticatorResponseData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthenticatorResponse {
|
||||||
|
pub fn new_pending_registration_success(
|
||||||
|
registration_data: RegistrationData,
|
||||||
|
request_id: u64,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorResponseData::PendingRegistration(PendingRegistrationResponse {
|
||||||
|
reply: registration_data,
|
||||||
|
request_id,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_registered(registred_data: RegistredData, request_id: u64) -> Self {
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorResponseData::Registered(RegisteredResponse {
|
||||||
|
reply: registred_data,
|
||||||
|
request_id,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_remaining_bandwidth(
|
||||||
|
remaining_bandwidth_data: Option<RemainingBandwidthData>,
|
||||||
|
request_id: u64,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorResponseData::RemainingBandwidth(RemainingBandwidthResponse {
|
||||||
|
reply: remaining_bandwidth_data,
|
||||||
|
request_id,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_topup_bandwidth(
|
||||||
|
remaining_bandwidth_data: RemainingBandwidthData,
|
||||||
|
request_id: u64,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
protocol: Protocol {
|
||||||
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
|
version: VERSION,
|
||||||
|
},
|
||||||
|
data: AuthenticatorResponseData::TopUpBandwidth(TopUpBandwidthResponse {
|
||||||
|
reply: remaining_bandwidth_data,
|
||||||
|
request_id,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
||||||
|
use bincode::Options;
|
||||||
|
make_bincode_serializer().serialize(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_reconstructed_message(
|
||||||
|
message: &nym_sphinx::receiver::ReconstructedMessage,
|
||||||
|
) -> Result<Self, bincode::Error> {
|
||||||
|
use bincode::Options;
|
||||||
|
make_bincode_serializer().deserialize(&message.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> Option<u64> {
|
||||||
|
match &self.data {
|
||||||
|
AuthenticatorResponseData::PendingRegistration(response) => Some(response.request_id),
|
||||||
|
AuthenticatorResponseData::Registered(response) => Some(response.request_id),
|
||||||
|
AuthenticatorResponseData::RemainingBandwidth(response) => Some(response.request_id),
|
||||||
|
AuthenticatorResponseData::TopUpBandwidth(response) => Some(response.request_id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum AuthenticatorResponseData {
|
||||||
|
PendingRegistration(PendingRegistrationResponse),
|
||||||
|
Registered(RegisteredResponse),
|
||||||
|
RemainingBandwidth(RemainingBandwidthResponse),
|
||||||
|
TopUpBandwidth(TopUpBandwidthResponse),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct PendingRegistrationResponse {
|
||||||
|
pub request_id: u64,
|
||||||
|
pub reply: RegistrationData,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct RegisteredResponse {
|
||||||
|
pub request_id: u64,
|
||||||
|
pub reply: RegistredData,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct RemainingBandwidthResponse {
|
||||||
|
pub request_id: u64,
|
||||||
|
pub reply: Option<RemainingBandwidthData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub struct TopUpBandwidthResponse {
|
||||||
|
pub request_id: u64,
|
||||||
|
pub reply: RemainingBandwidthData,
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use nym_credentials_interface::CredentialSpendingData;
|
||||||
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
pub struct TopUpMessage {
|
||||||
|
/// Base64 encoded x25519 public key
|
||||||
|
pub pub_key: PeerPublicKey,
|
||||||
|
|
||||||
|
/// Ecash credential
|
||||||
|
pub credential: CredentialSpendingData,
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ use nym_validator_client::coconut::all_ecash_api_clients;
|
|||||||
use nym_validator_client::nym_api::EpochId;
|
use nym_validator_client::nym_api::EpochId;
|
||||||
use nym_validator_client::nyxd::contract_traits::EcashSigningClient;
|
use nym_validator_client::nyxd::contract_traits::EcashSigningClient;
|
||||||
use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, EcashQueryClient};
|
use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, EcashQueryClient};
|
||||||
use nym_validator_client::nyxd::cosmwasm_client::ToSingletonContractData;
|
use nym_validator_client::nyxd::cosmwasm_client::ContractResponseData;
|
||||||
use nym_validator_client::EcashApiClient;
|
use nym_validator_client::EcashApiClient;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
|
|||||||
@@ -105,26 +105,24 @@ impl<C, St: Storage> BandwidthController<C, St> {
|
|||||||
async fn get_aggregate_verification_key(
|
async fn get_aggregate_verification_key(
|
||||||
&self,
|
&self,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
apis: &mut ApiClientsWrapper,
|
ecash_apis: &mut ApiClientsWrapper<'_, C>,
|
||||||
) -> Result<VerificationKeyAuth, BandwidthControllerError>
|
) -> Result<VerificationKeyAuth, BandwidthControllerError>
|
||||||
where
|
where
|
||||||
C: DkgQueryClient + Sync + Send,
|
C: DkgQueryClient + Sync + Send,
|
||||||
<St as Storage>::StorageError: Send + Sync + 'static,
|
<St as Storage>::StorageError: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let ecash_apis = apis.get_or_init(epoch_id, &self.client).await?;
|
|
||||||
get_aggregate_verification_key(&self.storage, epoch_id, ecash_apis).await
|
get_aggregate_verification_key(&self.storage, epoch_id, ecash_apis).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_coin_index_signatures(
|
async fn get_coin_index_signatures(
|
||||||
&self,
|
&self,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
apis: &mut ApiClientsWrapper,
|
ecash_apis: &mut ApiClientsWrapper<'_, C>,
|
||||||
) -> Result<Vec<AnnotatedCoinIndexSignature>, BandwidthControllerError>
|
) -> Result<Vec<AnnotatedCoinIndexSignature>, BandwidthControllerError>
|
||||||
where
|
where
|
||||||
C: DkgQueryClient + Sync + Send,
|
C: DkgQueryClient + Sync + Send,
|
||||||
<St as Storage>::StorageError: Send + Sync + 'static,
|
<St as Storage>::StorageError: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let ecash_apis = apis.get_or_init(epoch_id, &self.client).await?;
|
|
||||||
get_coin_index_signatures(&self.storage, epoch_id, ecash_apis).await
|
get_coin_index_signatures(&self.storage, epoch_id, ecash_apis).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,13 +130,12 @@ impl<C, St: Storage> BandwidthController<C, St> {
|
|||||||
&self,
|
&self,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
expiration_date: Date,
|
expiration_date: Date,
|
||||||
apis: &mut ApiClientsWrapper,
|
ecash_apis: &mut ApiClientsWrapper<'_, C>,
|
||||||
) -> Result<Vec<AnnotatedExpirationDateSignature>, BandwidthControllerError>
|
) -> Result<Vec<AnnotatedExpirationDateSignature>, BandwidthControllerError>
|
||||||
where
|
where
|
||||||
C: DkgQueryClient + Sync + Send,
|
C: DkgQueryClient + Sync + Send,
|
||||||
<St as Storage>::StorageError: Send + Sync + 'static,
|
<St as Storage>::StorageError: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let ecash_apis = apis.get_or_init(epoch_id, &self.client).await?;
|
|
||||||
get_expiration_date_signatures(&self.storage, epoch_id, expiration_date, ecash_apis).await
|
get_expiration_date_signatures(&self.storage, epoch_id, expiration_date, ecash_apis).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +151,7 @@ impl<C, St: Storage> BandwidthController<C, St> {
|
|||||||
{
|
{
|
||||||
let epoch_id = retrieved_ticketbook.ticketbook.epoch_id();
|
let epoch_id = retrieved_ticketbook.ticketbook.epoch_id();
|
||||||
let expiration_date = retrieved_ticketbook.ticketbook.expiration_date();
|
let expiration_date = retrieved_ticketbook.ticketbook.expiration_date();
|
||||||
let mut api_clients = Default::default();
|
let mut api_clients = ApiClientsWrapper::new(&self.client, epoch_id);
|
||||||
|
|
||||||
let verification_key = self
|
let verification_key = self
|
||||||
.get_aggregate_verification_key(epoch_id, &mut api_clients)
|
.get_aggregate_verification_key(epoch_id, &mut api_clients)
|
||||||
|
|||||||
@@ -21,30 +21,67 @@ use rand::thread_rng;
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
// it really doesn't need the RwLock because it's never moved across tasks,
|
pub(crate) trait EcashClientsProvider {
|
||||||
// but we need all the Send/Sync action
|
async fn try_get_ecash_clients(
|
||||||
#[derive(Default)]
|
|
||||||
pub(crate) struct ApiClientsWrapper(Option<Vec<EcashApiClient>>);
|
|
||||||
|
|
||||||
impl ApiClientsWrapper {
|
|
||||||
pub(crate) async fn get_or_init<C>(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
|
) -> Result<Vec<EcashApiClient>, BandwidthControllerError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EcashClientsProvider for Vec<EcashApiClient> {
|
||||||
|
async fn try_get_ecash_clients(
|
||||||
|
&mut self,
|
||||||
|
) -> Result<Vec<EcashApiClient>, BandwidthControllerError> {
|
||||||
|
Ok(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> EcashClientsProvider for &mut ApiClientsWrapper<'_, C>
|
||||||
|
where
|
||||||
|
C: DkgQueryClient + Sync + Send,
|
||||||
|
{
|
||||||
|
async fn try_get_ecash_clients(
|
||||||
|
&mut self,
|
||||||
|
) -> Result<Vec<EcashApiClient>, BandwidthControllerError> {
|
||||||
|
self.clients().await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) enum ApiClientsWrapper<'a, C> {
|
||||||
|
Uninitialised {
|
||||||
|
query_client: &'a C,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
dkg_client: &C,
|
},
|
||||||
) -> Result<Vec<EcashApiClient>, BandwidthControllerError>
|
Cached {
|
||||||
|
clients: Vec<EcashApiClient>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, C> ApiClientsWrapper<'a, C> {
|
||||||
|
pub(crate) fn new(query_client: &'a C, epoch_id: EpochId) -> Self {
|
||||||
|
ApiClientsWrapper::Uninitialised {
|
||||||
|
query_client,
|
||||||
|
epoch_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn clients(&mut self) -> Result<Vec<EcashApiClient>, BandwidthControllerError>
|
||||||
where
|
where
|
||||||
C: DkgQueryClient + Sync + Send,
|
C: DkgQueryClient + Sync + Send,
|
||||||
{
|
{
|
||||||
if let Some(cached) = &self.0 {
|
match self {
|
||||||
return Ok(cached.clone());
|
ApiClientsWrapper::Uninitialised {
|
||||||
|
query_client,
|
||||||
|
epoch_id,
|
||||||
|
} => {
|
||||||
|
let clients = all_ecash_api_clients(*query_client, *epoch_id).await?;
|
||||||
|
*self = ApiClientsWrapper::Cached {
|
||||||
|
clients: clients.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(clients)
|
||||||
|
}
|
||||||
|
ApiClientsWrapper::Cached { clients } => Ok(clients.clone()),
|
||||||
}
|
}
|
||||||
|
|
||||||
let clients = all_ecash_api_clients(dkg_client, epoch_id).await?;
|
|
||||||
|
|
||||||
// technically we don't have to be cloning all the clients here, but it's way simpler than
|
|
||||||
// dealing with locking and whatnot given the performance penalty is negligible
|
|
||||||
self.0 = Some(clients.clone());
|
|
||||||
Ok(clients)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +113,7 @@ where
|
|||||||
pub(crate) async fn get_aggregate_verification_key<St>(
|
pub(crate) async fn get_aggregate_verification_key<St>(
|
||||||
storage: &St,
|
storage: &St,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
ecash_apis: Vec<EcashApiClient>,
|
mut ecash_apis: impl EcashClientsProvider,
|
||||||
) -> Result<VerificationKeyAuth, BandwidthControllerError>
|
) -> Result<VerificationKeyAuth, BandwidthControllerError>
|
||||||
where
|
where
|
||||||
St: Storage,
|
St: Storage,
|
||||||
@@ -90,6 +127,8 @@ where
|
|||||||
return Ok(stored);
|
return Ok(stored);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let ecash_apis = ecash_apis.try_get_ecash_clients().await?;
|
||||||
|
|
||||||
let master_vk = query_random_apis_until_success(
|
let master_vk = query_random_apis_until_success(
|
||||||
ecash_apis,
|
ecash_apis,
|
||||||
|api| async move { api.api_client.master_verification_key(Some(epoch_id)).await },
|
|api| async move { api.api_client.master_verification_key(Some(epoch_id)).await },
|
||||||
@@ -115,7 +154,7 @@ where
|
|||||||
pub(crate) async fn get_coin_index_signatures<St>(
|
pub(crate) async fn get_coin_index_signatures<St>(
|
||||||
storage: &St,
|
storage: &St,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
ecash_apis: Vec<EcashApiClient>,
|
mut ecash_apis: impl EcashClientsProvider,
|
||||||
) -> Result<Vec<AnnotatedCoinIndexSignature>, BandwidthControllerError>
|
) -> Result<Vec<AnnotatedCoinIndexSignature>, BandwidthControllerError>
|
||||||
where
|
where
|
||||||
St: Storage,
|
St: Storage,
|
||||||
@@ -129,6 +168,8 @@ where
|
|||||||
return Ok(stored);
|
return Ok(stored);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let ecash_apis = ecash_apis.try_get_ecash_clients().await?;
|
||||||
|
|
||||||
let index_sigs = query_random_apis_until_success(
|
let index_sigs = query_random_apis_until_success(
|
||||||
ecash_apis,
|
ecash_apis,
|
||||||
|api| async move {
|
|api| async move {
|
||||||
@@ -159,7 +200,7 @@ pub(crate) async fn get_expiration_date_signatures<St>(
|
|||||||
storage: &St,
|
storage: &St,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
expiration_date: Date,
|
expiration_date: Date,
|
||||||
ecash_apis: Vec<EcashApiClient>,
|
mut ecash_apis: impl EcashClientsProvider,
|
||||||
) -> Result<Vec<AnnotatedExpirationDateSignature>, BandwidthControllerError>
|
) -> Result<Vec<AnnotatedExpirationDateSignature>, BandwidthControllerError>
|
||||||
where
|
where
|
||||||
St: Storage,
|
St: Storage,
|
||||||
@@ -173,6 +214,8 @@ where
|
|||||||
return Ok(stored);
|
return Ok(stored);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let ecash_apis = ecash_apis.try_get_ecash_clients().await?;
|
||||||
|
|
||||||
let expiration_sigs = query_random_apis_until_success(
|
let expiration_sigs = query_random_apis_until_success(
|
||||||
ecash_apis,
|
ecash_apis,
|
||||||
|api| async move {
|
|api| async move {
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ const-str = { workspace = true }
|
|||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
pretty_env_logger = { workspace = true }
|
pretty_env_logger = { workspace = true }
|
||||||
schemars = { workspace = true, features = ["preserve_order"], optional = true }
|
schemars = { workspace = true, features = ["preserve_order"], optional = true }
|
||||||
semver.workspace = true
|
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json = { workspace = true, optional = true }
|
serde_json = { workspace = true, optional = true }
|
||||||
|
|
||||||
## tracing
|
## tracing
|
||||||
tracing-subscriber = { workspace = true, features = ["env-filter"], optional = true }
|
tracing-subscriber = { workspace = true, features = ["env-filter"], optional = true }
|
||||||
tracing-tree = { workspace = true, optional = true }
|
tracing-tree = { workspace = true, optional = true }
|
||||||
|
tracing = { workspace = true, optional = true }
|
||||||
opentelemetry-jaeger = { workspace = true, features = ["rt-tokio", "collector_client", "isahc_collector_client"], optional = true }
|
opentelemetry-jaeger = { workspace = true, features = ["rt-tokio", "collector_client", "isahc_collector_client"], optional = true }
|
||||||
tracing-opentelemetry = { workspace = true, optional = true }
|
tracing-opentelemetry = { workspace = true, optional = true }
|
||||||
utoipa = { workspace = true, optional = true }
|
utoipa = { workspace = true, optional = true }
|
||||||
@@ -36,7 +36,7 @@ default = []
|
|||||||
openapi = ["utoipa"]
|
openapi = ["utoipa"]
|
||||||
output_format = ["serde_json", "dep:clap"]
|
output_format = ["serde_json", "dep:clap"]
|
||||||
bin_info_schema = ["schemars"]
|
bin_info_schema = ["schemars"]
|
||||||
basic_tracing = ["tracing-subscriber"]
|
basic_tracing = ["dep:tracing", "tracing-subscriber"]
|
||||||
tracing = [
|
tracing = [
|
||||||
"basic_tracing",
|
"basic_tracing",
|
||||||
"tracing-tree",
|
"tracing-tree",
|
||||||
@@ -44,5 +44,5 @@ tracing = [
|
|||||||
"tracing-opentelemetry",
|
"tracing-opentelemetry",
|
||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
]
|
]
|
||||||
clap = [ "dep:clap", "dep:clap_complete", "dep:clap_complete_fig" ]
|
clap = ["dep:clap", "dep:clap_complete", "dep:clap_complete_fig"]
|
||||||
models = []
|
models = []
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
pub mod build_information;
|
pub mod build_information;
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
pub mod version_checker;
|
|
||||||
|
|
||||||
#[cfg(feature = "clap")]
|
#[cfg(feature = "clap")]
|
||||||
pub mod completions;
|
pub mod completions;
|
||||||
|
|||||||
@@ -44,10 +44,38 @@ pub fn setup_logging() {
|
|||||||
.init();
|
.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't call init so that we could attach additional layers
|
||||||
#[cfg(feature = "basic_tracing")]
|
#[cfg(feature = "basic_tracing")]
|
||||||
pub fn setup_tracing_logger() {
|
pub fn build_tracing_logger() -> impl tracing_subscriber::layer::SubscriberExt {
|
||||||
let log_builder = tracing_subscriber::fmt()
|
use tracing_subscriber::prelude::*;
|
||||||
.with_writer(std::io::stderr)
|
|
||||||
|
tracing_subscriber::registry()
|
||||||
|
.with(default_tracing_fmt_layer(std::io::stderr))
|
||||||
|
.with(default_tracing_env_filter())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "basic_tracing")]
|
||||||
|
pub fn default_tracing_env_filter() -> tracing_subscriber::filter::EnvFilter {
|
||||||
|
if ::std::env::var("RUST_LOG").is_ok() {
|
||||||
|
tracing_subscriber::filter::EnvFilter::from_default_env()
|
||||||
|
} else {
|
||||||
|
// if the env value was not found, default to `INFO` level rather than `ERROR`
|
||||||
|
tracing_subscriber::filter::EnvFilter::builder()
|
||||||
|
.with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into())
|
||||||
|
.parse_lossy("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "basic_tracing")]
|
||||||
|
pub fn default_tracing_fmt_layer<S, W>(
|
||||||
|
writer: W,
|
||||||
|
) -> impl tracing_subscriber::Layer<S> + Sync + Send + 'static
|
||||||
|
where
|
||||||
|
S: tracing::Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
|
||||||
|
W: for<'writer> tracing_subscriber::fmt::MakeWriter<'writer> + Sync + Send + 'static,
|
||||||
|
{
|
||||||
|
tracing_subscriber::fmt::layer()
|
||||||
|
.with_writer(writer)
|
||||||
// Use a more compact, abbreviated log format
|
// Use a more compact, abbreviated log format
|
||||||
.compact()
|
.compact()
|
||||||
// Display source code file paths
|
// Display source code file paths
|
||||||
@@ -55,18 +83,13 @@ pub fn setup_tracing_logger() {
|
|||||||
// Display source code line numbers
|
// Display source code line numbers
|
||||||
.with_line_number(true)
|
.with_line_number(true)
|
||||||
// Don't display the event's target (module path)
|
// Don't display the event's target (module path)
|
||||||
.with_target(false);
|
.with_target(false)
|
||||||
|
}
|
||||||
|
|
||||||
if ::std::env::var("RUST_LOG").is_ok() {
|
#[cfg(feature = "basic_tracing")]
|
||||||
log_builder
|
pub fn setup_tracing_logger() {
|
||||||
.with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
.init()
|
build_tracing_logger().init()
|
||||||
} else {
|
|
||||||
// default to 'Info
|
|
||||||
log_builder
|
|
||||||
.with_max_level(tracing_subscriber::filter::LevelFilter::INFO)
|
|
||||||
.init()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This has to be a macro, running it as a function does not work for the file_appender for some reason
|
// TODO: This has to be a macro, running it as a function does not work for the file_appender for some reason
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
pub use semver::Version;
|
|
||||||
|
|
||||||
/// Checks if the version is minor version compatible.
|
|
||||||
///
|
|
||||||
/// Checks whether given `version` is compatible with a given semantic version requirement `req`
|
|
||||||
/// according to major-minor semver rules. The semantic version requirement can be passed as a full,
|
|
||||||
/// concrete version number, because that's what we'll have in our Cargo.toml files (e.g. 0.3.2).
|
|
||||||
/// The patch number in the requirement gets dropped and replaced with a wildcard (0.3.*) as all
|
|
||||||
/// minor versions should be compatible with each other.
|
|
||||||
pub fn is_minor_version_compatible(version: &str, req: &str) -> bool {
|
|
||||||
let expected_version = match Version::parse(version) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
let req_version = match Version::parse(req) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
expected_version.major == req_version.major && expected_version.minor == req_version.minor
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_version(raw_version: &str) -> Result<Version, semver::Error> {
|
|
||||||
Version::parse(raw_version)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn version_0_3_0_is_compatible_with_requirement_0_3_x() {
|
|
||||||
assert!(is_minor_version_compatible("0.3.0", "0.3.2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn version_0_3_1_is_compatible_with_minimum_requirement_0_3_x() {
|
|
||||||
assert!(is_minor_version_compatible("0.3.1", "0.3.2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn version_0_3_2_is_compatible_with_minimum_requirement_0_3_x() {
|
|
||||||
assert!(is_minor_version_compatible("0.3.2", "0.3.0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn version_0_2_0_is_not_compatible_with_requirement_0_3_x() {
|
|
||||||
assert!(!is_minor_version_compatible("0.2.0", "0.3.2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn version_0_4_0_is_not_compatible_with_requirement_0_3_x() {
|
|
||||||
assert!(!is_minor_version_compatible("0.4.0", "0.3.2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn version_1_3_2_is_not_compatible_with_requirement_0_3_x() {
|
|
||||||
assert!(!is_minor_version_compatible("1.3.2", "0.3.2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn version_0_4_0_rc_1_is_compatible_with_version_0_4_0_rc_1() {
|
|
||||||
assert!(is_minor_version_compatible("0.4.0-rc.1", "0.4.0-rc.1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_false_on_foo_version() {
|
|
||||||
assert!(!is_minor_version_compatible("foo", "0.3.2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_false_on_bar_version() {
|
|
||||||
assert!(!is_minor_version_compatible("0.3.2", "bar"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ name = "nym-client-core"
|
|||||||
version = "1.1.15"
|
version = "1.1.15"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.70"
|
rust-version = "1.76"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
@@ -40,12 +40,13 @@ nym-crypto = { path = "../crypto" }
|
|||||||
nym-explorer-client = { path = "../../explorer-api/explorer-client" }
|
nym-explorer-client = { path = "../../explorer-api/explorer-client" }
|
||||||
nym-gateway-client = { path = "../client-libs/gateway-client" }
|
nym-gateway-client = { path = "../client-libs/gateway-client" }
|
||||||
nym-gateway-requests = { path = "../gateway-requests" }
|
nym-gateway-requests = { path = "../gateway-requests" }
|
||||||
|
nym-http-api-client = { path = "../http-api-client" }
|
||||||
nym-metrics = { path = "../nym-metrics" }
|
nym-metrics = { path = "../nym-metrics" }
|
||||||
nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" }
|
nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" }
|
||||||
nym-sphinx = { path = "../nymsphinx" }
|
nym-sphinx = { path = "../nymsphinx" }
|
||||||
nym-statistics-common = { path = "../statistics" }
|
nym-statistics-common = { path = "../statistics" }
|
||||||
nym-pemstore = { path = "../pemstore" }
|
nym-pemstore = { path = "../pemstore" }
|
||||||
nym-topology = { path = "../topology", features = ["serializable"] }
|
nym-topology = { path = "../topology", features = ["persistence"] }
|
||||||
nym-mixnet-client = { path = "../client-libs/mixnet-client", default-features = false }
|
nym-mixnet-client = { path = "../client-libs/mixnet-client", default-features = false }
|
||||||
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
|
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
|
||||||
nym-task = { path = "../task" }
|
nym-task = { path = "../task" }
|
||||||
|
|||||||
@@ -45,11 +45,12 @@ const DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO: f64 = 0.70;
|
|||||||
// clients/client-core/src/client/replies/reply_storage/surb_storage.rs
|
// clients/client-core/src/client/replies/reply_storage/surb_storage.rs
|
||||||
const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10;
|
const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10;
|
||||||
const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200;
|
const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200;
|
||||||
|
const DEFAULT_MINIMUM_REPLY_SURB_THRESHOLD_BUFFER: usize = 0;
|
||||||
|
|
||||||
// define how much to request at once
|
// define how much to request at once
|
||||||
// clients/client-core/src/client/replies/reply_controller.rs
|
// clients/client-core/src/client/replies/reply_controller.rs
|
||||||
const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10;
|
const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10;
|
||||||
const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 100;
|
const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 50;
|
||||||
|
|
||||||
const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500;
|
const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500;
|
||||||
|
|
||||||
@@ -145,6 +146,11 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_forget_me(mut self, forget_me: ForgetMe) -> Self {
|
||||||
|
self.debug.forget_me = forget_me;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: this should be refactored properly
|
// TODO: this should be refactored properly
|
||||||
// as of 12.09.23 the below is true (not sure how this comment will rot in the future)
|
// as of 12.09.23 the below is true (not sure how this comment will rot in the future)
|
||||||
// medium_toggle:
|
// medium_toggle:
|
||||||
@@ -517,7 +523,7 @@ impl Default for Acknowledgements {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default)]
|
||||||
pub struct Topology {
|
pub struct Topology {
|
||||||
/// The uniform delay every which clients are querying the directory server
|
/// The uniform delay every which clients are querying the directory server
|
||||||
/// to try to obtain a compatible network topology to send sphinx packets through.
|
/// to try to obtain a compatible network topology to send sphinx packets through.
|
||||||
@@ -550,6 +556,18 @@ pub struct Topology {
|
|||||||
/// Specifies a minimum performance of a gateway that is used on route construction.
|
/// Specifies a minimum performance of a gateway that is used on route construction.
|
||||||
/// This setting is only applicable when `NymApi` topology is used.
|
/// This setting is only applicable when `NymApi` topology is used.
|
||||||
pub minimum_gateway_performance: u8,
|
pub minimum_gateway_performance: u8,
|
||||||
|
|
||||||
|
/// Specifies whether this client should attempt to retrieve all available network nodes
|
||||||
|
/// as opposed to just active mixnodes/gateways.
|
||||||
|
pub use_extended_topology: bool,
|
||||||
|
|
||||||
|
/// Specifies whether this client should ignore the current epoch role of the target egress node
|
||||||
|
/// when constructing the final hop packets.
|
||||||
|
pub ignore_egress_epoch_role: bool,
|
||||||
|
|
||||||
|
/// Specifies whether this client should ignore the current epoch role of the ingress node
|
||||||
|
/// when attempting to establish new connection
|
||||||
|
pub ignore_ingress_epoch_role: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
@@ -586,6 +604,10 @@ impl Default for Topology {
|
|||||||
topology_structure: TopologyStructure::default(),
|
topology_structure: TopologyStructure::default(),
|
||||||
minimum_mixnode_performance: DEFAULT_MIN_MIXNODE_PERFORMANCE,
|
minimum_mixnode_performance: DEFAULT_MIN_MIXNODE_PERFORMANCE,
|
||||||
minimum_gateway_performance: DEFAULT_MIN_GATEWAY_PERFORMANCE,
|
minimum_gateway_performance: DEFAULT_MIN_GATEWAY_PERFORMANCE,
|
||||||
|
use_extended_topology: false,
|
||||||
|
|
||||||
|
ignore_egress_epoch_role: true,
|
||||||
|
ignore_ingress_epoch_role: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -600,6 +622,10 @@ pub struct ReplySurbs {
|
|||||||
/// Defines the maximum number of reply surbs the client wants to keep in its storage at any times.
|
/// Defines the maximum number of reply surbs the client wants to keep in its storage at any times.
|
||||||
pub maximum_reply_surb_storage_threshold: usize,
|
pub maximum_reply_surb_storage_threshold: usize,
|
||||||
|
|
||||||
|
/// Defines the soft threshold ontop of the minimum reply surb storage threshold for when the client
|
||||||
|
/// should proactively request additional reply surbs.
|
||||||
|
pub minimum_reply_surb_threshold_buffer: usize,
|
||||||
|
|
||||||
/// Defines the minimum number of reply surbs the client would request.
|
/// Defines the minimum number of reply surbs the client would request.
|
||||||
pub minimum_reply_surb_request_size: u32,
|
pub minimum_reply_surb_request_size: u32,
|
||||||
|
|
||||||
@@ -632,6 +658,9 @@ pub struct ReplySurbs {
|
|||||||
/// Specifies the number of mixnet hops the packet should go through. If not specified, then
|
/// Specifies the number of mixnet hops the packet should go through. If not specified, then
|
||||||
/// the default value is used.
|
/// the default value is used.
|
||||||
pub surb_mix_hops: Option<u8>,
|
pub surb_mix_hops: Option<u8>,
|
||||||
|
|
||||||
|
/// Specifies if we should reset all the sender tags on startup
|
||||||
|
pub fresh_sender_tags: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ReplySurbs {
|
impl Default for ReplySurbs {
|
||||||
@@ -639,6 +668,7 @@ impl Default for ReplySurbs {
|
|||||||
ReplySurbs {
|
ReplySurbs {
|
||||||
minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
||||||
maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
||||||
|
minimum_reply_surb_threshold_buffer: DEFAULT_MINIMUM_REPLY_SURB_THRESHOLD_BUFFER,
|
||||||
minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE,
|
minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE,
|
||||||
maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE,
|
maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE,
|
||||||
maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE,
|
maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE,
|
||||||
@@ -648,6 +678,7 @@ impl Default for ReplySurbs {
|
|||||||
maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE,
|
maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE,
|
||||||
maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE,
|
maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE,
|
||||||
surb_mix_hops: None,
|
surb_mix_hops: None,
|
||||||
|
fresh_sender_tags: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,6 +734,9 @@ pub struct DebugConfig {
|
|||||||
|
|
||||||
/// Defines all configuration options related to stats reporting.
|
/// Defines all configuration options related to stats reporting.
|
||||||
pub stats_reporting: StatsReporting,
|
pub stats_reporting: StatsReporting,
|
||||||
|
|
||||||
|
/// Defines all configuration options related to the forget me flag.
|
||||||
|
pub forget_me: ForgetMe,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugConfig {
|
impl DebugConfig {
|
||||||
@@ -725,6 +759,69 @@ impl Default for DebugConfig {
|
|||||||
topology: Default::default(),
|
topology: Default::default(),
|
||||||
reply_surbs: Default::default(),
|
reply_surbs: Default::default(),
|
||||||
stats_reporting: Default::default(),
|
stats_reporting: Default::default(),
|
||||||
|
forget_me: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Default, Debug, Deserialize, PartialEq, Serialize, Copy)]
|
||||||
|
pub struct ForgetMe {
|
||||||
|
client: bool,
|
||||||
|
stats: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bool> for ForgetMe {
|
||||||
|
fn from(value: bool) -> Self {
|
||||||
|
if value {
|
||||||
|
Self::new_all()
|
||||||
|
} else {
|
||||||
|
Self::new_none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ForgetMe {
|
||||||
|
pub fn new_all() -> Self {
|
||||||
|
Self {
|
||||||
|
client: true,
|
||||||
|
stats: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_client() -> Self {
|
||||||
|
Self {
|
||||||
|
client: true,
|
||||||
|
stats: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_stats() -> Self {
|
||||||
|
Self {
|
||||||
|
client: false,
|
||||||
|
stats: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(client: bool, stats: bool) -> Self {
|
||||||
|
Self { client, stats }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn any(&self) -> bool {
|
||||||
|
self.client || self.stats
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn client(&self) -> bool {
|
||||||
|
self.client
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stats(&self) -> bool {
|
||||||
|
self.stats
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_none() -> Self {
|
||||||
|
Self {
|
||||||
|
client: false,
|
||||||
|
stats: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,8 +181,9 @@ impl From<ConfigV5> for Config {
|
|||||||
maximum_reply_surb_age: value.debug.reply_surbs.maximum_reply_surb_age,
|
maximum_reply_surb_age: value.debug.reply_surbs.maximum_reply_surb_age,
|
||||||
maximum_reply_key_age: value.debug.reply_surbs.maximum_reply_key_age,
|
maximum_reply_key_age: value.debug.reply_surbs.maximum_reply_key_age,
|
||||||
surb_mix_hops: value.debug.reply_surbs.surb_mix_hops,
|
surb_mix_hops: value.debug.reply_surbs.surb_mix_hops,
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
stats_reporting: Default::default(),
|
..Default::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use sqlx::ConnectOptions;
|
use sqlx::{
|
||||||
|
sqlite::{SqliteAutoVacuum, SqliteSynchronous},
|
||||||
|
ConnectOptions,
|
||||||
|
};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -30,6 +33,9 @@ impl StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let opts = sqlx::sqlite::SqliteConnectOptions::new()
|
let opts = sqlx::sqlite::SqliteConnectOptions::new()
|
||||||
|
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
|
||||||
|
.synchronous(SqliteSynchronous::Normal)
|
||||||
|
.auto_vacuum(SqliteAutoVacuum::Incremental)
|
||||||
.filename(database_path)
|
.filename(database_path)
|
||||||
.create_if_missing(true)
|
.create_if_missing(true)
|
||||||
.disable_statement_logging();
|
.disable_statement_logging();
|
||||||
@@ -110,7 +116,7 @@ impl StorageManager {
|
|||||||
) -> Result<(), sqlx::Error> {
|
) -> Result<(), sqlx::Error> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO registered_gateway(gateway_id_bs58, registration_timestamp, gateway_type)
|
INSERT INTO registered_gateway(gateway_id_bs58, registration_timestamp, gateway_type)
|
||||||
VALUES (?, ?, ?)
|
VALUES (?, ?, ?)
|
||||||
"#,
|
"#,
|
||||||
registered_gateway.gateway_id_bs58,
|
registered_gateway.gateway_id_bs58,
|
||||||
@@ -224,7 +230,7 @@ impl StorageManager {
|
|||||||
) -> Result<(), sqlx::Error> {
|
) -> Result<(), sqlx::Error> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO custom_gateway_details(gateway_id_bs58, data)
|
INSERT INTO custom_gateway_details(gateway_id_bs58, data)
|
||||||
VALUES (?, ?)
|
VALUES (?, ?)
|
||||||
"#,
|
"#,
|
||||||
custom.gateway_id_bs58,
|
custom.gateway_id_bs58,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub mod error;
|
|||||||
mod manager;
|
mod manager;
|
||||||
mod models;
|
mod models;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct OnDiskGatewaysDetails {
|
pub struct OnDiskGatewaysDetails {
|
||||||
manager: StorageManager,
|
manager: StorageManager,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ pub enum InMemStorageError {
|
|||||||
MalformedGateway(#[from] BadGateway),
|
MalformedGateway(#[from] BadGateway),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct InMemGatewaysDetails {
|
pub struct InMemGatewaysDetails {
|
||||||
inner: Arc<RwLock<InMemStorageInner>>,
|
inner: Arc<RwLock<InMemStorageInner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
struct InMemStorageInner {
|
struct InMemStorageInner {
|
||||||
active_gateway: Option<String>,
|
active_gateway: Option<String>,
|
||||||
gateways: HashMap<String, GatewayRegistration>,
|
gateways: HashMap<String, GatewayRegistration>,
|
||||||
|
|||||||
@@ -112,18 +112,24 @@ where
|
|||||||
source,
|
source,
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
hardcoded_topology.get_gateways()
|
hardcoded_topology.entry_capable_nodes().cloned().collect()
|
||||||
} else {
|
} else {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls, user_agent)
|
crate::init::helpers::gateways_for_init(
|
||||||
.await?
|
&mut rng,
|
||||||
|
&core.client.nym_api_urls,
|
||||||
|
user_agent,
|
||||||
|
core.debug.topology.minimum_gateway_performance,
|
||||||
|
core.debug.topology.ignore_ingress_epoch_role,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
// since we're registering with a brand new gateway,
|
// since we're registering with a brand new gateway,
|
||||||
// make sure the list of available gateways doesn't overlap the list of known gateways
|
// make sure the list of available gateways doesn't overlap the list of known gateways
|
||||||
let available_gateways = available_gateways
|
let available_gateways = available_gateways
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|g| !registered_gateways.contains(g.identity()))
|
.filter(|g| !registered_gateways.contains(&g.identity()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if available_gateways.is_empty() {
|
if available_gateways.is_empty() {
|
||||||
@@ -133,6 +139,8 @@ where
|
|||||||
let gateway_setup = GatewaySetup::New {
|
let gateway_setup = GatewaySetup::New {
|
||||||
specification: selection_spec,
|
specification: selection_spec,
|
||||||
available_gateways,
|
available_gateways,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let init_details =
|
let init_details =
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ pub struct CommonClientInitArgs {
|
|||||||
/// Sets the address to report statistics
|
/// Sets the address to report statistics
|
||||||
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
||||||
pub stats_reporting_address: Option<Recipient>,
|
pub stats_reporting_address: Option<Recipient>,
|
||||||
|
|
||||||
|
/// Sets the forget me flag
|
||||||
|
#[cfg_attr(feature = "cli", clap(long, hide = true, default_value_t = false))]
|
||||||
|
pub forget_me: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InitResultsWithConfig<T> {
|
pub struct InitResultsWithConfig<T> {
|
||||||
@@ -167,16 +171,24 @@ where
|
|||||||
source,
|
source,
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
hardcoded_topology.get_gateways()
|
hardcoded_topology.entry_capable_nodes().cloned().collect()
|
||||||
} else {
|
} else {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls, user_agent)
|
crate::init::helpers::gateways_for_init(
|
||||||
.await?
|
&mut rng,
|
||||||
|
&core.client.nym_api_urls,
|
||||||
|
user_agent,
|
||||||
|
core.debug.topology.minimum_gateway_performance,
|
||||||
|
core.debug.topology.ignore_ingress_epoch_role,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
let gateway_setup = GatewaySetup::New {
|
let gateway_setup = GatewaySetup::New {
|
||||||
specification: selection_spec,
|
specification: selection_spec,
|
||||||
available_gateways,
|
available_gateways,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let init_details =
|
let init_details =
|
||||||
|
|||||||
@@ -61,4 +61,8 @@ pub struct CommonClientRunArgs {
|
|||||||
/// Sets the address to report statistics
|
/// Sets the address to report statistics
|
||||||
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
||||||
pub stats_reporting_address: Option<Recipient>,
|
pub stats_reporting_address: Option<Recipient>,
|
||||||
|
|
||||||
|
/// Sets the forget me flag
|
||||||
|
#[cfg_attr(feature = "cli", clap(long, hide = true, default_value_t = false))]
|
||||||
|
pub forget_me: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use super::mix_traffic::ClientRequestSender;
|
||||||
use super::received_buffer::ReceivedBufferMessage;
|
use super::received_buffer::ReceivedBufferMessage;
|
||||||
use super::statistics_control::StatisticsControl;
|
use super::statistics_control::StatisticsControl;
|
||||||
use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider;
|
|
||||||
use crate::client::base_client::storage::helpers::store_client_keys;
|
use crate::client::base_client::storage::helpers::store_client_keys;
|
||||||
use crate::client::base_client::storage::MixnetClientStorage;
|
use crate::client::base_client::storage::MixnetClientStorage;
|
||||||
use crate::client::cover_traffic_stream::LoopCoverTrafficStream;
|
use crate::client::cover_traffic_stream::LoopCoverTrafficStream;
|
||||||
@@ -24,7 +24,7 @@ use crate::client::replies::reply_storage::{
|
|||||||
};
|
};
|
||||||
use crate::client::topology_control::nym_api_provider::NymApiTopologyProvider;
|
use crate::client::topology_control::nym_api_provider::NymApiTopologyProvider;
|
||||||
use crate::client::topology_control::{
|
use crate::client::topology_control::{
|
||||||
nym_api_provider, TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
|
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
|
||||||
};
|
};
|
||||||
use crate::config::{Config, DebugConfig};
|
use crate::config::{Config, DebugConfig};
|
||||||
use crate::error::ClientCoreError;
|
use crate::error::ClientCoreError;
|
||||||
@@ -36,9 +36,11 @@ use crate::{config, spawn_future};
|
|||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use log::*;
|
use log::*;
|
||||||
use nym_bandwidth_controller::BandwidthController;
|
use nym_bandwidth_controller::BandwidthController;
|
||||||
|
use nym_client_core_config_types::ForgetMe;
|
||||||
use nym_client_core_gateways_storage::{GatewayDetails, GatewaysDetailsStore};
|
use nym_client_core_gateways_storage::{GatewayDetails, GatewaysDetailsStore};
|
||||||
use nym_credential_storage::storage::Storage as CredentialStorage;
|
use nym_credential_storage::storage::Storage as CredentialStorage;
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
use nym_crypto::asymmetric::{encryption, identity};
|
||||||
|
use nym_crypto::hkdf::DerivationMaterial;
|
||||||
use nym_gateway_client::client::config::GatewayClientConfig;
|
use nym_gateway_client::client::config::GatewayClientConfig;
|
||||||
use nym_gateway_client::{
|
use nym_gateway_client::{
|
||||||
AcknowledgementReceiver, GatewayClient, GatewayConfig, MixnetMessageReceiver, PacketRouter,
|
AcknowledgementReceiver, GatewayClient, GatewayConfig, MixnetMessageReceiver, PacketRouter,
|
||||||
@@ -176,8 +178,8 @@ impl From<bool> for CredentialsToggle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BaseClientBuilder<'a, C, S: MixnetClientStorage> {
|
pub struct BaseClientBuilder<C, S: MixnetClientStorage> {
|
||||||
config: &'a Config,
|
config: Config,
|
||||||
client_store: S,
|
client_store: S,
|
||||||
dkg_query_client: Option<C>,
|
dkg_query_client: Option<C>,
|
||||||
|
|
||||||
@@ -188,18 +190,23 @@ pub struct BaseClientBuilder<'a, C, S: MixnetClientStorage> {
|
|||||||
user_agent: Option<UserAgent>,
|
user_agent: Option<UserAgent>,
|
||||||
|
|
||||||
setup_method: GatewaySetup,
|
setup_method: GatewaySetup,
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||||
|
|
||||||
|
derivation_material: Option<DerivationMaterial>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C, S> BaseClientBuilder<'a, C, S>
|
impl<C, S> BaseClientBuilder<C, S>
|
||||||
where
|
where
|
||||||
S: MixnetClientStorage + 'static,
|
S: MixnetClientStorage + 'static,
|
||||||
C: DkgQueryClient + Send + Sync + 'static,
|
C: DkgQueryClient + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
base_config: &'a Config,
|
base_config: Config,
|
||||||
client_store: S,
|
client_store: S,
|
||||||
dkg_query_client: Option<C>,
|
dkg_query_client: Option<C>,
|
||||||
) -> BaseClientBuilder<'a, C, S> {
|
) -> BaseClientBuilder<C, S> {
|
||||||
BaseClientBuilder {
|
BaseClientBuilder {
|
||||||
config: base_config,
|
config: base_config,
|
||||||
client_store,
|
client_store,
|
||||||
@@ -210,9 +217,27 @@ where
|
|||||||
shutdown: None,
|
shutdown: None,
|
||||||
user_agent: None,
|
user_agent: None,
|
||||||
setup_method: GatewaySetup::MustLoad { gateway_id: None },
|
setup_method: GatewaySetup::MustLoad { gateway_id: None },
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: None,
|
||||||
|
derivation_material: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_derivation_material(
|
||||||
|
mut self,
|
||||||
|
derivation_material: Option<DerivationMaterial>,
|
||||||
|
) -> Self {
|
||||||
|
self.derivation_material = derivation_material;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_forget_me(mut self, forget_me: &ForgetMe) -> Self {
|
||||||
|
self.config.debug.forget_me = *forget_me;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_gateway_setup(mut self, setup: GatewaySetup) -> Self {
|
pub fn with_gateway_setup(mut self, setup: GatewaySetup) -> Self {
|
||||||
self.setup_method = setup;
|
self.setup_method = setup;
|
||||||
@@ -261,6 +286,15 @@ where
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub fn with_connection_fd_callback(
|
||||||
|
mut self,
|
||||||
|
callback: Arc<dyn Fn(RawFd) + Send + Sync>,
|
||||||
|
) -> Self {
|
||||||
|
self.connection_fd_callback = Some(callback);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
// note: do **NOT** make this method public as its only valid usage is from within `start_base`
|
// note: do **NOT** make this method public as its only valid usage is from within `start_base`
|
||||||
// because it relies on the crypto keys being already loaded
|
// because it relies on the crypto keys being already loaded
|
||||||
fn mix_address(details: &InitialisationResult) -> Recipient {
|
fn mix_address(details: &InitialisationResult) -> Recipient {
|
||||||
@@ -276,7 +310,7 @@ where
|
|||||||
topology_accessor: TopologyAccessor,
|
topology_accessor: TopologyAccessor,
|
||||||
mix_tx: BatchMixMessageSender,
|
mix_tx: BatchMixMessageSender,
|
||||||
stats_tx: ClientStatsSender,
|
stats_tx: ClientStatsSender,
|
||||||
shutdown: TaskClient,
|
task_client: TaskClient,
|
||||||
) {
|
) {
|
||||||
info!("Starting loop cover traffic stream...");
|
info!("Starting loop cover traffic stream...");
|
||||||
|
|
||||||
@@ -289,9 +323,10 @@ where
|
|||||||
debug_config.traffic,
|
debug_config.traffic,
|
||||||
debug_config.cover_traffic,
|
debug_config.cover_traffic,
|
||||||
stats_tx,
|
stats_tx,
|
||||||
|
task_client,
|
||||||
);
|
);
|
||||||
|
|
||||||
stream.start_with_shutdown(shutdown);
|
stream.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@@ -306,7 +341,7 @@ where
|
|||||||
reply_controller_receiver: ReplyControllerReceiver,
|
reply_controller_receiver: ReplyControllerReceiver,
|
||||||
lane_queue_lengths: LaneQueueLengths,
|
lane_queue_lengths: LaneQueueLengths,
|
||||||
client_connection_rx: ConnectionCommandReceiver,
|
client_connection_rx: ConnectionCommandReceiver,
|
||||||
shutdown: TaskClient,
|
task_client: TaskClient,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
stats_tx: ClientStatsSender,
|
stats_tx: ClientStatsSender,
|
||||||
) {
|
) {
|
||||||
@@ -324,8 +359,9 @@ where
|
|||||||
lane_queue_lengths,
|
lane_queue_lengths,
|
||||||
client_connection_rx,
|
client_connection_rx,
|
||||||
stats_tx,
|
stats_tx,
|
||||||
|
task_client,
|
||||||
)
|
)
|
||||||
.start_with_shutdown(shutdown, packet_type);
|
.start(packet_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// buffer controlling all messages fetched from provider
|
// buffer controlling all messages fetched from provider
|
||||||
@@ -348,10 +384,12 @@ where
|
|||||||
reply_key_storage,
|
reply_key_storage,
|
||||||
reply_controller_sender,
|
reply_controller_sender,
|
||||||
metrics_reporter,
|
metrics_reporter,
|
||||||
|
shutdown,
|
||||||
);
|
);
|
||||||
controller.start_with_shutdown(shutdown)
|
controller.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn start_gateway_client(
|
async fn start_gateway_client(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
initialisation_result: InitialisationResult,
|
initialisation_result: InitialisationResult,
|
||||||
@@ -359,6 +397,7 @@ where
|
|||||||
details_store: &S::GatewaysDetailsStore,
|
details_store: &S::GatewaysDetailsStore,
|
||||||
packet_router: PacketRouter,
|
packet_router: PacketRouter,
|
||||||
stats_reporter: ClientStatsSender,
|
stats_reporter: ClientStatsSender,
|
||||||
|
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||||
shutdown: TaskClient,
|
shutdown: TaskClient,
|
||||||
) -> Result<GatewayClient<C, S::CredentialStore>, ClientCoreError>
|
) -> Result<GatewayClient<C, S::CredentialStore>, ClientCoreError>
|
||||||
where
|
where
|
||||||
@@ -401,6 +440,8 @@ where
|
|||||||
packet_router,
|
packet_router,
|
||||||
bandwidth_controller,
|
bandwidth_controller,
|
||||||
stats_reporter,
|
stats_reporter,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback,
|
||||||
shutdown,
|
shutdown,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@@ -437,8 +478,8 @@ where
|
|||||||
details_store
|
details_store
|
||||||
.upgrade_stored_remote_gateway_key(gateway_client.gateway_identity(), &updated_key)
|
.upgrade_stored_remote_gateway_key(gateway_client.gateway_identity(), &updated_key)
|
||||||
.await.map_err(|err| {
|
.await.map_err(|err| {
|
||||||
error!("failed to store upgraded gateway key! this connection might be forever broken now: {err}");
|
error!("failed to store upgraded gateway key! this connection might be forever broken now: {err}");
|
||||||
ClientCoreError::GatewaysDetailsStoreError { source: Box::new(err) }
|
ClientCoreError::GatewaysDetailsStoreError { source: Box::new(err) }
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,6 +487,7 @@ where
|
|||||||
.claim_initial_bandwidth()
|
.claim_initial_bandwidth()
|
||||||
.await
|
.await
|
||||||
.map_err(gateway_failure)?;
|
.map_err(gateway_failure)?;
|
||||||
|
|
||||||
gateway_client
|
gateway_client
|
||||||
.start_listening_for_mixnet_messages()
|
.start_listening_for_mixnet_messages()
|
||||||
.map_err(gateway_failure)?;
|
.map_err(gateway_failure)?;
|
||||||
@@ -462,6 +504,7 @@ where
|
|||||||
details_store: &S::GatewaysDetailsStore,
|
details_store: &S::GatewaysDetailsStore,
|
||||||
packet_router: PacketRouter,
|
packet_router: PacketRouter,
|
||||||
stats_reporter: ClientStatsSender,
|
stats_reporter: ClientStatsSender,
|
||||||
|
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||||
mut shutdown: TaskClient,
|
mut shutdown: TaskClient,
|
||||||
) -> Result<Box<dyn GatewayTransceiver + Send>, ClientCoreError>
|
) -> Result<Box<dyn GatewayTransceiver + Send>, ClientCoreError>
|
||||||
where
|
where
|
||||||
@@ -493,6 +536,8 @@ where
|
|||||||
details_store,
|
details_store,
|
||||||
packet_router,
|
packet_router,
|
||||||
stats_reporter,
|
stats_reporter,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback,
|
||||||
shutdown,
|
shutdown,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -509,20 +554,15 @@ where
|
|||||||
// if no custom provider was ... provided ..., create one using nym-api
|
// if no custom provider was ... provided ..., create one using nym-api
|
||||||
custom_provider.unwrap_or_else(|| match config_topology.topology_structure {
|
custom_provider.unwrap_or_else(|| match config_topology.topology_structure {
|
||||||
config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new(
|
config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new(
|
||||||
nym_api_provider::Config {
|
config_topology,
|
||||||
min_mixnode_performance: config_topology.minimum_mixnode_performance,
|
|
||||||
min_gateway_performance: config_topology.minimum_gateway_performance,
|
|
||||||
},
|
|
||||||
nym_api_urls,
|
nym_api_urls,
|
||||||
env!("CARGO_PKG_VERSION").to_string(),
|
|
||||||
user_agent,
|
user_agent,
|
||||||
)),
|
)),
|
||||||
config::TopologyStructure::GeoAware(group_by) => {
|
config::TopologyStructure::GeoAware(group_by) => {
|
||||||
Box::new(GeoAwareTopologyProvider::new(
|
warn!("using deprecated 'GeoAware' topology provider - this option will be removed very soon");
|
||||||
nym_api_urls,
|
|
||||||
env!("CARGO_PKG_VERSION").to_string(),
|
#[allow(deprecated)]
|
||||||
group_by,
|
Box::new(crate::client::topology_control::GeoAwareTopologyProvider::new(nym_api_urls, group_by))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -533,17 +573,24 @@ where
|
|||||||
topology_provider: Box<dyn TopologyProvider + Send + Sync>,
|
topology_provider: Box<dyn TopologyProvider + Send + Sync>,
|
||||||
topology_config: config::Topology,
|
topology_config: config::Topology,
|
||||||
topology_accessor: TopologyAccessor,
|
topology_accessor: TopologyAccessor,
|
||||||
local_gateway: &NodeIdentity,
|
local_gateway: NodeIdentity,
|
||||||
wait_for_gateway: bool,
|
wait_for_gateway: bool,
|
||||||
mut shutdown: TaskClient,
|
mut task_client: TaskClient,
|
||||||
) -> Result<(), ClientCoreError> {
|
) -> Result<(), ClientCoreError> {
|
||||||
let topology_refresher_config =
|
let topology_refresher_config =
|
||||||
TopologyRefresherConfig::new(topology_config.topology_refresh_rate);
|
TopologyRefresherConfig::new(topology_config.topology_refresh_rate);
|
||||||
|
|
||||||
|
if topology_config.disable_refreshing {
|
||||||
|
// if we're not spawning the refresher, don't cause shutdown immediately
|
||||||
|
info!("The background topology refesher is not going to be started");
|
||||||
|
task_client.disarm();
|
||||||
|
}
|
||||||
|
|
||||||
let mut topology_refresher = TopologyRefresher::new(
|
let mut topology_refresher = TopologyRefresher::new(
|
||||||
topology_refresher_config,
|
topology_refresher_config,
|
||||||
topology_accessor,
|
topology_accessor,
|
||||||
topology_provider,
|
topology_provider,
|
||||||
|
task_client,
|
||||||
);
|
);
|
||||||
// before returning, block entire runtime to refresh the current network view so that any
|
// before returning, block entire runtime to refresh the current network view so that any
|
||||||
// components depending on topology would see a non-empty view
|
// components depending on topology would see a non-empty view
|
||||||
@@ -565,7 +612,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = topology_refresher
|
if let Err(err) = topology_refresher
|
||||||
.ensure_contains_gateway(local_gateway)
|
.ensure_contains_routable_egress(local_gateway)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
if let Some(waiting_timeout) = gateway_wait_timeout {
|
if let Some(waiting_timeout) = gateway_wait_timeout {
|
||||||
@@ -584,15 +631,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if topology_config.disable_refreshing {
|
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.disarm();
|
|
||||||
} else {
|
|
||||||
// don't spawn the refresher if we don't want to be refreshing the topology.
|
// don't spawn the refresher if we don't want to be refreshing the topology.
|
||||||
// only use the initial values obtained
|
// only use the initial values obtained
|
||||||
info!("Starting topology refresher...");
|
info!("Starting topology refresher...");
|
||||||
topology_refresher.start_with_shutdown(shutdown);
|
topology_refresher.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -603,28 +646,29 @@ where
|
|||||||
user_agent: Option<UserAgent>,
|
user_agent: Option<UserAgent>,
|
||||||
client_stats_id: String,
|
client_stats_id: String,
|
||||||
input_sender: Sender<InputMessage>,
|
input_sender: Sender<InputMessage>,
|
||||||
shutdown: TaskClient,
|
task_client: TaskClient,
|
||||||
) -> ClientStatsSender {
|
) -> ClientStatsSender {
|
||||||
info!("Starting statistics control...");
|
info!("Starting statistics control...");
|
||||||
StatisticsControl::create_and_start_with_shutdown(
|
StatisticsControl::create_and_start(
|
||||||
config.debug.stats_reporting,
|
config.debug.stats_reporting,
|
||||||
user_agent
|
user_agent
|
||||||
.map(|u| u.application)
|
.map(|u| u.application)
|
||||||
.unwrap_or("unknown".to_string()),
|
.unwrap_or("unknown".to_string()),
|
||||||
client_stats_id,
|
client_stats_id,
|
||||||
input_sender.clone(),
|
input_sender.clone(),
|
||||||
shutdown.with_suffix("controller"),
|
task_client,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_mix_traffic_controller(
|
fn start_mix_traffic_controller(
|
||||||
gateway_transceiver: Box<dyn GatewayTransceiver + Send>,
|
gateway_transceiver: Box<dyn GatewayTransceiver + Send>,
|
||||||
shutdown: TaskClient,
|
shutdown: TaskClient,
|
||||||
) -> BatchMixMessageSender {
|
) -> (BatchMixMessageSender, ClientRequestSender) {
|
||||||
info!("Starting mix traffic controller...");
|
info!("Starting mix traffic controller...");
|
||||||
let (mix_traffic_controller, mix_tx) = MixTrafficController::new(gateway_transceiver);
|
let (mix_traffic_controller, mix_tx, client_tx) =
|
||||||
mix_traffic_controller.start_with_shutdown(shutdown);
|
MixTrafficController::new(gateway_transceiver, shutdown);
|
||||||
mix_tx
|
mix_traffic_controller.start();
|
||||||
|
(mix_tx, client_tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: rename it as it implies the data is persistent whilst one can use InMemBackend
|
// TODO: rename it as it implies the data is persistent whilst one can use InMemBackend
|
||||||
@@ -659,6 +703,7 @@ where
|
|||||||
setup_method: GatewaySetup,
|
setup_method: GatewaySetup,
|
||||||
key_store: &S::KeyStore,
|
key_store: &S::KeyStore,
|
||||||
details_store: &S::GatewaysDetailsStore,
|
details_store: &S::GatewaysDetailsStore,
|
||||||
|
derivation_material: Option<DerivationMaterial>,
|
||||||
) -> Result<InitialisationResult, ClientCoreError>
|
) -> Result<InitialisationResult, ClientCoreError>
|
||||||
where
|
where
|
||||||
<S::KeyStore as KeyStore>::StorageError: Sync + Send,
|
<S::KeyStore as KeyStore>::StorageError: Sync + Send,
|
||||||
@@ -668,7 +713,12 @@ where
|
|||||||
if key_store.load_keys().await.is_err() {
|
if key_store.load_keys().await.is_err() {
|
||||||
info!("could not find valid client keys - a new set will be generated");
|
info!("could not find valid client keys - a new set will be generated");
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let keys = ClientKeys::generate_new(&mut rng);
|
let keys = if let Some(derivation_material) = derivation_material {
|
||||||
|
ClientKeys::from_master_key(&mut rng, &derivation_material)
|
||||||
|
.map_err(|_| ClientCoreError::HkdfDerivationError {})?
|
||||||
|
} else {
|
||||||
|
ClientKeys::generate_new(&mut rng)
|
||||||
|
};
|
||||||
store_client_keys(keys, key_store).await?;
|
store_client_keys(keys, key_store).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,6 +740,7 @@ where
|
|||||||
self.setup_method,
|
self.setup_method,
|
||||||
self.client_store.key_store(),
|
self.client_store.key_store(),
|
||||||
self.client_store.gateway_details_store(),
|
self.client_store.gateway_details_store(),
|
||||||
|
self.derivation_material,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -713,7 +764,8 @@ where
|
|||||||
|
|
||||||
// channels responsible for controlling ack messages
|
// channels responsible for controlling ack messages
|
||||||
let (ack_sender, ack_receiver) = mpsc::unbounded();
|
let (ack_sender, ack_receiver) = mpsc::unbounded();
|
||||||
let shared_topology_accessor = TopologyAccessor::new();
|
let shared_topology_accessor =
|
||||||
|
TopologyAccessor::new(self.config.debug.topology.ignore_egress_epoch_role);
|
||||||
|
|
||||||
// Shutdown notifier for signalling tasks to stop
|
// Shutdown notifier for signalling tasks to stop
|
||||||
let shutdown = self
|
let shutdown = self
|
||||||
@@ -745,7 +797,7 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
let stats_reporter = Self::start_statistics_control(
|
let stats_reporter = Self::start_statistics_control(
|
||||||
self.config,
|
&self.config,
|
||||||
self.user_agent.clone(),
|
self.user_agent.clone(),
|
||||||
generate_client_stats_id(*self_address.identity()),
|
generate_client_stats_id(*self_address.identity()),
|
||||||
input_sender.clone(),
|
input_sender.clone(),
|
||||||
@@ -771,12 +823,14 @@ where
|
|||||||
|
|
||||||
let gateway_transceiver = Self::setup_gateway_transceiver(
|
let gateway_transceiver = Self::setup_gateway_transceiver(
|
||||||
self.custom_gateway_transceiver,
|
self.custom_gateway_transceiver,
|
||||||
self.config,
|
&self.config,
|
||||||
init_res,
|
init_res,
|
||||||
bandwidth_controller,
|
bandwidth_controller,
|
||||||
&details_store,
|
&details_store,
|
||||||
gateway_packet_router,
|
gateway_packet_router,
|
||||||
stats_reporter.clone(),
|
stats_reporter.clone(),
|
||||||
|
#[cfg(unix)]
|
||||||
|
self.connection_fd_callback,
|
||||||
shutdown.fork("gateway_transceiver"),
|
shutdown.fork("gateway_transceiver"),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -802,7 +856,8 @@ where
|
|||||||
// that are to be sent to the mixnet. They are used by cover traffic stream and real
|
// that are to be sent to the mixnet. They are used by cover traffic stream and real
|
||||||
// traffic stream.
|
// traffic stream.
|
||||||
// The MixTrafficController then sends the actual traffic
|
// The MixTrafficController then sends the actual traffic
|
||||||
let message_sender = Self::start_mix_traffic_controller(
|
|
||||||
|
let (message_sender, client_request_sender) = Self::start_mix_traffic_controller(
|
||||||
gateway_transceiver,
|
gateway_transceiver,
|
||||||
shutdown.fork("mix_traffic_controller"),
|
shutdown.fork("mix_traffic_controller"),
|
||||||
);
|
);
|
||||||
@@ -879,6 +934,8 @@ where
|
|||||||
},
|
},
|
||||||
stats_reporter,
|
stats_reporter,
|
||||||
task_handle: shutdown,
|
task_handle: shutdown,
|
||||||
|
client_request_sender,
|
||||||
|
forget_me: self.config.debug.forget_me,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -890,6 +947,7 @@ pub struct BaseClient {
|
|||||||
pub client_output: ClientOutputStatus,
|
pub client_output: ClientOutputStatus,
|
||||||
pub client_state: ClientState,
|
pub client_state: ClientState,
|
||||||
pub stats_reporter: ClientStatsSender,
|
pub stats_reporter: ClientStatsSender,
|
||||||
|
pub client_request_sender: ClientRequestSender,
|
||||||
pub task_handle: TaskHandle,
|
pub task_handle: TaskHandle,
|
||||||
|
pub forget_me: ForgetMe,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>(
|
|||||||
let db_path = db_path.as_ref();
|
let db_path = db_path.as_ref();
|
||||||
if db_path.exists() {
|
if db_path.exists() {
|
||||||
info!("loading existing surb database");
|
info!("loading existing surb database");
|
||||||
match fs_backend::Backend::try_load(db_path).await {
|
match fs_backend::Backend::try_load(db_path, surb_config.fresh_sender_tags).await {
|
||||||
Ok(backend) => Ok(backend),
|
Ok(backend) => Ok(backend),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("failed to setup persistent storage backend for our reply needs: {err}. We're going to create a fresh database instead. This behaviour might change in the future");
|
error!("failed to setup persistent storage backend for our reply needs: {err}. We're going to create a fresh database instead. This behaviour might change in the future");
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
// TODO: combine those more closely. Perhaps into a single underlying store.
|
// TODO: combine those more closely. Perhaps into a single underlying store.
|
||||||
// Like for persistent, on-disk, storage, what's the point of having 3 different databases?
|
// Like for persistent, on-disk, storage, what's the point of having 3 different databases?
|
||||||
|
|
||||||
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore};
|
use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore};
|
||||||
use crate::client::replies::reply_storage;
|
use crate::client::replies::reply_storage;
|
||||||
use crate::client::replies::reply_storage::ReplyStorageBackend;
|
use crate::client::replies::reply_storage::ReplyStorageBackend;
|
||||||
@@ -63,7 +65,7 @@ pub trait MixnetClientStorage {
|
|||||||
fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore;
|
fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Clone)]
|
||||||
pub struct Ephemeral {
|
pub struct Ephemeral {
|
||||||
key_store: InMemEphemeralKeys,
|
key_store: InMemEphemeralKeys,
|
||||||
reply_store: reply_storage::Empty,
|
reply_store: reply_storage::Empty,
|
||||||
@@ -71,9 +73,14 @@ pub struct Ephemeral {
|
|||||||
gateway_details_store: InMemGatewaysDetails,
|
gateway_details_store: InMemGatewaysDetails,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ephemeral {
|
impl Default for Ephemeral {
|
||||||
pub fn new() -> Self {
|
fn default() -> Self {
|
||||||
Default::default()
|
Ephemeral {
|
||||||
|
key_store: InMemEphemeralKeys::new(&mut OsRng),
|
||||||
|
reply_store: Default::default(),
|
||||||
|
credential_store: Default::default(),
|
||||||
|
gateway_details_store: Default::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +121,7 @@ impl MixnetClientStorage for Ephemeral {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(target_arch = "wasm32"),
|
not(target_arch = "wasm32"),
|
||||||
feature = "fs-surb-storage",
|
feature = "fs-surb-storage",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use nym_sphinx::cover::generate_loop_cover_packet;
|
|||||||
use nym_sphinx::params::{PacketSize, PacketType};
|
use nym_sphinx::params::{PacketSize, PacketType};
|
||||||
use nym_sphinx::utils::sample_poisson_duration;
|
use nym_sphinx::utils::sample_poisson_duration;
|
||||||
use nym_statistics_common::clients::{packet_statistics::PacketStatisticsEvent, ClientStatsSender};
|
use nym_statistics_common::clients::{packet_statistics::PacketStatisticsEvent, ClientStatsSender};
|
||||||
|
use nym_task::TaskClient;
|
||||||
use rand::{rngs::OsRng, CryptoRng, Rng};
|
use rand::{rngs::OsRng, CryptoRng, Rng};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -64,6 +65,8 @@ where
|
|||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
|
|
||||||
stats_tx: ClientStatsSender,
|
stats_tx: ClientStatsSender,
|
||||||
|
|
||||||
|
task_client: TaskClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> Stream for LoopCoverTrafficStream<R>
|
impl<R> Stream for LoopCoverTrafficStream<R>
|
||||||
@@ -110,6 +113,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
traffic_config: config::Traffic,
|
traffic_config: config::Traffic,
|
||||||
cover_config: config::CoverTraffic,
|
cover_config: config::CoverTraffic,
|
||||||
stats_tx: ClientStatsSender,
|
stats_tx: ClientStatsSender,
|
||||||
|
task_client: TaskClient,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let rng = OsRng;
|
let rng = OsRng;
|
||||||
|
|
||||||
@@ -128,6 +132,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
secondary_packet_size: traffic_config.secondary_packet_size,
|
secondary_packet_size: traffic_config.secondary_packet_size,
|
||||||
packet_type: traffic_config.packet_type,
|
packet_type: traffic_config.packet_type,
|
||||||
stats_tx,
|
stats_tx,
|
||||||
|
task_client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +168,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
// poisson delay, but is it really a problem?
|
// poisson delay, but is it really a problem?
|
||||||
let topology_permit = self.topology_access.get_read_permit().await;
|
let topology_permit = self.topology_access.get_read_permit().await;
|
||||||
// the ack is sent back to ourselves (and then ignored)
|
// the ack is sent back to ourselves (and then ignored)
|
||||||
|
|
||||||
let topology_ref = match topology_permit.try_get_valid_topology_ref(
|
let topology_ref = match topology_permit.try_get_valid_topology_ref(
|
||||||
&self.our_full_destination,
|
&self.our_full_destination,
|
||||||
Some(&self.our_full_destination),
|
Some(&self.our_full_destination),
|
||||||
@@ -174,7 +180,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let cover_message = generate_loop_cover_packet(
|
let cover_message = match generate_loop_cover_packet(
|
||||||
&mut self.rng,
|
&mut self.rng,
|
||||||
topology_ref,
|
topology_ref,
|
||||||
&self.ack_key,
|
&self.ack_key,
|
||||||
@@ -183,8 +189,15 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
self.cover_traffic.loop_cover_traffic_average_delay,
|
self.cover_traffic.loop_cover_traffic_average_delay,
|
||||||
cover_traffic_packet_size,
|
cover_traffic_packet_size,
|
||||||
self.packet_type,
|
self.packet_type,
|
||||||
)
|
) {
|
||||||
.expect("Somehow failed to generate a loop cover message with a valid topology");
|
Ok(cover_message) => cover_message,
|
||||||
|
Err(err) => {
|
||||||
|
warn!(
|
||||||
|
"Somehow failed to generate a loop cover message with a valid topology: {err}"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Err(err) = self.mix_tx.try_send(vec![cover_message]) {
|
if let Err(err) = self.mix_tx.try_send(vec![cover_message]) {
|
||||||
match err {
|
match err {
|
||||||
@@ -216,7 +229,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
tokio::task::yield_now().await;
|
tokio::task::yield_now().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_with_shutdown(mut self, mut shutdown: nym_task::TaskClient) {
|
pub fn start(mut self) {
|
||||||
if self.cover_traffic.disable_loop_cover_traffic_stream {
|
if self.cover_traffic.disable_loop_cover_traffic_stream {
|
||||||
// we should have never got here in the first place - the task should have never been created to begin with
|
// we should have never got here in the first place - the task should have never been created to begin with
|
||||||
// so panic and review the code that lead to this branch
|
// so panic and review the code that lead to this branch
|
||||||
@@ -230,6 +243,8 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
);
|
);
|
||||||
self.set_next_delay(sampled);
|
self.set_next_delay(sampled);
|
||||||
|
|
||||||
|
let mut shutdown = self.task_client.fork("select");
|
||||||
|
|
||||||
spawn_future(async move {
|
spawn_future(async move {
|
||||||
debug!("Started LoopCoverTrafficStream with graceful shutdown support");
|
debug!("Started LoopCoverTrafficStream with graceful shutdown support");
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ pub enum InputMessage {
|
|||||||
recipient: Recipient,
|
recipient: Recipient,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
mix_hops: Option<u8>,
|
max_retransmissions: Option<u32>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Creates a message used for a duplex anonymous communication where the recipient
|
/// Creates a message used for a duplex anonymous communication where the recipient
|
||||||
@@ -44,7 +44,7 @@ pub enum InputMessage {
|
|||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
reply_surbs: u32,
|
reply_surbs: u32,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
mix_hops: Option<u8>,
|
max_retransmissions: Option<u32>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Attempt to use our internally received and stored `ReplySurb` to send the message back
|
/// Attempt to use our internally received and stored `ReplySurb` to send the message back
|
||||||
@@ -55,6 +55,7 @@ pub enum InputMessage {
|
|||||||
recipient_tag: AnonymousSenderTag,
|
recipient_tag: AnonymousSenderTag,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
},
|
},
|
||||||
|
|
||||||
MessageWrapper {
|
MessageWrapper {
|
||||||
@@ -94,29 +95,7 @@ impl InputMessage {
|
|||||||
recipient,
|
recipient,
|
||||||
data,
|
data,
|
||||||
lane,
|
lane,
|
||||||
mix_hops: None,
|
max_retransmissions: None,
|
||||||
};
|
|
||||||
if let Some(packet_type) = packet_type {
|
|
||||||
InputMessage::new_wrapper(message, packet_type)
|
|
||||||
} else {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IMHO `new_regular` should take `mix_hops: Option<u8>` as an argument instead of creating
|
|
||||||
// this function, but that would potentially break backwards compatibility with the current API
|
|
||||||
pub fn new_regular_with_custom_hops(
|
|
||||||
recipient: Recipient,
|
|
||||||
data: Vec<u8>,
|
|
||||||
lane: TransmissionLane,
|
|
||||||
packet_type: Option<PacketType>,
|
|
||||||
mix_hops: Option<u8>,
|
|
||||||
) -> Self {
|
|
||||||
let message = InputMessage::Regular {
|
|
||||||
recipient,
|
|
||||||
data,
|
|
||||||
lane,
|
|
||||||
mix_hops,
|
|
||||||
};
|
};
|
||||||
if let Some(packet_type) = packet_type {
|
if let Some(packet_type) = packet_type {
|
||||||
InputMessage::new_wrapper(message, packet_type)
|
InputMessage::new_wrapper(message, packet_type)
|
||||||
@@ -137,31 +116,7 @@ impl InputMessage {
|
|||||||
data,
|
data,
|
||||||
reply_surbs,
|
reply_surbs,
|
||||||
lane,
|
lane,
|
||||||
mix_hops: None,
|
max_retransmissions: None,
|
||||||
};
|
|
||||||
if let Some(packet_type) = packet_type {
|
|
||||||
InputMessage::new_wrapper(message, packet_type)
|
|
||||||
} else {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IMHO `new_anonymous` should take `mix_hops: Option<u8>` as an argument instead of creating
|
|
||||||
// this function, but that would potentially break backwards compatibility with the current API
|
|
||||||
pub fn new_anonymous_with_custom_hops(
|
|
||||||
recipient: Recipient,
|
|
||||||
data: Vec<u8>,
|
|
||||||
reply_surbs: u32,
|
|
||||||
lane: TransmissionLane,
|
|
||||||
packet_type: Option<PacketType>,
|
|
||||||
mix_hops: Option<u8>,
|
|
||||||
) -> Self {
|
|
||||||
let message = InputMessage::Anonymous {
|
|
||||||
recipient,
|
|
||||||
data,
|
|
||||||
reply_surbs,
|
|
||||||
lane,
|
|
||||||
mix_hops,
|
|
||||||
};
|
};
|
||||||
if let Some(packet_type) = packet_type {
|
if let Some(packet_type) = packet_type {
|
||||||
InputMessage::new_wrapper(message, packet_type)
|
InputMessage::new_wrapper(message, packet_type)
|
||||||
@@ -180,6 +135,7 @@ impl InputMessage {
|
|||||||
recipient_tag,
|
recipient_tag,
|
||||||
data,
|
data,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions: None,
|
||||||
};
|
};
|
||||||
if let Some(packet_type) = packet_type {
|
if let Some(packet_type) = packet_type {
|
||||||
InputMessage::new_wrapper(message, packet_type)
|
InputMessage::new_wrapper(message, packet_type)
|
||||||
@@ -197,4 +153,34 @@ impl InputMessage {
|
|||||||
InputMessage::MessageWrapper { message, .. } => message.lane(),
|
InputMessage::MessageWrapper { message, .. } => message.lane(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_max_retransmissions(&mut self, max_retransmissions: u32) -> &mut Self {
|
||||||
|
match self {
|
||||||
|
InputMessage::Regular {
|
||||||
|
max_retransmissions: m,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| InputMessage::Anonymous {
|
||||||
|
max_retransmissions: m,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| InputMessage::Reply {
|
||||||
|
max_retransmissions: m,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
*m = Some(max_retransmissions);
|
||||||
|
}
|
||||||
|
InputMessage::Premade { .. } => {}
|
||||||
|
InputMessage::MessageWrapper { message, .. } => {
|
||||||
|
message.set_max_retransmissions(max_retransmissions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_max_retransmissions(mut self, max_retransmissions: u32) -> Self {
|
||||||
|
self.set_max_retransmissions(max_retransmissions);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user