From 65c5ddacb22dd5f77121d016def7bdf8bfb9bf3e Mon Sep 17 00:00:00 2001 From: Xinyu Ma Date: Sun, 3 Mar 2024 02:50:40 -0800 Subject: [PATCH 1/5] Slow down retransmission to avoid failure --- deno.lock | 2 +- package.json | 2 +- pnpm-lock.yaml | 134 ++++++++++++++++++----------------- src/sync-agent/deliveries.ts | 11 ++- 4 files changed, 79 insertions(+), 70 deletions(-) diff --git a/deno.lock b/deno.lock index 94beea4..b601526 100644 --- a/deno.lock +++ b/deno.lock @@ -207,7 +207,7 @@ "npm:type-fest@^4.10.3", "npm:wait-your-turn@^1.0.1", "npm:y-protocols@^1.0.6", - "npm:yjs@^13.6.12" + "npm:yjs@^13.6.14" ] } } diff --git a/package.json b/package.json index c18e923..cddae5d 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "type-fest": "^4.10.3", "wait-your-turn": "^1.0.1", "y-protocols": "^1.0.6", - "yjs": "^13.6.12" + "yjs": "^13.6.14" }, "devDependencies": { "@ndn/endpoint": "https://ndnts-nightly.ndn.today/endpoint.tgz", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 110177a..807500b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,10 +28,10 @@ dependencies: version: 1.0.1 y-protocols: specifier: ^1.0.6 - version: 1.0.6(yjs@13.6.12) + version: 1.0.6(yjs@13.6.14) yjs: - specifier: ^13.6.12 - version: 13.6.12 + specifier: ^13.6.14 + version: 13.6.14 devDependencies: '@ndn/endpoint': @@ -118,14 +118,14 @@ packages: /@types/imap@0.8.40: resolution: {integrity: sha512-kWFwOc88CGwWZlHqCnZiceS6EralsAHdjpQyk1+fIA875NQdIHvLpdD5NU3Pi1yZ8FKFdOF81UDNAo8/XS6HiQ==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.11.24 dev: true /@types/minimalistic-assert@1.0.3: resolution: {integrity: sha512-Ku87cam4YxiXcEpeUemo+vO8QWGQ7U2CwEEcLcYFhxG8b4CK8gWxSX/oWjePWKwqPaWWxxVqXAdAjGdlJtVzDA==} - /@types/node@20.11.20: - resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} + /@types/node@20.11.24: + resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==} dependencies: undici-types: 5.26.5 dev: true @@ -133,7 +133,7 @@ packages: /@types/nodemailer@6.4.14: resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.11.24 dev: true /@types/retry@0.12.5: @@ -151,7 +151,7 @@ packages: /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.11.24 dev: true /@yoursunny/asn1@0.0.20200718: @@ -364,7 +364,7 @@ packages: tslib: ^2.3.0 dependencies: imap: 0.8.19 - mailparser: 3.6.7 + mailparser: 3.6.9 tslib: 2.6.2 dev: true @@ -431,8 +431,8 @@ packages: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} dev: true - /lib0@0.2.89: - resolution: {integrity: sha512-5j19vcCjsQhvLG6mcDD+nprtJUCbmqLz5Hzt5xgi9SV6RIW/Dty7ZkVZHGBuPOADMKjQuKDvuQTH495wsmw8DQ==} + /lib0@0.2.90: + resolution: {integrity: sha512-iQmk+fThPq1ZTD2cFUu8xN6JLp9gFWnjs8auR6hmI6QQXoy6sSEh85uKcdkqpuEnkhhwQm4GSlKHOYfSCVp0Mw==} engines: {node: '>=16'} hasBin: true dependencies: @@ -443,6 +443,10 @@ packages: resolution: {integrity: sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew==} dev: true + /libbase64@1.3.0: + resolution: {integrity: sha512-GgOXd0Eo6phYgh0DJtjQ2tO8dc0IVINtZJeARPeiIJqge+HdsWSuaDTe8ztQ7j/cONByDZ3zeB325AHiv5O0dg==} + dev: true + /libmime@5.2.0: resolution: {integrity: sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw==} dependencies: @@ -452,37 +456,42 @@ packages: libqp: 2.0.1 dev: true - /libmime@5.2.1: - resolution: {integrity: sha512-A0z9O4+5q+ZTj7QwNe/Juy1KARNb4WaviO4mYeFC4b8dBT2EEqK2pkM+GC8MVnkOjqhl5nYQxRgnPYRRTNmuSQ==} + /libmime@5.3.4: + resolution: {integrity: sha512-TsqPdercr6DHrnoQx1F0nS2Y4yPT+fWuOjEP2rqzvV77hMYWomTe/rpm0u9JORQ/FavEXybAGcBJsQbLr9+hjA==} dependencies: encoding-japanese: 2.0.0 iconv-lite: 0.6.3 - libbase64: 1.2.1 - libqp: 2.0.1 + libbase64: 1.3.0 + libqp: 2.1.0 dev: true /libqp@2.0.1: resolution: {integrity: sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg==} dev: true + /libqp@2.1.0: + resolution: {integrity: sha512-O6O6/fsG5jiUVbvdgT7YX3xY3uIadR6wEZ7+vy9u7PKHAlSEB6blvC1o5pHBjgsi95Uo0aiBBdkyFecj6jtb7A==} + dev: true + /linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} dependencies: - uc.micro: 2.0.0 + uc.micro: 2.1.0 dev: true - /mailparser@3.6.7: - resolution: {integrity: sha512-/3x8HW70DNehw+3vdOPKdlLuxOHoWcGB5jfx5vJ5XUbY9/2jUJbrrhda5Si8Dj/3w08U0y5uGAkqs5+SPTPKoA==} + /mailparser@3.6.9: + resolution: {integrity: sha512-1fIDZlgN1NnuzmTSEUxkaViquXYkw5NbQehVc+kz55QRy98QgLdTtRSKv289Jy4NrCiDchRx6zAijB4HrPsvkA==} dependencies: encoding-japanese: 2.0.0 he: 1.2.0 html-to-text: 9.0.5 iconv-lite: 0.6.3 - libmime: 5.2.1 + libmime: 5.3.4 linkify-it: 5.0.0 mailsplit: 5.4.0 - nodemailer: 6.9.9 - tlds: 1.248.0 + nodemailer: 6.9.11 + punycode: 2.3.1 + tlds: 1.250.0 dev: true /mailsplit@5.4.0: @@ -516,13 +525,8 @@ packages: requiresBuild: true dev: true - /nodemailer@6.9.10: - resolution: {integrity: sha512-qtoKfGFhvIFW5kLfrkw2R6Nm6Ur4LNUMykyqu6n9BRKJuyQrqEGwdXXUAbwWEKt33dlWUGXb7rzmJP/p4+O+CA==} - engines: {node: '>=6.0.0'} - dev: true - - /nodemailer@6.9.9: - resolution: {integrity: sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==} + /nodemailer@6.9.11: + resolution: {integrity: sha512-UiAkgiERuG94kl/3bKfE8o10epvDnl0vokNEtZDPTq9BWzIl6EFT9336SbIT4oaTBD8NmmUTLsQyXHV82eXSWg==} engines: {node: '>=6.0.0'} dev: true @@ -548,8 +552,8 @@ packages: engines: {node: '>=12'} dev: true - /p-event@6.0.0: - resolution: {integrity: sha512-Xbfxd0CfZmHLGKXH32k1JKjQYX6Rkv0UtQdaFJ8OyNcf+c0oWCeXHc1C4CX/IESZLmcvfPa5aFIO/vCr5gqtag==} + /p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} engines: {node: '>=16.17'} dependencies: p-timeout: 6.1.2 @@ -664,8 +668,8 @@ packages: resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==} dev: true - /tlds@1.248.0: - resolution: {integrity: sha512-noj0KdpWTBhwsKxMOXk0rN9otg4kTgLm4WohERRHbJ9IY+kSDKr3RmjitaQ3JFzny+DyvBOQKlFZhp0G0qNSfg==} + /tlds@1.250.0: + resolution: {integrity: sha512-rWsBfFCWKrjM/o2Q1TTUeYQv6tHSd/umUutDjVs6taTuEgRDIreVYIBgWRWW4ot7jp6n0UVUuxhTLWBtUmPu/w==} hasBin: true dev: true @@ -679,8 +683,8 @@ packages: /typescript-event-target@1.1.0: resolution: {integrity: sha512-PMrzUVryhnUq2n8M7tjNHNRuIHlUqly5RfGltBTpPCdVpbytgALTRDegF/t6+mFmmtBVhOqEYlbjVNBxwabIug==} - /uc.micro@2.0.0: - resolution: {integrity: sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==} + /uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} dev: true /undici-types@5.26.5: @@ -737,27 +741,27 @@ packages: bufferutil: 4.0.8 dev: true - /y-protocols@1.0.6(yjs@13.6.12): + /y-protocols@1.0.6(yjs@13.6.14): resolution: {integrity: sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} peerDependencies: yjs: ^13.0.0 dependencies: - lib0: 0.2.89 - yjs: 13.6.12 + lib0: 0.2.90 + yjs: 13.6.14 dev: false - /yjs@13.6.12: - resolution: {integrity: sha512-KOT8ILoyVH2f/PxPadeu5kVVS055D1r3x1iFfJVJzFdnN98pVGM8H07NcKsO+fG3F7/0tf30Vnokf5YIqhU/iw==} + /yjs@13.6.14: + resolution: {integrity: sha512-D+7KcUr0j+vBCUSKXXEWfA+bG4UQBviAwP3gYBhkstkgwy5+8diOPMx0iqLIOxNo/HxaREUimZRxqHGAHCL2BQ==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} dependencies: - lib0: 0.2.89 + lib0: 0.2.90 dev: false '@ndnts-nightly.ndn.today/endpoint.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/endpoint.tgz} name: '@ndn/endpoint' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' @@ -770,7 +774,7 @@ packages: '@ndnts-nightly.ndn.today/fw.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/fw.tgz} name: '@ndn/fw' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' @@ -787,7 +791,7 @@ packages: '@ndnts-nightly.ndn.today/keychain.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/keychain.tgz} name: '@ndn/keychain' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' @@ -806,7 +810,7 @@ packages: '@ndnts-nightly.ndn.today/l3face.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/l3face.tgz} name: '@ndn/l3face' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' '@ndn/lp': '@ndnts-nightly.ndn.today/lp.tgz' @@ -815,7 +819,7 @@ packages: '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' abortable-iterator: 5.0.1 it-pushable: 3.2.3 - p-event: 6.0.0 + p-event: 6.0.1 retry: 0.13.1 streaming-iterables: 8.0.1 tslib: 2.6.2 @@ -826,7 +830,7 @@ packages: '@ndnts-nightly.ndn.today/lp.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/lp.tgz} name: '@ndn/lp' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/tlv': '@ndnts-nightly.ndn.today/tlv.tgz' @@ -838,7 +842,7 @@ packages: '@ndnts-nightly.ndn.today/naming-convention2.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/naming-convention2.tgz} name: '@ndn/naming-convention2' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/tlv': '@ndnts-nightly.ndn.today/tlv.tgz' @@ -849,7 +853,7 @@ packages: '@ndnts-nightly.ndn.today/ndncert.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/ndncert.tgz} name: '@ndn/ndncert' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/keychain': '@ndnts-nightly.ndn.today/keychain.tgz' @@ -863,7 +867,7 @@ packages: ajv: 8.12.0 b64-lite: 1.4.0 imap-emails: 1.0.4(tslib@2.6.2) - nodemailer: 6.9.10 + nodemailer: 6.9.11 p-timeout: 6.1.2 tslib: 2.6.2 type-fest: 4.10.3 @@ -873,7 +877,7 @@ packages: '@ndnts-nightly.ndn.today/ndnsec.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/ndnsec.tgz} name: '@ndn/ndnsec' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/keychain': '@ndnts-nightly.ndn.today/keychain.tgz' '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' @@ -888,7 +892,7 @@ packages: '@ndnts-nightly.ndn.today/nfdmgmt.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/nfdmgmt.tgz} name: '@ndn/nfdmgmt' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' @@ -904,11 +908,11 @@ packages: '@ndnts-nightly.ndn.today/node-transport.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/node-transport.tgz} name: '@ndn/node-transport' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/l3face': '@ndnts-nightly.ndn.today/l3face.tgz' event-iterator: 2.0.0 - p-event: 6.0.0 + p-event: 6.0.1 tslib: 2.6.2 type-fest: 4.10.3 url-format-lax: 2.0.0 @@ -918,7 +922,7 @@ packages: '@ndnts-nightly.ndn.today/packet.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/packet.tgz} name: '@ndn/packet' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/tlv': '@ndnts-nightly.ndn.today/tlv.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' @@ -930,7 +934,7 @@ packages: '@ndnts-nightly.ndn.today/rdr.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/rdr.tgz} name: '@ndn/rdr' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' @@ -942,7 +946,7 @@ packages: '@ndnts-nightly.ndn.today/repo-api.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/repo-api.tgz} name: '@ndn/repo-api' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/l3face': '@ndnts-nightly.ndn.today/l3face.tgz' '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' @@ -953,7 +957,7 @@ packages: is-stream: 4.0.1 it-pushable: 3.2.3 p-defer: 4.0.0 - p-event: 6.0.0 + p-event: 6.0.1 streaming-iterables: 8.0.1 throat: 6.0.2 tslib: 2.6.2 @@ -964,7 +968,7 @@ packages: '@ndnts-nightly.ndn.today/segmented-object.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/segmented-object.tgz} name: '@ndn/segmented-object' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' @@ -975,7 +979,7 @@ packages: hirestime: 7.0.4 mnemonist: 0.39.8 p-defer: 4.0.0 - p-event: 6.0.0 + p-event: 6.0.1 p-lazy: 4.0.0 streaming-iterables: 8.0.1 tslib: 2.6.2 @@ -985,7 +989,7 @@ packages: '@ndnts-nightly.ndn.today/svs.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/svs.tgz} name: '@ndn/svs' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' @@ -1004,7 +1008,7 @@ packages: '@ndnts-nightly.ndn.today/sync-api.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/sync-api.tgz} name: '@ndn/sync-api' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' @@ -1014,7 +1018,7 @@ packages: '@ndnts-nightly.ndn.today/tlv.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/tlv.tgz} name: '@ndn/tlv' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' mnemonist: 0.39.8 @@ -1024,7 +1028,7 @@ packages: '@ndnts-nightly.ndn.today/util.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/util.tgz} name: '@ndn/util' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b engines: {node: ^18.18.0 || ^20.10.0 || ^21.0.0} dependencies: '@shigen/polyfill-symbol-dispose': 1.0.1 @@ -1039,13 +1043,13 @@ packages: '@ndnts-nightly.ndn.today/ws-transport.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/ws-transport.tgz} name: '@ndn/ws-transport' - version: 0.0.20240222-nightly-a7c3335 + version: 0.0.20240303-nightly-d813d7b dependencies: '@ndn/l3face': '@ndnts-nightly.ndn.today/l3face.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' '@types/ws': 8.5.10 event-iterator: 2.0.0 - p-event: 6.0.0 + p-event: 6.0.1 tslib: 2.6.2 ws: 8.16.0(bufferutil@4.0.8) optionalDependencies: diff --git a/src/sync-agent/deliveries.ts b/src/sync-agent/deliveries.ts index 8854dc4..10e446b 100644 --- a/src/sync-agent/deliveries.ts +++ b/src/sync-agent/deliveries.ts @@ -6,7 +6,7 @@ import { Decoder, Encoder } from '@ndn/tlv'; import { fetch as fetchSegments, TcpCubic } from '@ndn/segmented-object'; import { getNamespace } from './namespace.ts'; import { Storage } from '../storage/mod.ts'; -import { panic } from '../utils/panic.ts'; +import { LimitedCwnd, panic } from '../utils/mod.ts'; export function encodeSyncState(state: StateVector): Uint8Array { return Encoder.encode(state); @@ -242,9 +242,14 @@ export class AtLeastOnceDelivery extends SyncDelivery { const continuation = fetchSegments(prefix, { segmentNumConvention: SequenceNum, segmentRange: [update.loSeqNum, update.hiSeqNum + 1], - retxLimit: 25, + retxLimit: 40, lifetimeAfterRto: 1000, // The true timeout timer is the RTO - ca: new TcpCubic(), + rtte: { + initRto: 1000, + minRto: 1000, // Minimal RTO is 1000 + maxRto: 120000, + }, + ca: new LimitedCwnd(new TcpCubic(), 10), verifier: this.verifier, endpoint: this.endpoint, // WARN: an abort controller is required! NDNts's fetcher cannot close itself even after From 07fbf1bd3cd91c3842054522c56d615142452be5 Mon Sep 17 00:00:00 2001 From: Xinyu Ma Date: Sun, 3 Mar 2024 02:51:12 -0800 Subject: [PATCH 2/5] Prepare 1.1.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cddae5d..13cd26d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ucla-irl/ndnts-aux", - "version": "1.1.2", + "version": "1.1.3", "description": "NDNts Auxiliary Package for Web and Deno", "scripts": { "test": "deno test --no-check", From a6c953b3fb8177886cb01ded79d3896cb6625854 Mon Sep 17 00:00:00 2001 From: Xinyu Ma Date: Fri, 8 Mar 2024 16:47:32 -0500 Subject: [PATCH 3/5] Polyfill crypto.randomUUID for VSCode --- deno.lock | 5 +- package.json | 7 +-- pnpm-lock.yaml | 97 ++++++++++++++++++++---------------- src/sync-agent/namespace.ts | 3 +- src/sync-agent/sync-agent.ts | 4 +- src/utils/mod.ts | 1 + src/utils/random-uuid.ts | 9 ++++ 7 files changed, 74 insertions(+), 52 deletions(-) create mode 100644 src/utils/random-uuid.ts diff --git a/deno.lock b/deno.lock index b601526..1f3e367 100644 --- a/deno.lock +++ b/deno.lock @@ -200,11 +200,12 @@ "npm:event-iterator@^2.0.0", "npm:eventemitter3@^5.0.1", "npm:it-pushable@^3.2.3", - "npm:jose@^5.2.2", + "npm:jose@^5.2.3", "npm:p-defer@^4.0.0", "npm:streaming-iterables@^8.0.1", "npm:tslib@^2.6.2", - "npm:type-fest@^4.10.3", + "npm:type-fest@^4.11.1", + "npm:uuid@^9.0.1", "npm:wait-your-turn@^1.0.1", "npm:y-protocols@^1.0.6", "npm:yjs@^13.6.14" diff --git a/package.json b/package.json index 13cd26d..cf1710c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ucla-irl/ndnts-aux", - "version": "1.1.3", + "version": "1.1.4", "description": "NDNts Auxiliary Package for Web and Deno", "scripts": { "test": "deno test --no-check", @@ -22,9 +22,10 @@ "@ndn/sync-api": "https://ndnts-nightly.ndn.today/sync-api.tgz", "event-iterator": "^2.0.0", "eventemitter3": "^5.0.1", - "jose": "^5.2.2", + "jose": "^5.2.3", "tslib": "^2.6.2", - "type-fest": "^4.10.3", + "type-fest": "^4.11.1", + "uuid": "^9.0.1", "wait-your-turn": "^1.0.1", "y-protocols": "^1.0.6", "yjs": "^13.6.14" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 807500b..45b315d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,14 +15,17 @@ dependencies: specifier: ^5.0.1 version: 5.0.1 jose: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.2.3 + version: 5.2.3 tslib: specifier: ^2.6.2 version: 2.6.2 type-fest: - specifier: ^4.10.3 - version: 4.10.3 + specifier: ^4.11.1 + version: 4.11.1 + uuid: + specifier: ^9.0.1 + version: 9.0.1 wait-your-turn: specifier: ^1.0.1 version: 1.0.1 @@ -118,14 +121,14 @@ packages: /@types/imap@0.8.40: resolution: {integrity: sha512-kWFwOc88CGwWZlHqCnZiceS6EralsAHdjpQyk1+fIA875NQdIHvLpdD5NU3Pi1yZ8FKFdOF81UDNAo8/XS6HiQ==} dependencies: - '@types/node': 20.11.24 + '@types/node': 20.11.25 dev: true /@types/minimalistic-assert@1.0.3: resolution: {integrity: sha512-Ku87cam4YxiXcEpeUemo+vO8QWGQ7U2CwEEcLcYFhxG8b4CK8gWxSX/oWjePWKwqPaWWxxVqXAdAjGdlJtVzDA==} - /@types/node@20.11.24: - resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==} + /@types/node@20.11.25: + resolution: {integrity: sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==} dependencies: undici-types: 5.26.5 dev: true @@ -133,7 +136,7 @@ packages: /@types/nodemailer@6.4.14: resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==} dependencies: - '@types/node': 20.11.24 + '@types/node': 20.11.25 dev: true /@types/retry@0.12.5: @@ -151,7 +154,7 @@ packages: /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 20.11.24 + '@types/node': 20.11.25 dev: true /@yoursunny/asn1@0.0.20200718: @@ -419,8 +422,8 @@ packages: engines: {node: '>=16.0.0', npm: '>=7.0.0'} dev: true - /jose@5.2.2: - resolution: {integrity: sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==} + /jose@5.2.3: + resolution: {integrity: sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==} dev: false /json-schema-traverse@1.0.0: @@ -431,8 +434,8 @@ packages: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} dev: true - /lib0@0.2.90: - resolution: {integrity: sha512-iQmk+fThPq1ZTD2cFUu8xN6JLp9gFWnjs8auR6hmI6QQXoy6sSEh85uKcdkqpuEnkhhwQm4GSlKHOYfSCVp0Mw==} + /lib0@0.2.91: + resolution: {integrity: sha512-LRcTp8RmdHexL8olb7qErdROnJ2L6Js5Am99WQo0hiTRDWtk6vyUJJjTB6I/RcW8jwNQshM3NqH598DdhSOajA==} engines: {node: '>=16'} hasBin: true dependencies: @@ -676,8 +679,8 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - /type-fest@4.10.3: - resolution: {integrity: sha512-JLXyjizi072smKGGcZiAJDCNweT8J+AuRxmPZ1aG7TERg4ijx9REl8CNhbr36RV4qXqL1gO1FF9HL8OkVmmrsA==} + /type-fest@4.11.1: + resolution: {integrity: sha512-MFMf6VkEVZAETidGGSYW2B1MjXbGX+sWIywn2QPEaJ3j08V+MwVRHMXtf2noB8ENJaD0LIun9wh5Z6OPNf1QzQ==} engines: {node: '>=16'} /typescript-event-target@1.1.0: @@ -715,6 +718,11 @@ packages: semver: 5.3.0 dev: true + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + /wait-your-turn@1.0.1: resolution: {integrity: sha512-UejbIY32KXhghXGwH4J2pTKUNvgdrCjdDGrtrdfHHJUAwXCok1l9ptEp4n13lg6PuyQIgxPGkWyKeJvvKeAqsA==} @@ -747,7 +755,7 @@ packages: peerDependencies: yjs: ^13.0.0 dependencies: - lib0: 0.2.90 + lib0: 0.2.91 yjs: 13.6.14 dev: false @@ -755,13 +763,13 @@ packages: resolution: {integrity: sha512-D+7KcUr0j+vBCUSKXXEWfA+bG4UQBviAwP3gYBhkstkgwy5+8diOPMx0iqLIOxNo/HxaREUimZRxqHGAHCL2BQ==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} dependencies: - lib0: 0.2.90 + lib0: 0.2.91 dev: false '@ndnts-nightly.ndn.today/endpoint.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/endpoint.tgz} name: '@ndn/endpoint' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' @@ -774,7 +782,7 @@ packages: '@ndnts-nightly.ndn.today/fw.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/fw.tgz} name: '@ndn/fw' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' @@ -791,7 +799,7 @@ packages: '@ndnts-nightly.ndn.today/keychain.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/keychain.tgz} name: '@ndn/keychain' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' @@ -803,14 +811,14 @@ packages: mnemonist: 0.39.8 throat: 6.0.2 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 wait-your-turn: 1.0.1 dev: true '@ndnts-nightly.ndn.today/l3face.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/l3face.tgz} name: '@ndn/l3face' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' '@ndn/lp': '@ndnts-nightly.ndn.today/lp.tgz' @@ -823,14 +831,14 @@ packages: retry: 0.13.1 streaming-iterables: 8.0.1 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 typescript-event-target: 1.1.0 dev: true '@ndnts-nightly.ndn.today/lp.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/lp.tgz} name: '@ndn/lp' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/tlv': '@ndnts-nightly.ndn.today/tlv.tgz' @@ -842,7 +850,7 @@ packages: '@ndnts-nightly.ndn.today/naming-convention2.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/naming-convention2.tgz} name: '@ndn/naming-convention2' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/tlv': '@ndnts-nightly.ndn.today/tlv.tgz' @@ -853,7 +861,7 @@ packages: '@ndnts-nightly.ndn.today/ndncert.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/ndncert.tgz} name: '@ndn/ndncert' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/keychain': '@ndnts-nightly.ndn.today/keychain.tgz' @@ -870,14 +878,14 @@ packages: nodemailer: 6.9.11 p-timeout: 6.1.2 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 typescript-event-target: 1.1.0 dev: true '@ndnts-nightly.ndn.today/ndnsec.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/ndnsec.tgz} name: '@ndn/ndnsec' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/keychain': '@ndnts-nightly.ndn.today/keychain.tgz' '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' @@ -892,7 +900,7 @@ packages: '@ndnts-nightly.ndn.today/nfdmgmt.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/nfdmgmt.tgz} name: '@ndn/nfdmgmt' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' @@ -908,13 +916,13 @@ packages: '@ndnts-nightly.ndn.today/node-transport.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/node-transport.tgz} name: '@ndn/node-transport' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/l3face': '@ndnts-nightly.ndn.today/l3face.tgz' event-iterator: 2.0.0 p-event: 6.0.1 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 url-format-lax: 2.0.0 url-parse-lax: 5.0.0 dev: true @@ -922,19 +930,19 @@ packages: '@ndnts-nightly.ndn.today/packet.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/packet.tgz} name: '@ndn/packet' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/tlv': '@ndnts-nightly.ndn.today/tlv.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' buffer-compare: 1.1.1 mnemonist: 0.39.8 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 '@ndnts-nightly.ndn.today/rdr.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/rdr.tgz} name: '@ndn/rdr' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' @@ -946,7 +954,7 @@ packages: '@ndnts-nightly.ndn.today/repo-api.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/repo-api.tgz} name: '@ndn/repo-api' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/l3face': '@ndnts-nightly.ndn.today/l3face.tgz' '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' @@ -968,7 +976,7 @@ packages: '@ndnts-nightly.ndn.today/segmented-object.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/segmented-object.tgz} name: '@ndn/segmented-object' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' @@ -989,9 +997,10 @@ packages: '@ndnts-nightly.ndn.today/svs.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/svs.tgz} name: '@ndn/svs' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/endpoint': '@ndnts-nightly.ndn.today/endpoint.tgz' + '@ndn/fw': '@ndnts-nightly.ndn.today/fw.tgz' '@ndn/naming-convention2': '@ndnts-nightly.ndn.today/naming-convention2.tgz' '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/repo-api': '@ndnts-nightly.ndn.today/repo-api.tgz' @@ -1001,14 +1010,14 @@ packages: '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' streaming-iterables: 8.0.1 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 typescript-event-target: 1.1.0 dev: true '@ndnts-nightly.ndn.today/sync-api.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/sync-api.tgz} name: '@ndn/sync-api' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/packet': '@ndnts-nightly.ndn.today/packet.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' @@ -1018,17 +1027,17 @@ packages: '@ndnts-nightly.ndn.today/tlv.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/tlv.tgz} name: '@ndn/tlv' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' mnemonist: 0.39.8 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 '@ndnts-nightly.ndn.today/util.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/util.tgz} name: '@ndn/util' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 engines: {node: ^18.18.0 || ^20.10.0 || ^21.0.0} dependencies: '@shigen/polyfill-symbol-dispose': 1.0.1 @@ -1037,13 +1046,13 @@ packages: minimalistic-assert: 1.0.1 streaming-iterables: 8.0.1 tslib: 2.6.2 - type-fest: 4.10.3 + type-fest: 4.11.1 wait-your-turn: 1.0.1 '@ndnts-nightly.ndn.today/ws-transport.tgz': resolution: {tarball: https://ndnts-nightly.ndn.today/ws-transport.tgz} name: '@ndn/ws-transport' - version: 0.0.20240303-nightly-d813d7b + version: 0.0.20240307-nightly-6d3d262 dependencies: '@ndn/l3face': '@ndnts-nightly.ndn.today/l3face.tgz' '@ndn/util': '@ndnts-nightly.ndn.today/util.tgz' diff --git a/src/sync-agent/namespace.ts b/src/sync-agent/namespace.ts index 98814f5..e9f70c4 100644 --- a/src/sync-agent/namespace.ts +++ b/src/sync-agent/namespace.ts @@ -1,5 +1,6 @@ import { type Component, Name } from '@ndn/packet'; import { Keyword as KeywordComponent } from '@ndn/naming-convention2'; +import { randomUUID } from '../utils/mod.ts'; let currentNamespace: SyncAgentNamespace | undefined = undefined; @@ -97,7 +98,7 @@ function createDefaultNamespace(): SyncAgentNamespace { return '/8=local' + baseName.toString() + '/8=syncVector'; }, genBlobName(appPrefix: Name): Name { - return new Name([...appPrefix.comps, 'blob', crypto.randomUUID()]); + return new Name([...appPrefix.comps, 'blob', randomUUID()]); }, syncKeyword: KeywordComponent.create('sync'), atLeastOnceKeyword: KeywordComponent.create('alo'), diff --git a/src/sync-agent/sync-agent.ts b/src/sync-agent/sync-agent.ts index 6a216c9..95b146e 100644 --- a/src/sync-agent/sync-agent.ts +++ b/src/sync-agent/sync-agent.ts @@ -7,7 +7,7 @@ import { AtLeastOnceDelivery, LatestOnlyDelivery, UpdateEvent } from './deliveri import { getNamespace } from './namespace.ts'; import { InMemoryStorage, Storage } from '../storage/mod.ts'; import { StateVector } from '@ndn/svs'; -import { panic } from '../utils/panic.ts'; +import { panic, randomUUID } from '../utils/mod.ts'; export type ChannelType = 'update' | 'blob' | 'status' | 'blobUpdate'; const AllChannelValues = ['update', 'blob', 'status', 'blobUpdate']; @@ -113,7 +113,7 @@ export class SyncAgent implements AsyncDisposable { private makeInnerData(channel: ChannelType, topic: string, content: Uint8Array) { const data = new Data( - new Name([channel, topic, crypto.randomUUID()]), + new Name([channel, topic, randomUUID()]), content, ); return Encoder.encode(data); diff --git a/src/utils/mod.ts b/src/utils/mod.ts index cb3035e..1b23383 100644 --- a/src/utils/mod.ts +++ b/src/utils/mod.ts @@ -10,3 +10,4 @@ export * from './name-lit.ts'; export * from './disposable-stacks.ts'; export * from './responder.ts'; export * from './event-chain.ts'; +export * from './random-uuid.ts'; diff --git a/src/utils/random-uuid.ts b/src/utils/random-uuid.ts new file mode 100644 index 0000000..621ecea --- /dev/null +++ b/src/utils/random-uuid.ts @@ -0,0 +1,9 @@ +import { v4 as uuidv4 } from 'uuid'; + +export const randomUUID = (): string => { + if (crypto && crypto.randomUUID) { + return crypto.randomUUID(); + } else { + return uuidv4(); + } +}; From 6b455159fa388e989b92b0da83571536e0500f6e Mon Sep 17 00:00:00 2001 From: Xinyu Ma Date: Fri, 8 Mar 2024 16:53:52 -0500 Subject: [PATCH 4/5] Bug fix: Polyfill crypto.randomUUID for VSCode --- package.json | 2 +- src/utils/random-uuid.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index cf1710c..d129ecf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ucla-irl/ndnts-aux", - "version": "1.1.4", + "version": "1.1.5", "description": "NDNts Auxiliary Package for Web and Deno", "scripts": { "test": "deno test --no-check", diff --git a/src/utils/random-uuid.ts b/src/utils/random-uuid.ts index 621ecea..8ea32a5 100644 --- a/src/utils/random-uuid.ts +++ b/src/utils/random-uuid.ts @@ -1,9 +1,13 @@ import { v4 as uuidv4 } from 'uuid'; export const randomUUID = (): string => { - if (crypto && crypto.randomUUID) { - return crypto.randomUUID(); - } else { + try { + if (globalThis.crypto && globalThis.crypto.randomUUID !== undefined) { + return crypto.randomUUID(); + } else { + return uuidv4(); + } + } catch { return uuidv4(); } }; From 330c34cf600e57c035e3a0f26fdc6db8cd651aef Mon Sep 17 00:00:00 2001 From: Xinyu Ma Date: Thu, 14 Mar 2024 06:15:09 -0700 Subject: [PATCH 5/5] Remove the use of endpoint --- deno.jsonc | 30 ++++++++++---- package.json | 2 +- src/namespace/base-node.ts | 10 ++--- src/namespace/expressing-point.ts | 6 ++- src/namespace/nt-schema.test.ts | 26 +++++------- src/namespace/nt-schema.ts | 26 ++++++++---- .../segmented-object/fetcher.test.ts | 7 +--- .../segmented-object/segmented-object.test.ts | 10 ++--- src/namespace/sync/sync.ts | 2 +- src/security/cert-storage.test.ts | 41 +++++++------------ src/security/cert-storage.ts | 12 +++--- src/storage/deno-kv.ts | 1 + src/sync-agent/deliveries.ts | 29 ++++++------- src/sync-agent/delivery-alo.test.ts | 14 +++---- src/sync-agent/sync-agent.ts | 15 ++++--- src/utils/responder.ts | 8 ++-- src/workspace/workspace.ts | 10 ++--- 17 files changed, 129 insertions(+), 120 deletions(-) diff --git a/deno.jsonc b/deno.jsonc index 24e7fce..bb0a496 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,7 +1,10 @@ { - "tasks": { - }, - "unstable": ["byonm", "net", "fs"], + "tasks": {}, + "unstable": [ + "byonm", + "net", + "fs" + ], "compilerOptions": { "types": [ "@types/wicg-file-system-access" @@ -13,12 +16,25 @@ "indentWidth": 2, "useTabs": false, "semiColons": true, - "include": ["src/**", "build.ts"] + "include": [ + "src/**", + "build.ts" + ] }, "lint": { - "include": ["src/**", "build.ts"] + "include": [ + "src/**", + "build.ts" + ], + "rules": { + "include": [ + "deprecated" + ] + } }, "test": { - "exclude": ["dist/"] + "exclude": [ + "dist/" + ] } -} +} \ No newline at end of file diff --git a/package.json b/package.json index d129ecf..f3c8fd5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ucla-irl/ndnts-aux", - "version": "1.1.5", + "version": "2.0.0", "description": "NDNts Auxiliary Package for Web and Deno", "scripts": { "test": "deno test --no-check", diff --git a/src/namespace/base-node.ts b/src/namespace/base-node.ts index 637909c..91487f2 100644 --- a/src/namespace/base-node.ts +++ b/src/namespace/base-node.ts @@ -1,4 +1,4 @@ -import { Endpoint } from '@ndn/endpoint'; +import type { Forwarder } from '@ndn/fw'; import type { Data, Interest, Verifier } from '@ndn/packet'; import * as namePattern from './name-pattern.ts'; import * as schemaTree from './schema-tree.ts'; @@ -6,8 +6,8 @@ import { EventChain } from '../utils/event-chain.ts'; import { NamespaceHandler } from './nt-schema.ts'; export interface BaseNodeEvents { - attach(path: namePattern.Pattern, endpoint: Endpoint): Promise; - detach(endpoint: Endpoint): Promise; + attach(path: namePattern.Pattern, fw: Forwarder): Promise; + detach(fw: Forwarder): Promise; } export class BaseNode { @@ -58,11 +58,11 @@ export class BaseNode { public async processAttach(path: namePattern.Pattern, handler: NamespaceHandler) { // All children's attach events are called this.handler = handler; - await this.onAttach.emit(path, handler.endpoint!); + await this.onAttach.emit(path, handler.fw!); } public async processDetach() { - await this.onDetach.emit(this.handler!.endpoint!); + await this.onDetach.emit(this.handler!.fw!); this.handler = undefined; // Then call children's detach } diff --git a/src/namespace/expressing-point.ts b/src/namespace/expressing-point.ts index 2fc55f6..30a4800 100644 --- a/src/namespace/expressing-point.ts +++ b/src/namespace/expressing-point.ts @@ -1,4 +1,4 @@ -import { RetxPolicy } from '@ndn/endpoint'; +import { consume, RetxPolicy } from '@ndn/endpoint'; import { Data, Interest, Signer, type Verifier } from '@ndn/packet'; import * as schemaTree from './schema-tree.ts'; import { BaseNode, BaseNodeEvents } from './base-node.ts'; @@ -198,7 +198,9 @@ export class ExpressingPoint extends BaseNode { throw new Error(`Interest surpressed: ${interestName.toString()} @${this.describe}`); } - const data = await this.handler!.endpoint!.consume(interest, { + // TODO: Handle data directly instead of relying on consume. Because of the segmented object. + const data = await consume(interest, { + fw: this.handler!.fw!, // deno-lint-ignore no-explicit-any signal: opts.abortSignal as any, retx: this.config.retx, diff --git a/src/namespace/nt-schema.test.ts b/src/namespace/nt-schema.test.ts index 544502e..fb0bf5c 100644 --- a/src/namespace/nt-schema.test.ts +++ b/src/namespace/nt-schema.test.ts @@ -1,6 +1,6 @@ import { assert } from '../dep.ts'; import { AsyncDisposableStack, name, Responder } from '../utils/mod.ts'; -import { Endpoint } from '@ndn/endpoint'; +import { consume } from '@ndn/endpoint'; import { Data, digestSigning, SigType } from '@ndn/packet'; import { Decoder, Encoder } from '@ndn/tlv'; import { Bridge } from '@ndn/l3face'; @@ -15,8 +15,6 @@ export const b = ([value]: TemplateStringsArray) => new TextEncoder().encode(val Deno.test('NtSchema.1 Basic Interest and Data', async () => { using bridge = Bridge.create({}); const { fwA, fwB } = bridge; - const epA = new Endpoint({ fw: fwA }); - const epB = new Endpoint({ fw: fwB }); await using closers = new AsyncDisposableStack(); const appPrefix = name`/prefix`; @@ -44,13 +42,13 @@ Deno.test('NtSchema.1 Basic Interest and Data', async () => { await digestSigning.sign(data3); return data3; }); - await schema.attach(appPrefix, epA); + await schema.attach(appPrefix, fwA); closers.defer(async () => await schema.detach()); // Responder side const storage = new InMemoryStorage(); closers.use(storage); - const responder = new Responder(appPrefix, epB, storage); + const responder = new Responder(appPrefix, fwB, storage); closers.use(responder); const data1 = new Data( name`${appPrefix}/records/8=rec1`, @@ -85,8 +83,9 @@ Deno.test('NtSchema.1 Basic Interest and Data', async () => { assert.assertEquals(recved2.content, b`World.`); // Test NTSchema's producing data (on request, without storage) - const recved3 = await epB.consume(name`${appPrefix}/records/8=rec3`, { + const recved3 = await consume(name`${appPrefix}/records/8=rec3`, { verifier: digestSigning, + fw: fwB, }); assert.assertExists(recved3); assert.assert(recved3.name.equals(name`${appPrefix}/records/8=rec3`)); @@ -97,8 +96,6 @@ Deno.test('NtSchema.1 Basic Interest and Data', async () => { Deno.test('NtSchema.2 Data Storage', async () => { using bridge = Bridge.create({}); const { fwA, fwB } = bridge; - const epA = new Endpoint({ fw: fwA }); - const epB = new Endpoint({ fw: fwB }); await using closers = new AsyncDisposableStack(); const appPrefix = name`/prefix`; @@ -127,13 +124,13 @@ Deno.test('NtSchema.2 Data Storage', async () => { return undefined; } }); - await schema.attach(appPrefix, epA); + await schema.attach(appPrefix, fwA); closers.defer(async () => await schema.detach()); // Responder side const storageB = new InMemoryStorage(); closers.use(storageB); - const responder = new Responder(appPrefix, epB, storageB); + const responder = new Responder(appPrefix, fwB, storageB); closers.use(responder); const data1 = new Data( name`${appPrefix}/records/8=rec1`, @@ -149,8 +146,9 @@ Deno.test('NtSchema.2 Data Storage', async () => { 'provide', b`World.`, ); - const received = await epB.consume(name`${appPrefix}/records/8=rec2`, { + const received = await consume(name`${appPrefix}/records/8=rec2`, { verifier: digestSigning, + fw: fwB, }); assert.assertExists(received); assert.assert(received.name.equals(name`${appPrefix}/records/8=rec2`)); @@ -178,8 +176,6 @@ Deno.test('NtSchema.2 Data Storage', async () => { Deno.test('NtSchema.3 Verification', async () => { using bridge = Bridge.create({}); const { fwA, fwB } = bridge; - const epA = new Endpoint({ fw: fwA }); - const epB = new Endpoint({ fw: fwB }); await using closers = new AsyncDisposableStack(); const appPrefix = name`/prefix`; const [prvKey, pubKey] = await generateSigningKey(/*identity*/ appPrefix, Ed25519); @@ -216,13 +212,13 @@ Deno.test('NtSchema.3 Verification', async () => { return prevResult; } }); - await schema.attach(appPrefix, epA); + await schema.attach(appPrefix, fwA); closers.defer(async () => await schema.detach()); // Responder side const storage = new InMemoryStorage(); closers.use(storage); - const responder = new Responder(appPrefix, epB, storage); + const responder = new Responder(appPrefix, fwB, storage); closers.use(responder); const data1 = new Data( name`${appPrefix}/records/8=rec1`, diff --git a/src/namespace/nt-schema.ts b/src/namespace/nt-schema.ts index 6ba33f9..e6626cc 100644 --- a/src/namespace/nt-schema.ts +++ b/src/namespace/nt-schema.ts @@ -1,4 +1,5 @@ -import { Endpoint, Producer } from '@ndn/endpoint'; +import { produce, Producer } from '@ndn/endpoint'; +import type { Forwarder } from '@ndn/fw'; import { Data, Interest, Name, type Verifier } from '@ndn/packet'; import * as namePattern from './name-pattern.ts'; import * as schemaTree from './schema-tree.ts'; @@ -14,7 +15,7 @@ export enum VerifyResult { } export interface NamespaceHandler { - get endpoint(): Endpoint | undefined; + get fw(): Forwarder | undefined; get attachedPrefix(): Name | undefined; getVerifier(deadline: number | undefined, verificationContext?: Record): Verifier; storeData(data: Data): Promise; @@ -22,12 +23,12 @@ export interface NamespaceHandler { export class NtSchema implements NamespaceHandler, AsyncDisposable { public readonly tree = schemaTree.create(); - protected _endpoint: Endpoint | undefined; + protected _fw: Forwarder | undefined; protected _attachedPrefix: Name | undefined; protected _producer: Producer | undefined; - get endpoint() { - return this._endpoint; + get fw() { + return this._fw; } get attachedPrefix() { @@ -71,17 +72,24 @@ export class NtSchema implements NamespaceHandler, AsyncDisposable { return undefined; } - public async attach(prefix: Name, endpoint: Endpoint) { + public async attach(prefix: Name, fw: Forwarder) { + if (this._fw !== undefined) { + if (this._fw !== fw) { + throw new Error('You cannot attach a running NTSchema to another forwarder'); + } + return; + } this._attachedPrefix = prefix; - this._endpoint = endpoint; + this._fw = fw; await schemaTree.traverse(this.tree, { post: async (node, path) => await node.resource?.processAttach(path, this), }); - this._producer = endpoint.produce(prefix, this.onInterest.bind(this), { + this._producer = produce(prefix, this.onInterest.bind(this), { describe: `NtSchema[${prefix.toString()}]`, routeCapture: false, announcement: prefix, + fw: fw, }); } @@ -90,7 +98,7 @@ export class NtSchema implements NamespaceHandler, AsyncDisposable { await schemaTree.traverse(this.tree, { pre: async (node) => await node.resource?.processDetach(), }); - this._endpoint = undefined; + this._fw = undefined; this._attachedPrefix = undefined; } diff --git a/src/namespace/segmented-object/fetcher.test.ts b/src/namespace/segmented-object/fetcher.test.ts index 7cab498..b4e1d8d 100644 --- a/src/namespace/segmented-object/fetcher.test.ts +++ b/src/namespace/segmented-object/fetcher.test.ts @@ -1,6 +1,5 @@ import { assert } from '../../dep.ts'; import { AsyncDisposableStack, name, Responder } from '../../utils/mod.ts'; -import { Endpoint } from '@ndn/endpoint'; import { Data, digestSigning } from '@ndn/packet'; import { Encoder } from '@ndn/tlv'; import { Bridge } from '@ndn/l3face'; @@ -14,8 +13,6 @@ export const b = ([value]: TemplateStringsArray) => new TextEncoder().encode(val Deno.test('Fetcher.1 Basic fetching', async () => { using bridge = Bridge.create({}); const { fwA, fwB } = bridge; - const epA = new Endpoint({ fw: fwA }); - const epB = new Endpoint({ fw: fwB }); await using closers = new AsyncDisposableStack(); const appPrefix = name`/prefix`; @@ -30,13 +27,13 @@ Deno.test('Fetcher.1 Basic fetching', async () => { return VerifyResult.Fail; } }); - await schema.attach(appPrefix, epA); + await schema.attach(appPrefix, fwA); closers.defer(async () => await schema.detach()); // Responder side const storage = new InMemoryStorage(); closers.use(storage); - const responder = new Responder(appPrefix, epB, storage); + const responder = new Responder(appPrefix, fwB, storage); closers.use(responder); const payloads = [b`SEG1 `, b`SEG2 `, b`SEG3;`]; for (const [i, p] of payloads.entries()) { diff --git a/src/namespace/segmented-object/segmented-object.test.ts b/src/namespace/segmented-object/segmented-object.test.ts index 6814919..e7ff87a 100644 --- a/src/namespace/segmented-object/segmented-object.test.ts +++ b/src/namespace/segmented-object/segmented-object.test.ts @@ -1,6 +1,5 @@ import { assert } from '../../dep.ts'; import { AsyncDisposableStack, name, Responder } from '../../utils/mod.ts'; -import { Endpoint } from '@ndn/endpoint'; import { Data, digestSigning } from '@ndn/packet'; import { Decoder, Encoder } from '@ndn/tlv'; import { Bridge } from '@ndn/l3face'; @@ -16,8 +15,6 @@ export const b = ([value]: TemplateStringsArray) => new TextEncoder().encode(val Deno.test('SegmentedObject.1 Basic fetching', async () => { using bridge = Bridge.create({}); const { fwA, fwB } = bridge; - const epA = new Endpoint({ fw: fwA }); - const epB = new Endpoint({ fw: fwB }); await using closers = new AsyncDisposableStack(); const appPrefix = name`/prefix`; @@ -36,13 +33,13 @@ Deno.test('SegmentedObject.1 Basic fetching', async () => { leafNode, lifetimeAfterRto: 100, }); - await schema.attach(appPrefix, epA); + await schema.attach(appPrefix, fwA); closers.defer(async () => await schema.detach()); // Responder side const storage = new InMemoryStorage(); closers.use(storage); - const responder = new Responder(appPrefix, epB, storage); + const responder = new Responder(appPrefix, fwB, storage); closers.use(responder); const payloads = [b`SEG1 `, b`SEG2 `, b`SEG3;`]; for (const [i, p] of payloads.entries()) { @@ -70,7 +67,6 @@ Deno.test('SegmentedObject.1 Basic fetching', async () => { Deno.test('SegmentedObject.2 Basic provide', async () => { using bridge = Bridge.create({}); const { fwA, fwB } = bridge; - const epA = new Endpoint({ fw: fwA }); await using closers = new AsyncDisposableStack(); const appPrefix = name`/prefix`; @@ -102,7 +98,7 @@ Deno.test('SegmentedObject.2 Basic provide', async () => { leafNode, lifetimeAfterRto: 100, }); - await schema.attach(appPrefix, epA); + await schema.attach(appPrefix, fwA); closers.defer(async () => await schema.detach()); // Provide object diff --git a/src/namespace/sync/sync.ts b/src/namespace/sync/sync.ts index 948b143..c8f9e89 100644 --- a/src/namespace/sync/sync.ts +++ b/src/namespace/sync/sync.ts @@ -63,7 +63,7 @@ export class SvsInstNode extends BaseNode { const describe = this.describe ? `${this.describe}(${matched.name.toString()})` : undefined; const ret = await SvSync.create({ - endpoint: this.handler!.endpoint!, + fw: this.handler!.fw!, syncPrefix: matched.name, signer: signer, verifier: verifier, diff --git a/src/security/cert-storage.test.ts b/src/security/cert-storage.test.ts index c2d14cd..9b1b83e 100644 --- a/src/security/cert-storage.test.ts +++ b/src/security/cert-storage.test.ts @@ -1,16 +1,8 @@ -import { Endpoint } from '@ndn/endpoint'; import { Encoder } from '@ndn/tlv'; import { Forwarder } from '@ndn/fw'; -import { Data, Interest } from '@ndn/packet'; -import { - Certificate, - CertNaming, - createSigner, - createVerifier, - ECDSA, - generateSigningKey, - ValidityPeriod, -} from '@ndn/keychain'; +import * as endpoint from '@ndn/endpoint'; +import { Data, Interest, ValidityPeriod } from '@ndn/packet'; +import { Certificate, CertNaming, createSigner, createVerifier, ECDSA, generateSigningKey } from '@ndn/keychain'; import { InMemoryStorage } from '../storage/mod.ts'; import { CertStorage } from './cert-storage.ts'; import { assert as assertMod } from '../dep.ts'; @@ -58,7 +50,6 @@ Deno.test('Known certificates', async () => { closers.use(storage); const fwAB = Forwarder.create(); closers.defer(() => fwAB.close()); - const endpoint = new Endpoint({ fw: fwAB }); // const responder = new Responder(appPrefix, endpoint, storage); // closers.use(responder); @@ -66,7 +57,7 @@ Deno.test('Known certificates', async () => { storage.set(ownCert.name.toString(), Encoder.encode(ownCert.data)); storage.set(otherCert.name.toString(), Encoder.encode(otherCert.data)); - const cs = await CertStorage.create(anchor, ownCert, storage, endpoint, new Uint8Array(ownPrvKeyBits), 800); + const cs = await CertStorage.create(anchor, ownCert, storage, fwAB, new Uint8Array(ownPrvKeyBits), 800); // await cs.verifier.verify(anchor.data); // Unable to do so, since it is not signed with a Cert name. await cs.verifier.verify(ownCert.data); @@ -122,8 +113,7 @@ Deno.test('Fetch missing certificate once', async () => { closers.use(storage2); const fwAB = Forwarder.create(); closers.defer(() => fwAB.close()); - const endpoint = new Endpoint({ fw: fwAB }); - const responder = new Responder(appPrefix, endpoint, storage2); + const responder = new Responder(appPrefix, fwAB, storage2); closers.use(responder); storage.set(anchor.name.toString(), Encoder.encode(anchor.data)); @@ -131,7 +121,7 @@ Deno.test('Fetch missing certificate once', async () => { storage2.set(otherCert.name.toString(), Encoder.encode(otherCert.data)); storage2.set(dataToFetch.name.toString(), Encoder.encode(dataToFetch)); - const cs = await CertStorage.create(anchor, ownCert, storage, endpoint, new Uint8Array(ownPrvKeyBits), 800); + const cs = await CertStorage.create(anchor, ownCert, storage, fwAB, new Uint8Array(ownPrvKeyBits), 800); const fetchedData = await endpoint.consume( new Interest( @@ -141,6 +131,7 @@ Deno.test('Fetch missing certificate once', async () => { ), { verifier: cs.verifier, + fw: fwAB, }, ); assertEquals(fetchedData.content, new TextEncoder().encode('Hello World')); @@ -173,12 +164,11 @@ Deno.test('Properly sign packets', async () => { closers.use(storage); const fwAB = Forwarder.create(); closers.defer(() => fwAB.close()); - const endpoint = new Endpoint({ fw: fwAB }); storage.set(anchor.name.toString(), Encoder.encode(anchor.data)); storage.set(ownCert.name.toString(), Encoder.encode(ownCert.data)); - const cs = await CertStorage.create(anchor, ownCert, storage, endpoint, new Uint8Array(ownPrvKeyBits), 800); + const cs = await CertStorage.create(anchor, ownCert, storage, fwAB, new Uint8Array(ownPrvKeyBits), 800); const dataToSign = new Data( name`/${appPrefix}/8=node-0/data`, @@ -237,8 +227,7 @@ Deno.test('Reject unavailable certificate', async () => { closers.use(storage2); const fwAB = Forwarder.create(); closers.defer(() => fwAB.close()); - const endpoint = new Endpoint({ fw: fwAB }); - const responder = new Responder(appPrefix, endpoint, storage2); + const responder = new Responder(appPrefix, fwAB, storage2); closers.use(responder); storage.set(anchor.name.toString(), Encoder.encode(anchor.data)); @@ -246,7 +235,7 @@ Deno.test('Reject unavailable certificate', async () => { // storage2.set(otherCert.name.toString(), Encoder.encode(otherCert.data)); // Certificate is missing - const cs = await CertStorage.create(anchor, ownCert, storage, endpoint, new Uint8Array(ownPrvKeyBits), 800); + const cs = await CertStorage.create(anchor, ownCert, storage, fwAB, new Uint8Array(ownPrvKeyBits), 800); await assertRejects(async () => { await cs.verifier.verify(dataToFetch); }, 'Failed to reject not existing certificates'); @@ -311,8 +300,7 @@ Deno.test('Reject mutual loop', async () => { closers.use(storage2); const fwAB = Forwarder.create(); closers.defer(() => fwAB.close()); - const endpoint = new Endpoint({ fw: fwAB }); - const responder = new Responder(appPrefix, endpoint, storage2); + const responder = new Responder(appPrefix, fwAB, storage2); closers.use(responder); storage.set(anchor.name.toString(), Encoder.encode(anchor.data)); @@ -321,7 +309,7 @@ Deno.test('Reject mutual loop', async () => { storage2.set(otherCert2.name.toString(), Encoder.encode(otherCert2.data)); storage2.set(dataToFetch.name.toString(), Encoder.encode(dataToFetch)); - const cs = await CertStorage.create(anchor, ownCert, storage, endpoint, new Uint8Array(ownPrvKeyBits), 800); + const cs = await CertStorage.create(anchor, ownCert, storage, fwAB, new Uint8Array(ownPrvKeyBits), 800); await assertRejects(async () => { await cs.verifier.verify(dataToFetch); }, 'Failed to reject mutually signed certificates'); @@ -374,15 +362,14 @@ Deno.test('Reject self-signed certificate', async () => { closers.use(storage2); const fwAB = Forwarder.create(); closers.defer(() => fwAB.close()); - const endpoint = new Endpoint({ fw: fwAB }); - const responder = new Responder(appPrefix, endpoint, storage2); + const responder = new Responder(appPrefix, fwAB, storage2); closers.use(responder); storage.set(anchor.name.toString(), Encoder.encode(anchor.data)); storage.set(ownCert.name.toString(), Encoder.encode(ownCert.data)); storage2.set(otherCert.name.toString(), Encoder.encode(otherCert.data)); - const cs = await CertStorage.create(anchor, ownCert, storage, endpoint, new Uint8Array(ownPrvKeyBits), 800); + const cs = await CertStorage.create(anchor, ownCert, storage, fwAB, new Uint8Array(ownPrvKeyBits), 800); await assertRejects(async () => { await cs.verifier.verify(dataToFetch); }, 'Failed to reject self-signed certificates'); diff --git a/src/security/cert-storage.ts b/src/security/cert-storage.ts index 8c6f372..756be9d 100644 --- a/src/security/cert-storage.ts +++ b/src/security/cert-storage.ts @@ -1,7 +1,8 @@ import { Decoder, Encoder } from '@ndn/tlv'; import { Data, Interest, Name, Signer, Verifier } from '@ndn/packet'; import { Certificate, createSigner, createVerifier, ECDSA } from '@ndn/keychain'; -import { Endpoint } from '@ndn/endpoint'; +import * as endpoint from '@ndn/endpoint'; +import type { Forwarder } from '@ndn/fw'; import { Storage } from '../storage/mod.ts'; import { SecurityAgent } from './types.ts'; @@ -18,7 +19,7 @@ export class CertStorage implements SecurityAgent { readonly trustAnchor: Certificate, readonly ownCertificate: Certificate, readonly storage: Storage, - readonly endpoint: Endpoint, + readonly fw: Forwarder, prvKeyBits: Uint8Array, protected readonly interestLifetime = 5000, ) { @@ -64,7 +65,7 @@ export class CertStorage implements SecurityAgent { return undefined; } else { try { - const result = await this.endpoint.consume( + const result = await endpoint.consume( new Interest( keyName, Interest.MustBeFresh, @@ -75,6 +76,7 @@ export class CertStorage implements SecurityAgent { // TODO: Find a better way to handle security verifier: this.localVerifier, retx: 5, + fw: this.fw, }, ); @@ -131,7 +133,7 @@ export class CertStorage implements SecurityAgent { trustAnchor: Certificate, ownCertificate: Certificate, storage: Storage, - endpoint: Endpoint, + fw: Forwarder, prvKeyBits: Uint8Array, interestLifetime = 5000, ) { @@ -139,7 +141,7 @@ export class CertStorage implements SecurityAgent { trustAnchor, ownCertificate, storage, - endpoint, + fw, prvKeyBits, interestLifetime, ); diff --git a/src/storage/deno-kv.ts b/src/storage/deno-kv.ts index 8f4000b..69f67c3 100644 --- a/src/storage/deno-kv.ts +++ b/src/storage/deno-kv.ts @@ -19,6 +19,7 @@ export class DenoKvStorage implements Storage { } async set(key: string, value: Uint8Array | undefined): Promise { + // TODO: There is a size limit await this.kv.set([key], value); } diff --git a/src/sync-agent/deliveries.ts b/src/sync-agent/deliveries.ts index 10e446b..e1011b7 100644 --- a/src/sync-agent/deliveries.ts +++ b/src/sync-agent/deliveries.ts @@ -1,4 +1,5 @@ -import { type Endpoint } from '@ndn/endpoint'; +import * as endpoint from '@ndn/endpoint'; +import { type Forwarder } from '@ndn/fw'; import { StateVector, SvSync, type SyncNode, type SyncUpdate } from '@ndn/svs'; import { Data, digestSigning, Name, Signer, type Verifier } from '@ndn/packet'; import { SequenceNum } from '@ndn/naming-convention2'; @@ -47,7 +48,7 @@ export abstract class SyncDelivery implements AsyncDisposable { // TODO: Use options to configure parameters constructor( readonly nodeId: Name, - readonly endpoint: Endpoint, + readonly fw: Forwarder, readonly syncPrefix: Name, readonly signer: Signer, readonly verifier: Verifier, @@ -66,7 +67,7 @@ export abstract class SyncDelivery implements AsyncDisposable { this._lastTillNow = new StateVector(this.state); SvSync.create({ - endpoint: endpoint, + fw: fw, syncPrefix: syncPrefix, signer: signer, verifier: verifier, @@ -159,7 +160,7 @@ export abstract class SyncDelivery implements AsyncDisposable { this._syncInst.close(); this._syncNode = undefined; const svSync = await SvSync.create({ - endpoint: this.endpoint, + fw: this.fw, syncPrefix: this.syncPrefix, signer: digestSigning, // We can do so because the state has not been set @@ -221,7 +222,7 @@ export abstract class SyncDelivery implements AsyncDisposable { export class AtLeastOnceDelivery extends SyncDelivery { constructor( readonly nodeId: Name, - readonly endpoint: Endpoint, + readonly fw: Forwarder, readonly syncPrefix: Name, readonly signer: Signer, readonly verifier: Verifier, @@ -229,7 +230,7 @@ export class AtLeastOnceDelivery extends SyncDelivery { onUpdatePromise: Promise, protected state?: StateVector, ) { - super(nodeId, endpoint, syncPrefix, signer, verifier, onUpdatePromise, state); + super(nodeId, fw, syncPrefix, signer, verifier, onUpdatePromise, state); } override async handleSyncUpdate(update: SyncUpdate) { @@ -251,7 +252,7 @@ export class AtLeastOnceDelivery extends SyncDelivery { }, ca: new LimitedCwnd(new TcpCubic(), 10), verifier: this.verifier, - endpoint: this.endpoint, + fw: this.fw, // WARN: an abort controller is required! NDNts's fetcher cannot close itself even after // the face is destroyed and there exists no way to send the Interest. // deno-lint-ignore no-explicit-any @@ -353,7 +354,7 @@ export class AtLeastOnceDelivery extends SyncDelivery { static async create( nodeId: Name, - endpoint: Endpoint, + fw: Forwarder, syncPrefix: Name, signer: Signer, verifier: Verifier, @@ -367,7 +368,7 @@ export class AtLeastOnceDelivery extends SyncDelivery { if (encoded) { syncState = parseSyncState(encoded); } - return new AtLeastOnceDelivery(nodeId, endpoint, syncPrefix, signer, verifier, storage, onUpdatePromise, syncState); + return new AtLeastOnceDelivery(nodeId, fw, syncPrefix, signer, verifier, storage, onUpdatePromise, syncState); } override async destroy() { @@ -399,7 +400,7 @@ export class AtLeastOnceDelivery extends SyncDelivery { export class LatestOnlyDelivery extends SyncDelivery { constructor( readonly nodeId: Name, - readonly endpoint: Endpoint, + readonly fw: Forwarder, readonly syncPrefix: Name, readonly signer: Signer, readonly verifier: Verifier, @@ -408,14 +409,14 @@ export class LatestOnlyDelivery extends SyncDelivery { readonly onUpdatePromise: Promise, protected state?: StateVector, ) { - super(nodeId, endpoint, syncPrefix, signer, verifier, onUpdatePromise, state); + super(nodeId, fw, syncPrefix, signer, verifier, onUpdatePromise, state); } override async handleSyncUpdate(update: SyncUpdate) { const prefix = getNamespace().baseName(update.id, this.syncPrefix); const name = prefix.append(SequenceNum.create(update.hiSeqNum)); try { - const data = await this.endpoint.consume(name, { verifier: this.verifier }); + const data = await endpoint.consume(name, { verifier: this.verifier, fw: this.fw }); // Update the storage // Note that this will overwrite old data @@ -460,7 +461,7 @@ export class LatestOnlyDelivery extends SyncDelivery { static async create( nodeId: Name, - endpoint: Endpoint, + fw: Forwarder, syncPrefix: Name, signer: Signer, verifier: Verifier, @@ -478,7 +479,7 @@ export class LatestOnlyDelivery extends SyncDelivery { } return new LatestOnlyDelivery( nodeId, - endpoint, + fw, syncPrefix, signer, verifier, diff --git a/src/sync-agent/delivery-alo.test.ts b/src/sync-agent/delivery-alo.test.ts index e663c2c..3b9314c 100644 --- a/src/sync-agent/delivery-alo.test.ts +++ b/src/sync-agent/delivery-alo.test.ts @@ -1,4 +1,3 @@ -import { Endpoint } from '@ndn/endpoint'; import { Forwarder } from '@ndn/fw'; import { Data, digestSigning, Name, type Signer, type Verifier } from '@ndn/packet'; import { GenericNumber } from '@ndn/naming-convention2'; @@ -17,7 +16,7 @@ type SyncUpdateEvent = { class DeliveryTester implements AsyncDisposable { readonly #closers = new AsyncDisposableStack(); - readonly endpoint: Endpoint; + readonly fwAB: Forwarder; readonly syncPrefix = name`/test/32=alo`; readonly stores; readonly alos = [] as AtLeastOnceDelivery[]; @@ -27,16 +26,15 @@ class DeliveryTester implements AsyncDisposable { readonly svsCount: number, readonly updateEvent?: (evt: SyncUpdateEvent, inst: DeliveryTester) => Promise, ) { - const fwAB = Forwarder.create(); - this.endpoint = new Endpoint({ fw: fwAB }); + this.fwAB = Forwarder.create(); this.#closers.defer(() => { - fwAB.close(); + this.fwAB.close(); }); this.stores = Array.from({ length: svsCount }, (_, i) => { const store = new InMemoryStorage(); this.#closers.use(store); - const responder = new Responder(name`/test/32=node/${i}`, this.endpoint, store); + const responder = new Responder(name`/test/32=node/${i}`, this.fwAB, store); this.#closers.use(responder); return store; }); @@ -46,7 +44,7 @@ class DeliveryTester implements AsyncDisposable { for (let i = 0; this.svsCount > i; i++) { const alo = await AtLeastOnceDelivery.create( name`/test/32=node/${i}`, - this.endpoint, + this.fwAB, this.syncPrefix, signer, verifier, @@ -382,7 +380,7 @@ Deno.test('Alo.3 Recover after shutdown', async () => { // Restart alo 0. It is supposed to deliver 'C' again. tester.alos[0] = await AtLeastOnceDelivery.create( name`/test/32=node/${0}`, - tester.endpoint, + tester.fwAB, tester.syncPrefix, digestSigning, digestSigning, diff --git a/src/sync-agent/sync-agent.ts b/src/sync-agent/sync-agent.ts index 95b146e..b04bd49 100644 --- a/src/sync-agent/sync-agent.ts +++ b/src/sync-agent/sync-agent.ts @@ -1,4 +1,5 @@ -import { Endpoint } from '@ndn/endpoint'; +import * as endpoint from '@ndn/endpoint'; +import type { Forwarder } from '@ndn/fw'; import { Data, type Interest, Name, Signer, type Verifier } from '@ndn/packet'; import { Decoder, Encoder } from '@ndn/tlv'; import { BufferChunkSource, DataProducer, fetch } from '@ndn/segmented-object'; @@ -23,7 +24,7 @@ export class SyncAgent implements AsyncDisposable { readonly appPrefix: Name, readonly persistStorage: Storage, readonly tempStorage: Storage, - readonly endpoint: Endpoint, + readonly fw: Forwarder, readonly signer: Signer, readonly verifier: Verifier, readonly atLeastOnce: AtLeastOnceDelivery, @@ -43,6 +44,7 @@ export class SyncAgent implements AsyncDisposable { describe: 'SyncAgent.serve', routeCapture: false, announcement: appPrefix, + fw: fw, }); // NodeID should be announced to attract traffic. // Design decision: suppose node A, B and C connect to the same network. @@ -53,6 +55,7 @@ export class SyncAgent implements AsyncDisposable { describe: 'SyncAgent.trafficAttractor', routeCapture: false, announcement: nodeId, + fw: fw, }); } @@ -369,7 +372,7 @@ export class SyncAgent implements AsyncDisposable { static async create( nodeId: Name, persistStorage: Storage, - endpoint: Endpoint, + fw: Forwarder, signer: Signer, verifier: Verifier, onReset?: () => void, @@ -385,7 +388,7 @@ export class SyncAgent implements AsyncDisposable { const onUpdatePromise = new Promise((resolve) => resolver = resolve); const latestOnly = await LatestOnlyDelivery.create( nodeId, - endpoint, + fw, lateSyncPrefix, signer, verifier, @@ -395,7 +398,7 @@ export class SyncAgent implements AsyncDisposable { ); const atLeastOnce = await AtLeastOnceDelivery.create( nodeId, - endpoint, + fw, aloSyncPrefix, signer, verifier, @@ -407,7 +410,7 @@ export class SyncAgent implements AsyncDisposable { appPrefix, persistStorage, tempStorage, - endpoint, + fw, signer, verifier, atLeastOnce, diff --git a/src/utils/responder.ts b/src/utils/responder.ts index 98f425f..b4b173e 100644 --- a/src/utils/responder.ts +++ b/src/utils/responder.ts @@ -1,4 +1,5 @@ -import { type Endpoint } from '@ndn/endpoint'; +import { produce } from '@ndn/endpoint'; +import type { Forwarder } from '@ndn/fw'; import { Data, Interest, Name } from '@ndn/packet'; import { Decoder } from '@ndn/tlv'; import { Storage } from '../storage/mod.ts'; @@ -9,15 +10,16 @@ export class Responder implements Disposable { constructor( public readonly prefix: Name, - public readonly endpoint: Endpoint, + public readonly fw: Forwarder, public readonly store: Storage, ) { - this.producer = endpoint.produce(prefix, (interest) => { + this.producer = produce(prefix, (interest) => { return this.serve(interest); }, { describe: `Responder[${prefix.toString()}]`, routeCapture: false, announcement: prefix, + fw: fw, }); } diff --git a/src/workspace/workspace.ts b/src/workspace/workspace.ts index afafb61..64998da 100644 --- a/src/workspace/workspace.ts +++ b/src/workspace/workspace.ts @@ -1,5 +1,5 @@ import { Storage } from '../storage/mod.ts'; -import { Endpoint } from '@ndn/endpoint'; +import type { Forwarder } from '@ndn/fw'; import type { Name, Signer, Verifier } from '@ndn/packet'; import { encodeSyncState, parseSyncState, SyncAgent } from '../sync-agent/mod.ts'; import { NdnSvsAdaptor, YjsStateManager } from '../adaptors/mod.ts'; @@ -9,7 +9,7 @@ export class Workspace implements AsyncDisposable { private constructor( public readonly nodeId: Name, public readonly persistStore: Storage, - public readonly endpoint: Endpoint, + public readonly fw: Forwarder, public readonly onReset: (() => void) | undefined, public readonly syncAgent: SyncAgent, public readonly yjsSnapshotMgr: YjsStateManager, @@ -20,7 +20,7 @@ export class Workspace implements AsyncDisposable { public static async create(opts: { nodeId: Name; persistStore: Storage; - endpoint: Endpoint; + fw: Forwarder; rootDoc: Y.Doc; signer: Signer; verifier: Verifier; @@ -40,7 +40,7 @@ export class Workspace implements AsyncDisposable { const syncAgent = await SyncAgent.create( opts.nodeId, opts.persistStore, - opts.endpoint, + opts.fw, opts.signer, opts.verifier, opts.onReset, @@ -73,7 +73,7 @@ export class Workspace implements AsyncDisposable { return new Workspace( opts.nodeId, opts.persistStore, - opts.endpoint, + opts.fw, opts.onReset, syncAgent, yjsSnapshotMgr,