From 49056a6a6ff710854523a2cccd19c7480e6076ad Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Thu, 24 Oct 2024 10:44:36 +0330 Subject: [PATCH 01/35] feat(utils): add `readPrivateKeyFromFile` utility function --- .changeset/lazy-laws-shout.md | 5 ++++ packages/utils/lib/index.ts | 3 ++- packages/utils/lib/readPrivateKeyFromFile.ts | 26 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 .changeset/lazy-laws-shout.md create mode 100644 packages/utils/lib/readPrivateKeyFromFile.ts diff --git a/.changeset/lazy-laws-shout.md b/.changeset/lazy-laws-shout.md new file mode 100644 index 0000000..f1aeb88 --- /dev/null +++ b/.changeset/lazy-laws-shout.md @@ -0,0 +1,5 @@ +--- +'@rosen-bridge/rosenet-utils': minor +--- + +Add `readPrivateKeyFromFile` utility function for the management of a RoseNet private key in a file diff --git a/packages/utils/lib/index.ts b/packages/utils/lib/index.ts index 4baa595..ec9d7d6 100644 --- a/packages/utils/lib/index.ts +++ b/packages/utils/lib/index.ts @@ -1,3 +1,4 @@ export { default as addEventListeners } from './addEventListeners'; -export { default as privateKeyToPeerId } from './privateKeyToPeerId'; export { default as libp2pLoggerFactory } from './logger'; +export { default as privateKeyToPeerId } from './privateKeyToPeerId'; +export { default as readPrivateKeyFromFile } from './readPrivateKeyFromFile'; diff --git a/packages/utils/lib/readPrivateKeyFromFile.ts b/packages/utils/lib/readPrivateKeyFromFile.ts new file mode 100644 index 0000000..90a4c77 --- /dev/null +++ b/packages/utils/lib/readPrivateKeyFromFile.ts @@ -0,0 +1,26 @@ +import { generateKeyPair, marshalPrivateKey } from '@libp2p/crypto/keys'; +import { readFile, writeFile } from 'fs/promises'; +import { resolve } from 'path'; + +/** + * read private key from a file and return its string representation, creating + * the file with a random private key if it doesn't exist + * @param path relative or absolute path to the file + */ +const readPrivateKeyFromFile = async (path: string) => { + const fullPath = resolve(path); + try { + return await readFile(fullPath, 'utf-8'); + } catch (error) { + const privateKey = await generateKeyPair('Ed25519'); + const privateKeyString = Buffer.from( + marshalPrivateKey(privateKey), + ).toString('hex'); + + await writeFile(fullPath, privateKeyString, 'utf-8'); + + return privateKeyString; + } +}; + +export default readPrivateKeyFromFile; From 493842ef8bf4f023d242a91943f9e0ad547dcd0a Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 06:16:39 +0330 Subject: [PATCH 02/35] chore: add global test package --- tests/global/.eslintignore | 1 + tests/global/README.md | 11 +++++++++ tests/global/package.json | 39 ++++++++++++++++++++++++++++++ tests/global/ts-node-esm-loader.js | 15 ++++++++++++ tests/global/tsconfig.json | 20 +++++++++++++++ 5 files changed, 86 insertions(+) create mode 100644 tests/global/.eslintignore create mode 100644 tests/global/README.md create mode 100644 tests/global/package.json create mode 100644 tests/global/ts-node-esm-loader.js create mode 100644 tests/global/tsconfig.json diff --git a/tests/global/.eslintignore b/tests/global/.eslintignore new file mode 100644 index 0000000..1521c8b --- /dev/null +++ b/tests/global/.eslintignore @@ -0,0 +1 @@ +dist diff --git a/tests/global/README.md b/tests/global/README.md new file mode 100644 index 0000000..c98d4a6 --- /dev/null +++ b/tests/global/README.md @@ -0,0 +1,11 @@ +# RoseNet global test + +## Table of contents + +- [RoseNet global test](#rosenet-global-test) + - [Table of contents](#table-of-contents) + - [Introduction](#introduction) + +## Introduction + +RoseNet global test diff --git a/tests/global/package.json b/tests/global/package.json new file mode 100644 index 0000000..5c6611f --- /dev/null +++ b/tests/global/package.json @@ -0,0 +1,39 @@ +{ + "name": "@rosenet-tests/global", + "private": true, + "version": "0.1.0", + "description": "RoseNet global test", + "repository": "https://github.com/rosen-bridge/rosenet", + "license": "GPL-3.0", + "author": "Rosen Team", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "lint": "eslint --fix . && npm run prettify", + "prettify": "prettier --write . --ignore-path ./.gitignore", + "start:node": "node --loader ./ts-node-esm-loader.js --loader extensionless ./src/node/node.ts", + "start:relay": "node --loader ./ts-node-esm-loader.js --loader extensionless ./src/relay/relay.ts", + "type-check": "tsc --noEmit" + }, + "devDependencies": { + "@types/express": "^5.0.0", + "@types/lodash-es": "^4.17.12", + "@types/node": "^20.11.9", + "@typescript-eslint/eslint-plugin": "^6.19.1", + "@typescript-eslint/parser": "^6.19.1", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "prettier": "^3.2.4", + "typescript": "^5.3.3" + }, + "dependencies": { + "@influxdata/influxdb-client": "^1.35.0", + "@rosen-bridge/rosenet-node": "^0.1.0", + "@rosen-bridge/rosenet-relay": "^0.1.0", + "extensionless": "^1.9.6", + "lodash-es": "^4.17.21", + "ts-node": "^10.7.0", + "tsconfig-paths": "^4.1.2" + } +} diff --git a/tests/global/ts-node-esm-loader.js b/tests/global/ts-node-esm-loader.js new file mode 100644 index 0000000..6a27e30 --- /dev/null +++ b/tests/global/ts-node-esm-loader.js @@ -0,0 +1,15 @@ +import { resolve as resolveTs } from 'ts-node/esm'; +import * as tsConfigPaths from 'tsconfig-paths'; +import { pathToFileURL } from 'url'; + +const { absoluteBaseUrl, paths } = tsConfigPaths.loadConfig(); +const matchPath = tsConfigPaths.createMatchPath(absoluteBaseUrl, paths); + +export function resolve(specifier, ctx, defaultResolve) { + const match = matchPath(specifier); + return match + ? resolveTs(pathToFileURL(`${match}`).href, ctx, defaultResolve) + : resolveTs(specifier, ctx, defaultResolve); +} + +export { load, transformSource } from 'ts-node/esm'; diff --git a/tests/global/tsconfig.json b/tests/global/tsconfig.json new file mode 100644 index 0000000..e6464bb --- /dev/null +++ b/tests/global/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "baseUrl": ".", + }, + "include": ["src"], + "ts-node": { + "esm": true, + "transpileOnly": true, + }, + "references": [ + { + "path": "../../packages/rosenet-node/tsconfig.build.json", + }, + { + "path": "../../packages/rosenet-relay/tsconfig.build.json", + }, + ], +} From 0a9559418cf2563f4c3a2d1d40fd36dadb4eed02 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 06:16:59 +0330 Subject: [PATCH 03/35] chore: add more items to `.dockerignore` --- .dockerignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.dockerignore b/.dockerignore index fb0c88b..c1e133f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,6 @@ **/node_modules **/coverage **/.terraform +.git +.gitignore +*.md From eb68458ed2c0148e4f6fb15db31e82fe91ab0bd4 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 06:19:32 +0330 Subject: [PATCH 04/35] feat(global-test): implement node logic --- package-lock.json | 283 +++++++++++++++----- tests/global/src/node/.env.example | 15 ++ tests/global/src/node/.env.influxdb | 6 + tests/global/src/node/.env.service | 10 + tests/global/src/node/Dockerfile | 23 ++ tests/global/src/node/config.ts | 16 ++ tests/global/src/node/docker-compose.yaml | 43 +++ tests/global/src/node/metric-store.ts | 55 ++++ tests/global/src/node/node.ts | 39 +++ tests/global/src/node/registerHandlers.ts | 30 +++ tests/global/src/node/scenarios/break.ts | 14 + tests/global/src/node/scenarios/combined.ts | 23 ++ tests/global/src/node/scenarios/direct.ts | 72 +++++ tests/global/src/node/scenarios/pubsub.ts | 35 +++ tests/global/src/node/types.ts | 5 + tests/global/src/node/utils.ts | 17 ++ 16 files changed, 620 insertions(+), 66 deletions(-) create mode 100644 tests/global/src/node/.env.example create mode 100644 tests/global/src/node/.env.influxdb create mode 100644 tests/global/src/node/.env.service create mode 100644 tests/global/src/node/Dockerfile create mode 100644 tests/global/src/node/config.ts create mode 100644 tests/global/src/node/docker-compose.yaml create mode 100644 tests/global/src/node/metric-store.ts create mode 100644 tests/global/src/node/node.ts create mode 100644 tests/global/src/node/registerHandlers.ts create mode 100644 tests/global/src/node/scenarios/break.ts create mode 100644 tests/global/src/node/scenarios/combined.ts create mode 100644 tests/global/src/node/scenarios/direct.ts create mode 100644 tests/global/src/node/scenarios/pubsub.ts create mode 100644 tests/global/src/node/types.ts create mode 100644 tests/global/src/node/utils.ts diff --git a/package-lock.json b/package-lock.json index 51f3042..10fe2f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1171,7 +1171,6 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -1183,7 +1182,6 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1651,6 +1649,11 @@ "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "node_modules/@influxdata/influxdb-client": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client/-/influxdb-client-1.35.0.tgz", + "integrity": "sha512-woWMi8PDpPQpvTsRaUw4Ig+nOGS/CWwAwS66Fa1Vr/EkW+NEwxI8YfPBsdBMn33jK2Y86/qMiiuX/ROHIkJLTw==" + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -1690,7 +1693,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1707,8 +1709,7 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.22", @@ -2438,6 +2439,10 @@ "resolved": "packages/utils", "link": true }, + "node_modules/@rosenet-tests/global": { + "resolved": "tests/global", + "link": true + }, "node_modules/@rosenet-tests/scale": { "resolved": "tests/scale", "link": true @@ -2484,26 +2489,41 @@ "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/dns-packet": { "version": "5.6.5", @@ -2519,11 +2539,41 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz", + "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -2543,11 +2593,20 @@ "dev": true }, "node_modules/@types/lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.12.tgz", + "integrity": "sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==", "dev": true }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/lodash.merge": { "version": "4.6.9", "resolved": "https://registry.npmjs.org/@types/lodash.merge/-/lodash.merge-4.6.9.tgz", @@ -2557,6 +2616,12 @@ "@types/lodash": "*" } }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, "node_modules/@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", @@ -2582,12 +2647,45 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, + "node_modules/@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, "node_modules/@types/semver": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/sinon": { "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", @@ -2944,7 +3042,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -2965,7 +3062,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -3066,8 +3162,7 @@ "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, "node_modules/argparse": { "version": "2.0.1", @@ -3342,14 +3437,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3616,8 +3716,7 @@ "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -3805,17 +3904,20 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { @@ -3867,7 +3969,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, "engines": { "node": ">=0.3.1" } @@ -4033,6 +4134,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", @@ -4416,8 +4538,7 @@ "node_modules/extensionless": { "version": "1.9.6", "resolved": "https://registry.npmjs.org/extensionless/-/extensionless-1.9.6.tgz", - "integrity": "sha512-40F6zThJu1MxaT1A1pJ/2SHlU1BPYYnQNHt0j2ZlPuxxm2ddMcNc1D7uS/LGc4K3VwMEMaZLkCdHWaKk0LnQXA==", - "dev": true + "integrity": "sha512-40F6zThJu1MxaT1A1pJ/2SHlU1BPYYnQNHt0j2ZlPuxxm2ddMcNc1D7uS/LGc4K3VwMEMaZLkCdHWaKk0LnQXA==" }, "node_modules/external-editor": { "version": "3.1.0", @@ -4660,16 +4781,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4867,12 +4992,12 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5776,7 +5901,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -6118,6 +6242,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "license": "MIT" @@ -6277,8 +6406,7 @@ "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "node_modules/map-obj": { "version": "4.3.0", @@ -6417,7 +6545,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7671,16 +7798,17 @@ "dev": true }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7720,14 +7848,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8197,7 +8329,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, "engines": { "node": ">=4" } @@ -8389,7 +8520,6 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -8432,7 +8562,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", - "dev": true, "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -8569,7 +8698,6 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8680,8 +8808,7 @@ "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "node_modules/v8-to-istanbul": { "version": "9.2.0", @@ -9130,7 +9257,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, "engines": { "node": ">=6" } @@ -9967,6 +10093,31 @@ "typescript": "^5.3.3" } }, + "tests/global": { + "name": "@rosenet-tests/global", + "version": "0.1.0", + "license": "GPL-3.0", + "dependencies": { + "@influxdata/influxdb-client": "^1.35.0", + "@rosen-bridge/rosenet-node": "^0.1.0", + "@rosen-bridge/rosenet-relay": "^0.1.0", + "extensionless": "^1.9.6", + "lodash-es": "^4.17.21", + "ts-node": "^10.7.0", + "tsconfig-paths": "^4.1.2" + }, + "devDependencies": { + "@types/express": "^5.0.0", + "@types/lodash-es": "^4.17.12", + "@types/node": "^20.11.9", + "@typescript-eslint/eslint-plugin": "^6.19.1", + "@typescript-eslint/parser": "^6.19.1", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "prettier": "^3.2.4", + "typescript": "^5.3.3" + } + }, "tests/scale": { "name": "@rosenet-tests/scale", "version": "0.0.0", diff --git a/tests/global/src/node/.env.example b/tests/global/src/node/.env.example new file mode 100644 index 0000000..4aaf6f6 --- /dev/null +++ b/tests/global/src/node/.env.example @@ -0,0 +1,15 @@ +# Required +RELAY_MULTIADDRS= + +# Optional +SHOULD_SEND_DIRECT_TO_OLD_PEERS= +DIRECT_BURST_SIZE= +PUBSUB_BURST_SIZE= +MIN_IDLE_TIME= +MAX_IDLE_TIME= +MIN_MESSAGE_SIZE= +MAX_MESSAGE_SIZE= +MIN_SCNEARIO_DURATION= +MAX_SCNEARIO_DURATION= +SERVICE_PORT= +INFLUXDB_PORT= diff --git a/tests/global/src/node/.env.influxdb b/tests/global/src/node/.env.influxdb new file mode 100644 index 0000000..6940744 --- /dev/null +++ b/tests/global/src/node/.env.influxdb @@ -0,0 +1,6 @@ +DOCKER_INFLUXDB_INIT_MODE=setup +DOCKER_INFLUXDB_INIT_USERNAME=admin +DOCKER_INFLUXDB_INIT_PASSWORD=1234 +DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=admintoken +DOCKER_INFLUXDB_INIT_ORG=Rosen +DOCKER_INFLUXDB_INIT_BUCKET=RoseNet diff --git a/tests/global/src/node/.env.service b/tests/global/src/node/.env.service new file mode 100644 index 0000000..0cd1788 --- /dev/null +++ b/tests/global/src/node/.env.service @@ -0,0 +1,10 @@ +SHOULD_SEND_DIRECT_TO_OLD_PEERS=${SHOULD_SEND_DIRECT_TO_OLD_PEERS:-} +DIRECT_BURST_SIZE=${DIRECT_BURST_SIZE:-} +PUBSUB_BURST_SIZE=${PUBSUB_BURST_SIZE:-} +MIN_IDLE_TIME=${MIN_IDLE_TIME:-} +MAX_IDLE_TIME=${MAX_IDLE_TIME:-} +MIN_MESSAGE_SIZE=${MIN_MESSAGE_SIZE:-} +MAX_MESSAGE_SIZE=${MAX_MESSAGE_SIZE:-} +MIN_SCNEARIO_DURATION=${MIN_SCNEARIO_DURATION:-} +MAX_SCNEARIO_DURATION=${MAX_SCNEARIO_DURATION:-} +RELAY_MULTIADDRS=${RELAY_MULTIADDRS:?} diff --git a/tests/global/src/node/Dockerfile b/tests/global/src/node/Dockerfile new file mode 100644 index 0000000..c088557 --- /dev/null +++ b/tests/global/src/node/Dockerfile @@ -0,0 +1,23 @@ +FROM node:20-slim AS base +WORKDIR /app +COPY . /app + +FROM base as build +RUN --mount=type=cache,target=/root/.npm npm i +RUN npm run build + +FROM base as prod-deps +RUN --mount=type=cache,target=/root/.npm npm i --omit=dev +RUN mkdir -p /app/packages/rosenet-node/node_modules +RUN mkdir -p /app/packages/utils/node_modules +RUN mkdir -p /app/tests/global/node_modules + +FROM base +COPY --from=build /app/packages/utils/dist /app/packages/utils/dist +COPY --from=prod-deps /app/node_modules /app/node_modules +COPY --from=prod-deps /app/packages/rosenet-node/node_modules /app/packages/rosenet-node/node_modules +COPY --from=prod-deps /app/packages/utils/node_modules /app/packages/utils/node_modules +COPY --from=prod-deps /app/tests/global/node_modules /app/tests/global/node_modules +WORKDIR /app/tests/global + +CMD npm run start:node diff --git a/tests/global/src/node/config.ts b/tests/global/src/node/config.ts new file mode 100644 index 0000000..b0b15cb --- /dev/null +++ b/tests/global/src/node/config.ts @@ -0,0 +1,16 @@ +const optional = (value: string | undefined, fallbackValue: number) => + value ? +value : fallbackValue; + +export default { + shouldSendDirectToOldPeers: + process.env.SHOULD_SEND_DIRECT_TO_OLD_PEERS === 'true', + directBurstSize: optional(process.env.DIRECT_BURST_SIZE, 100), + pubsubBurstSize: optional(process.env.PUBSUB_BURST_SIZE, 10), + minIdleTime: optional(process.env.MIN_IDLE_TIME, 5), + maxIdleTime: optional(process.env.MAX_IDLE_TIME, 10_000), + minMessageSize: optional(process.env.MIN_MESSAGE_SIZE, 10_000), + maxMessageSize: optional(process.env.MAX_MESSAGE_SIZE, 500_000), + minScenarioDuration: optional(process.env.MIN_SCNEARIO_DURATION, 60_000), + maxScenarioDuration: optional(process.env.MAX_SCNEARIO_DURATION, 300_000), + relayMultiaddrs: process.env.RELAY_MULTIADDRS!.split(','), +}; diff --git a/tests/global/src/node/docker-compose.yaml b/tests/global/src/node/docker-compose.yaml new file mode 100644 index 0000000..25cd7dc --- /dev/null +++ b/tests/global/src/node/docker-compose.yaml @@ -0,0 +1,43 @@ +name: 'global-rosenet-test' + +services: + rosenet-node: + build: + context: ../../../.. + dockerfile: ./tests/global/src/node/Dockerfile + env_file: + - .env.service + ports: + - ${SERVICE_PORT:-55123}:55123 + networks: + - internal + volumes: + - rosenet-node-pk:/app/tests/global/.rosenet + depends_on: + - influxdb + + influxdb: + image: influxdb + env_file: + - .env.influxdb + ports: + - ${INFLUXDB_PORT:-8086}:8086 + networks: + - internal + volumes: + - influxdb-data:/var/lib/influxdb2 + - influxdb2-config:/etc/influxdb2 + healthcheck: + test: ['influx', 'ping'] + timeout: 5s + interval: 5s + retries: 2 + start_period: 10s + +volumes: + rosenet-node-pk: + influxdb-data: + influxdb2-config: + +networks: + internal: diff --git a/tests/global/src/node/metric-store.ts b/tests/global/src/node/metric-store.ts new file mode 100644 index 0000000..7ddc5bf --- /dev/null +++ b/tests/global/src/node/metric-store.ts @@ -0,0 +1,55 @@ +import { InfluxDB, Point } from '@influxdata/influxdb-client'; + +const influxDB = new InfluxDB({ + url: 'http://influxdb:8086', + token: 'helloworld', +}); +const writeApi = influxDB.getWriteApi('Rosen', 'RoseNet'); + +/** + * Save data about a direct message + * + * @param direction + * @param status + * @param peer + * @param latency + * @param size + */ +export const saveDirect = async ( + direction: 'send' | 'receive', + status: 'success' | 'failure', + peer: string, + latency: number, + size: number, +) => { + const point = new Point('direct') + .tag('direction', direction) + .tag('status', status) + .tag('peer', peer) + .floatField('latency', latency) + .uintField('size', size); + + writeApi.writePoint(point); + await writeApi.flush(); +}; + +/** + * Save data about a pubsub message + * + * @param direction + * @param latency + * @param size + */ +export const savePubsub = async ( + direction: 'send' | 'receive', + latency: number, + size: number, +) => { + const point = new Point('pubsub') + .tag('direction', direction) + .floatField('latency', latency) + .uintField('size', size); + + writeApi.writePoint(point); + await writeApi.flush(); +}; diff --git a/tests/global/src/node/node.ts b/tests/global/src/node/node.ts new file mode 100644 index 0000000..863e622 --- /dev/null +++ b/tests/global/src/node/node.ts @@ -0,0 +1,39 @@ +import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; +import { readPrivateKeyFromFile } from '@rosen-bridge/rosenet-utils'; +import { random, sample } from 'lodash-es'; + +import config from './config'; +import { registerHandlers } from './registerHandlers'; +import { breakSenario } from './scenarios/break'; +import { combinedScenario } from './scenarios/combined'; +import { directScenario } from './scenarios/direct'; +import { pubsubSenario } from './scenarios/pubsub'; + +const privateKey = await readPrivateKeyFromFile('.rosenet/pk'); + +const node = await createRoseNetNode({ + relay: { + multiaddrs: config.relayMultiaddrs, + }, + privateKey, +}); +await node.start(); + +registerHandlers(node); + +const scenarios = [ + directScenario(node), + pubsubSenario(node), + combinedScenario(node), + breakSenario(), +]; + +await Promise.all(scenarios.map((scenario) => scenario.next())); + +// eslint-disable-next-line no-constant-condition +while (true) { + const scenario = sample(scenarios)!; + await scenario.next( + random(config.minScenarioDuration, config.maxScenarioDuration), + ); +} diff --git a/tests/global/src/node/registerHandlers.ts b/tests/global/src/node/registerHandlers.ts new file mode 100644 index 0000000..eb9df10 --- /dev/null +++ b/tests/global/src/node/registerHandlers.ts @@ -0,0 +1,30 @@ +import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; + +import { saveDirect, savePubsub } from './metric-store'; + +/** + * Register pubsub and direct message handlers + * + * @param node + */ +export const registerHandlers = ( + node: Awaited>, +) => { + node.handleIncomingMessage(async (from, message) => { + const roundtripEnd = Date.now(); + const roundtripStart = +message!.slice(-13); + saveDirect( + 'receive', + 'success', + from, + roundtripEnd - roundtripStart, + message!.length, + ); + }); + + node.subscribe('rosenet-news', (message) => { + const roundtripEnd = Date.now(); + const roundtripStart = +message.slice(-13); + savePubsub('receive', roundtripEnd - roundtripStart, message.length); + }); +}; diff --git a/tests/global/src/node/scenarios/break.ts b/tests/global/src/node/scenarios/break.ts new file mode 100644 index 0000000..55b8c91 --- /dev/null +++ b/tests/global/src/node/scenarios/break.ts @@ -0,0 +1,14 @@ +import { Scenario } from '../types'; +import { waitMs } from '../utils'; + +/** + * A scenario during which the node simply does nothing + */ +export async function* breakSenario(): Scenario { + while (true) { + const timeout = yield; + console.log(`Running break scenario for ${timeout}ms`); + await waitMs(timeout); + console.log('Break scenario finished'); + } +} diff --git a/tests/global/src/node/scenarios/combined.ts b/tests/global/src/node/scenarios/combined.ts new file mode 100644 index 0000000..faef644 --- /dev/null +++ b/tests/global/src/node/scenarios/combined.ts @@ -0,0 +1,23 @@ +import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; + +import { directScenario } from './direct'; +import { pubsubSenario } from './pubsub'; +import { Scenario } from '../types'; + +/** + * A scenario during which the node runs direct and pubsub scenarios + * concurrently + */ +export async function* combinedScenario( + node: Awaited>, +): Scenario { + const direct = directScenario(node); + const pubsub = pubsubSenario(node); + + while (true) { + const timeout = yield; + console.log(`Running combined scenario for ${timeout}ms`); + await Promise.all([direct.next(timeout), pubsub.next(timeout)]); + console.log('Combined scenario finished'); + } +} diff --git a/tests/global/src/node/scenarios/direct.ts b/tests/global/src/node/scenarios/direct.ts new file mode 100644 index 0000000..89d01c6 --- /dev/null +++ b/tests/global/src/node/scenarios/direct.ts @@ -0,0 +1,72 @@ +import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; +import config from '../config'; +import { saveDirect } from '../metric-store'; +import { wait } from '../utils'; +import { random, sample } from 'lodash-es'; +import { Scenario } from '../types'; + +const allConnectedPeersSoFar = new Set(); + +/** + * A scenario during which the node sends direct messages to random nodes in + * bursts + */ +export async function* directScenario( + node: Awaited>, +): Scenario { + while (true) { + const timeout = yield; + console.log(`Running direct scenario for ${timeout}ms`); + const signal = AbortSignal.timeout(timeout); + const peers = node.info + .getConnectedPeers() + .filter( + (peer) => + !config.relayMultiaddrs.some((relayMultiaddr) => + relayMultiaddr.includes(peer), + ), + ); + peers.forEach(allConnectedPeersSoFar.add); + // eslint-disable-next-line no-constant-condition + while (true) { + if (signal.aborted) { + break; + } + for (let i = 0; i < config.directBurstSize; i++) { + const peer = sample( + config.shouldSendDirectToOldPeers + ? [...allConnectedPeersSoFar] + : peers, + ); + if (!peer) continue; + const message = 'r' + .repeat(random(config.minMessageSize, config.maxMessageSize)) + .concat(Date.now().toString()); + + const roundtripStart = Date.now(); + await node.sendMessage(peer, message, async (error) => { + const roundtripEnd = Date.now(); + saveDirect( + 'send', + error ? 'failure' : 'success', + peer, + roundtripEnd - roundtripStart, + message.length, + ); + // if (error) { + // saveDirect('failure', peer, 0, message.length); + // } else { + // saveDirect( + // 'success', + // peer, + // roundtripEnd - roundtripStart, + // message.length, + // ); + // } + }); + } + await wait(); + } + console.log('Direct scenario finished'); + } +} diff --git a/tests/global/src/node/scenarios/pubsub.ts b/tests/global/src/node/scenarios/pubsub.ts new file mode 100644 index 0000000..2646043 --- /dev/null +++ b/tests/global/src/node/scenarios/pubsub.ts @@ -0,0 +1,35 @@ +import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; +import config from '../config'; +import { wait } from '../utils'; +import { random } from 'lodash-es'; +import { savePubsub } from '../metric-store'; +import { Scenario } from '../types'; + +/** + * A scenario during which the node sends pubsub messages in bursts + */ +export async function* pubsubSenario( + node: Awaited>, +): Scenario { + while (true) { + const timeout = yield; + console.log(`Running pubsub scenario for ${timeout}ms`); + const signal = AbortSignal.timeout(timeout); + // eslint-disable-next-line no-constant-condition + while (true) { + if (signal.aborted) { + break; + } + for (let i = 0; i < config.pubsubBurstSize; i++) { + const message = 'r' + .repeat(random(config.minMessageSize, config.maxMessageSize)) + .concat(Date.now().toString()); + + await node.publish('rosenet-pubsub', message); + savePubsub('send', 0, message.length); + } + await wait(); + } + console.log('Pubsub scenario finished'); + } +} diff --git a/tests/global/src/node/types.ts b/tests/global/src/node/types.ts new file mode 100644 index 0000000..3db8b57 --- /dev/null +++ b/tests/global/src/node/types.ts @@ -0,0 +1,5 @@ +/** + * A scenario is an async generator that yields nothing, never returns, and + * accepts scenario duration as parameter to generator's `next` method + */ +export type Scenario = AsyncGenerator; diff --git a/tests/global/src/node/utils.ts b/tests/global/src/node/utils.ts new file mode 100644 index 0000000..8a19e64 --- /dev/null +++ b/tests/global/src/node/utils.ts @@ -0,0 +1,17 @@ +import { random } from 'lodash-es'; +import config from './config'; + +/** + * Wait for a specific duration + * @param ms + */ +export const waitMs = (ms: number) => + new Promise((resolve) => { + setTimeout(resolve, ms); + }); + +/** + * Wait for a random duration based on config + */ +export const wait = () => + waitMs(random(config.minIdleTime, config.maxIdleTime)); From 3a362c5db7c6beacad8cf2e8497368b4269b1df6 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 06:20:22 +0330 Subject: [PATCH 05/35] feat(global-test): implement relay logic --- tests/global/src/relay/.env.example | 6 ++++++ tests/global/src/relay/.env.service | 2 ++ tests/global/src/relay/Dockerfile | 23 ++++++++++++++++++++++ tests/global/src/relay/config.ts | 4 ++++ tests/global/src/relay/docker-compose.yaml | 16 +++++++++++++++ tests/global/src/relay/relay.ts | 20 +++++++++++++++++++ 6 files changed, 71 insertions(+) create mode 100644 tests/global/src/relay/.env.example create mode 100644 tests/global/src/relay/.env.service create mode 100644 tests/global/src/relay/Dockerfile create mode 100644 tests/global/src/relay/config.ts create mode 100644 tests/global/src/relay/docker-compose.yaml create mode 100644 tests/global/src/relay/relay.ts diff --git a/tests/global/src/relay/.env.example b/tests/global/src/relay/.env.example new file mode 100644 index 0000000..328d78a --- /dev/null +++ b/tests/global/src/relay/.env.example @@ -0,0 +1,6 @@ +# Required +WHITELIST= # comma separated peer ids + +# Optional +PORT= +MAX_RESERVATIONS= diff --git a/tests/global/src/relay/.env.service b/tests/global/src/relay/.env.service new file mode 100644 index 0000000..509cfb8 --- /dev/null +++ b/tests/global/src/relay/.env.service @@ -0,0 +1,2 @@ +WHITELIST=${WHITELIST:?} +MAX_RESERVATIONS=${MAX_RESERVATIONS:-50} diff --git a/tests/global/src/relay/Dockerfile b/tests/global/src/relay/Dockerfile new file mode 100644 index 0000000..cc8e540 --- /dev/null +++ b/tests/global/src/relay/Dockerfile @@ -0,0 +1,23 @@ +FROM node:20-slim AS base +WORKDIR /app +COPY . /app + +FROM base as build +RUN --mount=type=cache,target=/root/.npm npm i +RUN npm run build + +FROM base as prod-deps +RUN --mount=type=cache,target=/root/.npm npm i --omit=dev +RUN mkdir -p /app/packages/rosenet-relay/node_modules +RUN mkdir -p /app/packages/utils/node_modules +RUN mkdir -p /app/tests/global/node_modules + +FROM base +COPY --from=build /app/packages/utils/dist /app/packages/utils/dist +COPY --from=prod-deps /app/node_modules /app/node_modules +COPY --from=prod-deps /app/packages/rosenet-relay/node_modules /app/packages/rosenet-relay/node_modules +COPY --from=prod-deps /app/packages/utils/node_modules /app/packages/utils/node_modules +COPY --from=prod-deps /app/tests/global/node_modules /app/tests/global/node_modules +WORKDIR /app/tests/global + +CMD npm run start:relay diff --git a/tests/global/src/relay/config.ts b/tests/global/src/relay/config.ts new file mode 100644 index 0000000..bc789cf --- /dev/null +++ b/tests/global/src/relay/config.ts @@ -0,0 +1,4 @@ +export default { + whitelist: process.env.WHITELIST!.split(','), + maxReservations: +process.env.MAX_RESERVATIONS!, +}; diff --git a/tests/global/src/relay/docker-compose.yaml b/tests/global/src/relay/docker-compose.yaml new file mode 100644 index 0000000..caab057 --- /dev/null +++ b/tests/global/src/relay/docker-compose.yaml @@ -0,0 +1,16 @@ +name: 'global-rosenet-test' + +services: + rosenet-relay: + build: + context: ../../../.. + dockerfile: ./tests/global/src/relay/Dockerfile + env_file: + - .env.service + ports: + - ${PORT:-44123}:44123 + volumes: + - rosenet-relay-pk:/app/tests/global/.rosenet + +volumes: + rosenet-relay-pk: diff --git a/tests/global/src/relay/relay.ts b/tests/global/src/relay/relay.ts new file mode 100644 index 0000000..2748976 --- /dev/null +++ b/tests/global/src/relay/relay.ts @@ -0,0 +1,20 @@ +import { createRoseNetRelay } from '@rosen-bridge/rosenet-relay'; +import { readPrivateKeyFromFile } from '@rosen-bridge/rosenet-utils'; + +import config from './config'; + +const privateKey = await readPrivateKeyFromFile('.rosenet/pk'); + +const node = await createRoseNetRelay({ + logger: console, + privateKey, + listen: { + host: '0.0.0.0', + port: 44123, + }, + whitelist: config.whitelist, + maxReservations: config.maxReservations, +}); + +await node.start(); +node.subscribe('rosenet-news', () => {}); From 07de1643299c5c170d880a51a2bd32645e8a92bd Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 06:20:48 +0330 Subject: [PATCH 06/35] fix(global-test): fix husky issue when installing prod deps --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ff8db37..7c2d7bc 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "npm run build --workspaces", "coverage": "npm run coverage --workspaces", "lint": "npm run lint --workspaces", - "prepare": "husky install", + "prepare": "husky install || true", "release": "npm run release --workspaces", "test": "npm run test --workspaces", "type-check": "npm run type-check --workspaces", From 9aa59c8a15c95fc4771c67d158be8fc1f27227a0 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 10:40:09 +0330 Subject: [PATCH 07/35] feat(global-test): add logger --- package-lock.json | 726 +++++++++++++++++++- tests/global/.gitignore | 1 + tests/global/package.json | 2 + tests/global/src/node/.env.example | 1 + tests/global/src/node/bootstrap.ts | 25 + tests/global/src/node/docker-compose.yaml | 3 +- tests/global/src/node/logger.ts | 5 + tests/global/src/node/node.ts | 5 + tests/global/src/node/scenarios/break.ts | 9 +- tests/global/src/node/scenarios/combined.ts | 7 +- tests/global/src/node/scenarios/direct.ts | 10 +- tests/global/src/node/scenarios/pubsub.ts | 12 +- tests/global/src/relay/.env.example | 1 + tests/global/src/relay/bootstrap.ts | 25 + tests/global/src/relay/docker-compose.yaml | 1 + tests/global/src/relay/logger.ts | 5 + tests/global/src/relay/relay.ts | 4 +- 17 files changed, 825 insertions(+), 17 deletions(-) create mode 100644 tests/global/.gitignore create mode 100644 tests/global/src/node/bootstrap.ts create mode 100644 tests/global/src/node/logger.ts create mode 100644 tests/global/src/relay/bootstrap.ts create mode 100644 tests/global/src/relay/logger.ts diff --git a/package-lock.json b/package-lock.json index 10fe2f8..f792839 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1167,6 +1167,14 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -1187,6 +1195,16 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", @@ -2189,6 +2207,201 @@ "multiformats": "^13.0.0" } }, + "node_modules/@napi-rs/snappy-android-arm-eabi": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm-eabi/-/snappy-android-arm-eabi-7.2.2.tgz", + "integrity": "sha512-H7DuVkPCK5BlAr1NfSU8bDEN7gYs+R78pSHhDng83QxRnCLmVIZk33ymmIwurmoA1HrdTxbkbuNl+lMvNqnytw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-android-arm64": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm64/-/snappy-android-arm64-7.2.2.tgz", + "integrity": "sha512-2R/A3qok+nGtpVK8oUMcrIi5OMDckGYNoBLFyli3zp8w6IArPRfg1yOfVUcHvpUDTo9T7LOS1fXgMOoC796eQw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-darwin-arm64": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-arm64/-/snappy-darwin-arm64-7.2.2.tgz", + "integrity": "sha512-USgArHbfrmdbuq33bD5ssbkPIoT7YCXCRLmZpDS6dMDrx+iM7eD2BecNbOOo7/v1eu6TRmQ0xOzeQ6I/9FIi5g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-darwin-x64": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-x64/-/snappy-darwin-x64-7.2.2.tgz", + "integrity": "sha512-0APDu8iO5iT0IJKblk2lH0VpWSl9zOZndZKnBYIc+ei1npw2L5QvuErFOTeTdHBtzvUHASB+9bvgaWnQo4PvTQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-freebsd-x64": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-freebsd-x64/-/snappy-freebsd-x64-7.2.2.tgz", + "integrity": "sha512-mRTCJsuzy0o/B0Hnp9CwNB5V6cOJ4wedDTWEthsdKHSsQlO7WU9W1yP7H3Qv3Ccp/ZfMyrmG98Ad7u7lG58WXA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-arm-gnueabihf": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm-gnueabihf/-/snappy-linux-arm-gnueabihf-7.2.2.tgz", + "integrity": "sha512-v1uzm8+6uYjasBPcFkv90VLZ+WhLzr/tnfkZ/iD9mHYiULqkqpRuC8zvc3FZaJy5wLQE9zTDkTJN1IvUcZ+Vcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-arm64-gnu": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-gnu/-/snappy-linux-arm64-gnu-7.2.2.tgz", + "integrity": "sha512-LrEMa5pBScs4GXWOn6ZYXfQ72IzoolZw5txqUHVGs8eK4g1HR9HTHhb2oY5ySNaKakG5sOgMsb1rwaEnjhChmQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-arm64-musl": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-musl/-/snappy-linux-arm64-musl-7.2.2.tgz", + "integrity": "sha512-3orWZo9hUpGQcB+3aTLW7UFDqNCQfbr0+MvV67x8nMNYj5eAeUtMmUE/HxLznHO4eZ1qSqiTwLbVx05/Socdlw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-x64-gnu": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-gnu/-/snappy-linux-x64-gnu-7.2.2.tgz", + "integrity": "sha512-jZt8Jit/HHDcavt80zxEkDpH+R1Ic0ssiVCoueASzMXa7vwPJeF4ZxZyqUw4qeSy7n8UUExomu8G8ZbP6VKhgw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-x64-musl": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-musl/-/snappy-linux-x64-musl-7.2.2.tgz", + "integrity": "sha512-Dh96IXgcZrV39a+Tej/owcd9vr5ihiZ3KRix11rr1v0MWtVb61+H1GXXlz6+Zcx9y8jM1NmOuiIuJwkV4vZ4WA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-win32-arm64-msvc": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-arm64-msvc/-/snappy-win32-arm64-msvc-7.2.2.tgz", + "integrity": "sha512-9No0b3xGbHSWv2wtLEn3MO76Yopn1U2TdemZpCaEgOGccz1V+a/1d16Piz3ofSmnA13HGFz3h9NwZH9EOaIgYA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-win32-ia32-msvc": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-ia32-msvc/-/snappy-win32-ia32-msvc-7.2.2.tgz", + "integrity": "sha512-QiGe+0G86J74Qz1JcHtBwM3OYdTni1hX1PFyLRo3HhQUSpmi13Bzc1En7APn+6Pvo7gkrcy81dObGLDSxFAkQQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-win32-x64-msvc": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-x64-msvc/-/snappy-win32-x64-msvc-7.2.2.tgz", + "integrity": "sha512-a43cyx1nK0daw6BZxVcvDEXxKMFLSBSDTAhsFD0VqSKcC7MGUBMaqyoWUcMiI7LBSz4bxUmxDWKfCYzpEmeb3w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@noble/curves": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.5.0.tgz", @@ -2243,6 +2456,60 @@ "node": ">= 8" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.9.6", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", @@ -2412,6 +2679,11 @@ "win32" ] }, + "node_modules/@rosen-bridge/abstract-logger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@rosen-bridge/abstract-logger/-/abstract-logger-2.0.1.tgz", + "integrity": "sha512-GC2TpPxrDRkwJvhBVdaQCrkkUkp1DwwzCGT2akUv6HKfHijrNMv9BVus9ia7mv//Cy4zJCq0yw9N1n48lD2aOg==" + }, "node_modules/@rosen-bridge/changeset-formatter": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@rosen-bridge/changeset-formatter/-/changeset-formatter-0.1.0.tgz", @@ -2421,6 +2693,17 @@ "node": ">=20.11.0" } }, + "node_modules/@rosen-bridge/json-bigint": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@rosen-bridge/json-bigint/-/json-bigint-0.1.0.tgz", + "integrity": "sha512-38+N0/rxjyO57MOdDJHaq+4F0H9X0Pom/qyG7zMkdWN2fTtoWg++BmKZL7Cm5CH8QgX2w+6SqdLoEVC0AWTD0g==", + "dependencies": { + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, "node_modules/@rosen-bridge/logger-interface": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@rosen-bridge/logger-interface/-/logger-interface-0.2.0.tgz", @@ -2439,6 +2722,21 @@ "resolved": "packages/utils", "link": true }, + "node_modules/@rosen-bridge/winston-logger": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rosen-bridge/winston-logger/-/winston-logger-1.0.2.tgz", + "integrity": "sha512-ihPjybyjZSheYCYOij0M7i+lMyFxvXCAF9qLAUi4Ih2WIiWX8fyTbwcfZ5nt3oVIHUZt9jHgqFgwaSylrEvB/Q==", + "dependencies": { + "@rosen-bridge/abstract-logger": "^2.0.1", + "@rosen-bridge/json-bigint": "^0.1.0", + "winston": "^3.10.0", + "winston-daily-rotate-file": "^4.7.1", + "winston-loki": "^6.0.7" + }, + "engines": { + "node": ">=18.12.0" + } + }, "node_modules/@rosenet-tests/global": { "resolved": "tests/global", "link": true @@ -2699,6 +2997,11 @@ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==" }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", @@ -3038,6 +3341,17 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -3270,6 +3584,19 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -3318,6 +3645,14 @@ "node": ">=4" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -3379,6 +3714,17 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", + "bin": { + "btoa": "bin/btoa.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -3670,6 +4016,15 @@ "node": ">=16" } }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "dev": true, @@ -3683,9 +4038,30 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, "node_modules/colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", @@ -3694,6 +4070,15 @@ "node": ">=0.1.90" } }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "node_modules/commander": { "version": "9.4.1", "dev": true, @@ -4054,6 +4439,11 @@ "dev": true, "license": "MIT" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", @@ -4450,11 +4840,27 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -4603,6 +5009,11 @@ "reusify": "^1.0.4" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "dev": true, @@ -4614,6 +5025,14 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-stream-rotator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", + "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==", + "dependencies": { + "moment": "^2.29.1" + } + }, "node_modules/fill-range": { "version": "7.0.1", "dev": true, @@ -4667,6 +5086,11 @@ "dev": true, "license": "ISC" }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -5215,7 +5639,6 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, "license": "ISC" }, "node_modules/interface-datastore": { @@ -5859,6 +6282,14 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -5949,6 +6380,11 @@ "node": ">=6" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/levn": { "version": "0.4.1", "dev": true, @@ -6329,6 +6765,22 @@ "node": ">=8" } }, + "node_modules/logform": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", + "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -6584,6 +7036,14 @@ "ufo": "^1.3.2" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, "node_modules/mortice": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/mortice/-/mortice-3.0.4.tgz", @@ -6596,7 +7056,6 @@ }, "node_modules/ms": { "version": "2.1.2", - "dev": true, "license": "MIT" }, "node_modules/multiformats": { @@ -6716,6 +7175,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -6769,6 +7236,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/onetime": { "version": "5.1.2", "dev": true, @@ -7228,6 +7703,14 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/progress-events": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.0.tgz", @@ -7237,6 +7720,29 @@ "npm": ">=7.0.0" } }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/protons-runtime": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-5.4.0.tgz", @@ -7538,6 +8044,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -7754,6 +8273,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safe-regex-test": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", @@ -7771,6 +8309,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -7876,6 +8422,19 @@ "dev": true, "license": "ISC" }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8065,6 +8624,34 @@ "node": ">=8" } }, + "node_modules/snappy": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/snappy/-/snappy-7.2.2.tgz", + "integrity": "sha512-iADMq1kY0v3vJmGTuKcFWSXt15qYUz7wFkArOrsSg0IFfI3nJqIJvK2/ZbEIndg7erIJLtAVX2nSOqPz7DcwbA==", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/snappy-android-arm-eabi": "7.2.2", + "@napi-rs/snappy-android-arm64": "7.2.2", + "@napi-rs/snappy-darwin-arm64": "7.2.2", + "@napi-rs/snappy-darwin-x64": "7.2.2", + "@napi-rs/snappy-freebsd-x64": "7.2.2", + "@napi-rs/snappy-linux-arm-gnueabihf": "7.2.2", + "@napi-rs/snappy-linux-arm64-gnu": "7.2.2", + "@napi-rs/snappy-linux-arm64-musl": "7.2.2", + "@napi-rs/snappy-linux-x64-gnu": "7.2.2", + "@napi-rs/snappy-linux-x64-musl": "7.2.2", + "@napi-rs/snappy-win32-arm64-msvc": "7.2.2", + "@napi-rs/snappy-win32-ia32-msvc": "7.2.2", + "@napi-rs/snappy-win32-x64-msvc": "7.2.2" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8191,6 +8778,14 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -8220,6 +8815,14 @@ "mixme": "^0.5.1" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-argv": { "version": "0.3.1", "dev": true, @@ -8430,6 +9033,11 @@ "node": ">=8" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -8505,6 +9113,14 @@ "node": ">=8" } }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "1.0.3", "dev": true, @@ -8805,6 +9421,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-polyfill": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.12.tgz", + "integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -9110,6 +9736,98 @@ "node": ">=8" } }, + "node_modules/winston": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.15.0.tgz", + "integrity": "sha512-RhruH2Cj0bV0WgNL+lOfoUBI4DVfdUNjVnJGVovWZmrcKtrFTTRzgXYK2O9cymSGjrERCtaAeHwMNnUWXlwZow==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.6.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.7.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-daily-rotate-file": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz", + "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==", + "dependencies": { + "file-stream-rotator": "^0.6.1", + "object-hash": "^2.0.1", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "winston": "^3" + } + }, + "node_modules/winston-loki": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/winston-loki/-/winston-loki-6.1.3.tgz", + "integrity": "sha512-DjWtJ230xHyYQWr9mZJa93yhwHttn3JEtSYWP8vXZWJOahiQheUhf+88dSIidbGXB3u0oLweV6G1vkL/ouT62Q==", + "dependencies": { + "async-exit-hook": "2.0.1", + "btoa": "^1.2.1", + "protobufjs": "^7.2.4", + "url-polyfill": "^1.1.12", + "winston-transport": "^4.3.0" + }, + "optionalDependencies": { + "snappy": "^7.2.2" + } + }, + "node_modules/winston-transport": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.8.0.tgz", + "integrity": "sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA==", + "dependencies": { + "logform": "^2.6.1", + "readable-stream": "^4.5.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/winston/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -10099,8 +10817,10 @@ "license": "GPL-3.0", "dependencies": { "@influxdata/influxdb-client": "^1.35.0", + "@rosen-bridge/abstract-logger": "^2.0.1", "@rosen-bridge/rosenet-node": "^0.1.0", "@rosen-bridge/rosenet-relay": "^0.1.0", + "@rosen-bridge/winston-logger": "^1.0.2", "extensionless": "^1.9.6", "lodash-es": "^4.17.21", "ts-node": "^10.7.0", diff --git a/tests/global/.gitignore b/tests/global/.gitignore new file mode 100644 index 0000000..98d8a5a --- /dev/null +++ b/tests/global/.gitignore @@ -0,0 +1 @@ +logs diff --git a/tests/global/package.json b/tests/global/package.json index 5c6611f..0a6c030 100644 --- a/tests/global/package.json +++ b/tests/global/package.json @@ -29,8 +29,10 @@ }, "dependencies": { "@influxdata/influxdb-client": "^1.35.0", + "@rosen-bridge/abstract-logger": "^2.0.1", "@rosen-bridge/rosenet-node": "^0.1.0", "@rosen-bridge/rosenet-relay": "^0.1.0", + "@rosen-bridge/winston-logger": "^1.0.2", "extensionless": "^1.9.6", "lodash-es": "^4.17.21", "ts-node": "^10.7.0", diff --git a/tests/global/src/node/.env.example b/tests/global/src/node/.env.example index 4aaf6f6..13f675d 100644 --- a/tests/global/src/node/.env.example +++ b/tests/global/src/node/.env.example @@ -13,3 +13,4 @@ MIN_SCNEARIO_DURATION= MAX_SCNEARIO_DURATION= SERVICE_PORT= INFLUXDB_PORT= +LOGS_DIRECTORY= diff --git a/tests/global/src/node/bootstrap.ts b/tests/global/src/node/bootstrap.ts new file mode 100644 index 0000000..86b71f5 --- /dev/null +++ b/tests/global/src/node/bootstrap.ts @@ -0,0 +1,25 @@ +import { DefaultLoggerFactory } from '@rosen-bridge/abstract-logger'; +import WinstonLogger from '@rosen-bridge/winston-logger'; + +const winstonLogger = new WinstonLogger([ + { + type: 'console', + level: 'info', + }, + { + type: 'file', + level: 'info', + maxFiles: '10', + maxSize: '5MB', + path: './logs/info/', + }, + { + type: 'file', + level: 'debug', + maxFiles: '100', + maxSize: '5MB', + path: './logs/debug/', + }, +]); + +DefaultLoggerFactory.init(winstonLogger); diff --git a/tests/global/src/node/docker-compose.yaml b/tests/global/src/node/docker-compose.yaml index 25cd7dc..75bfcd6 100644 --- a/tests/global/src/node/docker-compose.yaml +++ b/tests/global/src/node/docker-compose.yaml @@ -13,6 +13,7 @@ services: - internal volumes: - rosenet-node-pk:/app/tests/global/.rosenet + - ${LOGS_DIRECTORY:-./logs}:/app/tests/global/logs depends_on: - influxdb @@ -28,7 +29,7 @@ services: - influxdb-data:/var/lib/influxdb2 - influxdb2-config:/etc/influxdb2 healthcheck: - test: ['influx', 'ping'] + test: ['CMD', 'influx', 'ping'] timeout: 5s interval: 5s retries: 2 diff --git a/tests/global/src/node/logger.ts b/tests/global/src/node/logger.ts new file mode 100644 index 0000000..7eeebd3 --- /dev/null +++ b/tests/global/src/node/logger.ts @@ -0,0 +1,5 @@ +import { DefaultLoggerFactory } from '@rosen-bridge/abstract-logger'; + +const logger = DefaultLoggerFactory.getInstance().getDefaultLogger(); + +export default logger; diff --git a/tests/global/src/node/node.ts b/tests/global/src/node/node.ts index 863e622..cff0723 100644 --- a/tests/global/src/node/node.ts +++ b/tests/global/src/node/node.ts @@ -1,3 +1,5 @@ +import './bootstrap'; + import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; import { readPrivateKeyFromFile } from '@rosen-bridge/rosenet-utils'; import { random, sample } from 'lodash-es'; @@ -9,6 +11,8 @@ import { combinedScenario } from './scenarios/combined'; import { directScenario } from './scenarios/direct'; import { pubsubSenario } from './scenarios/pubsub'; +import logger from './logger'; + const privateKey = await readPrivateKeyFromFile('.rosenet/pk'); const node = await createRoseNetNode({ @@ -16,6 +20,7 @@ const node = await createRoseNetNode({ multiaddrs: config.relayMultiaddrs, }, privateKey, + logger, }); await node.start(); diff --git a/tests/global/src/node/scenarios/break.ts b/tests/global/src/node/scenarios/break.ts index 55b8c91..e98a991 100644 --- a/tests/global/src/node/scenarios/break.ts +++ b/tests/global/src/node/scenarios/break.ts @@ -1,14 +1,17 @@ -import { Scenario } from '../types'; import { waitMs } from '../utils'; +import logger from '../logger'; + +import { Scenario } from '../types'; + /** * A scenario during which the node simply does nothing */ export async function* breakSenario(): Scenario { while (true) { const timeout = yield; - console.log(`Running break scenario for ${timeout}ms`); + logger.info(`Running break scenario for ${timeout}ms`); await waitMs(timeout); - console.log('Break scenario finished'); + logger.info('Break scenario finished'); } } diff --git a/tests/global/src/node/scenarios/combined.ts b/tests/global/src/node/scenarios/combined.ts index faef644..77226fa 100644 --- a/tests/global/src/node/scenarios/combined.ts +++ b/tests/global/src/node/scenarios/combined.ts @@ -2,6 +2,9 @@ import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; import { directScenario } from './direct'; import { pubsubSenario } from './pubsub'; + +import logger from '../logger'; + import { Scenario } from '../types'; /** @@ -16,8 +19,8 @@ export async function* combinedScenario( while (true) { const timeout = yield; - console.log(`Running combined scenario for ${timeout}ms`); + logger.info(`Running combined scenario for ${timeout}ms`); await Promise.all([direct.next(timeout), pubsub.next(timeout)]); - console.log('Combined scenario finished'); + logger.info('Combined scenario finished'); } } diff --git a/tests/global/src/node/scenarios/direct.ts b/tests/global/src/node/scenarios/direct.ts index 89d01c6..5c92327 100644 --- a/tests/global/src/node/scenarios/direct.ts +++ b/tests/global/src/node/scenarios/direct.ts @@ -1,8 +1,12 @@ import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; +import { random, sample } from 'lodash-es'; + import config from '../config'; import { saveDirect } from '../metric-store'; import { wait } from '../utils'; -import { random, sample } from 'lodash-es'; + +import logger from '../logger'; + import { Scenario } from '../types'; const allConnectedPeersSoFar = new Set(); @@ -16,7 +20,7 @@ export async function* directScenario( ): Scenario { while (true) { const timeout = yield; - console.log(`Running direct scenario for ${timeout}ms`); + logger.info(`Running direct scenario for ${timeout}ms`); const signal = AbortSignal.timeout(timeout); const peers = node.info .getConnectedPeers() @@ -67,6 +71,6 @@ export async function* directScenario( } await wait(); } - console.log('Direct scenario finished'); + logger.info('Direct scenario finished'); } } diff --git a/tests/global/src/node/scenarios/pubsub.ts b/tests/global/src/node/scenarios/pubsub.ts index 2646043..a819507 100644 --- a/tests/global/src/node/scenarios/pubsub.ts +++ b/tests/global/src/node/scenarios/pubsub.ts @@ -1,8 +1,12 @@ import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; -import config from '../config'; -import { wait } from '../utils'; import { random } from 'lodash-es'; + +import config from '../config'; import { savePubsub } from '../metric-store'; +import { wait } from '../utils'; + +import logger from '../logger'; + import { Scenario } from '../types'; /** @@ -13,7 +17,7 @@ export async function* pubsubSenario( ): Scenario { while (true) { const timeout = yield; - console.log(`Running pubsub scenario for ${timeout}ms`); + logger.info(`Running pubsub scenario for ${timeout}ms`); const signal = AbortSignal.timeout(timeout); // eslint-disable-next-line no-constant-condition while (true) { @@ -30,6 +34,6 @@ export async function* pubsubSenario( } await wait(); } - console.log('Pubsub scenario finished'); + logger.info('Pubsub scenario finished'); } } diff --git a/tests/global/src/relay/.env.example b/tests/global/src/relay/.env.example index 328d78a..88269c5 100644 --- a/tests/global/src/relay/.env.example +++ b/tests/global/src/relay/.env.example @@ -4,3 +4,4 @@ WHITELIST= # comma separated peer ids # Optional PORT= MAX_RESERVATIONS= +LOGS_DIRECTORY= diff --git a/tests/global/src/relay/bootstrap.ts b/tests/global/src/relay/bootstrap.ts new file mode 100644 index 0000000..86b71f5 --- /dev/null +++ b/tests/global/src/relay/bootstrap.ts @@ -0,0 +1,25 @@ +import { DefaultLoggerFactory } from '@rosen-bridge/abstract-logger'; +import WinstonLogger from '@rosen-bridge/winston-logger'; + +const winstonLogger = new WinstonLogger([ + { + type: 'console', + level: 'info', + }, + { + type: 'file', + level: 'info', + maxFiles: '10', + maxSize: '5MB', + path: './logs/info/', + }, + { + type: 'file', + level: 'debug', + maxFiles: '100', + maxSize: '5MB', + path: './logs/debug/', + }, +]); + +DefaultLoggerFactory.init(winstonLogger); diff --git a/tests/global/src/relay/docker-compose.yaml b/tests/global/src/relay/docker-compose.yaml index caab057..81b651b 100644 --- a/tests/global/src/relay/docker-compose.yaml +++ b/tests/global/src/relay/docker-compose.yaml @@ -11,6 +11,7 @@ services: - ${PORT:-44123}:44123 volumes: - rosenet-relay-pk:/app/tests/global/.rosenet + - ${LOGS_DIRECTORY:-./logs}:/app/tests/global/logs volumes: rosenet-relay-pk: diff --git a/tests/global/src/relay/logger.ts b/tests/global/src/relay/logger.ts new file mode 100644 index 0000000..7eeebd3 --- /dev/null +++ b/tests/global/src/relay/logger.ts @@ -0,0 +1,5 @@ +import { DefaultLoggerFactory } from '@rosen-bridge/abstract-logger'; + +const logger = DefaultLoggerFactory.getInstance().getDefaultLogger(); + +export default logger; diff --git a/tests/global/src/relay/relay.ts b/tests/global/src/relay/relay.ts index 2748976..dd6f090 100644 --- a/tests/global/src/relay/relay.ts +++ b/tests/global/src/relay/relay.ts @@ -3,10 +3,11 @@ import { readPrivateKeyFromFile } from '@rosen-bridge/rosenet-utils'; import config from './config'; +import logger from './logger'; + const privateKey = await readPrivateKeyFromFile('.rosenet/pk'); const node = await createRoseNetRelay({ - logger: console, privateKey, listen: { host: '0.0.0.0', @@ -14,6 +15,7 @@ const node = await createRoseNetRelay({ }, whitelist: config.whitelist, maxReservations: config.maxReservations, + logger, }); await node.start(); From e4f4fd11f759f4fb439d3ddd76b725e64073f5e9 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 10:47:06 +0330 Subject: [PATCH 08/35] chore(global-test): remove some commented code --- tests/global/src/node/scenarios/direct.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/global/src/node/scenarios/direct.ts b/tests/global/src/node/scenarios/direct.ts index 5c92327..873c7ef 100644 --- a/tests/global/src/node/scenarios/direct.ts +++ b/tests/global/src/node/scenarios/direct.ts @@ -57,16 +57,6 @@ export async function* directScenario( roundtripEnd - roundtripStart, message.length, ); - // if (error) { - // saveDirect('failure', peer, 0, message.length); - // } else { - // saveDirect( - // 'success', - // peer, - // roundtripEnd - roundtripStart, - // message.length, - // ); - // } }); } await wait(); From 8ccea829f6878829aa38accc2a9b0490c71e1504 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 10:47:44 +0330 Subject: [PATCH 09/35] feat(global-test): handle possible errors --- tests/global/src/node/metric-store.ts | 42 ++++++++++++++++++--------- tests/global/src/node/node.ts | 22 +++++++++++++- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/tests/global/src/node/metric-store.ts b/tests/global/src/node/metric-store.ts index 7ddc5bf..994010c 100644 --- a/tests/global/src/node/metric-store.ts +++ b/tests/global/src/node/metric-store.ts @@ -1,5 +1,7 @@ import { InfluxDB, Point } from '@influxdata/influxdb-client'; +import logger from './logger'; + const influxDB = new InfluxDB({ url: 'http://influxdb:8086', token: 'helloworld', @@ -22,15 +24,21 @@ export const saveDirect = async ( latency: number, size: number, ) => { - const point = new Point('direct') - .tag('direction', direction) - .tag('status', status) - .tag('peer', peer) - .floatField('latency', latency) - .uintField('size', size); + try { + const point = new Point('direct') + .tag('direction', direction) + .tag('status', status) + .tag('peer', peer) + .floatField('latency', latency) + .uintField('size', size); - writeApi.writePoint(point); - await writeApi.flush(); + writeApi.writePoint(point); + await writeApi.flush(); + } catch { + logger.warn( + 'An error occurred while saving direct message data in database', + ); + } }; /** @@ -45,11 +53,17 @@ export const savePubsub = async ( latency: number, size: number, ) => { - const point = new Point('pubsub') - .tag('direction', direction) - .floatField('latency', latency) - .uintField('size', size); + try { + const point = new Point('pubsub') + .tag('direction', direction) + .floatField('latency', latency) + .uintField('size', size); - writeApi.writePoint(point); - await writeApi.flush(); + writeApi.writePoint(point); + await writeApi.flush(); + } catch { + logger.warn( + 'An error occurred while saving pubsub message data in database', + ); + } }; diff --git a/tests/global/src/node/node.ts b/tests/global/src/node/node.ts index cff0723..5d1008d 100644 --- a/tests/global/src/node/node.ts +++ b/tests/global/src/node/node.ts @@ -13,7 +13,27 @@ import { pubsubSenario } from './scenarios/pubsub'; import logger from './logger'; -const privateKey = await readPrivateKeyFromFile('.rosenet/pk'); +process.on('uncaughtException', (error) => { + logger.error('An uncaught exception occurred'); + logger.debug(error?.message ?? 'Unknown error message'); + process.exit(1); +}); + +process.on('unhandledRejection', (error) => { + logger.error('An unhandled rejection occurred'); + logger.debug( + (error instanceof Error && error?.message) || 'Unknown error message', + ); + process.exit(1); +}); + +const privateKey = await readPrivateKeyFromFile('.rosenet/pk').catch( + (error) => { + logger.error('An error occurred while getting private key from file'); + logger.debug(error?.message ?? 'Unknown error message'); + process.exit(1); + }, +); const node = await createRoseNetNode({ relay: { From 2e59c11fcb68919711c41b874d43b5ff9567f2fc Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 11:02:46 +0330 Subject: [PATCH 10/35] chore(global-test): add more logs --- tests/global/src/node/metric-store.ts | 12 ++++++++++-- tests/global/src/node/node.ts | 2 ++ tests/global/src/node/registerHandlers.ts | 21 +++++++++++++------- tests/global/src/node/scenarios/direct.ts | 24 ++++++++++++++++++++--- tests/global/src/node/scenarios/pubsub.ts | 11 ++++++++--- tests/global/src/node/utils.ts | 5 +++-- tests/global/src/relay/relay.ts | 2 ++ 7 files changed, 60 insertions(+), 17 deletions(-) diff --git a/tests/global/src/node/metric-store.ts b/tests/global/src/node/metric-store.ts index 994010c..48fead5 100644 --- a/tests/global/src/node/metric-store.ts +++ b/tests/global/src/node/metric-store.ts @@ -34,10 +34,14 @@ export const saveDirect = async ( writeApi.writePoint(point); await writeApi.flush(); - } catch { + logger.debug('Direct message data saved in database'); + } catch (error) { logger.warn( 'An error occurred while saving direct message data in database', ); + logger.debug( + (error instanceof Error && error.message) || 'Unknown error message', + ); } }; @@ -61,9 +65,13 @@ export const savePubsub = async ( writeApi.writePoint(point); await writeApi.flush(); - } catch { + logger.debug('Pubsub message data saved in database'); + } catch (error) { logger.warn( 'An error occurred while saving pubsub message data in database', ); + logger.debug( + (error instanceof Error && error.message) || 'Unknown error message', + ); } }; diff --git a/tests/global/src/node/node.ts b/tests/global/src/node/node.ts index 5d1008d..bf862f5 100644 --- a/tests/global/src/node/node.ts +++ b/tests/global/src/node/node.ts @@ -43,8 +43,10 @@ const node = await createRoseNetNode({ logger, }); await node.start(); +logger.info('RoseNet node started'); registerHandlers(node); +logger.debug('Message handlers registered'); const scenarios = [ directScenario(node), diff --git a/tests/global/src/node/registerHandlers.ts b/tests/global/src/node/registerHandlers.ts index eb9df10..c200a39 100644 --- a/tests/global/src/node/registerHandlers.ts +++ b/tests/global/src/node/registerHandlers.ts @@ -2,6 +2,8 @@ import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; import { saveDirect, savePubsub } from './metric-store'; +import logger from './logger'; + /** * Register pubsub and direct message handlers * @@ -13,18 +15,23 @@ export const registerHandlers = ( node.handleIncomingMessage(async (from, message) => { const roundtripEnd = Date.now(); const roundtripStart = +message!.slice(-13); - saveDirect( - 'receive', - 'success', + const latency = roundtripEnd - roundtripStart; + saveDirect('receive', 'success', from, latency, message!.length); + logger.info('Direct message received', { from, - roundtripEnd - roundtripStart, - message!.length, - ); + latency, + messageLength: message!.length, + }); }); node.subscribe('rosenet-news', (message) => { const roundtripEnd = Date.now(); const roundtripStart = +message.slice(-13); - savePubsub('receive', roundtripEnd - roundtripStart, message.length); + const latency = roundtripEnd - roundtripStart; + savePubsub('receive', latency, message.length); + logger.info('Pubsub message received', { + latency, + messageLength: message!.length, + }); }); }; diff --git a/tests/global/src/node/scenarios/direct.ts b/tests/global/src/node/scenarios/direct.ts index 873c7ef..8e13b85 100644 --- a/tests/global/src/node/scenarios/direct.ts +++ b/tests/global/src/node/scenarios/direct.ts @@ -3,7 +3,7 @@ import { random, sample } from 'lodash-es'; import config from '../config'; import { saveDirect } from '../metric-store'; -import { wait } from '../utils'; +import { waitBeforeNextBurst } from '../utils'; import logger from '../logger'; @@ -36,6 +36,9 @@ export async function* directScenario( if (signal.aborted) { break; } + logger.info( + `Sending ${config.directBurstSize} direct messages to random peers`, + ); for (let i = 0; i < config.directBurstSize; i++) { const peer = sample( config.shouldSendDirectToOldPeers @@ -50,16 +53,31 @@ export async function* directScenario( const roundtripStart = Date.now(); await node.sendMessage(peer, message, async (error) => { const roundtripEnd = Date.now(); + const latency = roundtripEnd - roundtripStart; saveDirect( 'send', error ? 'failure' : 'success', peer, - roundtripEnd - roundtripStart, + latency, message.length, ); + if (error) { + logger.warn( + `An error occurred while sending message to peer ${peer.slice(0, 5)}...${peer.slice(-5)}`, + { error }, + ); + } else { + logger.info( + `Message sent to peer ${peer.slice(0, 5)}...${peer.slice(-5)} successfully`, + { + latency, + messageLength: message.length, + }, + ); + } }); } - await wait(); + await waitBeforeNextBurst(); } logger.info('Direct scenario finished'); } diff --git a/tests/global/src/node/scenarios/pubsub.ts b/tests/global/src/node/scenarios/pubsub.ts index a819507..f74f640 100644 --- a/tests/global/src/node/scenarios/pubsub.ts +++ b/tests/global/src/node/scenarios/pubsub.ts @@ -3,7 +3,7 @@ import { random } from 'lodash-es'; import config from '../config'; import { savePubsub } from '../metric-store'; -import { wait } from '../utils'; +import { waitBeforeNextBurst } from '../utils'; import logger from '../logger'; @@ -29,10 +29,15 @@ export async function* pubsubSenario( .repeat(random(config.minMessageSize, config.maxMessageSize)) .concat(Date.now().toString()); - await node.publish('rosenet-pubsub', message); + await node.publish('rosenet-pubsub', message).catch((error) => { + logger.warn(`An error occurred while publishing message`, { error }); + }); savePubsub('send', 0, message.length); + logger.info(`Message published successfully`, { + messageLength: message.length, + }); } - await wait(); + await waitBeforeNextBurst(); } logger.info('Pubsub scenario finished'); } diff --git a/tests/global/src/node/utils.ts b/tests/global/src/node/utils.ts index 8a19e64..c1e7a56 100644 --- a/tests/global/src/node/utils.ts +++ b/tests/global/src/node/utils.ts @@ -11,7 +11,8 @@ export const waitMs = (ms: number) => }); /** - * Wait for a random duration based on config + * Wait for a random duration based on config before firing next burst of + * messages */ -export const wait = () => +export const waitBeforeNextBurst = () => waitMs(random(config.minIdleTime, config.maxIdleTime)); diff --git a/tests/global/src/relay/relay.ts b/tests/global/src/relay/relay.ts index dd6f090..2cd0630 100644 --- a/tests/global/src/relay/relay.ts +++ b/tests/global/src/relay/relay.ts @@ -20,3 +20,5 @@ const node = await createRoseNetRelay({ await node.start(); node.subscribe('rosenet-news', () => {}); + +logger.info('RoseNet relay started'); From f238fbf7f001cb53c478a7a7c16054d5933f3d3a Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 11:07:28 +0330 Subject: [PATCH 11/35] fix(global-test): import bootstrap module in relay main module --- tests/global/src/relay/relay.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/global/src/relay/relay.ts b/tests/global/src/relay/relay.ts index 2cd0630..a55cbd3 100644 --- a/tests/global/src/relay/relay.ts +++ b/tests/global/src/relay/relay.ts @@ -1,3 +1,5 @@ +import './bootstrap'; + import { createRoseNetRelay } from '@rosen-bridge/rosenet-relay'; import { readPrivateKeyFromFile } from '@rosen-bridge/rosenet-utils'; From b2b7b454485fbbbe825d73ac815bab022e3728e3 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 11:36:48 +0330 Subject: [PATCH 12/35] fix(global-test): update influxdb token --- tests/global/src/node/.env.influxdb | 2 +- tests/global/src/node/metric-store.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/global/src/node/.env.influxdb b/tests/global/src/node/.env.influxdb index 6940744..39e8928 100644 --- a/tests/global/src/node/.env.influxdb +++ b/tests/global/src/node/.env.influxdb @@ -1,6 +1,6 @@ DOCKER_INFLUXDB_INIT_MODE=setup DOCKER_INFLUXDB_INIT_USERNAME=admin -DOCKER_INFLUXDB_INIT_PASSWORD=1234 +DOCKER_INFLUXDB_INIT_PASSWORD=admin1234 DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=admintoken DOCKER_INFLUXDB_INIT_ORG=Rosen DOCKER_INFLUXDB_INIT_BUCKET=RoseNet diff --git a/tests/global/src/node/metric-store.ts b/tests/global/src/node/metric-store.ts index 48fead5..4f948d6 100644 --- a/tests/global/src/node/metric-store.ts +++ b/tests/global/src/node/metric-store.ts @@ -4,7 +4,7 @@ import logger from './logger'; const influxDB = new InfluxDB({ url: 'http://influxdb:8086', - token: 'helloworld', + token: 'admintoken', }); const writeApi = influxDB.getWriteApi('Rosen', 'RoseNet'); From 888251f635723dc873384140167158c771c29587 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 11:37:48 +0330 Subject: [PATCH 13/35] fix(global-test): fix typo --- tests/global/src/node/node.ts | 8 ++++---- tests/global/src/node/scenarios/break.ts | 2 +- tests/global/src/node/scenarios/pubsub.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/global/src/node/node.ts b/tests/global/src/node/node.ts index bf862f5..cc00bef 100644 --- a/tests/global/src/node/node.ts +++ b/tests/global/src/node/node.ts @@ -6,10 +6,10 @@ import { random, sample } from 'lodash-es'; import config from './config'; import { registerHandlers } from './registerHandlers'; -import { breakSenario } from './scenarios/break'; +import { breakScenario } from './scenarios/break'; import { combinedScenario } from './scenarios/combined'; import { directScenario } from './scenarios/direct'; -import { pubsubSenario } from './scenarios/pubsub'; +import { pubsubScenario } from './scenarios/pubsub'; import logger from './logger'; @@ -50,9 +50,9 @@ logger.debug('Message handlers registered'); const scenarios = [ directScenario(node), - pubsubSenario(node), + pubsubScenario(node), combinedScenario(node), - breakSenario(), + breakScenario(), ]; await Promise.all(scenarios.map((scenario) => scenario.next())); diff --git a/tests/global/src/node/scenarios/break.ts b/tests/global/src/node/scenarios/break.ts index e98a991..ff1c23b 100644 --- a/tests/global/src/node/scenarios/break.ts +++ b/tests/global/src/node/scenarios/break.ts @@ -7,7 +7,7 @@ import { Scenario } from '../types'; /** * A scenario during which the node simply does nothing */ -export async function* breakSenario(): Scenario { +export async function* breakScenario(): Scenario { while (true) { const timeout = yield; logger.info(`Running break scenario for ${timeout}ms`); diff --git a/tests/global/src/node/scenarios/pubsub.ts b/tests/global/src/node/scenarios/pubsub.ts index f74f640..d35436e 100644 --- a/tests/global/src/node/scenarios/pubsub.ts +++ b/tests/global/src/node/scenarios/pubsub.ts @@ -12,7 +12,7 @@ import { Scenario } from '../types'; /** * A scenario during which the node sends pubsub messages in bursts */ -export async function* pubsubSenario( +export async function* pubsubScenario( node: Awaited>, ): Scenario { while (true) { From b7cbc3486a8961f0968ac71aa9c68f428ba9a264 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 11:38:07 +0330 Subject: [PATCH 14/35] refactor(global-test): separate service and rosenet loggers --- tests/global/src/node/logger.ts | 7 ++++--- tests/global/src/node/metric-store.ts | 14 ++++++------- tests/global/src/node/node.ts | 22 +++++++++++---------- tests/global/src/node/registerHandlers.ts | 6 +++--- tests/global/src/node/scenarios/break.ts | 6 +++--- tests/global/src/node/scenarios/combined.ts | 10 +++++----- tests/global/src/node/scenarios/direct.ts | 12 +++++------ tests/global/src/node/scenarios/pubsub.ts | 12 ++++++----- tests/global/src/relay/logger.ts | 7 ++++--- tests/global/src/relay/relay.ts | 6 +++--- 10 files changed, 54 insertions(+), 48 deletions(-) diff --git a/tests/global/src/node/logger.ts b/tests/global/src/node/logger.ts index 7eeebd3..c65b75d 100644 --- a/tests/global/src/node/logger.ts +++ b/tests/global/src/node/logger.ts @@ -1,5 +1,6 @@ import { DefaultLoggerFactory } from '@rosen-bridge/abstract-logger'; -const logger = DefaultLoggerFactory.getInstance().getDefaultLogger(); - -export default logger; +export const serviceLogger = + DefaultLoggerFactory.getInstance().getLogger('service'); +export const rosenetLogger = + DefaultLoggerFactory.getInstance().getLogger('rosenet'); diff --git a/tests/global/src/node/metric-store.ts b/tests/global/src/node/metric-store.ts index 4f948d6..29ef58f 100644 --- a/tests/global/src/node/metric-store.ts +++ b/tests/global/src/node/metric-store.ts @@ -1,6 +1,6 @@ import { InfluxDB, Point } from '@influxdata/influxdb-client'; -import logger from './logger'; +import { serviceLogger } from './logger'; const influxDB = new InfluxDB({ url: 'http://influxdb:8086', @@ -34,12 +34,12 @@ export const saveDirect = async ( writeApi.writePoint(point); await writeApi.flush(); - logger.debug('Direct message data saved in database'); + serviceLogger.debug('Direct message data saved in database'); } catch (error) { - logger.warn( + serviceLogger.warn( 'An error occurred while saving direct message data in database', ); - logger.debug( + serviceLogger.debug( (error instanceof Error && error.message) || 'Unknown error message', ); } @@ -65,12 +65,12 @@ export const savePubsub = async ( writeApi.writePoint(point); await writeApi.flush(); - logger.debug('Pubsub message data saved in database'); + serviceLogger.debug('Pubsub message data saved in database'); } catch (error) { - logger.warn( + serviceLogger.warn( 'An error occurred while saving pubsub message data in database', ); - logger.debug( + serviceLogger.debug( (error instanceof Error && error.message) || 'Unknown error message', ); } diff --git a/tests/global/src/node/node.ts b/tests/global/src/node/node.ts index cc00bef..32f94b5 100644 --- a/tests/global/src/node/node.ts +++ b/tests/global/src/node/node.ts @@ -11,17 +11,17 @@ import { combinedScenario } from './scenarios/combined'; import { directScenario } from './scenarios/direct'; import { pubsubScenario } from './scenarios/pubsub'; -import logger from './logger'; +import { serviceLogger, rosenetLogger } from './logger'; process.on('uncaughtException', (error) => { - logger.error('An uncaught exception occurred'); - logger.debug(error?.message ?? 'Unknown error message'); + serviceLogger.error('An uncaught exception occurred'); + serviceLogger.debug(error?.message ?? 'Unknown error message'); process.exit(1); }); process.on('unhandledRejection', (error) => { - logger.error('An unhandled rejection occurred'); - logger.debug( + serviceLogger.error('An unhandled rejection occurred'); + serviceLogger.debug( (error instanceof Error && error?.message) || 'Unknown error message', ); process.exit(1); @@ -29,8 +29,10 @@ process.on('unhandledRejection', (error) => { const privateKey = await readPrivateKeyFromFile('.rosenet/pk').catch( (error) => { - logger.error('An error occurred while getting private key from file'); - logger.debug(error?.message ?? 'Unknown error message'); + serviceLogger.error( + 'An error occurred while getting private key from file', + ); + serviceLogger.debug(error?.message ?? 'Unknown error message'); process.exit(1); }, ); @@ -40,13 +42,13 @@ const node = await createRoseNetNode({ multiaddrs: config.relayMultiaddrs, }, privateKey, - logger, + logger: rosenetLogger, }); await node.start(); -logger.info('RoseNet node started'); +serviceLogger.info('RoseNet node started'); registerHandlers(node); -logger.debug('Message handlers registered'); +serviceLogger.debug('Message handlers registered'); const scenarios = [ directScenario(node), diff --git a/tests/global/src/node/registerHandlers.ts b/tests/global/src/node/registerHandlers.ts index c200a39..9245340 100644 --- a/tests/global/src/node/registerHandlers.ts +++ b/tests/global/src/node/registerHandlers.ts @@ -2,7 +2,7 @@ import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; import { saveDirect, savePubsub } from './metric-store'; -import logger from './logger'; +import { serviceLogger } from './logger'; /** * Register pubsub and direct message handlers @@ -17,7 +17,7 @@ export const registerHandlers = ( const roundtripStart = +message!.slice(-13); const latency = roundtripEnd - roundtripStart; saveDirect('receive', 'success', from, latency, message!.length); - logger.info('Direct message received', { + serviceLogger.info('Direct message received', { from, latency, messageLength: message!.length, @@ -29,7 +29,7 @@ export const registerHandlers = ( const roundtripStart = +message.slice(-13); const latency = roundtripEnd - roundtripStart; savePubsub('receive', latency, message.length); - logger.info('Pubsub message received', { + serviceLogger.info('Pubsub message received', { latency, messageLength: message!.length, }); diff --git a/tests/global/src/node/scenarios/break.ts b/tests/global/src/node/scenarios/break.ts index ff1c23b..abbc487 100644 --- a/tests/global/src/node/scenarios/break.ts +++ b/tests/global/src/node/scenarios/break.ts @@ -1,6 +1,6 @@ import { waitMs } from '../utils'; -import logger from '../logger'; +import { serviceLogger } from '../logger'; import { Scenario } from '../types'; @@ -10,8 +10,8 @@ import { Scenario } from '../types'; export async function* breakScenario(): Scenario { while (true) { const timeout = yield; - logger.info(`Running break scenario for ${timeout}ms`); + serviceLogger.info(`Running break scenario for ${timeout}ms`); await waitMs(timeout); - logger.info('Break scenario finished'); + serviceLogger.info('Break scenario finished'); } } diff --git a/tests/global/src/node/scenarios/combined.ts b/tests/global/src/node/scenarios/combined.ts index 77226fa..5663c76 100644 --- a/tests/global/src/node/scenarios/combined.ts +++ b/tests/global/src/node/scenarios/combined.ts @@ -1,9 +1,9 @@ import { createRoseNetNode } from '@rosen-bridge/rosenet-node'; import { directScenario } from './direct'; -import { pubsubSenario } from './pubsub'; +import { pubsubScenario } from './pubsub'; -import logger from '../logger'; +import { serviceLogger } from '../logger'; import { Scenario } from '../types'; @@ -15,12 +15,12 @@ export async function* combinedScenario( node: Awaited>, ): Scenario { const direct = directScenario(node); - const pubsub = pubsubSenario(node); + const pubsub = pubsubScenario(node); while (true) { const timeout = yield; - logger.info(`Running combined scenario for ${timeout}ms`); + serviceLogger.info(`Running combined scenario for ${timeout}ms`); await Promise.all([direct.next(timeout), pubsub.next(timeout)]); - logger.info('Combined scenario finished'); + serviceLogger.info('Combined scenario finished'); } } diff --git a/tests/global/src/node/scenarios/direct.ts b/tests/global/src/node/scenarios/direct.ts index 8e13b85..1946db5 100644 --- a/tests/global/src/node/scenarios/direct.ts +++ b/tests/global/src/node/scenarios/direct.ts @@ -5,7 +5,7 @@ import config from '../config'; import { saveDirect } from '../metric-store'; import { waitBeforeNextBurst } from '../utils'; -import logger from '../logger'; +import { serviceLogger } from '../logger'; import { Scenario } from '../types'; @@ -20,7 +20,7 @@ export async function* directScenario( ): Scenario { while (true) { const timeout = yield; - logger.info(`Running direct scenario for ${timeout}ms`); + serviceLogger.info(`Running direct scenario for ${timeout}ms`); const signal = AbortSignal.timeout(timeout); const peers = node.info .getConnectedPeers() @@ -36,7 +36,7 @@ export async function* directScenario( if (signal.aborted) { break; } - logger.info( + serviceLogger.info( `Sending ${config.directBurstSize} direct messages to random peers`, ); for (let i = 0; i < config.directBurstSize; i++) { @@ -62,12 +62,12 @@ export async function* directScenario( message.length, ); if (error) { - logger.warn( + serviceLogger.warn( `An error occurred while sending message to peer ${peer.slice(0, 5)}...${peer.slice(-5)}`, { error }, ); } else { - logger.info( + serviceLogger.info( `Message sent to peer ${peer.slice(0, 5)}...${peer.slice(-5)} successfully`, { latency, @@ -79,6 +79,6 @@ export async function* directScenario( } await waitBeforeNextBurst(); } - logger.info('Direct scenario finished'); + serviceLogger.info('Direct scenario finished'); } } diff --git a/tests/global/src/node/scenarios/pubsub.ts b/tests/global/src/node/scenarios/pubsub.ts index d35436e..105eb65 100644 --- a/tests/global/src/node/scenarios/pubsub.ts +++ b/tests/global/src/node/scenarios/pubsub.ts @@ -5,7 +5,7 @@ import config from '../config'; import { savePubsub } from '../metric-store'; import { waitBeforeNextBurst } from '../utils'; -import logger from '../logger'; +import { serviceLogger } from '../logger'; import { Scenario } from '../types'; @@ -17,7 +17,7 @@ export async function* pubsubScenario( ): Scenario { while (true) { const timeout = yield; - logger.info(`Running pubsub scenario for ${timeout}ms`); + serviceLogger.info(`Running pubsub scenario for ${timeout}ms`); const signal = AbortSignal.timeout(timeout); // eslint-disable-next-line no-constant-condition while (true) { @@ -30,15 +30,17 @@ export async function* pubsubScenario( .concat(Date.now().toString()); await node.publish('rosenet-pubsub', message).catch((error) => { - logger.warn(`An error occurred while publishing message`, { error }); + serviceLogger.warn(`An error occurred while publishing message`, { + error, + }); }); savePubsub('send', 0, message.length); - logger.info(`Message published successfully`, { + serviceLogger.info(`Message published successfully`, { messageLength: message.length, }); } await waitBeforeNextBurst(); } - logger.info('Pubsub scenario finished'); + serviceLogger.info('Pubsub scenario finished'); } } diff --git a/tests/global/src/relay/logger.ts b/tests/global/src/relay/logger.ts index 7eeebd3..c65b75d 100644 --- a/tests/global/src/relay/logger.ts +++ b/tests/global/src/relay/logger.ts @@ -1,5 +1,6 @@ import { DefaultLoggerFactory } from '@rosen-bridge/abstract-logger'; -const logger = DefaultLoggerFactory.getInstance().getDefaultLogger(); - -export default logger; +export const serviceLogger = + DefaultLoggerFactory.getInstance().getLogger('service'); +export const rosenetLogger = + DefaultLoggerFactory.getInstance().getLogger('rosenet'); diff --git a/tests/global/src/relay/relay.ts b/tests/global/src/relay/relay.ts index a55cbd3..816f3af 100644 --- a/tests/global/src/relay/relay.ts +++ b/tests/global/src/relay/relay.ts @@ -5,7 +5,7 @@ import { readPrivateKeyFromFile } from '@rosen-bridge/rosenet-utils'; import config from './config'; -import logger from './logger'; +import { serviceLogger, rosenetLogger } from './logger'; const privateKey = await readPrivateKeyFromFile('.rosenet/pk'); @@ -17,10 +17,10 @@ const node = await createRoseNetRelay({ }, whitelist: config.whitelist, maxReservations: config.maxReservations, - logger, + logger: rosenetLogger, }); await node.start(); node.subscribe('rosenet-news', () => {}); -logger.info('RoseNet relay started'); +serviceLogger.info('RoseNet relay started'); From 53d1566811f4c79b380fb1ea21ee8fbfe6c68d43 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 11:38:48 +0330 Subject: [PATCH 15/35] chore: add an empty changeset --- .changeset/sweet-cars-cross.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changeset/sweet-cars-cross.md diff --git a/.changeset/sweet-cars-cross.md b/.changeset/sweet-cars-cross.md new file mode 100644 index 0000000..a845151 --- /dev/null +++ b/.changeset/sweet-cars-cross.md @@ -0,0 +1,2 @@ +--- +--- From e42d1a774c09f7ed2f7d989c39f8207dc96b7a3d Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 16:16:17 +0330 Subject: [PATCH 16/35] fix(global-test): fix docker-related issues --- .dockerignore | 1 + tests/global/src/node/Dockerfile | 1 + tests/global/src/relay/Dockerfile | 1 + 3 files changed, 3 insertions(+) diff --git a/.dockerignore b/.dockerignore index c1e133f..61de704 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,4 @@ .git .gitignore *.md +**/Dockerfile diff --git a/tests/global/src/node/Dockerfile b/tests/global/src/node/Dockerfile index c088557..f1cfe82 100644 --- a/tests/global/src/node/Dockerfile +++ b/tests/global/src/node/Dockerfile @@ -13,6 +13,7 @@ RUN mkdir -p /app/packages/utils/node_modules RUN mkdir -p /app/tests/global/node_modules FROM base +COPY --from=build /app/packages/rosenet-node/dist /app/packages/rosenet-node/dist COPY --from=build /app/packages/utils/dist /app/packages/utils/dist COPY --from=prod-deps /app/node_modules /app/node_modules COPY --from=prod-deps /app/packages/rosenet-node/node_modules /app/packages/rosenet-node/node_modules diff --git a/tests/global/src/relay/Dockerfile b/tests/global/src/relay/Dockerfile index cc8e540..929cd64 100644 --- a/tests/global/src/relay/Dockerfile +++ b/tests/global/src/relay/Dockerfile @@ -13,6 +13,7 @@ RUN mkdir -p /app/packages/utils/node_modules RUN mkdir -p /app/tests/global/node_modules FROM base +COPY --from=build /app/packages/utils/rosenet-relay /app/packages/utils/rosenet-relay COPY --from=build /app/packages/utils/dist /app/packages/utils/dist COPY --from=prod-deps /app/node_modules /app/node_modules COPY --from=prod-deps /app/packages/rosenet-relay/node_modules /app/packages/rosenet-relay/node_modules From fc6896076ae0efd52f75b4cf2f79d6b4a0e6adb8 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sat, 26 Oct 2024 18:45:22 +0330 Subject: [PATCH 17/35] doc(global-test): update README --- tests/global/README.md | 136 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/tests/global/README.md b/tests/global/README.md index c98d4a6..fd68ab4 100644 --- a/tests/global/README.md +++ b/tests/global/README.md @@ -4,8 +4,138 @@ - [RoseNet global test](#rosenet-global-test) - [Table of contents](#table-of-contents) - - [Introduction](#introduction) + - [System Requirements](#system-requirements) + - [Quick Start](#quick-start) + - [Detailed Setup Instructions](#detailed-setup-instructions) + - [Relay Setup](#relay-setup) + - [Node Setup](#node-setup) + - [Test Execution](#test-execution) + - [Data Collection and Analysis](#data-collection-and-analysis) -## Introduction +## System Requirements -RoseNet global test +- Git +- Docker and Docker Compose +- Access to a server with a public ip (for relay setup) + +## Quick Start + +```bash +# Clone the repository +git clone https://github.com/rosen-bridge/rosenet.git + +# Choose your setup type: +# For relay setup: +cd tests/global/src/relay + +# For node setup: +cd tests/global/src/node + +# Create service configuration file +cp .env.example .env +# Edit .env file with your configuration +docker compose up -d +``` + +## Detailed Setup Instructions + +### Relay Setup + +1. **Clone the Repository** + + ```bash + git clone https://github.com/rosen-bridge/rosenet.git + cd tests/global/src/relay + ``` + +2. **Configure Environment** + + ```bash + cp .env.example .env + ``` + +3. **Configuration Options** + + - Required: + - `WHITELIST`: Comma-separated list of allowed node peer IDs + +4. **Launch Relay** + + ```bash + docker compose up -d + ``` + +5. **Get Relay Multiaddress** + + - Check debug logs at `tests/global/src/relay/logs/debug/*.log` + - Format your multiaddress: + ``` + /ip4//tcp//p2p/ + # or + /dns4//tcp//p2p/ + ``` + + For example, having this log entry in a server with ip address of `100.100.100.100`, domain of `example.com`, and default 44123 port: + + ```log + 2024-10-26T07:36:54.652Z debug: [rosenet] PeerId 12D3KooWDvTUsPV6DSCJXJWJQjSoJ4q172kPRe4MHgxYqTz7J4jp generated + ``` + + Your multiaddr can be represented as either `/ip4/100.100.100.100/tcp/44123/p2p/12D3KooWDvTUsPV6DSCJXJWJQjSoJ4q172kPRe4MHgxYqTz7J4jp` or `/dns4/example.com/tcp/44123/p2p/12D3KooWDvTUsPV6DSCJXJWJQjSoJ4q172kPRe4MHgxYqTz7J4jp`. + +### Node Setup + +1. **Clone and Navigate** + + ```bash + git clone https://github.com/rosen-bridge/rosenet.git + cd tests/global/src/node + ``` + +2. **Configure Environment** + + ```bash + cp .env.example .env + ``` + +3. **Configuration Options** + + - Required: + - `RELAY_MULTIADDRS`: Comma-separated list of relay multiaddresses + +4. **Initial Run and Whitelisting** + + ```bash + docker compose up -d + ``` + + > **Note**: The first run will fail as your node needs whitelisting. Check debug logs at `tests/global/src/node/logs/debug/*.log` to find your node's peer ID. + +5. **Complete Setup** + - Get your node's peer ID from the debug logs + - Have it whitelisted in at least one relay + - Restart the service: + ```bash + docker compose up -d + ``` + +## Test Execution + +Once properly configured, your node will automatically participate in the test network by sending and receiving pubsub and direct messages, and logging relevant activities. + +## Data Collection and Analysis + +After the test is over, the results can be analyzed by checking the database of the nodes: + +1. **Access InfluxDB Dashboard** + + - URL: `http://localhost:8086` + - Credentials: + - Username: `admin` + - Password: `admin1234` + +2. **Extract Test Results** + - Navigate to "Data Explorer" + - Select bucket: `RoseNet` + - Choose measurements: `direct` and `pubsub` + - Export data using the CSV button From c5ab6d5a9f6d22009260baf9cbe29919c55c020a Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sun, 27 Oct 2024 16:06:48 +0330 Subject: [PATCH 18/35] fix(global-test): fix wrong topic name --- tests/global/src/node/scenarios/pubsub.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/global/src/node/scenarios/pubsub.ts b/tests/global/src/node/scenarios/pubsub.ts index 105eb65..48deee1 100644 --- a/tests/global/src/node/scenarios/pubsub.ts +++ b/tests/global/src/node/scenarios/pubsub.ts @@ -29,7 +29,7 @@ export async function* pubsubScenario( .repeat(random(config.minMessageSize, config.maxMessageSize)) .concat(Date.now().toString()); - await node.publish('rosenet-pubsub', message).catch((error) => { + await node.publish('rosenet-news', message).catch((error) => { serviceLogger.warn(`An error occurred while publishing message`, { error, }); From 313a286193d169aabc814da1c62129516302ec91 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sun, 27 Oct 2024 16:07:30 +0330 Subject: [PATCH 19/35] fix(global-test): fix wrong log sizes --- tests/global/src/node/bootstrap.ts | 4 ++-- tests/global/src/relay/bootstrap.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/global/src/node/bootstrap.ts b/tests/global/src/node/bootstrap.ts index 86b71f5..9a1a687 100644 --- a/tests/global/src/node/bootstrap.ts +++ b/tests/global/src/node/bootstrap.ts @@ -10,14 +10,14 @@ const winstonLogger = new WinstonLogger([ type: 'file', level: 'info', maxFiles: '10', - maxSize: '5MB', + maxSize: '20m', path: './logs/info/', }, { type: 'file', level: 'debug', maxFiles: '100', - maxSize: '5MB', + maxSize: '20m', path: './logs/debug/', }, ]); diff --git a/tests/global/src/relay/bootstrap.ts b/tests/global/src/relay/bootstrap.ts index 86b71f5..9a1a687 100644 --- a/tests/global/src/relay/bootstrap.ts +++ b/tests/global/src/relay/bootstrap.ts @@ -10,14 +10,14 @@ const winstonLogger = new WinstonLogger([ type: 'file', level: 'info', maxFiles: '10', - maxSize: '5MB', + maxSize: '20m', path: './logs/info/', }, { type: 'file', level: 'debug', maxFiles: '100', - maxSize: '5MB', + maxSize: '20m', path: './logs/debug/', }, ]); From 92c1f78f924c21c2797794361fb9de57805c2710 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Tue, 29 Oct 2024 12:37:51 +0330 Subject: [PATCH 20/35] fix(rosenet-node): fix failing dials when nodes are behind a non-symmetric NAT --- .changeset/tough-insects-behave.md | 5 ++ packages/rosenet-node/lib/constants.ts | 4 ++ .../rosenet-node/lib/stream/stream-service.ts | 51 ++++++++++++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 .changeset/tough-insects-behave.md diff --git a/.changeset/tough-insects-behave.md b/.changeset/tough-insects-behave.md new file mode 100644 index 0000000..5967424 --- /dev/null +++ b/.changeset/tough-insects-behave.md @@ -0,0 +1,5 @@ +--- +"@rosen-bridge/rosenet-node": patch +--- + +fix failing dials when nodes are behind a non-symmetric NAT diff --git a/packages/rosenet-node/lib/constants.ts b/packages/rosenet-node/lib/constants.ts index 6f874ae..c5257da 100644 --- a/packages/rosenet-node/lib/constants.ts +++ b/packages/rosenet-node/lib/constants.ts @@ -119,3 +119,7 @@ export const DEFAULT_FAIL_FAST_THRESHOLD = * Default gossipsubMaxInboundDataLength config of Gossipsub */ export const DEFAULT_GOSSIPSUB_MAX_INBOUND_DATA_LENGTH = 170_000_000; +/** + * Timeout used when dialing a peer's hopefully public multiaddress + */ +export const PUBLIC_MULTIADDR_DIAL_TIMEOUT = 5000; diff --git a/packages/rosenet-node/lib/stream/stream-service.ts b/packages/rosenet-node/lib/stream/stream-service.ts index 6c836e8..13d0374 100644 --- a/packages/rosenet-node/lib/stream/stream-service.ts +++ b/packages/rosenet-node/lib/stream/stream-service.ts @@ -1,4 +1,5 @@ import { peerIdFromString } from '@libp2p/peer-id'; +import { Multiaddr } from '@multiformats/multiaddr'; import { circuitBreaker, CircuitBreakerPolicy, @@ -14,7 +15,10 @@ import { Libp2p } from 'libp2p'; import RoseNetNodeContext from '../context/RoseNetNodeContext'; -import { ROSENET_DIRECT_PROTOCOL_V1 } from '../constants'; +import { + ROSENET_DIRECT_PROTOCOL_V1, + PUBLIC_MULTIADDR_DIAL_TIMEOUT, +} from '../constants'; import { RoseNetNodeError } from '../errors'; @@ -70,7 +74,50 @@ async function getRoseNetDirectStreamTo(to: string, node: Libp2p) { */ const connection = possibleOpenConnectionToPeer ?? - (await peerBreakers[to].execute(() => node.dial(peerId))); + (await peerBreakers[to].execute(async () => { + /** + * The nodes advertise hopefully public multiaddresses, but these + * multiaddresses may be wrong because of being behind a non-symmetric + * NAT. In addition, there is a bug in libp2p that allows the dial to a + * single multiaddress of a peer to take all the timeout of a dial to the + * peer. These combined will cause the dial to nodes with unreachable + * public multiaddresses to always fail, because their relayed + * multiaddress is never tried. + * + * As a workaround, we manually first try to dial the public multiaddress + * but with a reduced timeout, and then the other ones if the first dial + * fails. + * + * Libp2p bug GitHub issue: + * https://github.com/libp2p/js-libp2p/issues/2368 + */ + const peerAddresses = (await node.peerStore.get(peerId)).addresses; + const [publicAddresses, otherAddresses] = peerAddresses.reduce( + (partialPartitions, address) => + address.multiaddr.isThinWaistAddress() + ? [ + [...partialPartitions[0], address.multiaddr], + partialPartitions[1], + ] + : [ + partialPartitions[0], + [...partialPartitions[1], address.multiaddr], + ], + [[], []] as [Multiaddr[], Multiaddr[]], + ); + + if (publicAddresses) { + try { + return await node.dial(publicAddresses, { + signal: AbortSignal.timeout(PUBLIC_MULTIADDR_DIAL_TIMEOUT), + }); + } catch { + return await node.dial(otherAddresses); + } + } else { + return await node.dial(otherAddresses); + } + })); RoseNetNodeContext.logger.debug( possibleOpenConnectionToPeer From 19cfbdfef192e7a1962b762e7e6c9b895f7b8ee6 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Tue, 29 Oct 2024 12:40:15 +0330 Subject: [PATCH 21/35] fix(rosenet-node): advertise full relayed multiaddresses --- packages/rosenet-node/lib/createRoseNetNode.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rosenet-node/lib/createRoseNetNode.ts b/packages/rosenet-node/lib/createRoseNetNode.ts index e364544..c59dc32 100644 --- a/packages/rosenet-node/lib/createRoseNetNode.ts +++ b/packages/rosenet-node/lib/createRoseNetNode.ts @@ -90,13 +90,13 @@ const createRoseNetNode = async (config: PartialRoseNetNodeConfig) => { listen: [ `/ip4/${RoseNetNodeContext.config.host}/tcp/${RoseNetNodeContext.config.port}`, ...sampledRelayMultiaddrs.map( - (multiaddr) => `${multiaddr}/p2p-circuit`, + (multiaddr) => `${multiaddr}/p2p-circuit/p2p/${peerId.toString()}`, ), ], announce: [ announceMultiaddr, ...sampledRelayMultiaddrs.map( - (multiaddr) => `${multiaddr}/p2p-circuit`, + (multiaddr) => `${multiaddr}/p2p-circuit/p2p/${peerId.toString()}`, ), ], }, From 48d678094f01ce905c4345a8d12bdd14934885d4 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Tue, 29 Oct 2024 12:40:58 +0330 Subject: [PATCH 22/35] feat(rosenet-node): add `getDiscoveredPeers` to public APIs --- .changeset/eighty-news-peel.md | 5 +++++ packages/rosenet-node/lib/createRoseNetNode.ts | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 .changeset/eighty-news-peel.md diff --git a/.changeset/eighty-news-peel.md b/.changeset/eighty-news-peel.md new file mode 100644 index 0000000..8932f6e --- /dev/null +++ b/.changeset/eighty-news-peel.md @@ -0,0 +1,5 @@ +--- +"@rosen-bridge/rosenet-node": minor +--- + +add `getDiscoveredPeers` to public APIs for gettting a list of discovered peer ids diff --git a/packages/rosenet-node/lib/createRoseNetNode.ts b/packages/rosenet-node/lib/createRoseNetNode.ts index c59dc32..d4ebb51 100644 --- a/packages/rosenet-node/lib/createRoseNetNode.ts +++ b/packages/rosenet-node/lib/createRoseNetNode.ts @@ -164,6 +164,10 @@ const createRoseNetNode = async (config: PartialRoseNetNodeConfig) => { info: { getPeerId: () => node.peerId.toString(), getConnectedPeers: () => node.getPeers().map((peer) => peer.toString()), + getDiscoveredPeers: async () => { + const peers = await node.peerStore.all(); + return peers.map((peer) => peer.id.toString()); + }, }, }; }; From c3bec846215db692ec1a06e0fc86470a0fd868ba Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Tue, 29 Oct 2024 12:42:54 +0330 Subject: [PATCH 23/35] refactor(global-test): use discovered peers for sending direct messages --- tests/global/src/node/scenarios/direct.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/global/src/node/scenarios/direct.ts b/tests/global/src/node/scenarios/direct.ts index 1946db5..adb1d20 100644 --- a/tests/global/src/node/scenarios/direct.ts +++ b/tests/global/src/node/scenarios/direct.ts @@ -22,15 +22,12 @@ export async function* directScenario( const timeout = yield; serviceLogger.info(`Running direct scenario for ${timeout}ms`); const signal = AbortSignal.timeout(timeout); - const peers = node.info - .getConnectedPeers() - .filter( - (peer) => - !config.relayMultiaddrs.some((relayMultiaddr) => - relayMultiaddr.includes(peer), - ), - ); - peers.forEach(allConnectedPeersSoFar.add); + const peers = (await node.info.getDiscoveredPeers()).filter( + (peer) => + !config.relayMultiaddrs.some((relayMultiaddr) => + relayMultiaddr.includes(peer), + ), + ); // eslint-disable-next-line no-constant-condition while (true) { if (signal.aborted) { From 8be190c2604cadc4df1bf1e05adf3a9f5d812cf9 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Tue, 29 Oct 2024 12:43:44 +0330 Subject: [PATCH 24/35] fix(global-test): fix `this` binding issue --- tests/global/src/node/scenarios/direct.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/global/src/node/scenarios/direct.ts b/tests/global/src/node/scenarios/direct.ts index adb1d20..3a79323 100644 --- a/tests/global/src/node/scenarios/direct.ts +++ b/tests/global/src/node/scenarios/direct.ts @@ -28,6 +28,7 @@ export async function* directScenario( relayMultiaddr.includes(peer), ), ); + peers.forEach(allConnectedPeersSoFar.add.bind(allConnectedPeersSoFar)); // eslint-disable-next-line no-constant-condition while (true) { if (signal.aborted) { From 892f85fb727830753e4ca85c84664caab277671a Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Tue, 29 Oct 2024 15:02:55 +0330 Subject: [PATCH 25/35] chore(rosenet-node): change level of peer id log to info --- .changeset/seven-carrots-refuse.md | 5 +++++ packages/rosenet-node/lib/createRoseNetNode.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/seven-carrots-refuse.md diff --git a/.changeset/seven-carrots-refuse.md b/.changeset/seven-carrots-refuse.md new file mode 100644 index 0000000..520d009 --- /dev/null +++ b/.changeset/seven-carrots-refuse.md @@ -0,0 +1,5 @@ +--- +"@rosen-bridge/rosenet-node": patch +--- + +Change level of peer id log to info diff --git a/packages/rosenet-node/lib/createRoseNetNode.ts b/packages/rosenet-node/lib/createRoseNetNode.ts index d4ebb51..78093e2 100644 --- a/packages/rosenet-node/lib/createRoseNetNode.ts +++ b/packages/rosenet-node/lib/createRoseNetNode.ts @@ -64,7 +64,7 @@ const createRoseNetNode = async (config: PartialRoseNetNodeConfig) => { const peerId = await privateKeyToPeerId(RoseNetNodeContext.config.privateKey); - RoseNetNodeContext.logger.debug(`PeerId ${peerId.toString()} generated`); + RoseNetNodeContext.logger.info(`PeerId ${peerId.toString()} generated`); const announceMultiaddr = await addressService.getAnnounceMultiaddr( RoseNetNodeContext.config.port, From 13629a61c28a4481fad94b543a5fd251d8420e93 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Tue, 29 Oct 2024 15:03:23 +0330 Subject: [PATCH 26/35] chore(global-test): add a log statement --- tests/global/src/node/scenarios/pubsub.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/global/src/node/scenarios/pubsub.ts b/tests/global/src/node/scenarios/pubsub.ts index 48deee1..65f41fe 100644 --- a/tests/global/src/node/scenarios/pubsub.ts +++ b/tests/global/src/node/scenarios/pubsub.ts @@ -24,6 +24,9 @@ export async function* pubsubScenario( if (signal.aborted) { break; } + serviceLogger.info( + `Publishing ${config.pubsubBurstSize} messages`, + ); for (let i = 0; i < config.pubsubBurstSize; i++) { const message = 'r' .repeat(random(config.minMessageSize, config.maxMessageSize)) From 2ff57b201b60fe6efae19a536cad2319fbc06477 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 10:38:06 +0330 Subject: [PATCH 27/35] fix(rosenet-node): fix issues related to fail fast mode --- .../rosenet-node/lib/rosenet-direct/sendMessage.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/rosenet-node/lib/rosenet-direct/sendMessage.ts b/packages/rosenet-node/lib/rosenet-direct/sendMessage.ts index f597faf..049d06d 100644 --- a/packages/rosenet-node/lib/rosenet-direct/sendMessage.ts +++ b/packages/rosenet-node/lib/rosenet-direct/sendMessage.ts @@ -135,16 +135,16 @@ const sendMessageWithRetryAndBulkheadFactory = (node: Libp2p) => { const sendMessageInner = sendMessageFactory(node); const shouldFailFast = - bulkheadPolicy.executionSlots > + bulkheadPolicy.executionSlots < RoseNetNodeContext.config.direct.failFastThreshold; const maxAttempts = shouldFailFast - ? RoseNetNodeContext.config.direct.maxRetryAttempts - : RoseNetNodeContext.config.direct.failFastMaxRetryAttempts; + ? RoseNetNodeContext.config.direct.failFastMaxRetryAttempts + : RoseNetNodeContext.config.direct.maxRetryAttempts; const initialDelay = shouldFailFast - ? RoseNetNodeContext.config.direct.retryInitialDelay - : RoseNetNodeContext.config.direct.failFastRetryInitialDelay; + ? RoseNetNodeContext.config.direct.failFastRetryInitialDelay + : RoseNetNodeContext.config.direct.retryInitialDelay; const retryPolicy = retry(handleAll, { maxAttempts, @@ -160,7 +160,7 @@ const sendMessageWithRetryAndBulkheadFactory = (node: Libp2p) => { }); retryPolicy.onRetry((data) => { RoseNetNodeContext.logger.debug( - `Retry sending message (attempt #${data.attempt}/${RoseNetNodeContext.config.direct.maxRetryAttempts})`, + `Retry sending message (attempt #${data.attempt}/${maxAttempts})`, { message, }, @@ -176,7 +176,7 @@ const sendMessageWithRetryAndBulkheadFactory = (node: Libp2p) => { RoseNetNodeContext.logger.warn( 'Message sending failed, dropping message', { - lastOccurredError: error, + lastOccurredError: JSON.stringify(error), isFailFastEnabled: shouldFailFast, }, ); From fbeee7ce766886fd35849c2374838fdaeae3527a Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 10:51:12 +0330 Subject: [PATCH 28/35] fix(rosenet-node): handle issue in dialing relayed multiaddresses --- packages/rosenet-node/lib/stream/stream-service.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/rosenet-node/lib/stream/stream-service.ts b/packages/rosenet-node/lib/stream/stream-service.ts index 13d0374..9331f36 100644 --- a/packages/rosenet-node/lib/stream/stream-service.ts +++ b/packages/rosenet-node/lib/stream/stream-service.ts @@ -101,7 +101,12 @@ async function getRoseNetDirectStreamTo(to: string, node: Libp2p) { ] : [ partialPartitions[0], - [...partialPartitions[1], address.multiaddr], + [ + ...partialPartitions[1], + address.multiaddr.toString().endsWith('p2p-circuit') + ? address.multiaddr.encapsulate(`/p2p/${peerId.toString()}`) + : address.multiaddr, + ], ], [[], []] as [Multiaddr[], Multiaddr[]], ); From 5f905a6145659b1b866ea77cebe4524815d6d5e8 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 11:45:10 +0330 Subject: [PATCH 29/35] fix(global-test): switch from listening `uncaughtException` event to `uncaughtExceptionMonitor` --- tests/global/src/node/node.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/global/src/node/node.ts b/tests/global/src/node/node.ts index 32f94b5..5e64ffd 100644 --- a/tests/global/src/node/node.ts +++ b/tests/global/src/node/node.ts @@ -13,18 +13,8 @@ import { pubsubScenario } from './scenarios/pubsub'; import { serviceLogger, rosenetLogger } from './logger'; -process.on('uncaughtException', (error) => { - serviceLogger.error('An uncaught exception occurred'); - serviceLogger.debug(error?.message ?? 'Unknown error message'); - process.exit(1); -}); - -process.on('unhandledRejection', (error) => { - serviceLogger.error('An unhandled rejection occurred'); - serviceLogger.debug( - (error instanceof Error && error?.message) || 'Unknown error message', - ); - process.exit(1); +process.on('uncaughtExceptionMonitor', (error) => { + serviceLogger.error('An uncaught exception occurred', { error }); }); const privateKey = await readPrivateKeyFromFile('.rosenet/pk').catch( From aa79a62bb7d3ce04d6f56415d1eccb1b71840406 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 12:02:02 +0330 Subject: [PATCH 30/35] fix(global-test): fix issue in `.env.example` file --- tests/global/src/relay/.env.example | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/global/src/relay/.env.example b/tests/global/src/relay/.env.example index 88269c5..1847798 100644 --- a/tests/global/src/relay/.env.example +++ b/tests/global/src/relay/.env.example @@ -1,5 +1,6 @@ # Required -WHITELIST= # comma separated peer ids +# comma separated whitelisted peer ids +WHITELIST= # Optional PORT= From 6b57a05a7443a365c27763c2a74c077c4e3eeab7 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 12:48:26 +0330 Subject: [PATCH 31/35] chore: capitalize changesets --- .changeset/eighty-news-peel.md | 4 ++-- .changeset/tough-insects-behave.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.changeset/eighty-news-peel.md b/.changeset/eighty-news-peel.md index 8932f6e..0fc995f 100644 --- a/.changeset/eighty-news-peel.md +++ b/.changeset/eighty-news-peel.md @@ -1,5 +1,5 @@ --- -"@rosen-bridge/rosenet-node": minor +'@rosen-bridge/rosenet-node': minor --- -add `getDiscoveredPeers` to public APIs for gettting a list of discovered peer ids +Add `getDiscoveredPeers` to public APIs for gettting a list of discovered peer ids diff --git a/.changeset/tough-insects-behave.md b/.changeset/tough-insects-behave.md index 5967424..5267966 100644 --- a/.changeset/tough-insects-behave.md +++ b/.changeset/tough-insects-behave.md @@ -1,5 +1,5 @@ --- -"@rosen-bridge/rosenet-node": patch +'@rosen-bridge/rosenet-node': patch --- -fix failing dials when nodes are behind a non-symmetric NAT +Fix failing dials when nodes are behind a non-symmetric NAT From 7a9f9620ce89f34bfb817fa975475d785e78d468 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 12:52:43 +0330 Subject: [PATCH 32/35] fix(global-test): fix issue in relay Dockerfile --- tests/global/src/relay/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/global/src/relay/Dockerfile b/tests/global/src/relay/Dockerfile index 929cd64..5f90d1c 100644 --- a/tests/global/src/relay/Dockerfile +++ b/tests/global/src/relay/Dockerfile @@ -13,7 +13,7 @@ RUN mkdir -p /app/packages/utils/node_modules RUN mkdir -p /app/tests/global/node_modules FROM base -COPY --from=build /app/packages/utils/rosenet-relay /app/packages/utils/rosenet-relay +COPY --from=build /app/packages/rosenet-relay /app/packages/rosenet-relay COPY --from=build /app/packages/utils/dist /app/packages/utils/dist COPY --from=prod-deps /app/node_modules /app/node_modules COPY --from=prod-deps /app/packages/rosenet-relay/node_modules /app/packages/rosenet-relay/node_modules From b7b3d7cebd7d61596a6451fd4c651feed5ac7f0f Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 12:57:42 +0330 Subject: [PATCH 33/35] chore(rosenet-node): add logs for manual dialing --- .../rosenet-node/lib/stream/stream-service.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/rosenet-node/lib/stream/stream-service.ts b/packages/rosenet-node/lib/stream/stream-service.ts index 9331f36..3de2621 100644 --- a/packages/rosenet-node/lib/stream/stream-service.ts +++ b/packages/rosenet-node/lib/stream/stream-service.ts @@ -111,15 +111,33 @@ async function getRoseNetDirectStreamTo(to: string, node: Libp2p) { [[], []] as [Multiaddr[], Multiaddr[]], ); + RoseNetNodeContext.logger.debug( + `Fetched and partitioned peer multiaddresses`, + { + publicAddresses: publicAddresses.map((address) => address.toString()), + otherAddresses: otherAddresses.map((address) => address.toString()), + }, + ); + if (publicAddresses) { try { - return await node.dial(publicAddresses, { + const connection = await node.dial(publicAddresses, { signal: AbortSignal.timeout(PUBLIC_MULTIADDR_DIAL_TIMEOUT), }); + RoseNetNodeContext.logger.debug( + `Public multiaddress dialed successfully`, + ); + return connection; } catch { + RoseNetNodeContext.logger.debug( + `Couldn't dial any public multiaddresses, trying relayed addresses`, + ); return await node.dial(otherAddresses); } } else { + RoseNetNodeContext.logger.debug( + 'No public multiaddress found for this peer, trying relayed addresses', + ); return await node.dial(otherAddresses); } })); From a8a4214d105d295ab9434de009fe94f799490d37 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 14:01:16 +0330 Subject: [PATCH 34/35] feat(global-test): enable influxdb configurations --- tests/global/src/node/.env.example | 6 +++++- tests/global/src/node/.env.influxdb | 6 +++--- tests/global/src/node/.env.service | 1 + tests/global/src/node/config.ts | 1 + tests/global/src/node/docker-compose.yaml | 2 +- tests/global/src/node/metric-store.ts | 4 +++- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/global/src/node/.env.example b/tests/global/src/node/.env.example index 13f675d..34025ce 100644 --- a/tests/global/src/node/.env.example +++ b/tests/global/src/node/.env.example @@ -12,5 +12,9 @@ MAX_MESSAGE_SIZE= MIN_SCNEARIO_DURATION= MAX_SCNEARIO_DURATION= SERVICE_PORT= -INFLUXDB_PORT= LOGS_DIRECTORY= +INFLUXDB_HOST= +INFLUXDB_PORT= +INFLUXDB_USERNAME= +INFLUXDB_PASSWORD= +INFLUXDB_ADMIN_TOKEN= diff --git a/tests/global/src/node/.env.influxdb b/tests/global/src/node/.env.influxdb index 39e8928..431a3b9 100644 --- a/tests/global/src/node/.env.influxdb +++ b/tests/global/src/node/.env.influxdb @@ -1,6 +1,6 @@ DOCKER_INFLUXDB_INIT_MODE=setup -DOCKER_INFLUXDB_INIT_USERNAME=admin -DOCKER_INFLUXDB_INIT_PASSWORD=admin1234 -DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=admintoken +DOCKER_INFLUXDB_INIT_USERNAME=${INFLUXDB_USERNAME:-admin} +DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_PASSWORD:-admin1234} +DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=${INFLUXDB_ADMIN_TOKEN:-admintoken} DOCKER_INFLUXDB_INIT_ORG=Rosen DOCKER_INFLUXDB_INIT_BUCKET=RoseNet diff --git a/tests/global/src/node/.env.service b/tests/global/src/node/.env.service index 0cd1788..8b0748b 100644 --- a/tests/global/src/node/.env.service +++ b/tests/global/src/node/.env.service @@ -8,3 +8,4 @@ MAX_MESSAGE_SIZE=${MAX_MESSAGE_SIZE:-} MIN_SCNEARIO_DURATION=${MIN_SCNEARIO_DURATION:-} MAX_SCNEARIO_DURATION=${MAX_SCNEARIO_DURATION:-} RELAY_MULTIADDRS=${RELAY_MULTIADDRS:?} +INFLUXDB_ADMIN_TOKEN=${INFLUXDB_ADMIN_TOKEN:-admintoken} diff --git a/tests/global/src/node/config.ts b/tests/global/src/node/config.ts index b0b15cb..197acfe 100644 --- a/tests/global/src/node/config.ts +++ b/tests/global/src/node/config.ts @@ -13,4 +13,5 @@ export default { minScenarioDuration: optional(process.env.MIN_SCNEARIO_DURATION, 60_000), maxScenarioDuration: optional(process.env.MAX_SCNEARIO_DURATION, 300_000), relayMultiaddrs: process.env.RELAY_MULTIADDRS!.split(','), + influxdbToken: process.env.INFLUXDB_ADMIN_TOKEN!, }; diff --git a/tests/global/src/node/docker-compose.yaml b/tests/global/src/node/docker-compose.yaml index 75bfcd6..1629abc 100644 --- a/tests/global/src/node/docker-compose.yaml +++ b/tests/global/src/node/docker-compose.yaml @@ -22,7 +22,7 @@ services: env_file: - .env.influxdb ports: - - ${INFLUXDB_PORT:-8086}:8086 + - ${INFLUXDB_HOST:-127.0.0.1}:${INFLUXDB_PORT:-8086}:8086 networks: - internal volumes: diff --git a/tests/global/src/node/metric-store.ts b/tests/global/src/node/metric-store.ts index 29ef58f..55b2124 100644 --- a/tests/global/src/node/metric-store.ts +++ b/tests/global/src/node/metric-store.ts @@ -2,9 +2,11 @@ import { InfluxDB, Point } from '@influxdata/influxdb-client'; import { serviceLogger } from './logger'; +import config from './config'; + const influxDB = new InfluxDB({ url: 'http://influxdb:8086', - token: 'admintoken', + token: config.influxdbToken, }); const writeApi = influxDB.getWriteApi('Rosen', 'RoseNet'); From c438319a9e6293015ff7ddddf69a23f5a7a7f685 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Wed, 30 Oct 2024 16:09:09 +0330 Subject: [PATCH 35/35] doc(global-test): fix issue in README --- tests/global/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/global/README.md b/tests/global/README.md index fd68ab4..6e1fdce 100644 --- a/tests/global/README.md +++ b/tests/global/README.md @@ -26,10 +26,10 @@ git clone https://github.com/rosen-bridge/rosenet.git # Choose your setup type: # For relay setup: -cd tests/global/src/relay +cd rosenet/tests/global/src/relay # For node setup: -cd tests/global/src/node +cd rosenet/tests/global/src/node # Create service configuration file cp .env.example .env @@ -45,7 +45,7 @@ docker compose up -d ```bash git clone https://github.com/rosen-bridge/rosenet.git - cd tests/global/src/relay + cd rosenet/tests/global/src/relay ``` 2. **Configure Environment**