Compare commits
164 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 600bf42a95 | |||
| 748e3e4248 | |||
| 8cf1b6427a | |||
| 7a888c6fdf | |||
| 9a9bb89d89 | |||
| 4cc14ddcc4 | |||
| 2dbf9d97cb | |||
| 91b6f3cc3e | |||
| 84cccffcbd | |||
| af16b3f059 | |||
| b1cde0716e | |||
| 45bcdb03d8 | |||
| 44682b5ef0 | |||
| 51c9b012e2 | |||
| 50b1175622 | |||
| 29ee5984fb | |||
| e542b25ffc | |||
| 516d3f04cf | |||
| 08c09781c7 | |||
| c92de832e4 | |||
| d9d62195cb | |||
| da9115d51b | |||
| 1367cad99d | |||
| 4f6d65ab95 | |||
| 4292d8ac03 | |||
| dcb6de2421 | |||
| 1f5ed41bb3 | |||
| 091e98aa74 | |||
| 0e38126fc5 | |||
| ecbe192a88 | |||
| f0ee49788c | |||
| d2ff3cb88d | |||
| 873d15a5e1 | |||
| 53792cc839 | |||
| 415ef1bf13 | |||
| a4f6426bf9 | |||
| 0870911b3c | |||
| 9f23887cc0 | |||
| 8ab269fa05 | |||
| 7b75f22a8e | |||
| ca0449e03d | |||
| 224e63d275 | |||
| 3d77283056 | |||
| 7cc473005b | |||
| f874284850 | |||
| 7b6077ba64 | |||
| 12026305d5 | |||
| 257e36ddcb | |||
| ad81c6d27e | |||
| ae52b7b71f | |||
| 854d3cceac | |||
| 1bdf867fdb | |||
| 5a88b5b6a8 | |||
| 5ab4d3c22c | |||
| b529883b81 | |||
| 07f624660c | |||
| 71f8e736d8 | |||
| d3573e78e0 | |||
| e6e74855af | |||
| b4865520a4 | |||
| f52ebfb9c3 | |||
| 6ca2a3c539 | |||
| 717c9066d6 | |||
| 2760a17323 | |||
| 4e9f1bc0ed | |||
| d35023d14b | |||
| 400aa6ba6d | |||
| 2ba74ae120 | |||
| 99d8aebea9 | |||
| 0bde4dfc84 | |||
| a56068e28a | |||
| 9a4293a5b9 | |||
| cdddb44099 | |||
| d309b44ad7 | |||
| 22539c3e7d | |||
| edde411568 | |||
| 75f2fb7039 | |||
| f768c8e8e2 | |||
| 200efebc37 | |||
| a429d6528e | |||
| ebed210de2 | |||
| d062524d32 | |||
| f1d3c33391 | |||
| 89eea3100e | |||
| d893c806c2 | |||
| 7846058802 | |||
| 3c98c9021e | |||
| 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 | |||
| 3baac1292d | |||
| dc88650d6d | |||
| 681c054890 | |||
| f623bbd57c | |||
| d4d576f363 | |||
| 84b6068ac9 |
@@ -1 +1,2 @@
|
|||||||
nym-validator-rewarder/.sqlx/** diff=nodiff
|
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",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-22.04
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: documentation/docs
|
working-directory: documentation/docs
|
||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
- name: Install Python3 modules
|
- name: Install Python3 modules
|
||||||
run: sudo pip3 install pandas tabulate
|
run: sudo pip3 install pandas tabulate
|
||||||
- name: Install rsync
|
- name: Install rsync
|
||||||
run: sudo apt-get install rsync
|
run: sudo apt-get install -y rsync
|
||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.0.0
|
uses: pnpm/action-setup@v4.0.0
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [arc-ubuntu-20.04]
|
platform: [arc-ubuntu-22.04]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install rsync
|
- name: Install rsync
|
||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
- 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: Build
|
- name: Build
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [ arc-ubuntu-20.04 ]
|
platform: [ arc-ubuntu-22.04 ]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -27,12 +27,18 @@ 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-windows-11, custom-runner-mac-m1 ]
|
os: [ arc-ubuntu-22.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
|
||||||
|
|||||||
@@ -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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -11,7 +11,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
check-schema:
|
check-schema:
|
||||||
name: Generate and check schema
|
name: Generate and check schema
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [ arc-ubuntu-20.04 ]
|
platform: [ arc-ubuntu-22.04 ]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
env:
|
env:
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -14,28 +14,12 @@ on:
|
|||||||
- '.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-22.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
|
||||||
|
|
||||||
@@ -43,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:
|
||||||
@@ -73,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
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-22.04
|
||||||
|
env:
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: documentation/docs
|
working-directory: documentation/docs
|
||||||
@@ -23,7 +25,7 @@ jobs:
|
|||||||
- name: Install Python3 modules
|
- name: Install Python3 modules
|
||||||
run: sudo pip3 install pandas tabulate
|
run: sudo pip3 install pandas tabulate
|
||||||
- name: Install rsync
|
- name: Install rsync
|
||||||
run: sudo apt-get install rsync
|
run: sudo apt-get install -y rsync
|
||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4.0.0
|
uses: pnpm/action-setup@v4.0.0
|
||||||
|
|||||||
@@ -15,14 +15,16 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: ubuntu-22.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
|
||||||
|
|
||||||
- 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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
name: ci-nym-network-explorer
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'explorer/**'
|
|
||||||
- '.github/workflows/ci-nym-network-explorer.yml'
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: explorer
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: custom-linux
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Install rsync
|
|
||||||
run: sudo apt-get install rsync
|
|
||||||
continue-on-error: true
|
|
||||||
- uses: rlespinasse/github-slug-action@v3.x
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
- name: Setup yarn
|
|
||||||
run: npm install -g yarn
|
|
||||||
continue-on-error: true
|
|
||||||
- name: Build shared packages
|
|
||||||
run: cd .. && yarn && yarn build
|
|
||||||
- name: Set environment from the example
|
|
||||||
run: cp .env.prod .env
|
|
||||||
# - run: yarn test
|
|
||||||
# continue-on-error: true
|
|
||||||
- run: yarn && yarn build
|
|
||||||
continue-on-error: true
|
|
||||||
- run: yarn storybook:build
|
|
||||||
name: Build storybook
|
|
||||||
- name: Deploy branch to CI www
|
|
||||||
continue-on-error: true
|
|
||||||
uses: easingthemes/ssh-deploy@main
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
|
||||||
ARGS: "-rltgoDzvO --delete"
|
|
||||||
SOURCE: "explorer/dist/"
|
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/network-explorer-${{ env.GITHUB_REF_SLUG }}
|
|
||||||
EXCLUDE: "/dist/, /node_modules/"
|
|
||||||
- name: Deploy storybook to CI www
|
|
||||||
continue-on-error: true
|
|
||||||
uses: easingthemes/ssh-deploy@main
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
|
||||||
ARGS: "-rltgoDzvO --delete"
|
|
||||||
SOURCE: "explorer/storybook-static/"
|
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ne-sb-${{ env.GITHUB_REF_SLUG }}
|
|
||||||
EXCLUDE: "/dist/, /node_modules/"
|
|
||||||
- name: Matrix - Node Install
|
|
||||||
run: npm install
|
|
||||||
working-directory: .github/workflows/support-files
|
|
||||||
- name: Matrix - Send Notification
|
|
||||||
env:
|
|
||||||
NYM_NOTIFICATION_KIND: network-explorer
|
|
||||||
NYM_PROJECT_NAME: "Network Explorer"
|
|
||||||
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
|
|
||||||
NYM_CI_WWW_LOCATION: "network-explorer-${{ env.GITHUB_REF_SLUG }}"
|
|
||||||
NYM_CI_WWW_LOCATION_STORYBOOK: "ne-sb-${{ env.GITHUB_REF_SLUG }}"
|
|
||||||
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
|
||||||
GIT_BRANCH: "${GITHUB_REF##*/}"
|
|
||||||
IS_SUCCESS: "${{ job.status == 'success' }}"
|
|
||||||
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
|
||||||
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
|
|
||||||
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
|
||||||
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
|
||||||
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
|
||||||
uses: docker://keybaseio/client:stable-node
|
|
||||||
with:
|
|
||||||
args: .github/workflows/support-files/notifications/entry_point.sh
|
|
||||||
- name: Deploy
|
|
||||||
if: github.event_name == 'workflow_dispatch'
|
|
||||||
uses: easingthemes/ssh-deploy@main
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CD_PROD_NE_SSH_PRIVATE_KEY }}
|
|
||||||
ARGS: "-rltgoDzvO --delete"
|
|
||||||
SOURCE: "explorer/dist/"
|
|
||||||
REMOTE_HOST: ${{ secrets.CD_PROD_NE_REMOTE_HOST }}
|
|
||||||
REMOTE_USER: ${{ secrets.CD_PROD_NE_REMOTE_USER }}
|
|
||||||
TARGET: ${{ secrets.CD_PROD_NE_REMOTE_TARGET }}
|
|
||||||
EXCLUDE: "/dist/, /node_modules/"
|
|
||||||
@@ -11,12 +11,17 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.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: Install Dependencies (Linux)
|
- name: Install system dependencies
|
||||||
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 install -y libdbus-1-dev libmnl-dev libnftnl-dev \
|
||||||
|
libwebkit2gtk-4.1-dev build-essential curl wget libssl-dev jq \
|
||||||
|
libgtk-3-dev squashfs-tools libayatana-appindicator3-dev make libfuse2 unzip librsvg2-dev file \
|
||||||
|
libsoup-3.0-dev libjavascriptcoregtk-4.1-dev
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -11,15 +11,16 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
wasm:
|
wasm:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-22.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
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
|
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -32,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
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
rust: [stable, beta]
|
rust: [stable, beta]
|
||||||
os: [ubuntu-20.04, windows-latest, macos-latest]
|
os: [ubuntu-22.04, windows-latest, macos-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler
|
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
if: matrix.os == 'ubuntu-20.04'
|
if: matrix.os == 'ubuntu-22.04'
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -59,7 +59,7 @@ jobs:
|
|||||||
|
|
||||||
# To avoid running out of disk space, skip generating debug symbols
|
# To avoid running out of disk space, skip generating debug symbols
|
||||||
- name: Set debug to false (unix)
|
- name: Set debug to false (unix)
|
||||||
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-latest'
|
if: matrix.os == 'ubuntu-22.04' || matrix.os == 'macos-latest'
|
||||||
run: |
|
run: |
|
||||||
sed -i.bak 's/\[profile.dev\]/\[profile.dev\]\ndebug = false/' Cargo.toml
|
sed -i.bak 's/\[profile.dev\]/\[profile.dev\]\ndebug = false/' Cargo.toml
|
||||||
git diff
|
git diff
|
||||||
@@ -106,7 +106,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04, macos-latest, windows-latest]
|
os: [ubuntu-22.04, macos-latest, windows-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
|
||||||
if: matrix.os == 'ubuntu-20.04'
|
if: matrix.os == 'ubuntu-22.04'
|
||||||
|
|
||||||
- name: Install rust toolchain
|
- name: Install rust toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ on:
|
|||||||
- cron: '5 9 * * *'
|
- cron: '5 9 * * *'
|
||||||
jobs:
|
jobs:
|
||||||
cargo-deny:
|
cargo-deny:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository code
|
- name: Checkout repository code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -38,7 +38,7 @@ jobs:
|
|||||||
- name: install npm
|
- name: install npm
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
- 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
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-ubuntu-20.04]
|
platform: [custom-ubuntu-22.04]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
|
|||||||
@@ -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,15 +14,11 @@ 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:
|
||||||
release_id: ${{ steps.create-release.outputs.id }}
|
release_tag: ${{ github.ref_name }}
|
||||||
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
|
||||||
version: ${{ steps.release-info.outputs.version }}
|
|
||||||
filename: ${{ steps.release-info.outputs.filename }}
|
|
||||||
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -30,11 +26,19 @@ 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: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
|
||||||
|
- 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: Install the Apple developer certificate for code signing
|
- name: Install the Apple developer certificate for code signing
|
||||||
env:
|
env:
|
||||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
@@ -64,11 +68,19 @@ jobs:
|
|||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- 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 }}
|
||||||
@@ -78,46 +90,48 @@ jobs:
|
|||||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }}
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }}
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
# Tauri v2 specific environment variables
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
run: yarn && yarn build
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
TAURI_NOTARIZATION_USERNAME: ${{ secrets.APPLE_ID }}
|
||||||
|
TAURI_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
|
TAURI_NOTARIZATION_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||||
|
run: |
|
||||||
|
yarn build-macx86
|
||||||
|
|
||||||
|
- name: Create app tarball
|
||||||
|
run: |
|
||||||
|
# Navigate to where the app bundle is and create the tarball
|
||||||
|
cd target/x86_64-apple-darwin/release/bundle/macos
|
||||||
|
echo "Creating tarball from app bundle"
|
||||||
|
tar -czf nym-wallet.app.tar.gz NymWallet.app
|
||||||
|
cd -
|
||||||
|
|
||||||
- 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
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
run: |
|
run: |
|
||||||
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
|
||||||
- id: create-release
|
- id: create-release
|
||||||
name: Upload to release based on tag name
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
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
|
|
||||||
continue-on-error: true
|
|
||||||
uses: easingthemes/ssh-deploy@main
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
|
||||||
ARGS: "-avzr"
|
|
||||||
SOURCE: "nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz"
|
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
|
|
||||||
EXCLUDE: "/dist/, /node_modules/"
|
|
||||||
|
|
||||||
push-release-data:
|
push-release-data:
|
||||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
uses: ./.github/workflows/release-calculate-hash.yml
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
needs: publish-tauri
|
needs: publish-tauri
|
||||||
with:
|
with:
|
||||||
release_tag: ${{ github.ref_name }}
|
release_tag: ${{ needs.publish-tauri.outputs.release_tag || github.ref_name }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
@@ -3,71 +3,108 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: nym-wallet
|
working-directory: nym-wallet
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-tauri:
|
publish-tauri:
|
||||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-ubuntu-20.04]
|
platform: [ubuntu-22.04]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
release_id: ${{ steps.create-release.outputs.id }}
|
release_tag: ${{ github.ref_name }}
|
||||||
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
|
||||||
version: ${{ steps.release-info.outputs.version }}
|
|
||||||
filename: ${{ steps.release-info.outputs.filename }}
|
|
||||||
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Tauri dependencies
|
- name: Install system dependencies
|
||||||
run: >
|
run: |
|
||||||
sudo apt-get update &&
|
sudo apt-get update && sudo apt-get install -y libdbus-1-dev libmnl-dev libnftnl-dev \
|
||||||
sudo apt-get install -y webkit2gtk-4.0
|
libwebkit2gtk-4.1-dev build-essential curl wget libssl-dev jq \
|
||||||
continue-on-error: true
|
libgtk-3-dev squashfs-tools libayatana-appindicator3-dev make libfuse2 unzip librsvg2-dev file \
|
||||||
|
libsoup-3.0-dev libjavascriptcoregtk-4.1-dev
|
||||||
|
|
||||||
- name: Node
|
- name: Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 21
|
||||||
|
cache: 'yarn'
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
|
||||||
- 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
|
- name: Install app dependencies
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|
||||||
- name: Create env file
|
- name: Create env file
|
||||||
uses: timheuer/base64-to-file@v1.2
|
uses: timheuer/base64-to-file@v1.2
|
||||||
with:
|
with:
|
||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
- name: Build app
|
- name: Build app
|
||||||
run: yarn build
|
run: yarn build
|
||||||
env:
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
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 }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Check bundle directory
|
||||||
|
run: |
|
||||||
|
echo "Checking bundle directory structure"
|
||||||
|
ls -la target/release/bundle || echo "Bundle directory not found"
|
||||||
|
if [ -d "target/release/bundle/appimage" ]; then
|
||||||
|
echo "AppImage bundle directory exists, checking contents:"
|
||||||
|
ls -la target/release/bundle/appimage
|
||||||
|
else
|
||||||
|
echo "AppImage bundle directory not found, checking alternatives:"
|
||||||
|
find target/release/bundle -type d -name "*appimage*" -o -name "*AppImage*" || echo "No AppImage directories found"
|
||||||
|
find target/release/bundle -name "*.AppImage" -o -name "*.appimage" || echo "No AppImage files found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create AppImage tarball if needed
|
||||||
|
run: |
|
||||||
|
# Find the AppImage file
|
||||||
|
APPIMAGE_FILE=$(find target/release/bundle -name "*.AppImage" | head -n 1)
|
||||||
|
if [ -n "$APPIMAGE_FILE" ]; then
|
||||||
|
echo "Found AppImage file: $APPIMAGE_FILE"
|
||||||
|
APPIMAGE_DIR=$(dirname "$APPIMAGE_FILE")
|
||||||
|
APPIMAGE_NAME=$(basename "$APPIMAGE_FILE")
|
||||||
|
|
||||||
|
# Create tarball if it doesn't exist
|
||||||
|
if [ ! -f "${APPIMAGE_FILE}.tar.gz" ]; then
|
||||||
|
echo "Creating tarball for $APPIMAGE_NAME"
|
||||||
|
cd "$APPIMAGE_DIR"
|
||||||
|
tar -czf "${APPIMAGE_NAME}.tar.gz" "$APPIMAGE_NAME"
|
||||||
|
cd -
|
||||||
|
echo "Created tarball: ${APPIMAGE_FILE}.tar.gz"
|
||||||
|
else
|
||||||
|
echo "Tarball already exists: ${APPIMAGE_FILE}.tar.gz"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "WARNING: No AppImage file found!"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: nym-wallet_1.0.0_amd64.AppImage.tar.gz
|
name: nym-wallet-appimage.tar.gz
|
||||||
path: nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz
|
path: |
|
||||||
|
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz
|
||||||
|
nym-wallet/target/release/bundle/*/nym-wallet*.AppImage.tar.gz
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- id: create-release
|
- id: create-release
|
||||||
name: Upload to release based on tag name
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
@@ -75,24 +112,26 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/appimage/*.AppImage
|
nym-wallet/target/release/bundle/appimage/*.AppImage
|
||||||
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz*
|
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz
|
||||||
|
nym-wallet/target/release/bundle/*/nym-wallet*.AppImage
|
||||||
- name: Deploy artifacts to CI www
|
nym-wallet/target/release/bundle/*/nym-wallet*.AppImage.tar.gz
|
||||||
continue-on-error: true
|
|
||||||
uses: easingthemes/ssh-deploy@main
|
- name: Find AppImage tarball path for deployment
|
||||||
env:
|
id: find-appimage
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
run: |
|
||||||
ARGS: "-avzr"
|
APPIMAGE_TARBALL=$(find target/release/bundle -name "*.AppImage.tar.gz" | head -n 1)
|
||||||
SOURCE: "nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz"
|
if [ -n "$APPIMAGE_TARBALL" ]; then
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
echo "Found AppImage tarball: $APPIMAGE_TARBALL"
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
echo "appimage_path=$APPIMAGE_TARBALL" >> $GITHUB_OUTPUT
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
|
else
|
||||||
EXCLUDE: "/dist/, /node_modules/"
|
echo "WARNING: No AppImage tarball found for deployment!"
|
||||||
|
echo "appimage_path=target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
push-release-data:
|
push-release-data:
|
||||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
uses: ./.github/workflows/release-calculate-hash.yml
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
needs: publish-tauri
|
needs: publish-tauri
|
||||||
with:
|
with:
|
||||||
release_tag: ${{ github.ref_name }}
|
release_tag: ${{ needs.publish-tauri.outputs.release_tag || github.ref_name }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
name: publish-nym-wallet-win11
|
name: publish-nym-wallet-win11
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
sign:
|
||||||
|
description: "Sign this build using SSL.com. Signing is billed per signature so be careful"
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
|
||||||
@@ -18,53 +24,61 @@ jobs:
|
|||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
release_id: ${{ steps.create-release.outputs.id }}
|
release_tag: ${{ github.ref_name }}
|
||||||
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
|
||||||
version: ${{ steps.release-info.outputs.version }}
|
|
||||||
filename: ${{ steps.release-info.outputs.filename }}
|
|
||||||
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean up first
|
|
||||||
continue-on-error: true
|
|
||||||
working-directory: .
|
|
||||||
run: |
|
|
||||||
cd ..
|
|
||||||
del /s /q /A:H nym
|
|
||||||
rmdir /s /q nym
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Import signing certificate
|
- name: Install Rust stable
|
||||||
env:
|
uses: dtolnay/rust-toolchain@stable
|
||||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
with:
|
||||||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
toolchain: stable
|
||||||
run: |
|
|
||||||
New-Item -ItemType directory -Path certificate
|
- name: Setup MSBuild.exe
|
||||||
Set-Content -Path certificate/tempCert.txt -Value $env:WINDOWS_CERTIFICATE
|
uses: microsoft/setup-msbuild@v2
|
||||||
certutil -decode certificate/tempCert.txt certificate/certificate.pfx
|
|
||||||
Remove-Item -path certificate -include tempCert.txt
|
|
||||||
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
|
|
||||||
|
|
||||||
- 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
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
|
|
||||||
- name: Create env file
|
|
||||||
uses: timheuer/base64-to-file@v1.2
|
|
||||||
with:
|
|
||||||
fileName: '.env'
|
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
|
||||||
|
|
||||||
- name: Install Yarn
|
|
||||||
run: npm install -g yarn
|
|
||||||
|
|
||||||
|
- name: Download EV CodeSignTool from ssl.com
|
||||||
|
working-directory: nym-wallet/src-tauri
|
||||||
|
if: ${{ inputs.sign }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
curl -L0 https://www.ssl.com/download/codesigntool-for-linux-and-macos/ -o codesigntool.zip
|
||||||
|
unzip codesigntool.zip
|
||||||
|
- name: Get EV certificate credential id
|
||||||
|
working-directory: nym-wallet/src-tauri
|
||||||
|
if: ${{ inputs.sign }}
|
||||||
|
id: get_credential_ids
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "SSL_COM_CREDENTIAL_ID=$(./CodeSignTool.sh get_credential_ids -username=${{ secrets.SSL_COM_USERNAME }} -password=${{ secrets.SSL_COM_PASSWORD }} | sed -n '1!p' | sed 's/- //')" >> "$GITHUB_OUTPUT"
|
||||||
|
- name: Add custom sign command to tauri.conf.json
|
||||||
|
working-directory: nym-wallet/src-tauri
|
||||||
|
if: ${{ inputs.sign }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
yq eval --inplace '.bundle.windows +=
|
||||||
|
{
|
||||||
|
"signCommand": {
|
||||||
|
"cmd": "C:\Program Files\Git\bin\bash.EXE",
|
||||||
|
"args": [
|
||||||
|
"/c/actions-runner/_work/nym/nym/nym-wallet/src-tauri/CodeSignTool.sh",
|
||||||
|
"sign",
|
||||||
|
"-username ${{ secrets.SSL_COM_USERNAME }}",
|
||||||
|
"-password ${{ secrets.SSL_COM_PASSWORD }}",
|
||||||
|
"-credential_id ${{ steps.get_credential_ids.outputs.SSL_COM_CREDENTIAL_ID }}",
|
||||||
|
"-totp_secret ${{ secrets.SSL_COM_TOTP_SECRET }}",
|
||||||
|
"-program_name NymWallet",
|
||||||
|
"-input_file_path",
|
||||||
|
"%1",
|
||||||
|
"-override"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}' tauri.conf.json
|
||||||
- name: Install project dependencies
|
- name: Install project dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cd .. && yarn --network-timeout 100000
|
run: cd .. && yarn --network-timeout 100000
|
||||||
@@ -77,18 +91,50 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }}
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
SSL_COM_USERNAME: ${{ inputs.sign && secrets.SSL_COM_USERNAME }}
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
SSL_COM_PASSWORD: ${{ inputs.sign && secrets.SSL_COM_PASSWORD }}
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
SSL_COM_CREDENTIAL_ID: ${{ inputs.sign && steps.get_credential_ids.outputs.SSL_COM_CREDENTIAL_ID }}
|
||||||
run: yarn build
|
SSL_COM_TOTP_SECRET: ${{ inputs.sign && secrets.SSL_COM_TOTP_SECRET }}
|
||||||
|
run: |
|
||||||
|
echo "Starting build process..."
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
- name: Check bundle directory
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "Checking bundle directory structure"
|
||||||
|
|
||||||
|
# Check standard location
|
||||||
|
if [ -d "target/release/bundle" ]; then
|
||||||
|
echo "Found bundle directory at standard location"
|
||||||
|
ls -la target/release/bundle || echo "Failed to list bundle directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check src-tauri location
|
||||||
|
if [ -d "src-tauri/target/release/bundle" ]; then
|
||||||
|
echo "Found bundle directory in src-tauri"
|
||||||
|
ls -la src-tauri/target/release/bundle || echo "Failed to list src-tauri bundle directory"
|
||||||
|
|
||||||
|
# Use this path for future steps
|
||||||
|
echo "BUNDLE_PATH=src-tauri/target/release/bundle" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "Using standard bundle path"
|
||||||
|
echo "BUNDLE_PATH=target/release/bundle" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for MSI files in any location
|
||||||
|
find . -name "*.msi" -type f
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: nym-wallet_1.0.0_x64_en-US.msi
|
name: nym-wallet.msi
|
||||||
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi
|
path: |
|
||||||
|
nym-wallet/${{ env.BUNDLE_PATH }}/msi/*.msi
|
||||||
|
nym-wallet/${{ env.BUNDLE_PATH }}/*/nym-wallet*.msi
|
||||||
|
nym-wallet/src-tauri/target/release/bundle/msi/*.msi
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- id: create-release
|
- id: create-release
|
||||||
@@ -97,25 +143,28 @@ jobs:
|
|||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/msi/*.msi
|
nym-wallet/${{ env.BUNDLE_PATH }}/msi/*.msi
|
||||||
nym-wallet/target/release/bundle/msi/*.msi.zip*
|
nym-wallet/${{ env.BUNDLE_PATH }}/msi/*.msi.zip*
|
||||||
|
nym-wallet/${{ env.BUNDLE_PATH }}/*/nym-wallet*.msi
|
||||||
- name: Deploy artifacts to CI www
|
nym-wallet/src-tauri/target/release/bundle/msi/*.msi
|
||||||
continue-on-error: true
|
|
||||||
uses: easingthemes/ssh-deploy@main
|
- name: Find MSI path for deployment
|
||||||
env:
|
id: find-msi
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
shell: bash
|
||||||
ARGS: "-avzr"
|
run: |
|
||||||
SOURCE: "nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi"
|
MSI_FILE=$(find . -name "*.msi" -type f | head -n 1)
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
if [ -n "$MSI_FILE" ]; then
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
echo "Found MSI file: $MSI_FILE"
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
|
echo "msi_path=$MSI_FILE" >> $GITHUB_OUTPUT
|
||||||
EXCLUDE: "/dist/, /node_modules/"
|
else
|
||||||
|
echo "WARNING: No MSI file found for deployment!"
|
||||||
|
echo "msi_path=${{ env.BUNDLE_PATH }}/msi/nym-wallet*.msi" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
push-release-data:
|
push-release-data:
|
||||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
uses: ./.github/workflows/release-calculate-hash.yml
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
needs: publish-tauri
|
needs: publish-tauri
|
||||||
with:
|
with:
|
||||||
release_tag: ${{ github.ref_name }}
|
release_tag: ${{ needs.publish-tauri.outputs.release_tag || github.ref_name }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
@@ -12,7 +12,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build APK
|
name: Build APK
|
||||||
runs-on: custom-ubuntu-20.04
|
runs-on: custom-ubuntu-22.04
|
||||||
env:
|
env:
|
||||||
ANDROID_HOME: ${{ github.workspace }}/android-sdk
|
ANDROID_HOME: ${{ github.workspace }}/android-sdk
|
||||||
NDK_VERSION: 25.2.9519653
|
NDK_VERSION: 25.2.9519653
|
||||||
@@ -49,7 +49,7 @@ 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: |
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Node
|
- name: Install Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
- uses: nymtech/nym/.github/actions/nym-hash-releases@develop
|
- uses: nymtech/nym/.github/actions/nym-hash-releases@develop
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
+184
-10
@@ -4,6 +4,180 @@ 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)
|
## [2025.4-dorina-patched] (2025-03-06)
|
||||||
|
|
||||||
- use legacy crypto for constructing SURB headers ([#5579])
|
- use legacy crypto for constructing SURB headers ([#5579])
|
||||||
@@ -160,7 +334,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
- Downgrade harmless log message from info to debug ([#5403])
|
- Downgrade harmless log message from info to debug ([#5403])
|
||||||
- Redirect from mixnode page to nodes page ([#5397])
|
- Redirect from mixnode page to nodes page ([#5397])
|
||||||
- chore :update version of chain watcher and validator rewarder ([#5394])
|
- chore :update version of chain watcher and validator rewarder ([#5394])
|
||||||
- bugfix: correctly handle ingore epoch roles flag ([#5390])
|
- bugfix: correctly handle ignore epoch roles flag ([#5390])
|
||||||
- bugfix: terminate mixnet socket listener on shutdown ([#5389])
|
- bugfix: terminate mixnet socket listener on shutdown ([#5389])
|
||||||
- feat: make client ignore dual mode nodes by default ([#5388])
|
- feat: make client ignore dual mode nodes by default ([#5388])
|
||||||
- Handle ecash network errors differently ([#5378])
|
- Handle ecash network errors differently ([#5378])
|
||||||
@@ -181,7 +355,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
- Use expect in geodata test to give error message on failure ([#5314])
|
- Use expect in geodata test to give error message on failure ([#5314])
|
||||||
- feature: periodically remove stale gateway messages ([#5312])
|
- feature: periodically remove stale gateway messages ([#5312])
|
||||||
- build(deps): bump the patch-updates group across 1 directory with 35 updates ([#5310])
|
- build(deps): bump the patch-updates group across 1 directory with 35 updates ([#5310])
|
||||||
- Add dependabot assignes for the root cargo ecosystem ([#5297])
|
- Add dependabot assigns for the root cargo ecosystem ([#5297])
|
||||||
- Move tun constants to network defaults ([#5286])
|
- Move tun constants to network defaults ([#5286])
|
||||||
- Include IPINFO_API_TOKEN in nightly CI ([#5285])
|
- Include IPINFO_API_TOKEN in nightly CI ([#5285])
|
||||||
- Nyx Chain Watcher ([#5274])
|
- Nyx Chain Watcher ([#5274])
|
||||||
@@ -234,7 +408,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [2025.1-reeses] (2025-01-15)
|
## [2025.1-reeses] (2025-01-15)
|
||||||
|
|
||||||
- Feture/legacy alert ([#5346])
|
- Feature, Future/legacy alert ([#5346])
|
||||||
- chore: readjusted --mode behaviour to fix the regression ([#5331])
|
- chore: readjusted --mode behaviour to fix the regression ([#5331])
|
||||||
- chore: apply 1.84 linter suggestions ([#5330])
|
- chore: apply 1.84 linter suggestions ([#5330])
|
||||||
- bugfix: make sure refresh data key matches bond info ([#5329])
|
- bugfix: make sure refresh data key matches bond info ([#5329])
|
||||||
@@ -314,7 +488,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [2024.14-crunch-patched] (2024-12-17)
|
## [2024.14-crunch-patched] (2024-12-17)
|
||||||
|
|
||||||
- Fixes an issue to allow previously registred clients to connect to latest nym-nodes
|
- Fixes an issue to allow previously registered clients to connect to latest nym-nodes
|
||||||
- Fixes compatibility issues between nym-nodes and older clients
|
- Fixes compatibility issues between nym-nodes and older clients
|
||||||
|
|
||||||
## [2024.14-crunch] (2024-12-11)
|
## [2024.14-crunch] (2024-12-11)
|
||||||
@@ -322,7 +496,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
- Merge/release/2024.14-crunch ([#5242])
|
- Merge/release/2024.14-crunch ([#5242])
|
||||||
- bugfix: added explicit openapi servers to account for route prefixes ([#5237])
|
- bugfix: added explicit openapi servers to account for route prefixes ([#5237])
|
||||||
- Further config score adjustments ([#5225])
|
- Further config score adjustments ([#5225])
|
||||||
- feature: remve any filtering on node semver ([#5224])
|
- feature: remove any filtering on node semver ([#5224])
|
||||||
- Backport #5218 ([#5220])
|
- Backport #5218 ([#5220])
|
||||||
- Derive serialize for UserAgent (#5210) ([#5217])
|
- Derive serialize for UserAgent (#5210) ([#5217])
|
||||||
- dont consider legacy nodes for rewarded set selection ([#5215])
|
- dont consider legacy nodes for rewarded set selection ([#5215])
|
||||||
@@ -501,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])
|
||||||
@@ -562,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])
|
||||||
|
|
||||||
@@ -946,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])
|
||||||
@@ -1567,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
|
||||||
|
|
||||||
@@ -2072,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
+768
-933
File diff suppressed because it is too large
Load Diff
+31
-36
@@ -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",
|
||||||
@@ -98,9 +97,9 @@ members = [
|
|||||||
"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",
|
||||||
"nym-api",
|
"nym-api",
|
||||||
@@ -153,7 +152,6 @@ members = [
|
|||||||
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-node",
|
"nym-node",
|
||||||
@@ -194,7 +192,7 @@ ammonia = "4"
|
|||||||
anyhow = "1.0.97"
|
anyhow = "1.0.97"
|
||||||
arc-swap = "1.7.1"
|
arc-swap = "1.7.1"
|
||||||
argon2 = "0.5.0"
|
argon2 = "0.5.0"
|
||||||
async-trait = "0.1.87"
|
async-trait = "0.1.88"
|
||||||
axum = "0.7.5"
|
axum = "0.7.5"
|
||||||
axum-client-ip = "0.6.1"
|
axum-client-ip = "0.6.1"
|
||||||
axum-extra = "0.9.4"
|
axum-extra = "0.9.4"
|
||||||
@@ -205,19 +203,19 @@ 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.6.1"
|
blake3 = "1.7.0"
|
||||||
bloomfilter = "1.0.14"
|
bloomfilter = "3.0.1"
|
||||||
bs58 = "0.5.1"
|
bs58 = "0.5.1"
|
||||||
bytecodec = "0.4.15"
|
bytecodec = "0.4.15"
|
||||||
bytes = "1.10.1"
|
bytes = "1.10.1"
|
||||||
cargo_metadata = "0.18.1"
|
cargo_metadata = "0.18.1"
|
||||||
celes = "2.5.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.40"
|
chrono = "0.4.40"
|
||||||
cipher = "0.4.3"
|
cipher = "0.4.3"
|
||||||
clap = "4.5.31"
|
clap = "4.5.34"
|
||||||
clap_complete = "4.5"
|
clap_complete = "4.5"
|
||||||
clap_complete_fig = "4.5"
|
clap_complete_fig = "4.5"
|
||||||
colored = "2.2"
|
colored = "2.2"
|
||||||
@@ -242,7 +240,7 @@ dotenvy = "0.15.6"
|
|||||||
ecdsa = "0.16"
|
ecdsa = "0.16"
|
||||||
ed25519-dalek = "2.1"
|
ed25519-dalek = "2.1"
|
||||||
encoding_rs = "0.8.35"
|
encoding_rs = "0.8.35"
|
||||||
env_logger = "0.11.6"
|
env_logger = "0.11.7"
|
||||||
envy = "0.4"
|
envy = "0.4"
|
||||||
etherparse = "0.13.0"
|
etherparse = "0.13.0"
|
||||||
eyre = "0.6.9"
|
eyre = "0.6.9"
|
||||||
@@ -264,7 +262,7 @@ http = "1"
|
|||||||
http-body-util = "0.1"
|
http-body-util = "0.1"
|
||||||
httpcodec = "0.2.3"
|
httpcodec = "0.2.3"
|
||||||
human-repr = "1.1.0"
|
human-repr = "1.1.0"
|
||||||
humantime = "2.1.0"
|
humantime = "2.2.0"
|
||||||
humantime-serde = "1.1.1"
|
humantime-serde = "1.1.1"
|
||||||
hyper = "1.6.0"
|
hyper = "1.6.0"
|
||||||
hyper-util = "0.1"
|
hyper-util = "0.1"
|
||||||
@@ -285,7 +283,7 @@ 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.3"
|
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"
|
||||||
@@ -304,10 +302,7 @@ 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_cors = "0.6.0"
|
|
||||||
rocket_okapi = "0.8.0"
|
|
||||||
rs_merkle = "1.5.0"
|
rs_merkle = "1.5.0"
|
||||||
safer-ffi = "0.1.13"
|
safer-ffi = "0.1.13"
|
||||||
schemars = "0.8.22"
|
schemars = "0.8.22"
|
||||||
@@ -322,7 +317,7 @@ 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.3.2"
|
sphinx-packet = "=0.5.0"
|
||||||
sqlx = "0.7.4"
|
sqlx = "0.7.4"
|
||||||
strum = "0.26"
|
strum = "0.26"
|
||||||
strum_macros = "0.26"
|
strum_macros = "0.26"
|
||||||
@@ -331,16 +326,16 @@ syn = "1"
|
|||||||
sysinfo = "0.33.0"
|
sysinfo = "0.33.0"
|
||||||
tap = "1.0.1"
|
tap = "1.0.1"
|
||||||
tar = "0.4.44"
|
tar = "0.4.44"
|
||||||
tempfile = "3.18"
|
tempfile = "3.19"
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
time = "0.3.39"
|
time = "0.3.41"
|
||||||
tokio = "1.44"
|
tokio = "1.44"
|
||||||
tokio-postgres = "0.7"
|
tokio-postgres = "0.7"
|
||||||
tokio-stream = "0.1.17"
|
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.13"
|
tokio-util = "0.7.14"
|
||||||
toml = "0.8.20"
|
toml = "0.8.20"
|
||||||
tower = "0.5.2"
|
tower = "0.5.2"
|
||||||
tower-http = "0.5.2"
|
tower-http = "0.5.2"
|
||||||
@@ -349,9 +344,10 @@ tracing-log = "0.2"
|
|||||||
tracing-opentelemetry = "0.19.0"
|
tracing-opentelemetry = "0.19.0"
|
||||||
tracing-subscriber = "0.3.19"
|
tracing-subscriber = "0.3.19"
|
||||||
tracing-tree = "0.2.2"
|
tracing-tree = "0.2.2"
|
||||||
|
tracing-indicatif = "0.3.9"
|
||||||
ts-rs = "10.1.0"
|
ts-rs = "10.1.0"
|
||||||
tungstenite = { version = "0.20.1", default-features = false }
|
tungstenite = { version = "0.20.1", default-features = false }
|
||||||
uniffi = "0.29.0"
|
uniffi = "0.29.1"
|
||||||
uniffi_build = "0.29.0"
|
uniffi_build = "0.29.0"
|
||||||
url = "2.5"
|
url = "2.5"
|
||||||
utoipa = "5.2"
|
utoipa = "5.2"
|
||||||
@@ -362,7 +358,7 @@ vergen = { version = "=8.3.1", default-features = false }
|
|||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
wasm-bindgen-test = "0.3.49"
|
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" }
|
||||||
|
|
||||||
@@ -376,19 +372,18 @@ 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.3", default-features = false }
|
bip32 = { version = "0.5.3", default-features = false }
|
||||||
@@ -403,7 +398,7 @@ prost = { version = "0.13", default-features = false }
|
|||||||
gloo-utils = "0.2.0"
|
gloo-utils = "0.2.0"
|
||||||
gloo-net = "0.6.0"
|
gloo-net = "0.6.0"
|
||||||
|
|
||||||
indexed_db_futures = "0.6.0"
|
indexed_db_futures = "0.6.1"
|
||||||
js-sys = "0.3.76"
|
js-sys = "0.3.76"
|
||||||
serde-wasm-bindgen = "0.6.5"
|
serde-wasm-bindgen = "0.6.5"
|
||||||
tsify = "0.4.5"
|
tsify = "0.4.5"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -67,3 +67,13 @@ As a general approach, licensing is as follows this pattern:
|
|||||||
- documentation is Apache 2.0 or CC0-1.0
|
- documentation is Apache 2.0 or CC0-1.0
|
||||||
|
|
||||||
Nym Node Operators and Validators Terms and Conditions can be found [here](https://nym.com/operators-validators-terms).
|
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.51"
|
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"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.51"
|
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"
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -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)]
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ 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 }
|
||||||
@@ -35,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,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
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ pub enum InputMessage {
|
|||||||
recipient: Recipient,
|
recipient: Recipient,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
|
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
|
||||||
@@ -43,6 +44,7 @@ pub enum InputMessage {
|
|||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
reply_surbs: u32,
|
reply_surbs: u32,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
|
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
|
||||||
@@ -53,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 {
|
||||||
@@ -92,6 +95,7 @@ impl InputMessage {
|
|||||||
recipient,
|
recipient,
|
||||||
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)
|
||||||
@@ -112,28 +116,7 @@ impl InputMessage {
|
|||||||
data,
|
data,
|
||||||
reply_surbs,
|
reply_surbs,
|
||||||
lane,
|
lane,
|
||||||
};
|
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>,
|
|
||||||
) -> Self {
|
|
||||||
let message = InputMessage::Anonymous {
|
|
||||||
recipient,
|
|
||||||
data,
|
|
||||||
reply_surbs,
|
|
||||||
lane,
|
|
||||||
};
|
};
|
||||||
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)
|
||||||
@@ -152,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)
|
||||||
@@ -169,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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ impl MixTrafficController {
|
|||||||
let (message_sender, message_receiver) =
|
let (message_sender, message_receiver) =
|
||||||
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
|
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
|
||||||
|
|
||||||
let (client_sender, client_receiver) = tokio::sync::mpsc::channel(1);
|
let (client_sender, client_receiver) = tokio::sync::mpsc::channel(8);
|
||||||
|
|
||||||
(
|
(
|
||||||
MixTrafficController {
|
MixTrafficController {
|
||||||
@@ -77,7 +77,7 @@ impl MixTrafficController {
|
|||||||
) {
|
) {
|
||||||
let (message_sender, message_receiver) =
|
let (message_sender, message_receiver) =
|
||||||
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
|
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
|
||||||
let (client_sender, client_receiver) = tokio::sync::mpsc::channel(1);
|
let (client_sender, client_receiver) = tokio::sync::mpsc::channel(8);
|
||||||
(
|
(
|
||||||
MixTrafficController {
|
MixTrafficController {
|
||||||
gateway_transceiver,
|
gateway_transceiver,
|
||||||
|
|||||||
-3
@@ -222,9 +222,6 @@ impl ActionController {
|
|||||||
|
|
||||||
// note: when the entry expires it's automatically removed from pending_acks_timers
|
// note: when the entry expires it's automatically removed from pending_acks_timers
|
||||||
fn handle_expired_ack_timer(&mut self, expired_ack: Expired<FragmentIdentifier>) {
|
fn handle_expired_ack_timer(&mut self, expired_ack: Expired<FragmentIdentifier>) {
|
||||||
// I'm honestly not sure how to handle it, because getting it means other things in our
|
|
||||||
// system are already misbehaving. If we ever see this panic, then I guess we should worry
|
|
||||||
// about it. Perhaps just reschedule it at later point?
|
|
||||||
let frag_id = expired_ack.into_inner();
|
let frag_id = expired_ack.into_inner();
|
||||||
|
|
||||||
trace!("{frag_id} has expired");
|
trace!("{frag_id} has expired");
|
||||||
|
|||||||
+59
-15
@@ -65,11 +65,12 @@ where
|
|||||||
recipient_tag: AnonymousSenderTag,
|
recipient_tag: AnonymousSenderTag,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) {
|
) {
|
||||||
// offload reply handling to the dedicated task
|
// offload reply handling to the dedicated task
|
||||||
if let Err(err) = self
|
if let Err(err) =
|
||||||
.reply_controller_sender
|
self.reply_controller_sender
|
||||||
.send_reply(recipient_tag, data, lane)
|
.send_reply(recipient_tag, data, lane, max_retransmissions)
|
||||||
{
|
{
|
||||||
if !self.task_client.is_shutdown_poll() {
|
if !self.task_client.is_shutdown_poll() {
|
||||||
error!("failed to send a reply - {err}");
|
error!("failed to send a reply - {err}");
|
||||||
@@ -83,10 +84,11 @@ where
|
|||||||
content: Vec<u8>,
|
content: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) {
|
) {
|
||||||
if let Err(err) = self
|
if let Err(err) = self
|
||||||
.message_handler
|
.message_handler
|
||||||
.try_send_plain_message(recipient, content, lane, packet_type)
|
.try_send_plain_message(recipient, content, lane, packet_type, max_retransmissions)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
warn!("failed to send a plain message - {err}")
|
warn!("failed to send a plain message - {err}")
|
||||||
@@ -100,10 +102,18 @@ where
|
|||||||
reply_surbs: u32,
|
reply_surbs: u32,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) {
|
) {
|
||||||
if let Err(err) = self
|
if let Err(err) = self
|
||||||
.message_handler
|
.message_handler
|
||||||
.try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane, packet_type)
|
.try_send_message_with_reply_surbs(
|
||||||
|
recipient,
|
||||||
|
content,
|
||||||
|
reply_surbs,
|
||||||
|
lane,
|
||||||
|
packet_type,
|
||||||
|
max_retransmissions,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
warn!("failed to send a repliable message - {err}")
|
warn!("failed to send a repliable message - {err}")
|
||||||
@@ -116,25 +126,42 @@ where
|
|||||||
recipient,
|
recipient,
|
||||||
data,
|
data,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions,
|
||||||
} => {
|
} => {
|
||||||
self.handle_plain_message(recipient, data, lane, PacketType::Mix)
|
self.handle_plain_message(
|
||||||
.await
|
recipient,
|
||||||
|
data,
|
||||||
|
lane,
|
||||||
|
PacketType::Mix,
|
||||||
|
max_retransmissions,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
InputMessage::Anonymous {
|
InputMessage::Anonymous {
|
||||||
recipient,
|
recipient,
|
||||||
data,
|
data,
|
||||||
reply_surbs,
|
reply_surbs,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions,
|
||||||
} => {
|
} => {
|
||||||
self.handle_repliable_message(recipient, data, reply_surbs, lane, PacketType::Mix)
|
self.handle_repliable_message(
|
||||||
.await
|
recipient,
|
||||||
|
data,
|
||||||
|
reply_surbs,
|
||||||
|
lane,
|
||||||
|
PacketType::Mix,
|
||||||
|
max_retransmissions,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
InputMessage::Reply {
|
InputMessage::Reply {
|
||||||
recipient_tag,
|
recipient_tag,
|
||||||
data,
|
data,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions,
|
||||||
} => {
|
} => {
|
||||||
self.handle_reply(recipient_tag, data, lane).await;
|
self.handle_reply(recipient_tag, data, lane, max_retransmissions)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
InputMessage::Premade { msgs, lane } => self.handle_premade_packets(msgs, lane).await,
|
InputMessage::Premade { msgs, lane } => self.handle_premade_packets(msgs, lane).await,
|
||||||
InputMessage::MessageWrapper {
|
InputMessage::MessageWrapper {
|
||||||
@@ -145,25 +172,42 @@ where
|
|||||||
recipient,
|
recipient,
|
||||||
data,
|
data,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions,
|
||||||
} => {
|
} => {
|
||||||
self.handle_plain_message(recipient, data, lane, packet_type)
|
self.handle_plain_message(
|
||||||
.await
|
recipient,
|
||||||
|
data,
|
||||||
|
lane,
|
||||||
|
packet_type,
|
||||||
|
max_retransmissions,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
InputMessage::Anonymous {
|
InputMessage::Anonymous {
|
||||||
recipient,
|
recipient,
|
||||||
data,
|
data,
|
||||||
reply_surbs,
|
reply_surbs,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions,
|
||||||
} => {
|
} => {
|
||||||
self.handle_repliable_message(recipient, data, reply_surbs, lane, packet_type)
|
self.handle_repliable_message(
|
||||||
.await
|
recipient,
|
||||||
|
data,
|
||||||
|
reply_surbs,
|
||||||
|
lane,
|
||||||
|
packet_type,
|
||||||
|
max_retransmissions,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
InputMessage::Reply {
|
InputMessage::Reply {
|
||||||
recipient_tag,
|
recipient_tag,
|
||||||
data,
|
data,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions,
|
||||||
} => {
|
} => {
|
||||||
self.handle_reply(recipient_tag, data, lane).await;
|
self.handle_reply(recipient_tag, data, lane, max_retransmissions)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
InputMessage::Premade { msgs, lane } => {
|
InputMessage::Premade { msgs, lane } => {
|
||||||
self.handle_premade_packets(msgs, lane).await
|
self.handle_premade_packets(msgs, lane).await
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ pub struct PendingAcknowledgement {
|
|||||||
delay: SphinxDelay,
|
delay: SphinxDelay,
|
||||||
destination: PacketDestination,
|
destination: PacketDestination,
|
||||||
retransmissions: u32,
|
retransmissions: u32,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PendingAcknowledgement {
|
impl PendingAcknowledgement {
|
||||||
@@ -80,12 +81,14 @@ impl PendingAcknowledgement {
|
|||||||
message_chunk: Fragment,
|
message_chunk: Fragment,
|
||||||
delay: SphinxDelay,
|
delay: SphinxDelay,
|
||||||
recipient: Recipient,
|
recipient: Recipient,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
PendingAcknowledgement {
|
PendingAcknowledgement {
|
||||||
message_chunk,
|
message_chunk,
|
||||||
delay,
|
delay,
|
||||||
destination: PacketDestination::KnownRecipient(recipient.into()),
|
destination: PacketDestination::KnownRecipient(recipient.into()),
|
||||||
retransmissions: 0,
|
retransmissions: 0,
|
||||||
|
max_retransmissions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +97,7 @@ impl PendingAcknowledgement {
|
|||||||
delay: SphinxDelay,
|
delay: SphinxDelay,
|
||||||
recipient_tag: AnonymousSenderTag,
|
recipient_tag: AnonymousSenderTag,
|
||||||
extra_surb_request: bool,
|
extra_surb_request: bool,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
PendingAcknowledgement {
|
PendingAcknowledgement {
|
||||||
message_chunk,
|
message_chunk,
|
||||||
@@ -103,6 +107,7 @@ impl PendingAcknowledgement {
|
|||||||
extra_surb_request,
|
extra_surb_request,
|
||||||
},
|
},
|
||||||
retransmissions: 0,
|
retransmissions: 0,
|
||||||
|
max_retransmissions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +123,18 @@ impl PendingAcknowledgement {
|
|||||||
self.delay = new_delay;
|
self.delay = new_delay;
|
||||||
self.retransmissions += 1;
|
self.retransmissions += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn reached_max_retransmissions(
|
||||||
|
&self,
|
||||||
|
global_max_retransmissions: Option<u32>,
|
||||||
|
) -> bool {
|
||||||
|
let reached_local_max = self
|
||||||
|
.max_retransmissions
|
||||||
|
.is_some_and(|limit| self.retransmissions >= limit);
|
||||||
|
let reached_global_max =
|
||||||
|
global_max_retransmissions.is_some_and(|limit| self.retransmissions >= limit);
|
||||||
|
reached_local_max || reached_global_max
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AcknowledgementControllerConnectors represents set of channels for communication with
|
/// AcknowledgementControllerConnectors represents set of channels for communication with
|
||||||
|
|||||||
+8
-10
@@ -79,17 +79,15 @@ where
|
|||||||
|
|
||||||
let frag_id = timed_out_ack.message_chunk.fragment_identifier();
|
let frag_id = timed_out_ack.message_chunk.fragment_identifier();
|
||||||
|
|
||||||
if let Some(limit) = self.maximum_retransmissions {
|
if timed_out_ack.reached_max_retransmissions(self.maximum_retransmissions) {
|
||||||
if timed_out_ack.retransmissions >= limit {
|
debug!("reached maximum number of allowed retransmissions for the packet");
|
||||||
warn!("reached maximum number of allowed retransmissions for the packet");
|
if let Err(err) = self
|
||||||
if let Err(err) = self
|
.action_sender
|
||||||
.action_sender
|
.unbounded_send(Action::new_remove(frag_id))
|
||||||
.unbounded_send(Action::new_remove(frag_id))
|
{
|
||||||
{
|
error!("Failed to send remove action to the controller: {err}");
|
||||||
error!("Failed to send remove action to the controller: {err}");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let maybe_prepared_fragment = match &timed_out_ack.destination {
|
let maybe_prepared_fragment = match &timed_out_ack.destination {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use crate::client::real_messages_control::real_traffic_stream::{
|
|||||||
BatchRealMessageSender, RealMessage,
|
BatchRealMessageSender, RealMessage,
|
||||||
};
|
};
|
||||||
use crate::client::real_messages_control::{AckActionSender, Action};
|
use crate::client::real_messages_control::{AckActionSender, Action};
|
||||||
|
use crate::client::replies::reply_controller::MaxRetransmissions;
|
||||||
use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags};
|
use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags};
|
||||||
use crate::client::topology_control::{TopologyAccessor, TopologyReadPermit};
|
use crate::client::topology_control::{TopologyAccessor, TopologyReadPermit};
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
@@ -142,6 +143,12 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) struct FragmentWithMaxRetransmissions {
|
||||||
|
pub(crate) fragment: Fragment,
|
||||||
|
pub(crate) max_retransmissions: MaxRetransmissions,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct MessageHandler<R> {
|
pub(crate) struct MessageHandler<R> {
|
||||||
config: Config,
|
config: Config,
|
||||||
@@ -198,10 +205,10 @@ where
|
|||||||
trace!("we already had sender tag for {recipient}");
|
trace!("we already had sender tag for {recipient}");
|
||||||
existing
|
existing
|
||||||
} else {
|
} else {
|
||||||
info!("creating new sender tag for {recipient}");
|
debug!("creating new sender tag for {recipient}");
|
||||||
let new_tag = AnonymousSenderTag::new_random(&mut self.rng);
|
let new_tag = AnonymousSenderTag::new_random(&mut self.rng);
|
||||||
self.tag_storage.insert_new(recipient, new_tag);
|
self.tag_storage.insert_new(recipient, new_tag);
|
||||||
info!("we'll be using {new_tag} for all anonymous messages sent to {recipient}");
|
info!("using {new_tag} for all anonymous messages sent to {recipient}");
|
||||||
new_tag
|
new_tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,8 +301,14 @@ where
|
|||||||
Some(chunk.fragment_identifier()),
|
Some(chunk.fragment_identifier()),
|
||||||
);
|
);
|
||||||
let delay = prepared_fragment.total_delay;
|
let delay = prepared_fragment.total_delay;
|
||||||
let pending_ack =
|
let max_retransmissions = None;
|
||||||
PendingAcknowledgement::new_anonymous(chunk, delay, target, is_extra_surb_request);
|
let pending_ack = PendingAcknowledgement::new_anonymous(
|
||||||
|
chunk,
|
||||||
|
delay,
|
||||||
|
target,
|
||||||
|
is_extra_surb_request,
|
||||||
|
max_retransmissions,
|
||||||
|
);
|
||||||
|
|
||||||
let lane = if is_extra_surb_request {
|
let lane = if is_extra_surb_request {
|
||||||
TransmissionLane::ReplySurbRequest
|
TransmissionLane::ReplySurbRequest
|
||||||
@@ -350,7 +363,7 @@ where
|
|||||||
pub(crate) async fn try_send_reply_chunks_on_lane(
|
pub(crate) async fn try_send_reply_chunks_on_lane(
|
||||||
&mut self,
|
&mut self,
|
||||||
target: AnonymousSenderTag,
|
target: AnonymousSenderTag,
|
||||||
fragments: Vec<Fragment>,
|
fragments: Vec<FragmentWithMaxRetransmissions>,
|
||||||
reply_surbs: Vec<ReplySurb>,
|
reply_surbs: Vec<ReplySurb>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
) -> Result<(), SurbWrappedPreparationError> {
|
) -> Result<(), SurbWrappedPreparationError> {
|
||||||
@@ -367,12 +380,12 @@ where
|
|||||||
pub(crate) async fn try_send_reply_chunks(
|
pub(crate) async fn try_send_reply_chunks(
|
||||||
&mut self,
|
&mut self,
|
||||||
target: AnonymousSenderTag,
|
target: AnonymousSenderTag,
|
||||||
fragments: Vec<(TransmissionLane, Fragment)>,
|
fragments: Vec<(TransmissionLane, FragmentWithMaxRetransmissions)>,
|
||||||
reply_surbs: Vec<ReplySurb>,
|
reply_surbs: Vec<ReplySurb>,
|
||||||
) -> Result<(), SurbWrappedPreparationError> {
|
) -> Result<(), SurbWrappedPreparationError> {
|
||||||
let prepared_fragments = self
|
let prepared_fragments = self
|
||||||
.prepare_reply_chunks_for_sending(
|
.prepare_reply_chunks_for_sending(
|
||||||
fragments.iter().map(|(_, f)| f.clone()).collect(),
|
fragments.iter().map(|(_, f)| f.fragment.clone()).collect(),
|
||||||
reply_surbs,
|
reply_surbs,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -382,12 +395,21 @@ where
|
|||||||
|
|
||||||
for (raw, prepared) in fragments.into_iter().zip(prepared_fragments.into_iter()) {
|
for (raw, prepared) in fragments.into_iter().zip(prepared_fragments.into_iter()) {
|
||||||
let lane = raw.0;
|
let lane = raw.0;
|
||||||
let fragment = raw.1;
|
let FragmentWithMaxRetransmissions {
|
||||||
|
fragment,
|
||||||
|
max_retransmissions,
|
||||||
|
} = raw.1;
|
||||||
|
|
||||||
let real_message =
|
let real_message =
|
||||||
RealMessage::new(prepared.mix_packet, Some(prepared.fragment_identifier));
|
RealMessage::new(prepared.mix_packet, Some(prepared.fragment_identifier));
|
||||||
let delay = prepared.total_delay;
|
let delay = prepared.total_delay;
|
||||||
let pending_ack = PendingAcknowledgement::new_anonymous(fragment, delay, target, false);
|
let pending_ack = PendingAcknowledgement::new_anonymous(
|
||||||
|
fragment,
|
||||||
|
delay,
|
||||||
|
target,
|
||||||
|
false,
|
||||||
|
max_retransmissions,
|
||||||
|
);
|
||||||
|
|
||||||
let entry = to_forward.entry(lane).or_default();
|
let entry = to_forward.entry(lane).or_default();
|
||||||
entry.push(real_message);
|
entry.push(real_message);
|
||||||
@@ -416,10 +438,17 @@ where
|
|||||||
message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) -> Result<(), PreparationError> {
|
) -> Result<(), PreparationError> {
|
||||||
let message = NymMessage::new_plain(message);
|
let message = NymMessage::new_plain(message);
|
||||||
self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type)
|
self.try_split_and_send_non_reply_message(
|
||||||
.await
|
message,
|
||||||
|
recipient,
|
||||||
|
lane,
|
||||||
|
packet_type,
|
||||||
|
max_retransmissions,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn try_split_and_send_non_reply_message(
|
pub(crate) async fn try_split_and_send_non_reply_message(
|
||||||
@@ -428,6 +457,7 @@ where
|
|||||||
recipient: Recipient,
|
recipient: Recipient,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) -> Result<(), PreparationError> {
|
) -> Result<(), PreparationError> {
|
||||||
debug!("Sending non-reply message with packet type {packet_type}");
|
debug!("Sending non-reply message with packet type {packet_type}");
|
||||||
// TODO: I really dislike existence of this assertion, it implies code has to be re-organised
|
// TODO: I really dislike existence of this assertion, it implies code has to be re-organised
|
||||||
@@ -467,7 +497,8 @@ where
|
|||||||
Some(fragment.fragment_identifier()),
|
Some(fragment.fragment_identifier()),
|
||||||
);
|
);
|
||||||
let delay = prepared_fragment.total_delay;
|
let delay = prepared_fragment.total_delay;
|
||||||
let pending_ack = PendingAcknowledgement::new_known(fragment, delay, recipient);
|
let pending_ack =
|
||||||
|
PendingAcknowledgement::new_known(fragment, delay, recipient, max_retransmissions);
|
||||||
|
|
||||||
real_messages.push(real_message);
|
real_messages.push(real_message);
|
||||||
pending_acks.push(pending_ack);
|
pending_acks.push(pending_ack);
|
||||||
@@ -495,11 +526,15 @@ where
|
|||||||
reply_surbs,
|
reply_surbs,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// When sending SURBs we want to retransmit
|
||||||
|
let max_retransmissions = None;
|
||||||
|
|
||||||
self.try_split_and_send_non_reply_message(
|
self.try_split_and_send_non_reply_message(
|
||||||
message,
|
message,
|
||||||
recipient,
|
recipient,
|
||||||
TransmissionLane::AdditionalReplySurbs,
|
TransmissionLane::AdditionalReplySurbs,
|
||||||
packet_type,
|
packet_type,
|
||||||
|
max_retransmissions,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -516,6 +551,7 @@ where
|
|||||||
num_reply_surbs: u32,
|
num_reply_surbs: u32,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) -> Result<(), SurbWrappedPreparationError> {
|
) -> Result<(), SurbWrappedPreparationError> {
|
||||||
debug!("Sending message with reply SURBs with packet type {packet_type}");
|
debug!("Sending message with reply SURBs with packet type {packet_type}");
|
||||||
let sender_tag = self.get_or_create_sender_tag(&recipient);
|
let sender_tag = self.get_or_create_sender_tag(&recipient);
|
||||||
@@ -526,8 +562,14 @@ where
|
|||||||
let message =
|
let message =
|
||||||
NymMessage::new_repliable(RepliableMessage::new_data(message, sender_tag, reply_surbs));
|
NymMessage::new_repliable(RepliableMessage::new_data(message, sender_tag, reply_surbs));
|
||||||
|
|
||||||
self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type)
|
self.try_split_and_send_non_reply_message(
|
||||||
.await?;
|
message,
|
||||||
|
recipient,
|
||||||
|
lane,
|
||||||
|
packet_type,
|
||||||
|
max_retransmissions,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
log::trace!("storing {} reply keys", reply_keys.len());
|
log::trace!("storing {} reply keys", reply_keys.len());
|
||||||
self.reply_key_storage.insert_multiple(reply_keys);
|
self.reply_key_storage.insert_multiple(reply_keys);
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ impl RealMessagesController<OsRng> {
|
|||||||
let rng = OsRng;
|
let rng = OsRng;
|
||||||
|
|
||||||
// create channels for inter-task communication
|
// create channels for inter-task communication
|
||||||
let (real_message_sender, real_message_receiver) = tokio::sync::mpsc::channel(1);
|
let (real_message_sender, real_message_receiver) = tokio::sync::mpsc::channel(8);
|
||||||
let (sent_notifier_tx, sent_notifier_rx) = mpsc::unbounded();
|
let (sent_notifier_tx, sent_notifier_rx) = mpsc::unbounded();
|
||||||
let (ack_action_tx, ack_action_rx) = mpsc::unbounded();
|
let (ack_action_tx, ack_action_rx) = mpsc::unbounded();
|
||||||
let ack_controller_connectors = AcknowledgementControllerConnectors::new(
|
let ack_controller_connectors = AcknowledgementControllerConnectors::new(
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ use nym_statistics_common::clients::{packet_statistics::PacketStatisticsEvent, C
|
|||||||
use nym_task::TaskClient;
|
use nym_task::TaskClient;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
// The interval at which we check for stale buffers
|
||||||
|
const STALE_BUFFER_CHECK_INTERVAL: Duration = Duration::from_secs(10);
|
||||||
|
|
||||||
// Buffer Requests to say "hey, send any reconstructed messages to this channel"
|
// Buffer Requests to say "hey, send any reconstructed messages to this channel"
|
||||||
// or to say "hey, I'm going offline, don't send anything more to me. Just buffer them instead"
|
// or to say "hey, I'm going offline, don't send anything more to me. Just buffer them instead"
|
||||||
@@ -48,6 +52,9 @@ struct ReceivedMessagesBufferInner<R: MessageReceiver> {
|
|||||||
recently_reconstructed: HashSet<i32>,
|
recently_reconstructed: HashSet<i32>,
|
||||||
|
|
||||||
stats_tx: ClientStatsSender,
|
stats_tx: ClientStatsSender,
|
||||||
|
|
||||||
|
// Periodically check for stale buffers to clean up
|
||||||
|
last_stale_check: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
|
impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
|
||||||
@@ -96,9 +103,10 @@ impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
_ => unreachable!(
|
_ => {
|
||||||
"no other error kind should have been returned here! If so, it's a bug!"
|
error!("unexpected error occurred during message reconstruction: {err}");
|
||||||
),
|
None
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Ok(reconstruction_result) => match reconstruction_result {
|
Ok(reconstruction_result) => match reconstruction_result {
|
||||||
Some((reconstructed_message, used_sets)) => {
|
Some((reconstructed_message, used_sets)) => {
|
||||||
@@ -144,6 +152,16 @@ impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
|
|||||||
|
|
||||||
self.recover_from_fragment(fragment_data, raw_fragment_size)
|
self.recover_from_fragment(fragment_data, raw_fragment_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cleanup_stale_buffers(&mut self) {
|
||||||
|
let now = Instant::now();
|
||||||
|
if now - self.last_stale_check > STALE_BUFFER_CHECK_INTERVAL {
|
||||||
|
self.last_stale_check = now;
|
||||||
|
self.message_receiver
|
||||||
|
.reconstructor()
|
||||||
|
.cleanup_stale_buffers();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -172,6 +190,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
|||||||
message_sender: None,
|
message_sender: None,
|
||||||
recently_reconstructed: HashSet::new(),
|
recently_reconstructed: HashSet::new(),
|
||||||
stats_tx,
|
stats_tx,
|
||||||
|
last_stale_check: Instant::now(),
|
||||||
})),
|
})),
|
||||||
reply_key_storage,
|
reply_key_storage,
|
||||||
reply_controller_sender,
|
reply_controller_sender,
|
||||||
@@ -392,6 +411,11 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup stale buffers, if there are any fragments that simply never arrived.
|
||||||
|
// We do this here as part of handling new received fragments so that we can keep the event
|
||||||
|
// loop focused on processing new messages.
|
||||||
|
inner_guard.cleanup_stale_buffers();
|
||||||
|
|
||||||
drop(inner_guard);
|
drop(inner_guard);
|
||||||
|
|
||||||
if !completed_messages.is_empty() {
|
if !completed_messages.is_empty() {
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement;
|
use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement;
|
||||||
use crate::client::real_messages_control::message_handler::{MessageHandler, PreparationError};
|
use crate::client::real_messages_control::message_handler::{
|
||||||
|
FragmentWithMaxRetransmissions, MessageHandler, PreparationError,
|
||||||
|
};
|
||||||
use crate::client::replies::reply_storage::CombinedReplyStorage;
|
use crate::client::replies::reply_storage::CombinedReplyStorage;
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
@@ -10,7 +12,7 @@ use log::{debug, error, info, trace, warn};
|
|||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||||
use nym_sphinx::anonymous_replies::ReplySurb;
|
use nym_sphinx::anonymous_replies::ReplySurb;
|
||||||
use nym_sphinx::chunking::fragment::{Fragment, FragmentIdentifier};
|
use nym_sphinx::chunking::fragment::FragmentIdentifier;
|
||||||
use nym_task::connections::{ConnectionId, TransmissionLane};
|
use nym_task::connections::{ConnectionId, TransmissionLane};
|
||||||
use nym_task::TaskClient;
|
use nym_task::TaskClient;
|
||||||
use rand::{CryptoRng, Rng};
|
use rand::{CryptoRng, Rng};
|
||||||
@@ -49,6 +51,8 @@ impl Config {
|
|||||||
// - replies to "give additional surbs" requests
|
// - replies to "give additional surbs" requests
|
||||||
// - will reply to future heartbeats
|
// - will reply to future heartbeats
|
||||||
|
|
||||||
|
pub type MaxRetransmissions = Option<u32>;
|
||||||
|
|
||||||
// TODO: this should be split into ingress and egress controllers
|
// TODO: this should be split into ingress and egress controllers
|
||||||
// because currently its trying to perform two distinct jobs
|
// because currently its trying to perform two distinct jobs
|
||||||
pub struct ReplyController<R> {
|
pub struct ReplyController<R> {
|
||||||
@@ -59,7 +63,8 @@ pub struct ReplyController<R> {
|
|||||||
// of surbs required to send the message through
|
// of surbs required to send the message through
|
||||||
// expected_reliability: f32,
|
// expected_reliability: f32,
|
||||||
request_receiver: ReplyControllerReceiver,
|
request_receiver: ReplyControllerReceiver,
|
||||||
pending_replies: HashMap<AnonymousSenderTag, TransmissionBuffer<Fragment>>,
|
pending_replies:
|
||||||
|
HashMap<AnonymousSenderTag, TransmissionBuffer<FragmentWithMaxRetransmissions>>,
|
||||||
|
|
||||||
/// Retransmission packets that have already timed out and are waiting for additional reply SURBs
|
/// Retransmission packets that have already timed out and are waiting for additional reply SURBs
|
||||||
/// so that they could be sent back to the network. Once we receive more SURBs, we should send them ASAP.
|
/// so that they could be sent back to the network. Once we receive more SURBs, we should send them ASAP.
|
||||||
@@ -96,7 +101,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_pending_replies<I: IntoIterator<Item = Fragment>>(
|
fn insert_pending_replies<I: IntoIterator<Item = FragmentWithMaxRetransmissions>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
recipient: &AnonymousSenderTag,
|
recipient: &AnonymousSenderTag,
|
||||||
fragments: I,
|
fragments: I,
|
||||||
@@ -112,7 +117,7 @@ where
|
|||||||
fn re_insert_pending_replies(
|
fn re_insert_pending_replies(
|
||||||
&mut self,
|
&mut self,
|
||||||
recipient: &AnonymousSenderTag,
|
recipient: &AnonymousSenderTag,
|
||||||
fragments: Vec<(TransmissionLane, Fragment)>,
|
fragments: Vec<(TransmissionLane, FragmentWithMaxRetransmissions)>,
|
||||||
) {
|
) {
|
||||||
trace!("re-inserting pending replies for {recipient}");
|
trace!("re-inserting pending replies for {recipient}");
|
||||||
// the buffer should ALWAYS exist at this point, if it doesn't, it's a bug...
|
// the buffer should ALWAYS exist at this point, if it doesn't, it's a bug...
|
||||||
@@ -205,6 +210,7 @@ where
|
|||||||
recipient_tag: AnonymousSenderTag,
|
recipient_tag: AnonymousSenderTag,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) {
|
) {
|
||||||
if !self
|
if !self
|
||||||
.full_reply_storage
|
.full_reply_storage
|
||||||
@@ -242,7 +248,14 @@ where
|
|||||||
.get_reply_surbs(&recipient_tag, max_to_send);
|
.get_reply_surbs(&recipient_tag, max_to_send);
|
||||||
|
|
||||||
if let Some(reply_surbs) = surbs {
|
if let Some(reply_surbs) = surbs {
|
||||||
let to_send = fragments.drain(..max_to_send).collect::<Vec<_>>();
|
let to_send = fragments
|
||||||
|
.drain(..max_to_send)
|
||||||
|
.map(|f| FragmentWithMaxRetransmissions {
|
||||||
|
fragment: f,
|
||||||
|
max_retransmissions,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if let Err(err) = self
|
if let Err(err) = self
|
||||||
.message_handler
|
.message_handler
|
||||||
.try_send_reply_chunks_on_lane(
|
.try_send_reply_chunks_on_lane(
|
||||||
@@ -276,6 +289,13 @@ where
|
|||||||
"buffering {no_fragments} fragments for {recipient_tag}",
|
"buffering {no_fragments} fragments for {recipient_tag}",
|
||||||
no_fragments = fragments.len()
|
no_fragments = fragments.len()
|
||||||
);
|
);
|
||||||
|
let fragments: Vec<_> = fragments
|
||||||
|
.into_iter()
|
||||||
|
.map(|fragment| FragmentWithMaxRetransmissions {
|
||||||
|
fragment,
|
||||||
|
max_retransmissions,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
self.insert_pending_replies(&recipient_tag, fragments, lane);
|
self.insert_pending_replies(&recipient_tag, fragments, lane);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +429,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
from: &AnonymousSenderTag,
|
from: &AnonymousSenderTag,
|
||||||
amount: usize,
|
amount: usize,
|
||||||
) -> Option<Vec<(TransmissionLane, Fragment)>> {
|
) -> Option<Vec<(TransmissionLane, FragmentWithMaxRetransmissions)>> {
|
||||||
// if possible, pop all pending replies, if not, pop only entries for which we'd have a reply surb
|
// if possible, pop all pending replies, if not, pop only entries for which we'd have a reply surb
|
||||||
let total = self.pending_replies.get(from)?.total_size();
|
let total = self.pending_replies.get(from)?.total_size();
|
||||||
trace!("pending queue has {total} elements");
|
trace!("pending queue has {total} elements");
|
||||||
@@ -689,7 +709,11 @@ where
|
|||||||
recipient,
|
recipient,
|
||||||
message,
|
message,
|
||||||
lane,
|
lane,
|
||||||
} => self.handle_send_reply(recipient, message, lane).await,
|
max_retransmissions,
|
||||||
|
} => {
|
||||||
|
self.handle_send_reply(recipient, message, lane, max_retransmissions)
|
||||||
|
.await
|
||||||
|
}
|
||||||
ReplyControllerMessage::AdditionalSurbs {
|
ReplyControllerMessage::AdditionalSurbs {
|
||||||
sender_tag,
|
sender_tag,
|
||||||
reply_surbs,
|
reply_surbs,
|
||||||
|
|||||||
@@ -66,12 +66,14 @@ impl ReplyControllerSender {
|
|||||||
recipient: AnonymousSenderTag,
|
recipient: AnonymousSenderTag,
|
||||||
message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
) -> Result<(), ReplyControllerSenderError> {
|
) -> Result<(), ReplyControllerSenderError> {
|
||||||
self.0
|
self.0
|
||||||
.unbounded_send(ReplyControllerMessage::SendReply {
|
.unbounded_send(ReplyControllerMessage::SendReply {
|
||||||
recipient,
|
recipient,
|
||||||
message,
|
message,
|
||||||
lane,
|
lane,
|
||||||
|
max_retransmissions,
|
||||||
})
|
})
|
||||||
.map_err(ReplyControllerSenderError::SendReply)
|
.map_err(ReplyControllerSenderError::SendReply)
|
||||||
}
|
}
|
||||||
@@ -160,6 +162,7 @@ pub enum ReplyControllerMessage {
|
|||||||
recipient: AnonymousSenderTag,
|
recipient: AnonymousSenderTag,
|
||||||
message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
lane: TransmissionLane,
|
lane: TransmissionLane,
|
||||||
|
max_retransmissions: Option<u32>,
|
||||||
},
|
},
|
||||||
|
|
||||||
AdditionalSurbs {
|
AdditionalSurbs {
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ pub(crate) async fn connect_async(
|
|||||||
// Do a DNS lookup for the domain using our custom DNS resolver
|
// Do a DNS lookup for the domain using our custom DNS resolver
|
||||||
resolver
|
resolver
|
||||||
.resolve_str(domain)
|
.resolve_str(domain)
|
||||||
.await
|
.await?
|
||||||
.inspect_err(|err| tracing::error!("Resolve error {err}"))?
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|a| SocketAddr::new(a, port))
|
.map(|a| SocketAddr::new(a, port))
|
||||||
.collect()
|
.collect()
|
||||||
@@ -50,27 +49,20 @@ pub(crate) async fn connect_async(
|
|||||||
address: endpoint.to_owned(),
|
address: endpoint.to_owned(),
|
||||||
});
|
});
|
||||||
for sock_addr in sock_addrs {
|
for sock_addr in sock_addrs {
|
||||||
tracing::info!("Trying with {sock_addr}");
|
|
||||||
let socket = if sock_addr.is_ipv4() {
|
let socket = if sock_addr.is_ipv4() {
|
||||||
TcpSocket::new_v4()
|
TcpSocket::new_v4()
|
||||||
} else {
|
} else {
|
||||||
TcpSocket::new_v6()
|
TcpSocket::new_v6()
|
||||||
}
|
}
|
||||||
.map_err(|err| {
|
.map_err(|err| GatewayClientError::NetworkConnectionFailed {
|
||||||
tracing::error!("Couldn't create the socket");
|
address: endpoint.to_owned(),
|
||||||
GatewayClientError::NetworkConnectionFailed {
|
source: err.into(),
|
||||||
address: endpoint.to_owned(),
|
|
||||||
source: err.into(),
|
|
||||||
}
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
tracing::info!("Preparing to call callback");
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
if let Some(callback) = connection_fd_callback.as_ref() {
|
if let Some(callback) = connection_fd_callback.as_ref() {
|
||||||
tracing::info!("Calling callback");
|
|
||||||
callback.as_ref()(socket.as_raw_fd());
|
callback.as_ref()(socket.as_raw_fd());
|
||||||
}
|
}
|
||||||
tracing::info!("Preparing to connect");
|
|
||||||
|
|
||||||
match socket.connect(sock_addr).await {
|
match socket.connect(sock_addr).await {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ use tracing::*;
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
initial_reconnection_backoff: Duration,
|
pub initial_reconnection_backoff: Duration,
|
||||||
maximum_reconnection_backoff: Duration,
|
pub maximum_reconnection_backoff: Duration,
|
||||||
initial_connection_timeout: Duration,
|
pub initial_connection_timeout: Duration,
|
||||||
maximum_connection_buffer_size: usize,
|
pub maximum_connection_buffer_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -50,7 +50,7 @@ pub trait SendWithoutResponse {
|
|||||||
// Without response in this context means we will not listen for anything we might get back (not
|
// Without response in this context means we will not listen for anything we might get back (not
|
||||||
// that we should get anything), including any possible io errors
|
// that we should get anything), including any possible io errors
|
||||||
fn send_without_response(
|
fn send_without_response(
|
||||||
&mut self,
|
&self,
|
||||||
address: NymNodeRoutingAddress,
|
address: NymNodeRoutingAddress,
|
||||||
packet: NymPacket,
|
packet: NymPacket,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
@@ -196,7 +196,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_connection(&mut self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) {
|
fn make_connection(&self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) {
|
||||||
let (sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size);
|
let (sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size);
|
||||||
|
|
||||||
// this CAN'T fail because we just created the channel which has a non-zero capacity
|
// this CAN'T fail because we just created the channel which has a non-zero capacity
|
||||||
@@ -247,7 +247,7 @@ impl Client {
|
|||||||
|
|
||||||
impl SendWithoutResponse for Client {
|
impl SendWithoutResponse for Client {
|
||||||
fn send_without_response(
|
fn send_without_response(
|
||||||
&mut self,
|
&self,
|
||||||
address: NymNodeRoutingAddress,
|
address: NymNodeRoutingAddress,
|
||||||
packet: NymPacket,
|
packet: NymPacket,
|
||||||
packet_type: PacketType,
|
packet_type: PacketType,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
|
|||||||
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
|
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
|
||||||
nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-contract" }
|
nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-contract" }
|
||||||
nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" }
|
nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" }
|
||||||
nym-coconut-bandwidth-contract-common = { path = "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
|
||||||
nym-ecash-contract-common = { path = "../../cosmwasm-smart-contracts/ecash-contract" }
|
nym-ecash-contract-common = { path = "../../cosmwasm-smart-contracts/ecash-contract" }
|
||||||
nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
|
nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
|
||||||
nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
|
nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
|
||||||
@@ -56,7 +55,7 @@ cw4 = { workspace = true }
|
|||||||
cw-controllers = { workspace = true }
|
cw-controllers = { workspace = true }
|
||||||
prost = { workspace = true, default-features = false }
|
prost = { workspace = true, default-features = false }
|
||||||
flate2 = { workspace = true }
|
flate2 = { workspace = true }
|
||||||
sha2 = { version = "0.9.5" }
|
sha2 = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
zeroize = { workspace = true, features = ["zeroize_derive"] }
|
zeroize = { workspace = true, features = ["zeroize_derive"] }
|
||||||
cosmwasm-std = { workspace = true }
|
cosmwasm-std = { workspace = true }
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ use crate::{
|
|||||||
use nym_api_requests::ecash::models::{
|
use nym_api_requests::ecash::models::{
|
||||||
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
|
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
|
||||||
BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse,
|
BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse,
|
||||||
IssuedTicketbooksChallengeResponse, IssuedTicketbooksForResponse, VerifyEcashTicketBody,
|
IssuedTicketbooksChallengeCommitmentRequest, IssuedTicketbooksChallengeCommitmentResponse,
|
||||||
|
IssuedTicketbooksDataRequest, IssuedTicketbooksDataResponse, IssuedTicketbooksForCountResponse,
|
||||||
|
IssuedTicketbooksForResponse, VerifyEcashTicketBody,
|
||||||
};
|
};
|
||||||
use nym_api_requests::ecash::{
|
use nym_api_requests::ecash::{
|
||||||
BlindSignRequestBody, BlindedSignatureResponse, PartialCoinIndicesSignatureResponse,
|
BlindSignRequestBody, BlindedSignatureResponse, PartialCoinIndicesSignatureResponse,
|
||||||
@@ -25,15 +27,14 @@ use nym_api_requests::models::{
|
|||||||
use nym_api_requests::models::{LegacyDescribedGateway, MixNodeBondAnnotated};
|
use nym_api_requests::models::{LegacyDescribedGateway, MixNodeBondAnnotated};
|
||||||
use nym_api_requests::nym_nodes::{NodesByAddressesResponse, SkimmedNode};
|
use nym_api_requests::nym_nodes::{NodesByAddressesResponse, SkimmedNode};
|
||||||
use nym_coconut_dkg_common::types::EpochId;
|
use nym_coconut_dkg_common::types::EpochId;
|
||||||
use nym_ecash_contract_common::deposit::DepositId;
|
|
||||||
use nym_http_api_client::UserAgent;
|
use nym_http_api_client::UserAgent;
|
||||||
|
use nym_mixnet_contract_common::EpochRewardedSet;
|
||||||
use nym_network_defaults::NymNetworkDetails;
|
use nym_network_defaults::NymNetworkDetails;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use time::Date;
|
use time::Date;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub use crate::nym_api::NymApiClientExt;
|
pub use crate::nym_api::NymApiClientExt;
|
||||||
use nym_mixnet_contract_common::EpochRewardedSet;
|
|
||||||
pub use nym_mixnet_contract_common::{
|
pub use nym_mixnet_contract_common::{
|
||||||
mixnode::MixNodeDetails, GatewayBond, IdentityKey, IdentityKeyRef, NodeId, NymNodeDetails,
|
mixnode::MixNodeDetails, GatewayBond, IdentityKey, IdentityKeyRef, NodeId, NymNodeDetails,
|
||||||
};
|
};
|
||||||
@@ -701,17 +702,33 @@ impl NymApiClient {
|
|||||||
Ok(self.nym_api.issued_ticketbooks_for(expiration_date).await?)
|
Ok(self.nym_api.issued_ticketbooks_for(expiration_date).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn issued_ticketbooks_challenge(
|
pub async fn issued_ticketbooks_for_count(
|
||||||
&self,
|
&self,
|
||||||
expiration_date: Date,
|
expiration_date: Date,
|
||||||
deposits: Vec<DepositId>,
|
) -> Result<IssuedTicketbooksForCountResponse, ValidatorClientError> {
|
||||||
) -> Result<IssuedTicketbooksChallengeResponse, ValidatorClientError> {
|
|
||||||
Ok(self
|
Ok(self
|
||||||
.nym_api
|
.nym_api
|
||||||
.issued_ticketbooks_challenge(expiration_date, deposits)
|
.issued_ticketbooks_for_count(expiration_date)
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn issued_ticketbooks_challenge_commitment(
|
||||||
|
&self,
|
||||||
|
request: &IssuedTicketbooksChallengeCommitmentRequest,
|
||||||
|
) -> Result<IssuedTicketbooksChallengeCommitmentResponse, ValidatorClientError> {
|
||||||
|
Ok(self
|
||||||
|
.nym_api
|
||||||
|
.issued_ticketbooks_challenge_commitment(request)
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn issued_ticketbooks_data(
|
||||||
|
&self,
|
||||||
|
request: &IssuedTicketbooksDataRequest,
|
||||||
|
) -> Result<IssuedTicketbooksDataResponse, ValidatorClientError> {
|
||||||
|
Ok(self.nym_api.issued_ticketbooks_data(request).await?)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn nodes_by_addresses(
|
pub async fn nodes_by_addresses(
|
||||||
&self,
|
&self,
|
||||||
addresses: Vec<IpAddr>,
|
addresses: Vec<IpAddr>,
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ use async_trait::async_trait;
|
|||||||
use nym_api_requests::ecash::models::{
|
use nym_api_requests::ecash::models::{
|
||||||
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
|
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
|
||||||
BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse,
|
BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse,
|
||||||
IssuedTicketbooksChallengeRequest, IssuedTicketbooksChallengeResponse,
|
IssuedTicketbooksChallengeCommitmentRequest, IssuedTicketbooksChallengeCommitmentResponse,
|
||||||
|
IssuedTicketbooksDataRequest, IssuedTicketbooksDataResponse, IssuedTicketbooksForCountResponse,
|
||||||
IssuedTicketbooksForResponse, VerifyEcashTicketBody,
|
IssuedTicketbooksForResponse, VerifyEcashTicketBody,
|
||||||
};
|
};
|
||||||
use nym_api_requests::ecash::VerificationKeyResponse;
|
use nym_api_requests::ecash::VerificationKeyResponse;
|
||||||
@@ -36,10 +37,7 @@ pub use nym_api_requests::{
|
|||||||
nym_nodes::{CachedNodesResponse, SkimmedNode},
|
nym_nodes::{CachedNodesResponse, SkimmedNode},
|
||||||
NymNetworkDetailsResponse,
|
NymNetworkDetailsResponse,
|
||||||
};
|
};
|
||||||
pub use nym_coconut_dkg_common::types::EpochId;
|
|
||||||
use nym_contracts_common::IdentityKey;
|
use nym_contracts_common::IdentityKey;
|
||||||
use nym_ecash_contract_common::deposit::DepositId;
|
|
||||||
pub use nym_http_api_client::Client;
|
|
||||||
use nym_http_api_client::{ApiClient, NO_PARAMS};
|
use nym_http_api_client::{ApiClient, NO_PARAMS};
|
||||||
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
|
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
|
||||||
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, NodeId, NymNodeDetails};
|
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, NodeId, NymNodeDetails};
|
||||||
@@ -48,6 +46,9 @@ use time::format_description::BorrowedFormatItem;
|
|||||||
use time::Date;
|
use time::Date;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
pub use nym_coconut_dkg_common::types::EpochId;
|
||||||
|
pub use nym_http_api_client::Client;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
@@ -1012,22 +1013,52 @@ pub trait NymApiClientExt: ApiClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
async fn issued_ticketbooks_challenge(
|
async fn issued_ticketbooks_for_count(
|
||||||
&self,
|
&self,
|
||||||
expiration_date: Date,
|
expiration_date: Date,
|
||||||
deposits: Vec<DepositId>,
|
) -> Result<IssuedTicketbooksForCountResponse, NymAPIError> {
|
||||||
) -> Result<IssuedTicketbooksChallengeResponse, NymAPIError> {
|
self.get_json(
|
||||||
|
&[
|
||||||
|
routes::API_VERSION,
|
||||||
|
routes::ECASH_ROUTES,
|
||||||
|
routes::ECASH_ISSUED_TICKETBOOKS_FOR_COUNT,
|
||||||
|
&expiration_date.to_string(),
|
||||||
|
],
|
||||||
|
NO_PARAMS,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
async fn issued_ticketbooks_challenge_commitment(
|
||||||
|
&self,
|
||||||
|
request: &IssuedTicketbooksChallengeCommitmentRequest,
|
||||||
|
) -> Result<IssuedTicketbooksChallengeCommitmentResponse, NymAPIError> {
|
||||||
self.post_json(
|
self.post_json(
|
||||||
&[
|
&[
|
||||||
routes::API_VERSION,
|
routes::API_VERSION,
|
||||||
routes::ECASH_ROUTES,
|
routes::ECASH_ROUTES,
|
||||||
routes::ECASH_ISSUED_TICKETBOOKS_CHALLENGE,
|
routes::ECASH_ISSUED_TICKETBOOKS_CHALLENGE_COMMITMENT,
|
||||||
],
|
],
|
||||||
NO_PARAMS,
|
NO_PARAMS,
|
||||||
&IssuedTicketbooksChallengeRequest {
|
request,
|
||||||
expiration_date,
|
)
|
||||||
deposits,
|
.await
|
||||||
},
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
async fn issued_ticketbooks_data(
|
||||||
|
&self,
|
||||||
|
request: &IssuedTicketbooksDataRequest,
|
||||||
|
) -> Result<IssuedTicketbooksDataResponse, NymAPIError> {
|
||||||
|
self.post_json(
|
||||||
|
&[
|
||||||
|
routes::API_VERSION,
|
||||||
|
routes::ECASH_ROUTES,
|
||||||
|
routes::ECASH_ISSUED_TICKETBOOKS_DATA,
|
||||||
|
],
|
||||||
|
NO_PARAMS,
|
||||||
|
request,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,12 @@ pub mod ecash {
|
|||||||
pub const GLOBAL_COIN_INDICES_SIGNATURES: &str = "aggregated-coin-indices-signatures";
|
pub const GLOBAL_COIN_INDICES_SIGNATURES: &str = "aggregated-coin-indices-signatures";
|
||||||
pub const MASTER_VERIFICATION_KEY: &str = "master-verification-key";
|
pub const MASTER_VERIFICATION_KEY: &str = "master-verification-key";
|
||||||
pub const ECASH_ISSUED_TICKETBOOKS_FOR: &str = "issued-ticketbooks-for";
|
pub const ECASH_ISSUED_TICKETBOOKS_FOR: &str = "issued-ticketbooks-for";
|
||||||
pub const ECASH_ISSUED_TICKETBOOKS_CHALLENGE: &str = "issued-ticketbooks-challenge";
|
pub const ECASH_ISSUED_TICKETBOOKS_COUNT: &str = "issued-ticketbooks-count";
|
||||||
|
pub const ECASH_ISSUED_TICKETBOOKS_FOR_COUNT: &str = "issued-ticketbooks-for-count";
|
||||||
|
pub const ECASH_ISSUED_TICKETBOOKS_ON_COUNT: &str = "issued-ticketbooks-on-count";
|
||||||
|
pub const ECASH_ISSUED_TICKETBOOKS_CHALLENGE_COMMITMENT: &str =
|
||||||
|
"issued-ticketbooks-challenge-commitment";
|
||||||
|
pub const ECASH_ISSUED_TICKETBOOKS_DATA: &str = "issued-ticketbooks-data";
|
||||||
|
|
||||||
pub const EXPIRATION_DATE_PARAM: &str = "expiration_date";
|
pub const EXPIRATION_DATE_PARAM: &str = "expiration_date";
|
||||||
pub const EPOCH_ID_PARAM: &str = "epoch_id";
|
pub const EPOCH_ID_PARAM: &str = "epoch_id";
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl Div<GasPrice> for &Coin {
|
|||||||
panic!("attempted to divide by zero!")
|
panic!("attempted to divide by zero!")
|
||||||
};
|
};
|
||||||
|
|
||||||
let implicit_gas_limit = gas_price_inv * Uint128::new(self.amount);
|
let implicit_gas_limit = Uint128::new(self.amount).mul_floor(gas_price_inv);
|
||||||
if implicit_gas_limit.u128() >= u64::MAX as u128 {
|
if implicit_gas_limit.u128() >= u64::MAX as u128 {
|
||||||
u64::MAX
|
u64::MAX
|
||||||
} else {
|
} else {
|
||||||
@@ -169,13 +169,7 @@ impl CoinConverter for CosmosCoin {
|
|||||||
type Target = CosmWasmCoin;
|
type Target = CosmWasmCoin;
|
||||||
|
|
||||||
fn convert_coin(&self) -> Self::Target {
|
fn convert_coin(&self) -> Self::Target {
|
||||||
CosmWasmCoin::new(
|
CosmWasmCoin::new(self.amount, self.denom.to_string())
|
||||||
self.amount
|
|
||||||
.to_string()
|
|
||||||
.parse()
|
|
||||||
.expect("cosmos coin had an invalid amount assigned"),
|
|
||||||
self.denom.to_string(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-28
@@ -7,10 +7,10 @@ use crate::nyxd::error::NyxdError;
|
|||||||
use crate::nyxd::{Coin, Fee, SigningCosmWasmClient};
|
use crate::nyxd::{Coin, Fee, SigningCosmWasmClient};
|
||||||
use crate::signing::signer::OfflineSigner;
|
use crate::signing::signer::OfflineSigner;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cosmwasm_std::{to_binary, CosmosMsg, WasmMsg};
|
use cosmwasm_std::{CosmosMsg, Empty};
|
||||||
use cw3::Vote;
|
use cw3::Vote;
|
||||||
use cw4::{MemberChangedHookMsg, MemberDiff};
|
use cw4::{MemberChangedHookMsg, MemberDiff};
|
||||||
use nym_coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg;
|
use cw_utils::Expiration;
|
||||||
use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg;
|
use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg;
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||||
@@ -24,35 +24,23 @@ pub trait MultisigSigningClient: NymContractsProvider {
|
|||||||
funds: Vec<Coin>,
|
funds: Vec<Coin>,
|
||||||
) -> Result<ExecuteResult, NyxdError>;
|
) -> Result<ExecuteResult, NyxdError>;
|
||||||
|
|
||||||
async fn propose_release_funds(
|
async fn propose(
|
||||||
&self,
|
&self,
|
||||||
title: String,
|
title: String,
|
||||||
blinded_serial_number: String,
|
description: String,
|
||||||
voucher_value: Coin,
|
msgs: Vec<CosmosMsg<Empty>>,
|
||||||
|
latest: Option<Expiration>,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
let ecash_contract_address = self
|
|
||||||
.ecash_contract_address()
|
|
||||||
.ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?;
|
|
||||||
|
|
||||||
let release_funds_req = CoconutBandwidthExecuteMsg::ReleaseFunds {
|
|
||||||
funds: voucher_value.into(),
|
|
||||||
};
|
|
||||||
let release_funds_msg = CosmosMsg::Wasm(WasmMsg::Execute {
|
|
||||||
contract_addr: ecash_contract_address.to_string(),
|
|
||||||
msg: to_binary(&release_funds_req)?,
|
|
||||||
funds: vec![],
|
|
||||||
});
|
|
||||||
let req = MultisigExecuteMsg::Propose {
|
|
||||||
title,
|
|
||||||
description: blinded_serial_number,
|
|
||||||
msgs: vec![release_funds_msg],
|
|
||||||
latest: None,
|
|
||||||
};
|
|
||||||
self.execute_multisig_contract(
|
self.execute_multisig_contract(
|
||||||
fee,
|
fee,
|
||||||
req,
|
MultisigExecuteMsg::Propose {
|
||||||
"Multisig::Propose::Execute::ReleaseFunds".to_string(),
|
title,
|
||||||
|
description,
|
||||||
|
msgs,
|
||||||
|
latest,
|
||||||
|
},
|
||||||
|
"Multisig::Propose".to_string(),
|
||||||
vec![],
|
vec![],
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -161,7 +149,7 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue};
|
use crate::nyxd::contract_traits::tests::IgnoreValue;
|
||||||
|
|
||||||
// it's enough that this compiles and clippy is happy about it
|
// it's enough that this compiles and clippy is happy about it
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -171,9 +159,12 @@ mod tests {
|
|||||||
) {
|
) {
|
||||||
match msg {
|
match msg {
|
||||||
MultisigExecuteMsg::Propose {
|
MultisigExecuteMsg::Propose {
|
||||||
title, description, ..
|
title,
|
||||||
|
description,
|
||||||
|
msgs,
|
||||||
|
latest,
|
||||||
} => client
|
} => client
|
||||||
.propose_release_funds(title, description, mock_coin(), None)
|
.propose(title, description, msgs, latest, None)
|
||||||
.ignore(),
|
.ignore(),
|
||||||
MultisigExecuteMsg::Vote { proposal_id, vote } => {
|
MultisigExecuteMsg::Vote { proposal_id, vote } => {
|
||||||
client.vote(proposal_id, vote, None).ignore()
|
client.vote(proposal_id, vote, None).ignore()
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ impl Mul<Gas> for &GasPrice {
|
|||||||
|
|
||||||
fn mul(self, gas_limit: Gas) -> Self::Output {
|
fn mul(self, gas_limit: Gas) -> Self::Output {
|
||||||
let limit_uint128 = Uint128::from(gas_limit);
|
let limit_uint128 = Uint128::from(gas_limit);
|
||||||
let mut amount = self.amount * limit_uint128;
|
let mut amount = limit_uint128.mul_floor(self.amount);
|
||||||
|
|
||||||
let gas_price_numerator = self.amount.numerator();
|
let gas_price_numerator = self.amount.numerator();
|
||||||
let gas_price_denominator = self.amount.denominator();
|
let gas_price_denominator = self.amount.denominator();
|
||||||
@@ -35,7 +35,7 @@ impl Mul<Gas> for &GasPrice {
|
|||||||
// gas price is a fraction of the smallest fee token unit, so we must ensure that
|
// gas price is a fraction of the smallest fee token unit, so we must ensure that
|
||||||
// for any multiplication, we have rounded up
|
// for any multiplication, we have rounded up
|
||||||
//
|
//
|
||||||
// I don't really like the this solution as it has a theoretical chance of
|
// I don't really like this solution as it has a theoretical chance of
|
||||||
// overflowing (internally cosmwasm uses U256 to avoid that)
|
// overflowing (internally cosmwasm uses U256 to avoid that)
|
||||||
// however, realistically that is impossible to happen as the resultant value
|
// however, realistically that is impossible to happen as the resultant value
|
||||||
// would have to be way higher than our token limit of 10^15 (1 billion of tokens * 1 million for denomination)
|
// would have to be way higher than our token limit of 10^15 (1 billion of tokens * 1 million for denomination)
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ async fn fetch_delegation_data(
|
|||||||
match event.event.kind {
|
match event.event.kind {
|
||||||
// If a pending undelegate tx is found, remove it from delegation map
|
// If a pending undelegate tx is found, remove it from delegation map
|
||||||
PendingEpochEventKind::Undelegate { owner, node_id, .. } => {
|
PendingEpochEventKind::Undelegate { owner, node_id, .. } => {
|
||||||
if owner == address.as_ref()
|
if owner.as_str() == address.as_ref()
|
||||||
&& existing_delegation_map.contains_key(&node_id.to_string())
|
&& existing_delegation_map.contains_key(&node_id.to_string())
|
||||||
{
|
{
|
||||||
existing_delegation_map.remove(&node_id.to_string());
|
existing_delegation_map.remove(&node_id.to_string());
|
||||||
@@ -169,7 +169,7 @@ async fn fetch_delegation_data(
|
|||||||
amount,
|
amount,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if owner == address.as_ref() {
|
if owner.as_str() == address.as_ref() {
|
||||||
let mut amount = Coin::from(amount);
|
let mut amount = Coin::from(amount);
|
||||||
if let Some(pending_record) = pending_delegation_map.get(&node_id.to_string()) {
|
if let Some(pending_record) = pending_delegation_map.get(&node_id.to_string()) {
|
||||||
amount.amount += pending_record.amount;
|
amount.amount += pending_record.amount;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ pub async fn create(args: Args, client: SigningClient, network_details: &NymNetw
|
|||||||
|
|
||||||
let denom = network_details.chain_details.mix_denom.base.to_string();
|
let denom = network_details.chain_details.mix_denom.base.to_string();
|
||||||
|
|
||||||
let coin = Coin::new(args.amount.into(), &denom);
|
let coin = Coin::new(args.amount, &denom);
|
||||||
|
|
||||||
let res = client
|
let res = client
|
||||||
.create_periodic_vesting_account(
|
.create_periodic_vesting_account(
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nym-coconut-bandwidth-contract-common"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
license.workspace = true
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
cosmwasm-std = { workspace = true }
|
|
||||||
cosmwasm-schema = { workspace = true }
|
|
||||||
cw2 = { workspace = true, optional = true }
|
|
||||||
nym-multisig-contract-common = { path = "../multisig-contract" }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
schema = ["cw2"]
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use cosmwasm_schema::cw_serde;
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct DepositData {
|
|
||||||
deposit_info: String,
|
|
||||||
identity_key: String,
|
|
||||||
encryption_key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DepositData {
|
|
||||||
pub fn new(deposit_info: String, identity_key: String, encryption_key: String) -> Self {
|
|
||||||
DepositData {
|
|
||||||
deposit_info,
|
|
||||||
identity_key,
|
|
||||||
encryption_key,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deposit_info(&self) -> &str {
|
|
||||||
&self.deposit_info
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn identity_key(&self) -> &str {
|
|
||||||
&self.identity_key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn encryption_key(&self) -> &str {
|
|
||||||
&self.encryption_key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
pub const BANDWIDTH_PROPOSAL_ID: &str = "proposal_id";
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
// event types
|
|
||||||
pub const DEPOSITED_FUNDS_EVENT_TYPE: &str = "deposited-funds";
|
|
||||||
|
|
||||||
// attributes that are used in multiple places
|
|
||||||
pub const DEPOSIT_VALUE: &str = "deposit-value";
|
|
||||||
pub const DEPOSIT_INFO: &str = "deposit-info";
|
|
||||||
pub const DEPOSIT_IDENTITY_KEY: &str = "deposit-identity-key";
|
|
||||||
pub const DEPOSIT_ENCRYPTION_KEY: &str = "deposit-encryption-key";
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
pub mod deposit;
|
|
||||||
pub mod event_attributes;
|
|
||||||
pub mod events;
|
|
||||||
pub mod msg;
|
|
||||||
pub mod spend_credential;
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::{deposit::DepositData, spend_credential::SpendCredentialData};
|
|
||||||
use cosmwasm_schema::cw_serde;
|
|
||||||
use cosmwasm_std::Coin;
|
|
||||||
|
|
||||||
#[cfg(feature = "schema")]
|
|
||||||
use crate::spend_credential::{PagedSpendCredentialResponse, SpendCredentialResponse};
|
|
||||||
#[cfg(feature = "schema")]
|
|
||||||
use cosmwasm_schema::QueryResponses;
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct InstantiateMsg {
|
|
||||||
pub multisig_addr: String,
|
|
||||||
pub pool_addr: String,
|
|
||||||
pub mix_denom: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub enum ExecuteMsg {
|
|
||||||
DepositFunds { data: DepositData },
|
|
||||||
SpendCredential { data: SpendCredentialData },
|
|
||||||
ReleaseFunds { funds: Coin },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
#[cfg_attr(feature = "schema", derive(QueryResponses))]
|
|
||||||
pub enum QueryMsg {
|
|
||||||
#[cfg_attr(feature = "schema", returns(SpendCredentialResponse))]
|
|
||||||
GetSpentCredential { blinded_serial_number: String },
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "schema", returns(PagedSpendCredentialResponse))]
|
|
||||||
GetAllSpentCredentials {
|
|
||||||
limit: Option<u32>,
|
|
||||||
start_after: Option<String>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct MigrateMsg {}
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use cosmwasm_schema::cw_serde;
|
|
||||||
use cosmwasm_std::{from_binary, to_binary, Addr, Coin, CosmosMsg, StdResult, WasmMsg};
|
|
||||||
use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg;
|
|
||||||
|
|
||||||
use crate::msg::ExecuteMsg;
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct SpendCredentialData {
|
|
||||||
funds: Coin,
|
|
||||||
blinded_serial_number: String,
|
|
||||||
gateway_cosmos_address: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpendCredentialData {
|
|
||||||
pub fn new(funds: Coin, blinded_serial_number: String, gateway_cosmos_address: String) -> Self {
|
|
||||||
SpendCredentialData {
|
|
||||||
funds,
|
|
||||||
blinded_serial_number,
|
|
||||||
gateway_cosmos_address,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn funds(&self) -> &Coin {
|
|
||||||
&self.funds
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blinded_serial_number(&self) -> &str {
|
|
||||||
&self.blinded_serial_number
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gateway_cosmos_address(&self) -> &str {
|
|
||||||
&self.gateway_cosmos_address
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
#[derive(Copy)]
|
|
||||||
pub enum SpendCredentialStatus {
|
|
||||||
#[serde(alias = "InProgress")]
|
|
||||||
InProgress,
|
|
||||||
#[serde(alias = "Spent")]
|
|
||||||
Spent,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct SpendCredential {
|
|
||||||
funds: Coin,
|
|
||||||
blinded_serial_number: String,
|
|
||||||
gateway_cosmos_address: Addr,
|
|
||||||
status: SpendCredentialStatus,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpendCredential {
|
|
||||||
pub fn new(funds: Coin, blinded_serial_number: String, gateway_cosmos_address: Addr) -> Self {
|
|
||||||
SpendCredential {
|
|
||||||
funds,
|
|
||||||
blinded_serial_number,
|
|
||||||
gateway_cosmos_address,
|
|
||||||
status: SpendCredentialStatus::InProgress,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn blinded_serial_number(&self) -> &str {
|
|
||||||
&self.blinded_serial_number
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn status(&self) -> SpendCredentialStatus {
|
|
||||||
self.status
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mark_as_spent(&mut self) {
|
|
||||||
self.status = SpendCredentialStatus::Spent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct PagedSpendCredentialResponse {
|
|
||||||
pub spend_credentials: Vec<SpendCredential>,
|
|
||||||
pub per_page: usize,
|
|
||||||
|
|
||||||
/// Field indicating paging information for the following queries if the caller wishes to get further entries.
|
|
||||||
pub start_next_after: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PagedSpendCredentialResponse {
|
|
||||||
pub fn new(
|
|
||||||
spend_credentials: Vec<SpendCredential>,
|
|
||||||
per_page: usize,
|
|
||||||
start_next_after: Option<String>,
|
|
||||||
) -> Self {
|
|
||||||
PagedSpendCredentialResponse {
|
|
||||||
spend_credentials,
|
|
||||||
per_page,
|
|
||||||
start_next_after,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct SpendCredentialResponse {
|
|
||||||
pub spend_credential: Option<SpendCredential>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpendCredentialResponse {
|
|
||||||
pub fn new(spend_credential: Option<SpendCredential>) -> Self {
|
|
||||||
SpendCredentialResponse { spend_credential }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_cosmos_msg(
|
|
||||||
funds: Coin,
|
|
||||||
blinded_serial_number: String,
|
|
||||||
coconut_bandwidth_addr: String,
|
|
||||||
multisig_addr: String,
|
|
||||||
) -> StdResult<CosmosMsg> {
|
|
||||||
let release_funds_req = ExecuteMsg::ReleaseFunds { funds };
|
|
||||||
let release_funds_msg = CosmosMsg::Wasm(WasmMsg::Execute {
|
|
||||||
contract_addr: coconut_bandwidth_addr,
|
|
||||||
msg: to_binary(&release_funds_req)?,
|
|
||||||
funds: vec![],
|
|
||||||
});
|
|
||||||
let req = MultisigExecuteMsg::Propose {
|
|
||||||
title: String::from("Release funds, as ordered by Coconut Bandwidth Contract"),
|
|
||||||
description: blinded_serial_number,
|
|
||||||
msgs: vec![release_funds_msg],
|
|
||||||
latest: None,
|
|
||||||
};
|
|
||||||
let msg = CosmosMsg::Wasm(WasmMsg::Execute {
|
|
||||||
contract_addr: multisig_addr,
|
|
||||||
msg: to_binary(&req)?,
|
|
||||||
funds: vec![],
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn funds_from_cosmos_msgs(msgs: Vec<CosmosMsg>) -> Option<Coin> {
|
|
||||||
if let Some(CosmosMsg::Wasm(WasmMsg::Execute {
|
|
||||||
contract_addr: _,
|
|
||||||
msg,
|
|
||||||
funds: _,
|
|
||||||
})) = msgs.first()
|
|
||||||
{
|
|
||||||
if let Ok(ExecuteMsg::ReleaseFunds { funds }) = from_binary::<ExecuteMsg>(msg) {
|
|
||||||
return Some(funds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
@@ -219,7 +219,7 @@ impl Epoch {
|
|||||||
EpochState::VerificationKeyFinalization { .. } => {
|
EpochState::VerificationKeyFinalization { .. } => {
|
||||||
time_configuration.verification_key_finalization_time_secs
|
time_configuration.verification_key_finalization_time_secs
|
||||||
}
|
}
|
||||||
EpochState::InProgress { .. } => 0,
|
EpochState::InProgress => 0,
|
||||||
};
|
};
|
||||||
finish += adding;
|
finish += adding;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
use crate::msg::ExecuteMsg;
|
use crate::msg::ExecuteMsg;
|
||||||
use crate::types::{EpochId, NodeIndex};
|
use crate::types::{EpochId, NodeIndex};
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::{from_binary, to_binary, Addr, CosmosMsg, StdResult, Timestamp, WasmMsg};
|
use cosmwasm_std::{from_json, to_json_binary, Addr, CosmosMsg, StdResult, Timestamp, WasmMsg};
|
||||||
use cw_utils::Expiration;
|
use cw_utils::Expiration;
|
||||||
use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg;
|
use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg;
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ pub fn to_cosmos_msg(
|
|||||||
};
|
};
|
||||||
let verify_vk_share_msg = CosmosMsg::Wasm(WasmMsg::Execute {
|
let verify_vk_share_msg = CosmosMsg::Wasm(WasmMsg::Execute {
|
||||||
contract_addr: coconut_dkg_addr,
|
contract_addr: coconut_dkg_addr,
|
||||||
msg: to_binary(&verify_vk_share_req)?,
|
msg: to_json_binary(&verify_vk_share_req)?,
|
||||||
funds: vec![],
|
funds: vec![],
|
||||||
});
|
});
|
||||||
let req = MultisigExecuteMsg::Propose {
|
let req = MultisigExecuteMsg::Propose {
|
||||||
@@ -60,7 +60,7 @@ pub fn to_cosmos_msg(
|
|||||||
};
|
};
|
||||||
let msg = CosmosMsg::Wasm(WasmMsg::Execute {
|
let msg = CosmosMsg::Wasm(WasmMsg::Execute {
|
||||||
contract_addr: multisig_addr,
|
contract_addr: multisig_addr,
|
||||||
msg: to_binary(&req)?,
|
msg: to_json_binary(&req)?,
|
||||||
funds: vec![],
|
funds: vec![],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ pub fn owner_from_cosmos_msgs(msgs: &[CosmosMsg]) -> Option<String> {
|
|||||||
})) = msgs.first()
|
})) = msgs.first()
|
||||||
{
|
{
|
||||||
if let Ok(ExecuteMsg::VerifyVerificationKeyShare { owner, .. }) =
|
if let Ok(ExecuteMsg::VerifyVerificationKeyShare { owner, .. }) =
|
||||||
from_binary::<ExecuteMsg>(msg)
|
from_json::<ExecuteMsg>(msg)
|
||||||
{
|
{
|
||||||
return Some(owner);
|
return Some(owner);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use cosmwasm_std::{from_slice, to_vec, Addr, Coin, MessageInfo, StdResult};
|
use cosmwasm_std::{from_json, to_json_vec, Addr, Coin, MessageInfo, StdResult};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
@@ -164,7 +164,7 @@ where
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
to_vec(self)
|
to_json_vec(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_sha256_plaintext_digest(&self) -> StdResult<Vec<u8>>
|
pub fn to_sha256_plaintext_digest(&self) -> StdResult<Vec<u8>>
|
||||||
@@ -195,7 +195,7 @@ where
|
|||||||
where
|
where
|
||||||
T: DeserializeOwned,
|
T: DeserializeOwned,
|
||||||
{
|
{
|
||||||
from_slice(bytes)
|
from_json(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from_string(raw: &str) -> StdResult<SignableMessage<T>>
|
pub fn try_from_string(raw: &str) -> StdResult<SignableMessage<T>>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::Decimal;
|
|
||||||
use cosmwasm_std::OverflowError;
|
use cosmwasm_std::OverflowError;
|
||||||
use cosmwasm_std::Uint128;
|
use cosmwasm_std::Uint128;
|
||||||
|
use cosmwasm_std::{Decimal, Fraction};
|
||||||
use serde::de::Error;
|
use serde::de::Error;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
@@ -17,7 +17,7 @@ pub type IdentityKey = String;
|
|||||||
pub type IdentityKeyRef<'a> = &'a str;
|
pub type IdentityKeyRef<'a> = &'a str;
|
||||||
|
|
||||||
pub fn truncate_decimal(amount: Decimal) -> Uint128 {
|
pub fn truncate_decimal(amount: Decimal) -> Uint128 {
|
||||||
amount * Uint128::new(1)
|
Uint128::new(1).mul_floor(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@@ -113,11 +113,17 @@ impl Mul<Percent> for Decimal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<Uint128> for Percent {
|
impl Fraction<Uint128> for Percent {
|
||||||
type Output = Uint128;
|
fn numerator(&self) -> Uint128 {
|
||||||
|
self.0.numerator()
|
||||||
|
}
|
||||||
|
|
||||||
fn mul(self, rhs: Uint128) -> Self::Output {
|
fn denominator(&self) -> Uint128 {
|
||||||
self.0 * rhs
|
self.0.denominator()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inv(&self) -> Option<Self> {
|
||||||
|
Percent::new(self.0.inv()?).ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "easy-addr"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
license.workspace = true
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cosmwasm-std = { workspace = true }
|
||||||
|
quote = { workspace = true }
|
||||||
|
syn = { workspace = true, features = ["full", "printing", "extra-traits"] }
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
use cosmwasm_std::testing::MockApi;
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn addr(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as syn::LitStr).value();
|
||||||
|
let addr = MockApi::default().addr_make(input.as_str()).to_string();
|
||||||
|
TokenStream::from(quote! {#addr})
|
||||||
|
}
|
||||||
@@ -241,10 +241,10 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn gateway_bond_partial_ord() {
|
fn gateway_bond_partial_ord() {
|
||||||
let _150foos = Coin::new(150, "foo");
|
let _150foos = Coin::new(150u32, "foo");
|
||||||
let _140foos = Coin::new(140, "foo");
|
let _140foos = Coin::new(140u32, "foo");
|
||||||
let _50foos = Coin::new(50, "foo");
|
let _50foos = Coin::new(50u32, "foo");
|
||||||
let _0foos = Coin::new(0, "foo");
|
let _0foos = Coin::new(0u32, "foo");
|
||||||
|
|
||||||
let gate1 = GatewayBond {
|
let gate1 = GatewayBond {
|
||||||
pledge_amount: _150foos.clone(),
|
pledge_amount: _150foos.clone(),
|
||||||
|
|||||||
@@ -34,8 +34,10 @@ where
|
|||||||
{
|
{
|
||||||
fn into_base_decimal(self) -> StdResult<Decimal> {
|
fn into_base_decimal(self) -> StdResult<Decimal> {
|
||||||
let atomics = self.into();
|
let atomics = self.into();
|
||||||
Decimal::from_atomics(atomics, 0).map_err(|_| StdError::GenericErr {
|
Decimal::from_atomics(atomics, 0).map_err(|_| {
|
||||||
msg: format!("Decimal range exceeded for {atomics} with 0 decimal places."),
|
StdError::generic_err(format!(
|
||||||
|
"Decimal range exceeded for {atomics} with 0 decimal places."
|
||||||
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ impl<'a> PrimaryKey<'a> for Role {
|
|||||||
impl KeyDeserialize for Role {
|
impl KeyDeserialize for Role {
|
||||||
type Output = Role;
|
type Output = Role;
|
||||||
|
|
||||||
|
const KEY_ELEMS: u16 = 1;
|
||||||
|
|
||||||
fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
|
fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
|
||||||
let u8_key: <u8 as KeyDeserialize>::Output = <u8 as KeyDeserialize>::from_vec(value)?;
|
let u8_key: <u8 as KeyDeserialize>::Output = <u8 as KeyDeserialize>::from_vec(value)?;
|
||||||
Role::try_from(u8_key).map_err(|err| StdError::generic_err(err.to_string()))
|
Role::try_from(u8_key).map_err(|err| StdError::generic_err(err.to_string()))
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ mod tests {
|
|||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
fn base_simulator(initial_pledge: u128) -> Simulator {
|
fn base_simulator(initial_pledge: u128) -> Simulator {
|
||||||
let profit_margin = Percent::from_percentage_value(10).unwrap();
|
let profit_margin = Percent::from_percentage_value(10).unwrap();
|
||||||
let interval_operating_cost = Coin::new(40_000_000, "unym");
|
let interval_operating_cost = Coin::new(40_000_000u64, "unym");
|
||||||
let epochs_in_interval = 720u32;
|
let epochs_in_interval = 720u32;
|
||||||
let interval_pool_emission = Percent::from_percentage_value(2).unwrap();
|
let interval_pool_emission = Percent::from_percentage_value(2).unwrap();
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ mod tests {
|
|||||||
fn single_delegation_at_genesis() {
|
fn single_delegation_at_genesis() {
|
||||||
let mut simulator = base_simulator(10000_000000);
|
let mut simulator = base_simulator(10000_000000);
|
||||||
simulator
|
simulator
|
||||||
.delegate("alice", Coin::new(18000_000000, "unym"), 0)
|
.delegate("alice", Coin::new(18000_000000u64, "unym"), 0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let node_params = NodeRewardingParameters::new(
|
let node_params = NodeRewardingParameters::new(
|
||||||
@@ -393,7 +393,7 @@ mod tests {
|
|||||||
compare_decimals(rewards1.operator, expected_operator1, None);
|
compare_decimals(rewards1.operator, expected_operator1, None);
|
||||||
|
|
||||||
simulator
|
simulator
|
||||||
.delegate("alice", Coin::new(18000_000000, "unym"), 0)
|
.delegate("alice", Coin::new(18000_000000u64, "unym"), 0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let rewards2 = simulator.simulate_epoch_single_node(node_params).unwrap();
|
let rewards2 = simulator.simulate_epoch_single_node(node_params).unwrap();
|
||||||
@@ -439,10 +439,10 @@ mod tests {
|
|||||||
// add 2 delegations at genesis (because it makes things easier and as shown with previous tests
|
// add 2 delegations at genesis (because it makes things easier and as shown with previous tests
|
||||||
// delegating at different times still work)
|
// delegating at different times still work)
|
||||||
simulator
|
simulator
|
||||||
.delegate("alice", Coin::new(18000_000000, "unym"), 0)
|
.delegate("alice", Coin::new(18000_000000u64, "unym"), 0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("bob", Coin::new(4000_000000, "unym"), 0)
|
.delegate("bob", Coin::new(4000_000000u64, "unym"), 0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// "normal", sanity check rewarding
|
// "normal", sanity check rewarding
|
||||||
@@ -484,10 +484,10 @@ mod tests {
|
|||||||
// add 2 delegations at genesis (because it makes things easier and as shown with previous tests
|
// add 2 delegations at genesis (because it makes things easier and as shown with previous tests
|
||||||
// delegating at different times still work)
|
// delegating at different times still work)
|
||||||
simulator
|
simulator
|
||||||
.delegate("alice", Coin::new(18000_000000, "unym"), 0)
|
.delegate("alice", Coin::new(18000_000000u64, "unym"), 0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("bob", Coin::new(4000_000000, "unym"), 0)
|
.delegate("bob", Coin::new(4000_000000u64, "unym"), 0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// "normal", sanity check rewarding
|
// "normal", sanity check rewarding
|
||||||
@@ -553,12 +553,12 @@ mod tests {
|
|||||||
for epoch in 0..720 {
|
for epoch in 0..720 {
|
||||||
if epoch == 0 {
|
if epoch == 0 {
|
||||||
simulator
|
simulator
|
||||||
.delegate("a", Coin::new(18000_000000, "unym"), 0)
|
.delegate("a", Coin::new(18000_000000u64, "unym"), 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
if epoch == 42 {
|
if epoch == 42 {
|
||||||
simulator
|
simulator
|
||||||
.delegate("b", Coin::new(2000_000000, "unym"), 0)
|
.delegate("b", Coin::new(2000_000000u64, "unym"), 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
if epoch == 89 {
|
if epoch == 89 {
|
||||||
@@ -566,7 +566,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
if epoch == 123 {
|
if epoch == 123 {
|
||||||
simulator
|
simulator
|
||||||
.delegate("c", Coin::new(6666_000000, "unym"), 0)
|
.delegate("c", Coin::new(6666_000000u64, "unym"), 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
if epoch == 167 {
|
if epoch == 167 {
|
||||||
@@ -574,7 +574,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
if epoch == 245 {
|
if epoch == 245 {
|
||||||
simulator
|
simulator
|
||||||
.delegate("d", Coin::new(2050_000000, "unym"), 0)
|
.delegate("d", Coin::new(2050_000000u64, "unym"), 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
if epoch == 264 {
|
if epoch == 264 {
|
||||||
@@ -597,7 +597,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
if epoch == 545 {
|
if epoch == 545 {
|
||||||
simulator
|
simulator
|
||||||
.delegate("e", Coin::new(5000_000000, "unym"), 0)
|
.delegate("e", Coin::new(5000_000000u64, "unym"), 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,132 +666,132 @@ mod tests {
|
|||||||
|
|
||||||
let n0 = simulator
|
let n0 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(11_000_000_000000, "unym"),
|
Coin::new(11_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(1_000_000_000000, "unym"), n0)
|
.delegate("delegator", Coin::new(1_000_000_000000u64, "unym"), n0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n1 = simulator
|
let n1 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1_000_000_000000, "unym"),
|
Coin::new(1_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(11_000_000_000000, "unym"), n1)
|
.delegate("delegator", Coin::new(11_000_000_000000u64, "unym"), n1)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n2 = simulator
|
let n2 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1_000_000_000000, "unym"),
|
Coin::new(1_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(9_000_000_000000, "unym"), n2)
|
.delegate("delegator", Coin::new(9_000_000_000000u64, "unym"), n2)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n3 = simulator
|
let n3 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1_000_000_000000, "unym"),
|
Coin::new(1_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(0).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(0).unwrap(),
|
||||||
interval_operating_cost: Coin::new(500_000_000, "unym"),
|
interval_operating_cost: Coin::new(500_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(7_000_000_000000, "unym"), n3)
|
.delegate("delegator", Coin::new(7_000_000_000000u64, "unym"), n3)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n4 = simulator
|
let n4 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1000_000000, "unym"),
|
Coin::new(1000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(7_999_000_000000, "unym"), n4)
|
.delegate("delegator", Coin::new(7_999_000_000000u64, "unym"), n4)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n5 = simulator
|
let n5 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1_000_000_000000, "unym"),
|
Coin::new(1_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(7_000_000_000000, "unym"), n5)
|
.delegate("delegator", Coin::new(7_000_000_000000u64, "unym"), n5)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n6 = simulator
|
let n6 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(11_000_000_000000, "unym"),
|
Coin::new(11_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(1_000_000_000000, "unym"), n6)
|
.delegate("delegator", Coin::new(1_000_000_000000u64, "unym"), n6)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n7 = simulator
|
let n7 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1_000_000_000000, "unym"),
|
Coin::new(1_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(9_000_000_000000, "unym"), n7)
|
.delegate("delegator", Coin::new(9_000_000_000000u64, "unym"), n7)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n8 = simulator
|
let n8 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1_000_000_000000, "unym"),
|
Coin::new(1_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(0).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(0).unwrap(),
|
||||||
interval_operating_cost: Coin::new(500_000_000, "unym"),
|
interval_operating_cost: Coin::new(500_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(7_000_000_000000, "unym"), n8)
|
.delegate("delegator", Coin::new(7_000_000_000000u64, "unym"), n8)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let n9 = simulator
|
let n9 = simulator
|
||||||
.bond(
|
.bond(
|
||||||
Coin::new(1_000_000_000000, "unym"),
|
Coin::new(1_000_000_000000u64, "unym"),
|
||||||
NodeCostParams {
|
NodeCostParams {
|
||||||
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
profit_margin_percent: Percent::from_percentage_value(10).unwrap(),
|
||||||
interval_operating_cost: Coin::new(40_000_000, "unym"),
|
interval_operating_cost: Coin::new(40_000_000u64, "unym"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
simulator
|
simulator
|
||||||
.delegate("delegator", Coin::new(7_000_000_000000, "unym"), n9)
|
.delegate("delegator", Coin::new(7_000_000_000000u64, "unym"), n9)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let uptime_1 = Percent::from_percentage_value(100).unwrap();
|
let uptime_1 = Percent::from_percentage_value(100).unwrap();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use crate::ecash::error::EcashTicketError;
|
use crate::ecash::error::EcashTicketError;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use cosmwasm_std::{from_binary, CosmosMsg, WasmMsg};
|
use cosmwasm_std::{from_json, CosmosMsg, WasmMsg};
|
||||||
use nym_credentials_interface::VerificationKeyAuth;
|
use nym_credentials_interface::VerificationKeyAuth;
|
||||||
use nym_ecash_contract_common::msg::ExecuteMsg;
|
use nym_ecash_contract_common::msg::ExecuteMsg;
|
||||||
use nym_gateway_storage::GatewayStorage;
|
use nym_gateway_storage::GatewayStorage;
|
||||||
@@ -72,7 +72,7 @@ impl SharedState {
|
|||||||
let CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) = msg else {
|
let CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) = msg else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let Ok(ExecuteMsg::RedeemTickets { gw, .. }) = from_binary(msg) else {
|
let Ok(ExecuteMsg::RedeemTickets { gw, .. }) = from_json(msg) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ impl PublicKey {
|
|||||||
*self.0.as_bytes()
|
*self.0.as_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_bytes(&self) -> &[u8; PUBLIC_KEY_SIZE] {
|
||||||
|
self.0.as_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_bytes(b: &[u8]) -> Result<Self, KeyRecoveryError> {
|
pub fn from_bytes(b: &[u8]) -> Result<Self, KeyRecoveryError> {
|
||||||
if b.len() != PUBLIC_KEY_SIZE {
|
if b.len() != PUBLIC_KEY_SIZE {
|
||||||
return Err(KeyRecoveryError::InvalidSizePublicKey {
|
return Err(KeyRecoveryError::InvalidSizePublicKey {
|
||||||
@@ -228,7 +232,6 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
|
|||||||
PublicKey((&pk.0).into())
|
PublicKey((&pk.0).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for PrivateKey {
|
impl FromStr for PrivateKey {
|
||||||
type Err = KeyRecoveryError;
|
type Err = KeyRecoveryError;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use ed25519_dalek::{SecretKey, Signer, SigningKey};
|
|||||||
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
|
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
|
||||||
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
||||||
use std::fmt::{self, Debug, Display, Formatter};
|
use std::fmt::{self, Debug, Display, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||||
@@ -154,17 +153,9 @@ impl PemStorableKeyPair for KeyPair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ed25519 EdDSA Public Key
|
/// ed25519 EdDSA Public Key
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct PublicKey(ed25519_dalek::VerifyingKey);
|
pub struct PublicKey(ed25519_dalek::VerifyingKey);
|
||||||
|
|
||||||
impl Hash for PublicKey {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
// each public key has unique bytes representation which can be used
|
|
||||||
// for the hash implementation
|
|
||||||
self.to_bytes().hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for PublicKey {
|
impl Display for PublicKey {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
Display::fmt(&self.to_base58_string(), f)
|
Display::fmt(&self.to_base58_string(), f)
|
||||||
|
|||||||
@@ -16,3 +16,20 @@ pub mod bs58_ed25519_pubkey {
|
|||||||
PublicKey::from_base58_string(s).map_err(serde::de::Error::custom)
|
PublicKey::from_base58_string(s).map_err(serde::de::Error::custom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod bs58_ed25519_signature {
|
||||||
|
use crate::asymmetric::identity::Signature;
|
||||||
|
use serde::{Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub fn serialize<S: Serializer>(
|
||||||
|
signature: &Signature,
|
||||||
|
serializer: S,
|
||||||
|
) -> Result<S::Ok, S::Error> {
|
||||||
|
serializer.serialize_str(&signature.to_base58_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Signature, D::Error> {
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
Signature::from_base58_string(s).map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,11 +36,10 @@ use std::{
|
|||||||
|
|
||||||
use hickory_resolver::{
|
use hickory_resolver::{
|
||||||
config::{LookupIpStrategy, NameServerConfigGroup, ResolverConfig, ResolverOpts},
|
config::{LookupIpStrategy, NameServerConfigGroup, ResolverConfig, ResolverOpts},
|
||||||
error::ResolveError,
|
error::{ResolveError, ResolveErrorKind},
|
||||||
lookup_ip::LookupIpIntoIter,
|
lookup_ip::{LookupIp, LookupIpIntoIter},
|
||||||
TokioAsyncResolver,
|
TokioAsyncResolver,
|
||||||
};
|
};
|
||||||
use hickory_resolver::{error::ResolveErrorKind, lookup_ip::LookupIp};
|
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
|
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
@@ -214,10 +213,7 @@ impl HickoryDnsResolver {
|
|||||||
/// Create a new resolver with a custom DoT based configuration. The options are overridden to look
|
/// Create a new resolver with a custom DoT based configuration. The options are overridden to look
|
||||||
/// up for both IPv4 and IPv6 addresses to work with "happy eyeballs" algorithm.
|
/// up for both IPv4 and IPv6 addresses to work with "happy eyeballs" algorithm.
|
||||||
fn new_resolver() -> Result<TokioAsyncResolver, HickoryDnsError> {
|
fn new_resolver() -> Result<TokioAsyncResolver, HickoryDnsError> {
|
||||||
let mut name_servers = NameServerConfigGroup::google_tls();
|
let mut name_servers = NameServerConfigGroup::quad9_tls();
|
||||||
name_servers.merge(NameServerConfigGroup::google_https());
|
|
||||||
// name_servers.merge(NameServerConfigGroup::google_h3());
|
|
||||||
name_servers.merge(NameServerConfigGroup::quad9_tls());
|
|
||||||
name_servers.merge(NameServerConfigGroup::quad9_https());
|
name_servers.merge(NameServerConfigGroup::quad9_https());
|
||||||
name_servers.merge(NameServerConfigGroup::cloudflare_tls());
|
name_servers.merge(NameServerConfigGroup::cloudflare_tls());
|
||||||
name_servers.merge(NameServerConfigGroup::cloudflare_https());
|
name_servers.merge(NameServerConfigGroup::cloudflare_https());
|
||||||
|
|||||||
@@ -23,14 +23,12 @@ const LENGTH_PREFIX_SIZE: usize = 2;
|
|||||||
// long for the buffer to fill up, since this kills latency.
|
// long for the buffer to fill up, since this kills latency.
|
||||||
pub struct MultiIpPacketCodec {
|
pub struct MultiIpPacketCodec {
|
||||||
buffer: BytesMut,
|
buffer: BytesMut,
|
||||||
buffer_timeout: tokio::time::Interval,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MultiIpPacketCodec {
|
impl MultiIpPacketCodec {
|
||||||
pub fn new(buffer_timeout: Duration) -> Self {
|
pub fn new() -> Self {
|
||||||
MultiIpPacketCodec {
|
MultiIpPacketCodec {
|
||||||
buffer: BytesMut::new(),
|
buffer: BytesMut::new(),
|
||||||
buffer_timeout: tokio::time::interval(buffer_timeout),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,56 +38,81 @@ impl MultiIpPacketCodec {
|
|||||||
bundled_packets.extend_from_slice(&packet);
|
bundled_packets.extend_from_slice(&packet);
|
||||||
bundled_packets.freeze()
|
bundled_packets.freeze()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Append a packet to the buffer and return the buffer if it's full
|
impl Default for MultiIpPacketCodec {
|
||||||
pub fn append_packet(&mut self, packet: Bytes) -> Option<Bytes> {
|
fn default() -> Self {
|
||||||
let mut bundled_packets = BytesMut::new();
|
Self::new()
|
||||||
self.encode(packet, &mut bundled_packets).unwrap();
|
}
|
||||||
if bundled_packets.is_empty() {
|
}
|
||||||
None
|
|
||||||
} else {
|
/// The packet that we encode and decode with the MultiIpPacketCodec into bundled multi-ip packets.
|
||||||
// log::info!("Sphinx packet utilization: {:.2}", self.buffer.len() as f64 / MAX_PACKET_SIZE as f64);
|
/// The data here is the actual IP packet that we want to send, not the bundled packets.
|
||||||
Some(bundled_packets.freeze())
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum IprPacket {
|
||||||
|
Data(Bytes),
|
||||||
|
Flush,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IprPacket {
|
||||||
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
|
match self {
|
||||||
|
IprPacket::Data(bytes) => bytes.as_ref(),
|
||||||
|
IprPacket::Flush => &[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the current buffer and return it.
|
pub fn into_bytes(self) -> Bytes {
|
||||||
pub fn flush_current_buffer(&mut self) -> Bytes {
|
match self {
|
||||||
let mut output_buffer = BytesMut::new();
|
IprPacket::Data(bytes) => bytes,
|
||||||
std::mem::swap(&mut output_buffer, &mut self.buffer);
|
IprPacket::Flush => Bytes::new(),
|
||||||
output_buffer.freeze()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the buffer_timeout to tick and then flush the buffer.
|
|
||||||
// This is useful when we want to send the buffer even if it's not full.
|
|
||||||
pub async fn buffer_timeout(&mut self) -> Option<Bytes> {
|
|
||||||
// Wait for buffer_timeout to tick
|
|
||||||
let _ = self.buffer_timeout.tick().await;
|
|
||||||
|
|
||||||
// Flush the buffer and return it
|
|
||||||
let packets = self.flush_current_buffer();
|
|
||||||
if packets.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(packets)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encoder<Bytes> for MultiIpPacketCodec {
|
impl From<Bytes> for IprPacket {
|
||||||
|
fn from(bytes: Bytes) -> Self {
|
||||||
|
IprPacket::Data(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<u8>> for IprPacket {
|
||||||
|
fn from(bytes: Vec<u8>) -> Self {
|
||||||
|
IprPacket::Data(Bytes::from(bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encoder<IprPacket> for MultiIpPacketCodec {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn encode(&mut self, packet: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
fn encode(&mut self, packet: IprPacket, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||||
if self.buffer.is_empty() {
|
let packet = match packet {
|
||||||
self.buffer_timeout.reset();
|
IprPacket::Flush => {
|
||||||
}
|
dst.extend_from_slice(&self.buffer);
|
||||||
|
self.buffer = BytesMut::new();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
IprPacket::Data(packet) => packet,
|
||||||
|
};
|
||||||
|
|
||||||
let packet_size = packet.len();
|
let packet_size = packet.len();
|
||||||
|
|
||||||
|
// If the existing buffer is empty, and the packet is too large, send it directly
|
||||||
|
if self.buffer.is_empty() && packet_size + LENGTH_PREFIX_SIZE > MAX_PACKET_SIZE {
|
||||||
|
// Add the packet size
|
||||||
|
dst.extend_from_slice(&(packet_size as u16).to_be_bytes());
|
||||||
|
// Add the packet to the buffer
|
||||||
|
dst.extend_from_slice(&packet);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the packet doesn't fit in the existing buffer, send what we have now in the buffer
|
||||||
|
// and then add it to the next buffer
|
||||||
if self.buffer.len() + packet_size + LENGTH_PREFIX_SIZE > MAX_PACKET_SIZE {
|
if self.buffer.len() + packet_size + LENGTH_PREFIX_SIZE > MAX_PACKET_SIZE {
|
||||||
// If the packet doesn't fit in the buffer, send the buffer and then add it to the buffer
|
// Send the existing buffer
|
||||||
dst.extend_from_slice(&self.buffer);
|
dst.extend_from_slice(&self.buffer);
|
||||||
|
// Start a new buffer
|
||||||
self.buffer = BytesMut::new();
|
self.buffer = BytesMut::new();
|
||||||
self.buffer_timeout.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the packet size
|
// Add the packet size
|
||||||
@@ -103,7 +126,7 @@ impl Encoder<Bytes> for MultiIpPacketCodec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for MultiIpPacketCodec {
|
impl Decoder for MultiIpPacketCodec {
|
||||||
type Item = Bytes;
|
type Item = IprPacket;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||||
@@ -125,6 +148,86 @@ impl Decoder for MultiIpPacketCodec {
|
|||||||
// Read the packet
|
// Read the packet
|
||||||
let packet = src.split_to(packet_size);
|
let packet = src.split_to(packet_size);
|
||||||
|
|
||||||
Ok(Some(packet.freeze()))
|
Ok(Some(IprPacket::Data(packet.freeze())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multi_ip_packet_codec_max_packet_size() {
|
||||||
|
let mut codec = MultiIpPacketCodec::new();
|
||||||
|
let mut buffer = BytesMut::new();
|
||||||
|
|
||||||
|
// A packet size that is large enough that two packets won't fit in the buffer
|
||||||
|
const PACKET_SIZE: usize = MAX_PACKET_SIZE - 100;
|
||||||
|
|
||||||
|
let packet1 = IprPacket::from(Bytes::from_static(&[0u8; PACKET_SIZE]));
|
||||||
|
let packet2 = IprPacket::from(Bytes::from_static(&[0u8; PACKET_SIZE]));
|
||||||
|
|
||||||
|
codec.encode(packet1.clone(), &mut buffer).unwrap();
|
||||||
|
assert_eq!(buffer.len(), 0);
|
||||||
|
|
||||||
|
codec.encode(packet2.clone(), &mut buffer).unwrap();
|
||||||
|
assert_eq!(buffer.len(), LENGTH_PREFIX_SIZE + PACKET_SIZE);
|
||||||
|
|
||||||
|
// First is the length prefix
|
||||||
|
assert_eq!(buffer[..2], (PACKET_SIZE as u16).to_be_bytes());
|
||||||
|
// Next is the packet
|
||||||
|
assert_eq!(&buffer[2..], packet1.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn encode_and_then_decode() {
|
||||||
|
let mut codec = MultiIpPacketCodec::new();
|
||||||
|
let mut buffer = BytesMut::new();
|
||||||
|
|
||||||
|
let packet = IprPacket::from(Bytes::from_static(&[0u8; 1000]));
|
||||||
|
codec.encode(packet.clone(), &mut buffer).unwrap();
|
||||||
|
codec.encode(packet.clone(), &mut buffer).unwrap();
|
||||||
|
|
||||||
|
let mut decoded_packets = Vec::new();
|
||||||
|
while let Some(decoded_packet) = codec.decode(&mut buffer).unwrap() {
|
||||||
|
decoded_packets.push(decoded_packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(decoded_packets.len(), 1);
|
||||||
|
assert_eq!(decoded_packets[0].as_bytes(), packet.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn encode_a_packat_that_is_too_large() {
|
||||||
|
let mut codec = MultiIpPacketCodec::new();
|
||||||
|
let mut buffer = BytesMut::new();
|
||||||
|
|
||||||
|
let packet = IprPacket::from(Bytes::from_static(
|
||||||
|
&[0u8; MAX_PACKET_SIZE + MAX_PACKET_SIZE],
|
||||||
|
));
|
||||||
|
codec.encode(packet, &mut buffer).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
buffer.len(),
|
||||||
|
MAX_PACKET_SIZE + MAX_PACKET_SIZE + LENGTH_PREFIX_SIZE
|
||||||
|
);
|
||||||
|
codec.encode(IprPacket::Flush, &mut buffer).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
buffer.len(),
|
||||||
|
MAX_PACKET_SIZE + MAX_PACKET_SIZE + LENGTH_PREFIX_SIZE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_that_max_size_does_not_flush() {
|
||||||
|
let mut codec = MultiIpPacketCodec::new();
|
||||||
|
let mut buffer = BytesMut::new();
|
||||||
|
|
||||||
|
let packet = IprPacket::from(Bytes::from_static(&[0u8; MAX_PACKET_SIZE - 2]));
|
||||||
|
codec.encode(packet.clone(), &mut buffer).unwrap();
|
||||||
|
assert_eq!(buffer.len(), 0);
|
||||||
|
|
||||||
|
let packet = IprPacket::from(Bytes::from_static(&[0u8; MAX_PACKET_SIZE - 2]));
|
||||||
|
codec.encode(packet.clone(), &mut buffer).unwrap();
|
||||||
|
assert_eq!(buffer.len(), MAX_PACKET_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ pub enum MixProcessingError {
|
|||||||
#[error("failed to recover the expected SURB-Ack packet: {0}")]
|
#[error("failed to recover the expected SURB-Ack packet: {0}")]
|
||||||
MalformedSurbAck(#[from] SurbAckRecoveryError),
|
MalformedSurbAck(#[from] SurbAckRecoveryError),
|
||||||
|
|
||||||
#[error("the received packet was set to use the very old and very much deprecated 'VPN' mode")]
|
|
||||||
ReceivedOldTypeVpnPacket,
|
|
||||||
|
|
||||||
#[error("failed to process received Nym packet: {0}")]
|
#[error("failed to process received Nym packet: {0}")]
|
||||||
NymPacketProcessingError(#[from] PacketProcessingError),
|
NymPacketProcessingError(#[from] PacketProcessingError),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ pub const TICKETBOOK_VALIDITY_DAYS: u32 = 7;
|
|||||||
/// Specifies the number of tickets in each issued ticketbook.
|
/// Specifies the number of tickets in each issued ticketbook.
|
||||||
pub const TICKETBOOK_SIZE: u64 = 50;
|
pub const TICKETBOOK_SIZE: u64 = 50;
|
||||||
|
|
||||||
|
/// Specifies the minimum request size each signer must support
|
||||||
|
pub const MINIMUM_TICKETBOOK_DATA_REQUEST_SIZE: usize = 50;
|
||||||
|
|
||||||
/// This type is defined mostly for the purposes of having constants (like sizes) associated with given variants
|
/// This type is defined mostly for the purposes of having constants (like sizes) associated with given variants
|
||||||
/// It's not meant to be serialised or have any fancy traits defined on it (in this crate)
|
/// It's not meant to be serialised or have any fancy traits defined on it (in this crate)
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
@@ -34,32 +37,3 @@ impl TicketTypeRepr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constants for bloom filter for double spending detection
|
|
||||||
//Chosen for FP of
|
|
||||||
//Calculator at https://hur.st/bloomfilter/
|
|
||||||
pub const ECASH_DS_BLOOMFILTER_PARAMS: BloomfilterParameters = BloomfilterParameters {
|
|
||||||
num_hashes: 10,
|
|
||||||
bitmap_size: 1_500_000_000,
|
|
||||||
sip_keys: [
|
|
||||||
(12345678910111213141, 1415926535897932384),
|
|
||||||
(7182818284590452353, 3571113171923293137),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub struct BloomfilterParameters {
|
|
||||||
pub num_hashes: u32,
|
|
||||||
pub bitmap_size: u64,
|
|
||||||
pub sip_keys: [(u64, u64); 2],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BloomfilterParameters {
|
|
||||||
pub const fn byte_size(&self) -> u64 {
|
|
||||||
self.bitmap_size / 8
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn default_ecash() -> Self {
|
|
||||||
ECASH_DS_BLOOMFILTER_PARAMS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ pub enum NodeType {
|
|||||||
|
|
||||||
impl NodeType {
|
impl NodeType {
|
||||||
pub fn is_mixnode(&self) -> bool {
|
pub fn is_mixnode(&self) -> bool {
|
||||||
matches!(self, NodeType::Mixnode { .. })
|
matches!(self, NodeType::Mixnode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -363,6 +363,7 @@ impl MetricsController {
|
|||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn to_writer(&self, writer: &mut dyn std::io::Write) {
|
pub fn to_writer(&self, writer: &mut dyn std::io::Write) {
|
||||||
let metrics = self.gather();
|
let metrics = self.gather();
|
||||||
match writer.write_all(&metrics) {
|
match writer.write_all(&metrics) {
|
||||||
@@ -371,6 +372,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn register_int_gauge<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
pub fn register_int_gauge<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
||||||
let Some(metric) = Metric::new_int_gauge(name, help.into().unwrap_or(name)) else {
|
let Some(metric) = Metric::new_int_gauge(name, help.into().unwrap_or(name)) else {
|
||||||
return;
|
return;
|
||||||
@@ -378,6 +380,7 @@ impl MetricsController {
|
|||||||
self.register_metric(metric);
|
self.register_metric(metric);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn register_float_gauge<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
pub fn register_float_gauge<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
||||||
let Some(metric) = Metric::new_float_gauge(name, help.into().unwrap_or(name)) else {
|
let Some(metric) = Metric::new_float_gauge(name, help.into().unwrap_or(name)) else {
|
||||||
return;
|
return;
|
||||||
@@ -385,6 +388,7 @@ impl MetricsController {
|
|||||||
self.register_metric(metric);
|
self.register_metric(metric);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn register_int_counter<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
pub fn register_int_counter<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
||||||
let Some(metric) = Metric::new_int_counter(name, help.into().unwrap_or(name)) else {
|
let Some(metric) = Metric::new_int_counter(name, help.into().unwrap_or(name)) else {
|
||||||
return;
|
return;
|
||||||
@@ -392,6 +396,7 @@ impl MetricsController {
|
|||||||
self.register_metric(metric);
|
self.register_metric(metric);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn register_histogram<'a>(
|
pub fn register_histogram<'a>(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -404,6 +409,7 @@ impl MetricsController {
|
|||||||
self.register_metric(metric);
|
self.register_metric(metric);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set(&self, name: &str, value: i64) -> bool {
|
pub fn set(&self, name: &str, value: i64) -> bool {
|
||||||
if let Some(metric) = self.registry_index.get(name) {
|
if let Some(metric) = self.registry_index.get(name) {
|
||||||
metric.set(value);
|
metric.set(value);
|
||||||
@@ -413,6 +419,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_float(&self, name: &str, value: f64) -> bool {
|
pub fn set_float(&self, name: &str, value: f64) -> bool {
|
||||||
if let Some(metric) = self.registry_index.get(name) {
|
if let Some(metric) = self.registry_index.get(name) {
|
||||||
metric.set_float(value);
|
metric.set_float(value);
|
||||||
@@ -422,6 +429,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn add_to_histogram(&self, name: &str, value: f64) -> bool {
|
pub fn add_to_histogram(&self, name: &str, value: f64) -> bool {
|
||||||
if let Some(metric) = self.registry_index.get(name) {
|
if let Some(metric) = self.registry_index.get(name) {
|
||||||
metric.add_histogram_observation(value);
|
metric.add_histogram_observation(value);
|
||||||
@@ -431,12 +439,14 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn start_timer(&self, name: &str) -> Option<HistogramTimer> {
|
pub fn start_timer(&self, name: &str) -> Option<HistogramTimer> {
|
||||||
self.registry_index
|
self.registry_index
|
||||||
.get(name)
|
.get(name)
|
||||||
.and_then(|metric| metric.start_timer())
|
.and_then(|metric| metric.start_timer())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn inc(&self, name: &str) -> bool {
|
pub fn inc(&self, name: &str) -> bool {
|
||||||
if let Some(metric) = self.registry_index.get(name) {
|
if let Some(metric) = self.registry_index.get(name) {
|
||||||
metric.inc();
|
metric.inc();
|
||||||
@@ -446,6 +456,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn inc_by(&self, name: &str, value: i64) -> bool {
|
pub fn inc_by(&self, name: &str, value: i64) -> bool {
|
||||||
if let Some(metric) = self.registry_index.get(name) {
|
if let Some(metric) = self.registry_index.get(name) {
|
||||||
metric.inc_by(value);
|
metric.inc_by(value);
|
||||||
@@ -455,6 +466,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn maybe_register_and_set<'a>(
|
pub fn maybe_register_and_set<'a>(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -468,6 +480,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn maybe_register_and_set_float<'a>(
|
pub fn maybe_register_and_set_float<'a>(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -481,6 +494,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn maybe_register_and_add_to_histogram<'a>(
|
pub fn maybe_register_and_add_to_histogram<'a>(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -495,6 +509,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn maybe_register_and_inc<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
pub fn maybe_register_and_inc<'a>(&self, name: &str, help: impl Into<Option<&'a str>>) {
|
||||||
if !self.inc(name) {
|
if !self.inc(name) {
|
||||||
let help = help.into();
|
let help = help.into();
|
||||||
@@ -503,6 +518,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn maybe_register_and_inc_by<'a>(
|
pub fn maybe_register_and_inc_by<'a>(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -516,6 +532,7 @@ impl MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn register_metric(&self, metric: impl Into<Metric>) {
|
pub fn register_metric(&self, metric: impl Into<Metric>) {
|
||||||
let m = metric.into();
|
let m = metric.into();
|
||||||
let fq_name = m.fq_name();
|
let fq_name = m.fq_name();
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ pub fn issue(
|
|||||||
/// * `sk_user` - Secret key of the user.
|
/// * `sk_user` - Secret key of the user.
|
||||||
/// * `blind_signature` - Blinded signature received from the authority.
|
/// * `blind_signature` - Blinded signature received from the authority.
|
||||||
/// * `req_info` - Information associated with the request, including the joined commitment hash,
|
/// * `req_info` - Information associated with the request, including the joined commitment hash,
|
||||||
/// private attributes openings, v, and expiration date.
|
/// private attributes openings, v, and expiration date.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -269,9 +269,8 @@ pub fn check_vk_pairing(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rand::RngCore;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn polynomial_evaluation() {
|
fn polynomial_evaluation() {
|
||||||
|
|||||||
@@ -57,8 +57,6 @@ impl SurbAck {
|
|||||||
let packet_size = match packet_type {
|
let packet_size = match packet_type {
|
||||||
PacketType::Outfox => surb_ack_payload.len().max(MIN_PACKET_SIZE),
|
PacketType::Outfox => surb_ack_payload.len().max(MIN_PACKET_SIZE),
|
||||||
PacketType::Mix => PacketSize::AckPacket.payload_size(),
|
PacketType::Mix => PacketSize::AckPacket.payload_size(),
|
||||||
#[allow(deprecated)]
|
|
||||||
PacketType::Vpn => PacketSize::AckPacket.payload_size(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let surb_ack_packet = match packet_type {
|
let surb_ack_packet = match packet_type {
|
||||||
@@ -75,14 +73,6 @@ impl SurbAck {
|
|||||||
&destination,
|
&destination,
|
||||||
&delays,
|
&delays,
|
||||||
)?,
|
)?,
|
||||||
#[allow(deprecated)]
|
|
||||||
PacketType::Vpn => NymPacket::sphinx_build(
|
|
||||||
packet_size,
|
|
||||||
surb_ack_payload,
|
|
||||||
&route,
|
|
||||||
&destination,
|
|
||||||
&delays,
|
|
||||||
)?,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// in our case, the last hop is a gateway that does NOT do any delays
|
// in our case, the last hop is a gateway that does NOT do any delays
|
||||||
@@ -106,8 +96,6 @@ impl SurbAck {
|
|||||||
PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
|
PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
|
||||||
}
|
}
|
||||||
PacketType::Mix => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
|
PacketType::Mix => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
|
||||||
#[allow(deprecated)]
|
|
||||||
PacketType::Vpn => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,8 +127,6 @@ impl SurbAck {
|
|||||||
let packet = match packet_type {
|
let packet = match packet_type {
|
||||||
PacketType::Outfox => NymPacket::outfox_from_bytes(&b[address_offset..])?,
|
PacketType::Outfox => NymPacket::outfox_from_bytes(&b[address_offset..])?,
|
||||||
PacketType::Mix => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
|
PacketType::Mix => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
|
||||||
#[allow(deprecated)]
|
|
||||||
PacketType::Vpn => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((address, packet))
|
Ok((address, packet))
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::fragment::Fragment;
|
|||||||
use crate::{monitoring, ChunkingError};
|
use crate::{monitoring, ChunkingError};
|
||||||
use log::*;
|
use log::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
// TODO: perhaps a more sophisticated approach with writing to disk periodically in case
|
// TODO: perhaps a more sophisticated approach with writing to disk periodically in case
|
||||||
// we're receiving fast & furious in uncompressed 4K - we don't want to keep that in memory;
|
// we're receiving fast & furious in uncompressed 4K - we don't want to keep that in memory;
|
||||||
@@ -31,6 +32,9 @@ struct ReconstructionBuffer {
|
|||||||
/// appropriately resized and all missing fragments are set to a `None`, thus keeping
|
/// appropriately resized and all missing fragments are set to a `None`, thus keeping
|
||||||
/// everything in order the whole time, allowing for O(1) insertions and O(n) reconstruction.
|
/// everything in order the whole time, allowing for O(1) insertions and O(n) reconstruction.
|
||||||
fragments: Vec<Option<Fragment>>,
|
fragments: Vec<Option<Fragment>>,
|
||||||
|
|
||||||
|
/// The timestamp of the last received fragment. Used for cleaning up stale buffers.
|
||||||
|
last_fragment_timestamp: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type alias representing fully reconstructed message - its original data and list of all
|
/// Type alias representing fully reconstructed message - its original data and list of all
|
||||||
@@ -56,6 +60,7 @@ impl ReconstructionBuffer {
|
|||||||
previous_fragments_set_id: None,
|
previous_fragments_set_id: None,
|
||||||
next_fragments_set_id: None,
|
next_fragments_set_id: None,
|
||||||
fragments: fragments_buffer,
|
fragments: fragments_buffer,
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +104,8 @@ impl ReconstructionBuffer {
|
|||||||
/// `previous_fragments_set_id` and `next_fragments_set_id` are set for the ease
|
/// `previous_fragments_set_id` and `next_fragments_set_id` are set for the ease
|
||||||
/// of access.
|
/// of access.
|
||||||
fn insert_fragment(&mut self, fragment: Fragment) {
|
fn insert_fragment(&mut self, fragment: Fragment) {
|
||||||
|
self.last_fragment_timestamp = Instant::now();
|
||||||
|
|
||||||
// all fragments in the buffer should always have the same id as before inserting an element,
|
// all fragments in the buffer should always have the same id as before inserting an element,
|
||||||
// the correct buffer instance is looked up based on the fragment to be inserted.
|
// the correct buffer instance is looked up based on the fragment to be inserted.
|
||||||
debug_assert!({
|
debug_assert!({
|
||||||
@@ -158,6 +165,10 @@ pub struct MessageReconstructor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MessageReconstructor {
|
impl MessageReconstructor {
|
||||||
|
// We want to be very conservative here. We remove these to avoid memory leaks, but it's okay
|
||||||
|
// to wait for a long time before we do so.
|
||||||
|
const INCOMPLETE_MESSAGE_TIMEOUT: Duration = Duration::from_secs(30 * 60);
|
||||||
|
|
||||||
/// Creates an empty `MessageReconstructor`.
|
/// Creates an empty `MessageReconstructor`.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
Default::default()
|
||||||
@@ -296,6 +307,25 @@ impl MessageReconstructor {
|
|||||||
pub fn recover_fragment(&self, fragment_data: Vec<u8>) -> Result<Fragment, ChunkingError> {
|
pub fn recover_fragment(&self, fragment_data: Vec<u8>) -> Result<Fragment, ChunkingError> {
|
||||||
Fragment::try_from_bytes(&fragment_data)
|
Fragment::try_from_bytes(&fragment_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cleanup_stale_buffers(&mut self) {
|
||||||
|
trace!("Cleaning up stale buffers");
|
||||||
|
let now = Instant::now();
|
||||||
|
self.reconstructed_sets.retain(|_, set_buf| {
|
||||||
|
let keep = now.duration_since(set_buf.last_fragment_timestamp)
|
||||||
|
< Self::INCOMPLETE_MESSAGE_TIMEOUT;
|
||||||
|
if !keep {
|
||||||
|
debug!(
|
||||||
|
"Removing stale buffer for set id {:?}",
|
||||||
|
set_buf
|
||||||
|
.fragments
|
||||||
|
.first()
|
||||||
|
.and_then(|f| f.as_ref().map(|f| f.id()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
keep
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -508,6 +538,8 @@ mod reconstruction_buffer {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod message_reconstructor {
|
mod message_reconstructor {
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::fragment::unlinked_fragment_payload_max_len;
|
use crate::fragment::unlinked_fragment_payload_max_len;
|
||||||
use crate::set::{max_one_way_linked_set_payload_length, two_way_linked_set_payload_length};
|
use crate::set::{max_one_way_linked_set_payload_length, two_way_linked_set_payload_length};
|
||||||
@@ -869,6 +901,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: None,
|
previous_fragments_set_id: None,
|
||||||
next_fragments_set_id: None,
|
next_fragments_set_id: None,
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -879,6 +912,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: None,
|
previous_fragments_set_id: None,
|
||||||
next_fragments_set_id: None,
|
next_fragments_set_id: None,
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1006,6 +1040,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: None,
|
previous_fragments_set_id: None,
|
||||||
next_fragments_set_id: Some(1234),
|
next_fragments_set_id: Some(1234),
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1016,6 +1051,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: Some(12345),
|
previous_fragments_set_id: Some(12345),
|
||||||
next_fragments_set_id: Some(123),
|
next_fragments_set_id: Some(123),
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1026,6 +1062,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: Some(1234),
|
previous_fragments_set_id: Some(1234),
|
||||||
next_fragments_set_id: Some(12),
|
next_fragments_set_id: Some(12),
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1036,6 +1073,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: Some(123),
|
previous_fragments_set_id: Some(123),
|
||||||
next_fragments_set_id: None,
|
next_fragments_set_id: None,
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1083,6 +1121,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: None,
|
previous_fragments_set_id: None,
|
||||||
next_fragments_set_id: Some(1234),
|
next_fragments_set_id: Some(1234),
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
reconstructor.reconstructed_sets.insert(
|
reconstructor.reconstructed_sets.insert(
|
||||||
@@ -1092,6 +1131,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: Some(12345),
|
previous_fragments_set_id: Some(12345),
|
||||||
next_fragments_set_id: None,
|
next_fragments_set_id: None,
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
assert_eq!(reconstructor.previous_linked_set_id(12345), None);
|
assert_eq!(reconstructor.previous_linked_set_id(12345), None);
|
||||||
@@ -1139,6 +1179,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: None,
|
previous_fragments_set_id: None,
|
||||||
next_fragments_set_id: Some(1234),
|
next_fragments_set_id: Some(1234),
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
reconstructor.reconstructed_sets.insert(
|
reconstructor.reconstructed_sets.insert(
|
||||||
@@ -1148,6 +1189,7 @@ mod message_reconstructor {
|
|||||||
previous_fragments_set_id: Some(12345),
|
previous_fragments_set_id: Some(12345),
|
||||||
next_fragments_set_id: None,
|
next_fragments_set_id: None,
|
||||||
fragments: vec![],
|
fragments: vec![],
|
||||||
|
last_fragment_timestamp: Instant::now(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
assert_eq!(reconstructor.next_linked_set_id(12345), Some(1234));
|
assert_eq!(reconstructor.next_linked_set_id(12345), Some(1234));
|
||||||
|
|||||||
@@ -132,14 +132,6 @@ where
|
|||||||
&destination,
|
&destination,
|
||||||
&delays,
|
&delays,
|
||||||
)?,
|
)?,
|
||||||
#[allow(deprecated)]
|
|
||||||
PacketType::Vpn => NymPacket::sphinx_build(
|
|
||||||
packet_size.payload_size(),
|
|
||||||
packet_payload,
|
|
||||||
&route,
|
|
||||||
&destination,
|
|
||||||
&delays,
|
|
||||||
)?,
|
|
||||||
PacketType::Outfox => NymPacket::outfox_build(
|
PacketType::Outfox => NymPacket::outfox_build(
|
||||||
packet_payload,
|
packet_payload,
|
||||||
&route,
|
&route,
|
||||||
@@ -171,6 +163,7 @@ pub fn is_cover(data: &[u8]) -> bool {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::iter::repeat_n;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_cover_works_for_identical_input() {
|
fn is_cover_works_for_identical_input() {
|
||||||
@@ -182,7 +175,7 @@ mod tests {
|
|||||||
let input: Vec<_> = LOOP_COVER_MESSAGE_PAYLOAD
|
let input: Vec<_> = LOOP_COVER_MESSAGE_PAYLOAD
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.chain(std::iter::repeat(42).take(100))
|
.chain(repeat_n(42, 100))
|
||||||
.collect();
|
.collect();
|
||||||
assert!(is_cover(&input))
|
assert!(is_cover(&input))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,11 @@ repository = { workspace = true }
|
|||||||
bytes = { workspace = true }
|
bytes = { workspace = true }
|
||||||
tokio-util = { workspace = true, features = ["codec"] }
|
tokio-util = { workspace = true, features = ["codec"] }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
log = { workspace = true }
|
tracing = { workspace = true }
|
||||||
|
|
||||||
nym-sphinx-types = { path = "../types", features = ["sphinx", "outfox"] }
|
nym-sphinx-types = { path = "../types", features = ["sphinx", "outfox"] }
|
||||||
nym-sphinx-params = { path = "../params", features = ["sphinx", "outfox"] }
|
nym-sphinx-params = { path = "../params", features = ["sphinx", "outfox"] }
|
||||||
nym-sphinx-forwarding = { path = "../forwarding" }
|
nym-sphinx-forwarding = { path = "../forwarding" }
|
||||||
nym-metrics = { path = "../../nym-metrics" }
|
|
||||||
nym-sphinx-addressing = { path = "../addressing" }
|
nym-sphinx-addressing = { path = "../addressing" }
|
||||||
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
|
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
|
||||||
|
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ impl Decoder for NymCodec {
|
|||||||
match header.packet_type {
|
match header.packet_type {
|
||||||
PacketType::Outfox => NymPacket::outfox_from_bytes(slice)?,
|
PacketType::Outfox => NymPacket::outfox_from_bytes(slice)?,
|
||||||
PacketType::Mix => NymPacket::sphinx_from_bytes(slice)?,
|
PacketType::Mix => NymPacket::sphinx_from_bytes(slice)?,
|
||||||
#[allow(deprecated)]
|
|
||||||
PacketType::Vpn => NymPacket::sphinx_from_bytes(slice)?,
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user