Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 846d1e54d0 | |||
| b195fb09bb | |||
| c4fee9ba4c | |||
| c495f35eff | |||
| c4324640e2 | |||
| 3a8b79e3e5 | |||
| 05bcdc073b | |||
| 7c48a198e3 | |||
| e7a8db432d | |||
| d20e675209 | |||
| 254ae1dc14 | |||
| 80894dc5c9 | |||
| 24c9843889 | |||
| 5fd0fb9bd8 | |||
| 3a7f850840 | |||
| e6e74855af | |||
| a56068e28a | |||
| d309b44ad7 | |||
| 22539c3e7d | |||
| edde411568 | |||
| 75f2fb7039 | |||
| f768c8e8e2 | |||
| 200efebc37 | |||
| a429d6528e | |||
| ebed210de2 | |||
| d062524d32 | |||
| f1d3c33391 | |||
| 89eea3100e | |||
| d893c806c2 | |||
| 7846058802 | |||
| 42fbb6684d | |||
| f705884a53 | |||
| 2f55c031da | |||
| a9eb6052ff | |||
| 3bc7ced2cf | |||
| 8abcc58055 | |||
| 76ff03b248 | |||
| ccf3420aab | |||
| 5df76ea2a9 | |||
| 33992542b1 | |||
| a95ee3f334 | |||
| 0a92f04048 | |||
| 368b105e27 | |||
| 813cbda891 | |||
| a8af641ec4 | |||
| f41a2d3a99 | |||
| a3b7cb52c9 | |||
| 60846b57f6 | |||
| 8ed09d74b3 | |||
| cd52bc577c | |||
| ed021ff467 | |||
| 4f67998127 | |||
| d06a8e0b21 | |||
| 3f05c0d4b9 | |||
| 1a37e60483 | |||
| 19775cf917 | |||
| 0abc07c96f | |||
| fbfeacf539 | |||
| e1583daaa3 | |||
| e904627513 | |||
| 04664c8ae1 | |||
| 4da68438c0 | |||
| 05c1554109 | |||
| 2b83442a6d | |||
| f982cb49c2 | |||
| 0c05727e58 | |||
| 3c432ac073 | |||
| 52ffd2e798 | |||
| be8c7b4953 | |||
| 8e4bc12b87 | |||
| 4895820985 | |||
| 8500618fe9 | |||
| a5b390b98f | |||
| ff66674f61 | |||
| a7cf34e812 | |||
| a85dad6bd7 | |||
| 5b8a14f74b | |||
| 730c2efea6 | |||
| c9d6a8cc25 | |||
| 230b2b1784 | |||
| e4e9615535 | |||
| 7bf1adff28 | |||
| e4fd87be2c |
+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",
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ 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:
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"rust":"stable",
|
|
||||||
"runOnEvent":"always"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -31,7 +31,6 @@ jobs:
|
|||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.77
|
|
||||||
target: wasm32-unknown-unknown
|
target: wasm32-unknown-unknown
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
@@ -40,6 +39,9 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
version: '114'
|
version: '114'
|
||||||
|
|
||||||
|
- name: Install cosmwasm-check
|
||||||
|
run: cargo install cosmwasm-check
|
||||||
|
|
||||||
- name: Build release contracts
|
- name: Build release contracts
|
||||||
run: make contracts
|
run: make contracts
|
||||||
|
|
||||||
@@ -50,7 +52,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_bandwidth.wasm $OUTPUT_DIR
|
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
|
||||||
|
|||||||
@@ -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-20.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
needs: matrix_prep
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
|
env:
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: documentation/docs
|
working-directory: documentation/docs
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
|
env:
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
@@ -42,7 +44,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: "1.23.7"
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ jobs:
|
|||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ jobs:
|
|||||||
runs-on: arc-ubuntu-20.04
|
runs-on: arc-ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -2,19 +2,18 @@ name: publish-nym-contracts
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [ created ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
runs-on: [self-hosted, custom-ubuntu-20.04]
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.77
|
|
||||||
target: wasm32-unknown-unknown
|
target: wasm32-unknown-unknown
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [macos-12-large]
|
platform: [macos-15]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
- name: Node
|
- name: Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 21
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -64,11 +64,25 @@ jobs:
|
|||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- name: Add Rust target for x86_64-apple-darwin
|
||||||
|
run: rustup target add x86_64-apple-darwin
|
||||||
|
|
||||||
|
- name: Set Cargo build target to x86_64
|
||||||
|
run: echo "CARGO_BUILD_TARGET=x86_64-apple-darwin" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: yarn cache clean
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn cache clean
|
||||||
|
|
||||||
- name: Install project dependencies
|
- name: Install project dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cd .. && yarn --network-timeout 100000
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Install app dependencies and build it
|
- name: yarn build
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn build
|
||||||
|
|
||||||
|
- name: Install dependencies and build it
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
@@ -80,13 +94,14 @@ jobs:
|
|||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
run: yarn && yarn build
|
run: |
|
||||||
|
yarn build-macx86
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: nym-wallet.app.tar.gz
|
name: nym-wallet.app.tar.gz
|
||||||
path: nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz
|
path: nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/nym-wallet.app.tar.gz
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
|
|
||||||
- name: Clean up keychain
|
- name: Clean up keychain
|
||||||
@@ -99,8 +114,8 @@ jobs:
|
|||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/dmg/*.dmg
|
nym-wallet/target/x86_64-apple-darwin/release/bundle/dmg/*.dmg
|
||||||
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
|
nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/*.app.tar.gz*
|
||||||
|
|
||||||
- name: Deploy artifacts to CI www
|
- name: Deploy artifacts to CI www
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -108,7 +123,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
||||||
ARGS: "-avzr"
|
ARGS: "-avzr"
|
||||||
SOURCE: "nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz"
|
SOURCE: "nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/nym-wallet.app.tar.gz"
|
||||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
||||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
||||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
|
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ jobs:
|
|||||||
- name: Node
|
- name: Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 21
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
- name: Node
|
- name: Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 21
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|||||||
@@ -49,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: |
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -4,6 +4,82 @@ 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)
|
## [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): bump braces from 3.0.2 to 3.0.3 in /sdk/typescript/packages/nodejs-client ([#5611])
|
||||||
|
|||||||
Generated
+645
-365
File diff suppressed because it is too large
Load Diff
+19
-20
@@ -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",
|
||||||
@@ -204,7 +203,7 @@ 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 = "1.0.14"
|
||||||
bs58 = "0.5.1"
|
bs58 = "0.5.1"
|
||||||
bytecodec = "0.4.15"
|
bytecodec = "0.4.15"
|
||||||
@@ -216,7 +215,7 @@ 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.32"
|
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"
|
||||||
@@ -284,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.21.1"
|
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"
|
||||||
@@ -303,7 +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 = "0.5.0"
|
||||||
rocket_cors = "0.6.0"
|
rocket_cors = "0.6.0"
|
||||||
rocket_okapi = "0.8.0"
|
rocket_okapi = "0.8.0"
|
||||||
@@ -332,7 +331,7 @@ tap = "1.0.1"
|
|||||||
tar = "0.4.44"
|
tar = "0.4.44"
|
||||||
tempfile = "3.19"
|
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"
|
||||||
@@ -348,9 +347,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"
|
||||||
@@ -361,7 +361,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.8.1"
|
zeroize = "1.7.0"
|
||||||
|
|
||||||
prometheus = { version = "0.13.0" }
|
prometheus = { version = "0.13.0" }
|
||||||
|
|
||||||
@@ -375,19 +375,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 }
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ where
|
|||||||
let gateway_setup = GatewaySetup::New {
|
let gateway_setup = GatewaySetup::New {
|
||||||
specification: selection_spec,
|
specification: selection_spec,
|
||||||
available_gateways,
|
available_gateways,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let init_details =
|
let init_details =
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ where
|
|||||||
let gateway_setup = GatewaySetup::New {
|
let gateway_setup = GatewaySetup::New {
|
||||||
specification: selection_spec,
|
specification: selection_spec,
|
||||||
available_gateways,
|
available_gateways,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let init_details =
|
let init_details =
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ use nym_topology::node::RoutingNode;
|
|||||||
use nym_validator_client::client::IdentityKeyRef;
|
use nym_validator_client::client::IdentityKeyRef;
|
||||||
use nym_validator_client::UserAgent;
|
use nym_validator_client::UserAgent;
|
||||||
use rand::{seq::SliceRandom, Rng};
|
use rand::{seq::SliceRandom, Rng};
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::fd::RawFd;
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use tungstenite::Message;
|
use tungstenite::Message;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@@ -313,9 +315,15 @@ pub(super) async fn register_with_gateway(
|
|||||||
gateway_id: identity::PublicKey,
|
gateway_id: identity::PublicKey,
|
||||||
gateway_listener: Url,
|
gateway_listener: Url,
|
||||||
our_identity: Arc<identity::KeyPair>,
|
our_identity: Arc<identity::KeyPair>,
|
||||||
|
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||||
) -> Result<RegistrationResult, ClientCoreError> {
|
) -> Result<RegistrationResult, ClientCoreError> {
|
||||||
let mut gateway_client =
|
let mut gateway_client = GatewayClient::new_init(
|
||||||
GatewayClient::new_init(gateway_listener, gateway_id, our_identity.clone());
|
gateway_listener,
|
||||||
|
gateway_id,
|
||||||
|
our_identity.clone(),
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback,
|
||||||
|
);
|
||||||
|
|
||||||
gateway_client.establish_connection().await.map_err(|err| {
|
gateway_client.establish_connection().await.map_err(|err| {
|
||||||
log::warn!("Failed to establish connection with gateway!");
|
log::warn!("Failed to establish connection with gateway!");
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ use nym_topology::node::RoutingNode;
|
|||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::{os::fd::RawFd, sync::Arc};
|
||||||
|
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
@@ -53,6 +55,7 @@ async fn setup_new_gateway<K, D>(
|
|||||||
details_store: &D,
|
details_store: &D,
|
||||||
selection_specification: GatewaySelectionSpecification,
|
selection_specification: GatewaySelectionSpecification,
|
||||||
available_gateways: Vec<RoutingNode>,
|
available_gateways: Vec<RoutingNode>,
|
||||||
|
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||||
) -> Result<InitialisationResult, ClientCoreError>
|
) -> Result<InitialisationResult, ClientCoreError>
|
||||||
where
|
where
|
||||||
K: KeyStore,
|
K: KeyStore,
|
||||||
@@ -108,9 +111,14 @@ where
|
|||||||
// if we're using a 'normal' gateway setup, do register
|
// if we're using a 'normal' gateway setup, do register
|
||||||
let our_identity = client_keys.identity_keypair();
|
let our_identity = client_keys.identity_keypair();
|
||||||
|
|
||||||
let registration =
|
let registration = helpers::register_with_gateway(
|
||||||
helpers::register_with_gateway(gateway_id, gateway_listener.clone(), our_identity)
|
gateway_id,
|
||||||
.await?;
|
gateway_listener.clone(),
|
||||||
|
our_identity,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
(
|
(
|
||||||
GatewayDetails::new_remote(
|
GatewayDetails::new_remote(
|
||||||
gateway_id,
|
gateway_id,
|
||||||
@@ -203,9 +211,19 @@ where
|
|||||||
GatewaySetup::New {
|
GatewaySetup::New {
|
||||||
specification,
|
specification,
|
||||||
available_gateways,
|
available_gateways,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("GatewaySetup::New with spec: {specification:?}");
|
log::debug!("GatewaySetup::New with spec: {specification:?}");
|
||||||
setup_new_gateway(key_store, details_store, specification, available_gateways).await
|
setup_new_gateway(
|
||||||
|
key_store,
|
||||||
|
details_store,
|
||||||
|
specification,
|
||||||
|
available_gateways,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
GatewaySetup::ReuseConnection {
|
GatewaySetup::ReuseConnection {
|
||||||
authenticated_ephemeral_client,
|
authenticated_ephemeral_client,
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ use nym_validator_client::client::IdentityKey;
|
|||||||
use nym_validator_client::nyxd::AccountId;
|
use nym_validator_client::nyxd::AccountId;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::fd::RawFd;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@@ -208,6 +210,10 @@ pub enum GatewaySetup {
|
|||||||
|
|
||||||
// TODO: seems to be a bit inefficient to pass them by value
|
// TODO: seems to be a bit inefficient to pass them by value
|
||||||
available_gateways: Vec<RoutingNode>,
|
available_gateways: Vec<RoutingNode>,
|
||||||
|
|
||||||
|
/// Callback useful for allowing initial connection to gateway
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
ReuseConnection {
|
ReuseConnection {
|
||||||
@@ -231,6 +237,8 @@ impl Debug for GatewaySetup {
|
|||||||
GatewaySetup::New {
|
GatewaySetup::New {
|
||||||
specification,
|
specification,
|
||||||
available_gateways,
|
available_gateways,
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: _,
|
||||||
} => f
|
} => f
|
||||||
.debug_struct("GatewaySetup::New")
|
.debug_struct("GatewaySetup::New")
|
||||||
.field("specification", specification)
|
.field("specification", specification)
|
||||||
@@ -270,6 +278,8 @@ impl GatewaySetup {
|
|||||||
additional_data: None,
|
additional_data: None,
|
||||||
},
|
},
|
||||||
available_gateways: vec![],
|
available_gateways: vec![],
|
||||||
|
#[cfg(unix)]
|
||||||
|
connection_fd_callback: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1065,6 +1065,7 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
|
|||||||
gateway_listener: Url,
|
gateway_listener: Url,
|
||||||
gateway_identity: identity::PublicKey,
|
gateway_identity: identity::PublicKey,
|
||||||
local_identity: Arc<identity::KeyPair>,
|
local_identity: Arc<identity::KeyPair>,
|
||||||
|
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
log::trace!("Initialising gateway client");
|
log::trace!("Initialising gateway client");
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
@@ -1090,7 +1091,7 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
|
|||||||
stats_reporter: ClientStatsSender::new(None, task_client.clone()),
|
stats_reporter: ClientStatsSender::new(None, task_client.clone()),
|
||||||
negotiated_protocol: None,
|
negotiated_protocol: None,
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
connection_fd_callback: None,
|
connection_fd_callback,
|
||||||
task_client,
|
task_client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use thiserror::Error;
|
|||||||
use nym_outfox::packet::{OutfoxPacket, OutfoxProcessedPacket};
|
use nym_outfox::packet::{OutfoxPacket, OutfoxProcessedPacket};
|
||||||
|
|
||||||
#[cfg(feature = "sphinx")]
|
#[cfg(feature = "sphinx")]
|
||||||
use sphinx_packet::{SphinxPacket, SphinxPacketBuilder};
|
pub use sphinx_packet::{SphinxPacket, SphinxPacketBuilder};
|
||||||
|
|
||||||
#[cfg(feature = "outfox")]
|
#[cfg(feature = "outfox")]
|
||||||
pub use nym_outfox::{
|
pub use nym_outfox::{
|
||||||
@@ -166,4 +166,20 @@ impl NymPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sphinx")]
|
||||||
|
pub fn sphinx_packet_ref(&self) -> Option<&SphinxPacket> {
|
||||||
|
match self {
|
||||||
|
NymPacket::Sphinx(packet) => Some(packet),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sphinx")]
|
||||||
|
pub fn as_sphinx_packet(self) -> Option<SphinxPacket> {
|
||||||
|
match self {
|
||||||
|
NymPacket::Sphinx(packet) => Some(packet),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,12 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
|
const LANE_CONSIDERED_CLEAR: usize = 10;
|
||||||
|
|
||||||
pub type ConnectionId = u64;
|
pub type ConnectionId = u64;
|
||||||
|
|
||||||
@@ -67,6 +72,32 @@ impl LaneQueueLengths {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn total(&self) -> usize {
|
||||||
|
match self.0.lock() {
|
||||||
|
Ok(inner) => inner.values().sum(),
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("Failed to get total queue length: {err}");
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn wait_until_clear(&self, lane: &TransmissionLane, timeout: Option<Duration>) {
|
||||||
|
let total_time_waited = Instant::now();
|
||||||
|
loop {
|
||||||
|
let lane_length = self.get(lane).unwrap_or_default();
|
||||||
|
if lane_length < LANE_CONSIDERED_CLEAR {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if timeout.is_some_and(|timeout| total_time_waited.elapsed() > timeout) {
|
||||||
|
log::warn!("Timeout reached while waiting for queue to clear");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
log::trace!("Waiting for queue to clear ({} items left)", lane_length);
|
||||||
|
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LaneQueueLengths {
|
impl Default for LaneQueueLengths {
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ impl TaskClient {
|
|||||||
"unnamed-TaskClient".to_string()
|
"unnamed-TaskClient".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
log!(target: target, level, "{}", format!("[{target}] {msg}"))
|
log!(target: target, level, "{}", format_args!("[{target}] {msg}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ pub struct IssuedTicketbooksFullMerkleProof {
|
|||||||
included_leaves: Vec<MerkleLeaf>,
|
included_leaves: Vec<MerkleLeaf>,
|
||||||
total_leaves: usize,
|
total_leaves: usize,
|
||||||
#[schemars(with = "String")]
|
#[schemars(with = "String")]
|
||||||
|
#[schema(value_type = String)]
|
||||||
#[serde(with = "nym_serde_helpers::hex")]
|
#[serde(with = "nym_serde_helpers::hex")]
|
||||||
root: Vec<u8>,
|
root: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ use base64::engine::general_purpose;
|
|||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use x25519_dalek::PublicKey;
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
pub struct PeerPublicKey(PublicKey);
|
pub struct PeerPublicKey(PublicKey);
|
||||||
|
|
||||||
impl PeerPublicKey {
|
impl PeerPublicKey {
|
||||||
@@ -36,12 +35,6 @@ impl fmt::Display for PeerPublicKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for PeerPublicKey {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.0.as_bytes().hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for PeerPublicKey {
|
impl Deref for PeerPublicKey {
|
||||||
type Target = PublicKey;
|
type Target = PublicKey;
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ impl PeerHandle {
|
|||||||
if SystemTime::now().duration_since(self.startup_timestamp)? >= AUTO_REMOVE_AFTER {
|
if SystemTime::now().duration_since(self.startup_timestamp)? >= AUTO_REMOVE_AFTER {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Peer {} has been present for 30 days, removing it",
|
"Peer {} has been present for 30 days, removing it",
|
||||||
self.public_key.to_string()
|
self.public_key
|
||||||
);
|
);
|
||||||
let success = self.remove_peer().await?;
|
let success = self.remove_peer().await?;
|
||||||
return Ok(!success);
|
return Ok(!success);
|
||||||
@@ -111,7 +111,7 @@ impl PeerHandle {
|
|||||||
if spent_bandwidth >= BANDWIDTH_CAP_PER_DAY {
|
if spent_bandwidth >= BANDWIDTH_CAP_PER_DAY {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Peer {} doesn't have bandwidth anymore, removing it",
|
"Peer {} doesn't have bandwidth anymore, removing it",
|
||||||
self.public_key.to_string()
|
self.public_key
|
||||||
);
|
);
|
||||||
let success = self.remove_peer().await?;
|
let success = self.remove_peer().await?;
|
||||||
return Ok(!success);
|
return Ok(!success);
|
||||||
|
|||||||
Generated
+559
-487
File diff suppressed because it is too large
Load Diff
+17
-19
@@ -1,9 +1,7 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
# "coconut-bandwidth",
|
|
||||||
"coconut-dkg",
|
"coconut-dkg",
|
||||||
"coconut-test",
|
|
||||||
"ecash",
|
"ecash",
|
||||||
"mixnet",
|
"mixnet",
|
||||||
"mixnet-vesting-integration-tests",
|
"mixnet-vesting-integration-tests",
|
||||||
@@ -33,24 +31,24 @@ overflow-checks = true
|
|||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
bs58 = "0.4.0"
|
bs58 = "0.5.1"
|
||||||
cosmwasm-crypto = "=1.4.3"
|
cosmwasm-crypto = "=2.2.2"
|
||||||
cosmwasm-derive = "=1.4.3"
|
cosmwasm-derive = "=2.2.2"
|
||||||
cosmwasm-schema = "=1.4.3"
|
cosmwasm-schema = "=2.2.2"
|
||||||
cosmwasm-std = "=1.4.3"
|
cosmwasm-std = "=2.2.2"
|
||||||
cosmwasm-storage = "=1.4.3"
|
cw-controllers = "=2.0.0"
|
||||||
cw-controllers = "=1.1.0"
|
cw-multi-test = "=2.3.2"
|
||||||
cw-multi-test = "=0.16.5"
|
cw-storage-plus = "=2.0.0"
|
||||||
cw-storage-plus = "=1.2.0"
|
cw-utils = "=2.0.0"
|
||||||
cw-utils = "=1.0.1"
|
cw2 = "=2.0.0"
|
||||||
cw2 = "=1.1.2"
|
cw3 = "=2.0.0"
|
||||||
cw3 = "=1.1.2"
|
cw3-fixed-multisig = "=2.0.0"
|
||||||
cw3-fixed-multisig = "=1.1.2"
|
cw4 = "=2.0.0"
|
||||||
cw4 = "=1.1.2"
|
cw20 = "=2.0.0"
|
||||||
cw20 = "=1.1.2"
|
cw20-base = "2.0.0"
|
||||||
semver = "1.0.21"
|
semver = "1.0.21"
|
||||||
serde = "1.0.196"
|
serde = "1.0.196"
|
||||||
sylvia = "0.8.0"
|
sylvia = "1.3.3"
|
||||||
schemars = "0.8.16"
|
schemars = "0.8.16"
|
||||||
|
|
||||||
thiserror = "1.0.48"
|
thiserror = "2.0.11"
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
schema: coconut-dkg-schema mixnet-schema vesting-schema multisig-schema group-schema ecash-schema
|
schema: coconut-dkg-schema mixnet-schema vesting-schema multisig-schema group-schema ecash-schema
|
||||||
|
|
||||||
#coconut-bandwidth-schema:
|
|
||||||
# $(MAKE) -C coconut-bandwidth generate-schema
|
|
||||||
|
|
||||||
coconut-dkg-schema:
|
coconut-dkg-schema:
|
||||||
$(MAKE) -C coconut-dkg generate-schema
|
$(MAKE) -C coconut-dkg generate-schema
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
[alias]
|
|
||||||
wasm = "build --release --lib --target wasm32-unknown-unknown"
|
|
||||||
unit-test = "test --lib"
|
|
||||||
schema = "run --bin schema --features=schema-gen"
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nym-coconut-bandwidth"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "schema"
|
|
||||||
required-features = ["schema-gen"]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["cdylib", "rlib"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
nym-coconut-bandwidth-contract-common = { path = "../../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
|
||||||
nym-multisig-contract-common = { path = "../../common/cosmwasm-smart-contracts/multisig-contract" }
|
|
||||||
|
|
||||||
cosmwasm-std = { workspace = true }
|
|
||||||
cosmwasm-schema = { workspace = true, optional = true }
|
|
||||||
cosmwasm-storage = { workspace = true }
|
|
||||||
cw-storage-plus = { workspace = true }
|
|
||||||
cw-controllers = { workspace = true }
|
|
||||||
|
|
||||||
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
|
|
||||||
thiserror = { workspace = true }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
schema-gen = ["nym-coconut-bandwidth-contract-common/schema", "cosmwasm-schema"]
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
generate-schema:
|
|
||||||
cargo schema
|
|
||||||
@@ -1,382 +0,0 @@
|
|||||||
{
|
|
||||||
"contract_name": "nym-coconut-bandwidth",
|
|
||||||
"contract_version": "0.1.0",
|
|
||||||
"idl_version": "1.0.0",
|
|
||||||
"instantiate": {
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "InstantiateMsg",
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"mix_denom",
|
|
||||||
"multisig_addr",
|
|
||||||
"pool_addr"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"mix_denom": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"multisig_addr": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"pool_addr": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"execute": {
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "ExecuteMsg",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"deposit_funds"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"deposit_funds": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"data"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"data": {
|
|
||||||
"$ref": "#/definitions/DepositData"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"spend_credential"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"spend_credential": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"data"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"data": {
|
|
||||||
"$ref": "#/definitions/SpendCredentialData"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"release_funds"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"release_funds": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"funds"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"funds": {
|
|
||||||
"$ref": "#/definitions/Coin"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"definitions": {
|
|
||||||
"Coin": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"amount",
|
|
||||||
"denom"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"amount": {
|
|
||||||
"$ref": "#/definitions/Uint128"
|
|
||||||
},
|
|
||||||
"denom": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"DepositData": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"deposit_info",
|
|
||||||
"encryption_key",
|
|
||||||
"identity_key"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"deposit_info": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"encryption_key": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"identity_key": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"SpendCredentialData": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"blinded_serial_number",
|
|
||||||
"funds",
|
|
||||||
"gateway_cosmos_address"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"blinded_serial_number": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"funds": {
|
|
||||||
"$ref": "#/definitions/Coin"
|
|
||||||
},
|
|
||||||
"gateway_cosmos_address": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"Uint128": {
|
|
||||||
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": {
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "QueryMsg",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"get_spent_credential"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"get_spent_credential": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"blinded_serial_number"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"blinded_serial_number": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"get_all_spent_credentials"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"get_all_spent_credentials": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"limit": {
|
|
||||||
"type": [
|
|
||||||
"integer",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"format": "uint32",
|
|
||||||
"minimum": 0.0
|
|
||||||
},
|
|
||||||
"start_after": {
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"migrate": {
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "MigrateMsg",
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"sudo": null,
|
|
||||||
"responses": {
|
|
||||||
"get_all_spent_credentials": {
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "PagedSpendCredentialResponse",
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"per_page",
|
|
||||||
"spend_credentials"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"per_page": {
|
|
||||||
"type": "integer",
|
|
||||||
"format": "uint",
|
|
||||||
"minimum": 0.0
|
|
||||||
},
|
|
||||||
"spend_credentials": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/SpendCredential"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start_next_after": {
|
|
||||||
"description": "Field indicating paging information for the following queries if the caller wishes to get further entries.",
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false,
|
|
||||||
"definitions": {
|
|
||||||
"Addr": {
|
|
||||||
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"Coin": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"amount",
|
|
||||||
"denom"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"amount": {
|
|
||||||
"$ref": "#/definitions/Uint128"
|
|
||||||
},
|
|
||||||
"denom": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"SpendCredential": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"blinded_serial_number",
|
|
||||||
"funds",
|
|
||||||
"gateway_cosmos_address",
|
|
||||||
"status"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"blinded_serial_number": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"funds": {
|
|
||||||
"$ref": "#/definitions/Coin"
|
|
||||||
},
|
|
||||||
"gateway_cosmos_address": {
|
|
||||||
"$ref": "#/definitions/Addr"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"$ref": "#/definitions/SpendCredentialStatus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"SpendCredentialStatus": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"in_progress",
|
|
||||||
"spent"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Uint128": {
|
|
||||||
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"get_spent_credential": {
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "SpendCredentialResponse",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"spend_credential": {
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/SpendCredential"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false,
|
|
||||||
"definitions": {
|
|
||||||
"Addr": {
|
|
||||||
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"Coin": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"amount",
|
|
||||||
"denom"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"amount": {
|
|
||||||
"$ref": "#/definitions/Uint128"
|
|
||||||
},
|
|
||||||
"denom": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"SpendCredential": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"blinded_serial_number",
|
|
||||||
"funds",
|
|
||||||
"gateway_cosmos_address",
|
|
||||||
"status"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"blinded_serial_number": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"funds": {
|
|
||||||
"$ref": "#/definitions/Coin"
|
|
||||||
},
|
|
||||||
"gateway_cosmos_address": {
|
|
||||||
"$ref": "#/definitions/Addr"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"$ref": "#/definitions/SpendCredentialStatus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"SpendCredentialStatus": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"in_progress",
|
|
||||||
"spent"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Uint128": {
|
|
||||||
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "ExecuteMsg",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"deposit_funds"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"deposit_funds": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"data"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"data": {
|
|
||||||
"$ref": "#/definitions/DepositData"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"spend_credential"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"spend_credential": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"data"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"data": {
|
|
||||||
"$ref": "#/definitions/SpendCredentialData"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"release_funds"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"release_funds": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"funds"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"funds": {
|
|
||||||
"$ref": "#/definitions/Coin"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"definitions": {
|
|
||||||
"Coin": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"amount",
|
|
||||||
"denom"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"amount": {
|
|
||||||
"$ref": "#/definitions/Uint128"
|
|
||||||
},
|
|
||||||
"denom": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"DepositData": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"deposit_info",
|
|
||||||
"encryption_key",
|
|
||||||
"identity_key"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"deposit_info": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"encryption_key": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"identity_key": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"SpendCredentialData": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"blinded_serial_number",
|
|
||||||
"funds",
|
|
||||||
"gateway_cosmos_address"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"blinded_serial_number": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"funds": {
|
|
||||||
"$ref": "#/definitions/Coin"
|
|
||||||
},
|
|
||||||
"gateway_cosmos_address": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"Uint128": {
|
|
||||||
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "InstantiateMsg",
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"mix_denom",
|
|
||||||
"multisig_addr",
|
|
||||||
"pool_addr"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"mix_denom": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"multisig_addr": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"pool_addr": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "MigrateMsg",
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "QueryMsg",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"get_spent_credential"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"get_spent_credential": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"blinded_serial_number"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"blinded_serial_number": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"get_all_spent_credentials"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"get_all_spent_credentials": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"limit": {
|
|
||||||
"type": [
|
|
||||||
"integer",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"format": "uint32",
|
|
||||||
"minimum": 0.0
|
|
||||||
},
|
|
||||||
"start_after": {
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "PagedSpendCredentialResponse",
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"per_page",
|
|
||||||
"spend_credentials"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"per_page": {
|
|
||||||
"type": "integer",
|
|
||||||
"format": "uint",
|
|
||||||
"minimum": 0.0
|
|
||||||
},
|
|
||||||
"spend_credentials": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/SpendCredential"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start_next_after": {
|
|
||||||
"description": "Field indicating paging information for the following queries if the caller wishes to get further entries.",
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false,
|
|
||||||
"definitions": {
|
|
||||||
"Addr": {
|
|
||||||
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"Coin": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"amount",
|
|
||||||
"denom"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"amount": {
|
|
||||||
"$ref": "#/definitions/Uint128"
|
|
||||||
},
|
|
||||||
"denom": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"SpendCredential": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"blinded_serial_number",
|
|
||||||
"funds",
|
|
||||||
"gateway_cosmos_address",
|
|
||||||
"status"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"blinded_serial_number": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"funds": {
|
|
||||||
"$ref": "#/definitions/Coin"
|
|
||||||
},
|
|
||||||
"gateway_cosmos_address": {
|
|
||||||
"$ref": "#/definitions/Addr"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"$ref": "#/definitions/SpendCredentialStatus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"SpendCredentialStatus": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"in_progress",
|
|
||||||
"spent"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Uint128": {
|
|
||||||
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user