diff --git a/docker-compose.yml b/docker-compose.yml index 58d1ea7f..53899562 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,24 +15,6 @@ services: volumes: - /nano:/root - nano-node-monitor: - image: nanotools/nanonodemonitor - container_name: nano-node-monitor - hostname: nano-node-monitor - restart: unless-stopped - volumes: - - ./nano-node-monitor:/opt/nanoNodeMonitor - ports: - - "80:80" - - watchtower: - image: v2tec/watchtower - container_name: watchtower - restart: unless-stopped - command: watchtower nano-node nano-node-monitor - volumes: - - /var/run/docker.sock:/var/run/docker.sock - networks: default: external: diff --git a/package-lock.json b/package-lock.json index 4da268b4..d0e92443 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@sentry/node": "^6.19.2", "antd": "^5.5.0", "bignumber.js": "^9.0.0", - "body-parser": "^1.19.0", + "body-parser": "^1.20.2", "cors": "^2.8.5", "dot-object": "^2.1.4", "dotenv": "^8.2.0", @@ -49,14 +49,14 @@ "react-responsive": "^9.0.2", "react-router-dom": "^5.2.0", "react-scripts": "^5.0.1", - "reconnecting-websocket": "^4.4.0", - "redis": "^3.1.2", + "redis": "^4.6.13", "remark-gfm": "^3.0.1", "rimraf": "^3.0.2", "saslprep": "^1.0.3", "source-map-explorer": "^2.5.2", "timeago-react": "^3.0.0", "use-deep-compare-effect": "^1.8.1", + "websocket-reconnect": "^1.0.10", "ws": "^7.5.7", "yargs": "^16.2.0" }, @@ -4095,6 +4095,59 @@ "react-dom": "^17.0.1" } }, + "node_modules/@redis/bloom": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/client": { + "version": "1.5.14", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz", + "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==", + "dependencies": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", + "yallist": "4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@redis/graph": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/json": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/search": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/time-series": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", @@ -7295,12 +7348,12 @@ "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==" }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -7308,7 +7361,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -7809,6 +7862,14 @@ "node": ">=0.8" } }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -8008,9 +8069,9 @@ ] }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } @@ -9046,14 +9107,6 @@ "node": ">=0.4.0" } }, - "node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", - "engines": { - "node": ">=0.10" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -10589,6 +10642,29 @@ "node": ">= 0.10.0" } }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/express/node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -10610,6 +10686,20 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -11388,6 +11478,14 @@ "node": ">=12" } }, + "node_modules/generic-pool": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", + "engines": { + "node": ">= 4" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -19680,9 +19778,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -20867,11 +20965,6 @@ "node": ">=8.10.0" } }, - "node_modules/reconnecting-websocket": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz", - "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==" - }, "node_modules/recursive-readdir": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", @@ -20897,45 +20990,16 @@ } }, "node_modules/redis": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", - "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==", - "dependencies": { - "denque": "^1.5.0", - "redis-commands": "^1.7.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-redis" - } - }, - "node_modules/redis-commands": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", - "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" - }, - "node_modules/redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz", + "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==", "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" + "@redis/bloom": "1.2.0", + "@redis/client": "1.5.14", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", + "@redis/time-series": "1.0.5" } }, "node_modules/redux": { @@ -24131,6 +24195,35 @@ "node": ">=0.8.0" } }, + "node_modules/websocket-reconnect": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/websocket-reconnect/-/websocket-reconnect-1.0.10.tgz", + "integrity": "sha512-XKOLCZ1vTey+VuljMzVEIKrfbO/bpslJDl2bH7mUZsraXbV9qfqgQGvgUeBF89NReIUpimmpIIi0dwBQEvFhJQ==", + "dependencies": { + "events": "^3.3.0", + "ws": "^8.11.0" + } + }, + "node_modules/websocket-reconnect/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -27672,6 +27765,46 @@ "integrity": "sha512-7PGLWa9MZ5x/cWy8EH2VzI4T8q5WpuHbixzCDXqixP/WyqwIrg5NDUPgYuFnB4IEIZF+6nA265mYzswFo/h1Pw==", "requires": {} }, + "@redis/bloom": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "requires": {} + }, + "@redis/client": { + "version": "1.5.14", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz", + "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==", + "requires": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", + "yallist": "4.0.0" + } + }, + "@redis/graph": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "requires": {} + }, + "@redis/json": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "requires": {} + }, + "@redis/search": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "requires": {} + }, + "@redis/time-series": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "requires": {} + }, "@rushstack/eslint-patch": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", @@ -30163,12 +30296,12 @@ "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==" }, "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "requires": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -30176,7 +30309,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -30542,6 +30675,11 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" }, + "cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -30696,9 +30834,9 @@ } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, "continuation-local-storage": { "version": "3.2.1", @@ -31424,11 +31562,6 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, - "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -32555,6 +32688,25 @@ "vary": "~1.1.2" }, "dependencies": { + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -32573,6 +32725,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -33145,6 +33308,11 @@ "json-bigint": "^1.0.0" } }, + "generic-pool": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==" + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -38876,9 +39044,9 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "requires": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -39721,11 +39889,6 @@ "picomatch": "^2.2.1" } }, - "reconnecting-websocket": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz", - "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==" - }, "recursive-readdir": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", @@ -39745,32 +39908,16 @@ } }, "redis": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", - "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==", + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz", + "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==", "requires": { - "denque": "^1.5.0", - "redis-commands": "^1.7.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0" - } - }, - "redis-commands": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", - "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" - }, - "redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==" - }, - "redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "requires": { - "redis-errors": "^1.0.0" + "@redis/bloom": "1.2.0", + "@redis/client": "1.5.14", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", + "@redis/time-series": "1.0.5" } }, "redux": { @@ -42135,6 +42282,23 @@ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" }, + "websocket-reconnect": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/websocket-reconnect/-/websocket-reconnect-1.0.10.tgz", + "integrity": "sha512-XKOLCZ1vTey+VuljMzVEIKrfbO/bpslJDl2bH7mUZsraXbV9qfqgQGvgUeBF89NReIUpimmpIIi0dwBQEvFhJQ==", + "requires": { + "events": "^3.3.0", + "ws": "^8.11.0" + }, + "dependencies": { + "ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "requires": {} + } + } + }, "whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", diff --git a/package.json b/package.json index 069b7f0f..acb7bf6a 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@sentry/node": "^6.19.2", "antd": "^5.5.0", "bignumber.js": "^9.0.0", - "body-parser": "^1.19.0", + "body-parser": "^1.20.2", "cors": "^2.8.5", "dot-object": "^2.1.4", "dotenv": "^8.2.0", @@ -78,14 +78,14 @@ "react-responsive": "^9.0.2", "react-router-dom": "^5.2.0", "react-scripts": "^5.0.1", - "reconnecting-websocket": "^4.4.0", - "redis": "^3.1.2", + "redis": "^4.6.13", "remark-gfm": "^3.0.1", "rimraf": "^3.0.2", "saslprep": "^1.0.3", "source-map-explorer": "^2.5.2", "timeago-react": "^3.0.0", "use-deep-compare-effect": "^1.8.1", + "websocket-reconnect": "^1.0.10", "ws": "^7.5.7", "yargs": "^16.2.0" }, diff --git a/server/api/delegators.js b/server/api/delegators.js index 2d1bc0c4..a4125b5a 100644 --- a/server/api/delegators.js +++ b/server/api/delegators.js @@ -1,15 +1,14 @@ -const { client: redisClient } = require("../client/redis"); +const { redisClient } = require("../client/redis"); const { Sentry } = require("../sentry"); const { DELEGATORS } = require("../constants"); const PER_PAGE = 50; const getTotal = account => - new Promise(async resolve => { - redisClient.zcard(`DELEGATORS:${account}`, (err, total) => { - if (err) Sentry.captureException(err); - resolve(total); - }); + new Promise(async () => { + const [total] = await redisClient.zCard(`DELEGATORS:${account}`); + + console.log("~~~~~total", total); }); const getDelegatorsPage = async ({ page = 1, account }) => @@ -44,33 +43,41 @@ const getDelegatorsPage = async ({ page = 1, account }) => }); const getAllDelegatorsCount = async () => - new Promise(async resolve => { - redisClient.keys(`${DELEGATORS}:*`, (err, res) => { - if (err) { - Sentry.captureException(err); - return; - } + async function findKeys(pattern) { + let cursor = "0"; + let keys = []; - Promise.all( - res.map(async key => { - const account = key.replace(`${DELEGATORS}:`, ""); - const count = await getTotal(account); + do { + const reply = await redisClient.scan(cursor, "MATCH", pattern, "COUNT", "100"); + keys.push(...reply.keys); + } while (cursor !== "0"); - return { - [account]: count, - }; - }), - ).then(result => { - resolve( - result.reduce((acc, value) => { - const key = Object.keys(value)[0]; - acc[key] = value[key]; - return acc; - }, {}), - ); - }); - }); + return keys; + }; +new Promise(async resolve => { + const delegators = await redisClient + .findKeys(`${DELEGATORS}:*`) + .filter(key => key.startsWith(`${DELEGATORS}`)); + + Promise.all( + res.map(async key => { + const account = key.replace(`${DELEGATORS}:`, ""); + const count = await getTotal(account); + + return { + [account]: count, + }; + }), + ).then(result => { + resolve( + result.reduce((acc, value) => { + const key = Object.keys(value)[0]; + acc[key] = value[key]; + return acc; + }, {}), + ); }); +}); module.exports = { getDelegatorsPage, diff --git a/server/api/richList.js b/server/api/richList.js index 75ad2217..1b1d95ec 100644 --- a/server/api/richList.js +++ b/server/api/richList.js @@ -1,23 +1,25 @@ -const { client: redisClient } = require("../client/redis"); +const { redisClient } = require("../client/redis"); const { Sentry } = require("../sentry"); const { REDIS_RICH_LIST } = require("../constants"); const PER_PAGE = 25; -const getTotal = () => - new Promise(async resolve => { - redisClient.zcard(REDIS_RICH_LIST, (err, total) => { - if (err) Sentry.captureException(err); - resolve(total); - }); - }); +const { NL_REDIS_DB_INDEX } = process.env; + +const getTotal = async () => { + const total = await redisClient.zCard(REDIS_RICH_LIST); + + console.log("~~~~total", total); + return total; +}; const getRichListPage = async (page = 1) => new Promise(async resolve => { + await redisClient.select(NL_REDIS_DB_INDEX); const offset = (page - 1) * PER_PAGE; const total = await getTotal(); - redisClient.zrevrange( + const list = await redisClient.zrevrange( REDIS_RICH_LIST, offset, offset + PER_PAGE - 1, diff --git a/server/client/redis.js b/server/client/redis.js index 27a99405..5a5f3a49 100644 --- a/server/client/redis.js +++ b/server/client/redis.js @@ -1,20 +1,52 @@ -const redis = require("redis"); -const { Sentry } = require("../sentry"); +const { createClient } = require("redis"); +const { + DEV_REDIS_PORT, + PROD_REDIS_PORT, + REDIS_HOST, + REDIS_USERNAME, + REDIS_PASSWORD, + NL_REDIS_DB_INDEX, + NBQ_REDIS_DB_INDEX, + NODE_ENV, +} = process.env; -const { NL_REDIS_PORT, NL_REDIS_HOST, NL_REDIS_PASSWORD, NL_REDIS_DB_INDEX } = process.env; -const client = redis.createClient(NL_REDIS_PORT, NL_REDIS_HOST, { - password: NL_REDIS_PASSWORD, -}); +let redisClient = null; +async function connectRedisInstance() { + const REDIS_OPTIONS = { + ...(NODE_ENV === "development" ? { port: DEV_REDIS_PORT } : { port: PROD_REDIS_PORT }), + host: REDIS_HOST, + username: REDIS_USERNAME, + database: Number(NBQ_REDIS_DB_INDEX), + ...(NODE_ENV !== "development" && REDIS_PASSWORD ? { password: REDIS_PASSWORD } : {}), + }; -client.on("connect", function () { - client.select(NL_REDIS_DB_INDEX); - console.log(`Connected to NL Redis ON DB ${NL_REDIS_DB_INDEX}`); -}); + console.log("~~~~REDIS_OPTIONS", REDIS_OPTIONS); -client.on("error", function (err) { - Sentry.captureException(err); -}); + // Create a Redis client with the specified configuration options + redisClient = createClient(REDIS_OPTIONS); + + // Properly handle connection errors + redisClient.on("error", err => console.log("Redis Client Error", err)); + + redisClient.on("connect", () => { + console.log("Connected to Redis server successfully!!"); + }); + + // Connect to the Redis server + await redisClient.connect(); + + return redisClient; +} + +// Example usage +connectRedisInstance() + .then(() => { + console.log("Connected to NBQ Redis server successful!"); + }) + .catch(err => { + console.error("Failed to connect to Redis:", err); + }); module.exports = { - client, + redisClient, }; diff --git a/server/constants.js b/server/constants.js index 46e36a89..ba0abb36 100644 --- a/server/constants.js +++ b/server/constants.js @@ -56,7 +56,7 @@ const PARTICIPANTS = "PARTICIPANTS"; const NANOTICKER_STATS = "NANOTICKER_STATS"; const NANOTPS_STATS = "NANOTPS_STATS"; const NANOSPEED_STATS = "NANOSPEED_STATS"; -const NANOBROWSERQUEST_PLAYERS = "NANOBROWSERQUEST_PLAYERS"; +const NANOBROWSERQUEST_ONLINE_PLAYERS = "NANOBROWSERQUEST_ONLINE_PLAYERS"; const NANOBROWSERQUEST_LEADERBOARD = "NANOBROWSERQUEST_LEADERBOARD"; const YOUTUBE_PLAYLIST = "YOUTUBE_PLAYLIST"; const MONGO_USER = process.env.MONGO_USER; @@ -128,7 +128,7 @@ module.exports = { NANOTICKER_STATS, NANOTPS_STATS, NANOSPEED_STATS, - NANOBROWSERQUEST_PLAYERS, + NANOBROWSERQUEST_ONLINE_PLAYERS, NANOBROWSERQUEST_LEADERBOARD, YOUTUBE_PLAYLIST, MONGO_URL, diff --git a/server/cron/nanobrowserquestStats.js b/server/cron/nanobrowserquestStats.js index 95256e50..f7662ac0 100644 --- a/server/cron/nanobrowserquestStats.js +++ b/server/cron/nanobrowserquestStats.js @@ -1,98 +1,89 @@ const cron = require("node-cron"); -const redis = require("redis"); const chunk = require("lodash/chunk"); -const { Sentry } = require("../sentry"); const { nodeCache } = require("../client/cache"); -const { NANOBROWSERQUEST_PLAYERS, NANOBROWSERQUEST_LEADERBOARD } = require("../constants"); +const { redisClient } = require("../client/redis"); -const { NBQ_REDIS_PORT, NBQ_REDIS_HOST, NBQ_REDIS_PASSWORD, NBQ_REDIS_DB_INDEX } = process.env; +const { + NANOBROWSERQUEST_ONLINE_PLAYERS, + NANOBROWSERQUEST_LEADERBOARD, + EXPIRE_1H, +} = require("../constants"); -const client = redis.createClient(NBQ_REDIS_PORT, NBQ_REDIS_HOST, { - password: NBQ_REDIS_PASSWORD, -}); - -client.on("connect", function () { - client.select(NBQ_REDIS_DB_INDEX); // NBQ DB - console.log(`Connected to NBQ Redis ON DB ${NBQ_REDIS_DB_INDEX}`); - - if (process.env.NODE_ENV === "production") { - getNanoBrowserQuestLeaderboard(); - } -}); - -client.on("error", function (err) { - Sentry.captureException(err); -}); +const { NBQ_REDIS_DB_INDEX } = process.env; const getNanoBrowserQuestPlayers = async () => { - let res; - - try { - client.get("total_players", (error, playerCount) => { - nodeCache.set(NANOBROWSERQUEST_PLAYERS, { playerCount }); - }); - } catch (err) { - console.log("Error", err); - Sentry.captureException(err, { extra: { res } }); - } + const playerCount = await redisClient.get("total_players"); + nodeCache.set(NANOBROWSERQUEST_ONLINE_PLAYERS, { playerCount }); }; const getNanoBrowserQuestLeaderboard = async () => { - let res; - try { - let playersData = []; - const PER_PAGES = 500; - client.keys("u:*", async (_err, players) => { - const playersChunks = chunk(players, PER_PAGES); - - for (let i = 0; i < playersChunks.length; i++) { - const rawPlayerData = await Promise.all( - playersChunks[i].map( - player => - new Promise(resolve => { - if (player === "u:running-coder") { - resolve(undefined); - } - - client.hmget( - player, - "hash", - "network", - "exp", - "gold", - "goldStash", - (_err, reply) => { - const network = reply[1]; - const exp = Number(reply[2] || 0); - const gold = Number(reply[3] || 0); - const goldStash = Number(reply[4] || 0); - - if (network === "ban" || !exp) { - resolve(undefined); - } else { - resolve({ - player: player.replace("u:", ""), - isCompleted: !!reply[0], - network, - exp: parseInt(reply[2] || 0), - gold: gold + goldStash, - }); - } - }, - ); - }), - ), - ); - - playersData = playersData.concat(rawPlayerData.filter(Boolean)); - } + await redisClient.select(NBQ_REDIS_DB_INDEX); + async function findKeys(pattern) { + let cursor = "0"; + // let rawCursor = null; + let keys = []; + let reply; + + redisClient.select(NBQ_REDIS_DB_INDEX); + do { + reply = await redisClient.scan( + reply ? reply.cursor : cursor, + "MATCH", + pattern, + "COUNT", + "100", + ); + // rawCursor = reply.cursor; + keys.push(...reply.keys); + } while (reply.cursor); + return keys; + } - nodeCache.set(NANOBROWSERQUEST_LEADERBOARD, playersData); - }); - } catch (err) { - console.log("Error", err); - Sentry.captureException(err, { extra: { res } }); + let playersData = []; + const PER_PAGES = 2; + // Usage + const players = (await findKeys("u:*")).filter(key => key.startsWith("u:")); + const playersChunks = chunk(players, PER_PAGES); + + console.log("~~~~~~~playersChunks", playersChunks); + + for (let i = 0; i < playersChunks.length; i++) { + const rawPlayerData = await Promise.all( + playersChunks[i].map( + player => + new Promise(async resolve => { + const userKey = player; + let [hash, network, exp, gold, goldStash] = await redisClient + .multi() + .hGet(userKey, "hash") + .hGet(userKey, "network") + .hGet(userKey, "exp") + .hGet(userKey, "gold") + .hGet(userKey, "goldStash") + .exec(); + + exp = Number(exp || 0); + gold = Number(gold || 0); + goldStash = Number(goldStash || 0); + + if (network === "ban" || exp <= 1000) { + resolve(undefined); + } else { + resolve({ + player: player.replace("u:", ""), + isCompleted: !!hash, + network, + exp, + gold: gold + goldStash, + }); + } + }), + ), + ); + + playersData = playersData.concat(rawPlayerData.filter(Boolean)); } + nodeCache.set(NANOBROWSERQUEST_LEADERBOARD, playersData, EXPIRE_1H); }; // Every 5 seconds @@ -106,6 +97,7 @@ cron.schedule("*/15 * * * *", async () => { getNanoBrowserQuestLeaderboard(); }); -if (!nodeCache.get(NANOBROWSERQUEST_LEADERBOARD)){ - getNanoBrowserQuestLeaderboard(); -} +// if (!nodeCache.get(NANOBROWSERQUEST_LEADERBOARD)) { +console.log("~~~2"); +getNanoBrowserQuestLeaderboard(); +// } diff --git a/server/cron/ws.js b/server/cron/ws.js index bf23e925..bcb029b5 100644 --- a/server/cron/ws.js +++ b/server/cron/ws.js @@ -49,7 +49,7 @@ cron.schedule("*/3 * * * * *", async () => { nodeCache.set( CONFIRMATIONS_PER_SECOND, - new BigNumber(confirmationsPerSecond).dividedBy(EXPIRE_1M).toFormat(2), + new BigNumber(confirmationsPerSecond || 0).dividedBy(EXPIRE_1M).toFormat(2), ); } catch (err) { Sentry.captureException(err, { diff --git a/server/rpc/index.js b/server/rpc/index.js index 9913f309..3fa0c9c0 100644 --- a/server/rpc/index.js +++ b/server/rpc/index.js @@ -4,6 +4,8 @@ const { transformer: representatives } = require("./transformers/representatives const { nodeCache } = require("../client/cache"); const { Sentry } = require("../sentry"); +const { EXPIRE_1H, EXPIRE_6H, EXPIRE_48H } = require("../constants"); + const transformers = { confirmation_quorum, representatives, @@ -30,27 +32,27 @@ const allowedRpcMethods = [ "uptime", "version", ]; -//@Note more cache due to 26.1 + const cacheSettings = { - account_history: 1000, - account_info: 1000, - account_representative: 3600, - accounts_balances: 100, - active_difficulty: 100, - available_supply: 3600 * 10, - block_count: 100, - block_info: 100, - blocks_info: 500, - confirmation_history: 500, - confirmation_quorum: 500, - frontier_count: 500, - peers: 3600, - pending: 500, - representatives: 3600 * 4, - representatives_online: 3600 * 4, - stats: 500, + account_history: 1, + account_info: 1, + account_representative: 5, + accounts_balances: 1, + active_difficulty: EXPIRE_48H, + available_supply: EXPIRE_6H, + block_count: 1, + block_info: 1, + blocks_info: 5, + confirmation_history: 5, + confirmation_quorum: 5, + frontier_count: 5, + peers: 5, + pending: 5, + representatives: EXPIRE_1H, + representatives_online: EXPIRE_1H, + stats: 5, uptime: 30, - version: 30, + version: EXPIRE_6H, }; const limits = { diff --git a/server/server.js b/server/server.js index bdff2a55..7c432aaf 100644 --- a/server/server.js +++ b/server/server.js @@ -24,7 +24,6 @@ const { getDistributionData } = require("./cron/distribution"); const { getExchangeBalances } = require("./cron/exchangeTracker"); const express = require("express"); const cors = require("cors"); -const fetch = require("node-fetch"); const { rpc, allowedRpcMethods } = require("./rpc"); const bodyParser = require("body-parser"); const path = require("path"); @@ -40,7 +39,7 @@ const { TOTAL_VOLUME_14D, CONFIRMATIONS_PER_SECOND, NANOTICKER_STATS, - NANOBROWSERQUEST_PLAYERS, + NANOBROWSERQUEST_ONLINE_PLAYERS, NANOBROWSERQUEST_LEADERBOARD, NANOTPS_STATS, NANOSPEED_STATS, @@ -59,17 +58,17 @@ const { getDeveloperFundTransactions } = require("./api/developerFundTransaction const { getLargeTransactions } = require("./api/largeTransactions"); const { getNodeStatus } = require("./api/nodeStatus"); const { getKnownAccounts, getKnownAccountsBalance } = require("./api/knownAccounts"); -const { getDelegatorsPage, getAllDelegatorsCount } = require("./api/delegators"); +// const { getDelegatorsPage, getAllDelegatorsCount } = require("./api/delegators"); const { getHistoryFilters } = require("./api/historyFilters"); -const { getRichListPage, getRichListAccount } = require("./api/richList"); +// const { getRichListPage, getRichListAccount } = require("./api/richList"); const { getParticipant, getParticipantsPage } = require("./api/participants"); const { getNodeLocations } = require("./api/nodeLocations"); const { getNodeMonitors } = require("./api/nodeMonitors"); const { getDelegatedEntity } = require("./api/delegatedEntity"); const { getTelemetry } = require("./api/telemetry"); const { getRepresentative, getAllRepresentatives } = require("./api/representative"); -const { Sentry } = require("./sentry"); + const { isValidAccountAddress } = require("./utils"); const { terminate } = require("./terminate"); @@ -110,18 +109,17 @@ app.get("/api/distribution", (req, res) => { }); // @TODO ADD getDelegators && getAllDelegators if req.account is specified -app.get("/api/delegators", async (req, res) => { - let data; - const { account, page } = req.query; - - if (isValidAccountAddress(account)) { - data = await getDelegatorsPage({ account, page }); - } else { - data = await getAllDelegatorsCount(); - } - - res.send(data); -}); +// app.get("/api/delegators", async (req, res) => { +// let data = []; +// const { account, page } = req.query; +// // if (isValidAccountAddress(account)) { +// // data = await getDelegatorsPage({ account, page }); +// // } else { +// // data = await getAllDelegatorsCount(); +// // } + +// res.send(data); +// }); app.get("/api/transaction-filters", async (req, res) => { const { account, filters } = req.query; @@ -257,13 +255,13 @@ app.get("/api/telemetry", async (req, res) => { }); app.get("/api/rich-list", async (req, res) => { - const { page, account } = req.query; - let data; - if (page) { - data = await getRichListPage(page); - } else if (account) { - data = await getRichListAccount(account); - } + // const { page, account } = req.query; + let data = []; + // if (page) { + // data = await getRichListPage(page); + // } else if (account) { + // data = await getRichListAccount(account); + // } res.send(data); }); @@ -310,22 +308,28 @@ app.get("/api/participants", async (req, res) => { app.get("/api/nanobrowserquest/players", async (req, res, next) => { try { - res.send(nodeCache.get(NANOBROWSERQUEST_PLAYERS) || {}); + res.send(nodeCache.get(NANOBROWSERQUEST_ONLINE_PLAYERS) || {}); } catch (err) { next(err); } }); app.get("/api/nanobrowserquest/leaderboard", async (req, res, next) => { + + console.log('~~~1') try { - res.send(nodeCache.get(NANOBROWSERQUEST_LEADERBOARD) || []); + res.send(nodeCache.get(NANOBROWSERQUEST_LEADERBOARD)); } catch (err) { next(err); } }); -app.get("/api/nanoticker", async (req, res) => { - res.send(nodeCache.get(NANOTICKER_STATS) || {}); +app.get("/api/nanoticker", async (req, res, next) => { + try { + res.send(nodeCache.get(NANOTICKER_STATS) || {}); + } catch (err) { + next(err); + } }); app.get("/api/youtube-playlist", async (req, res) => { @@ -354,3 +358,4 @@ process.on("SIGTERM", exitHandler(0, "SIGTERM")); process.on("SIGINT", exitHandler(0, "SIGINT")); console.log(`Server started on http://localhost:${process.env.SERVER_PORT}`); + diff --git a/server/ws/index.js b/server/ws/index.js index 690c7686..98f5ee15 100644 --- a/server/ws/index.js +++ b/server/ws/index.js @@ -1,6 +1,6 @@ const WS = require("ws"); const BigNumber = require("bignumber.js"); -const ReconnectingWebSocket = require("reconnecting-websocket"); +const { WsReconnect } = require("websocket-reconnect"); const { Sentry } = require("../sentry"); const db = require("../client/mongo"); const { @@ -18,15 +18,9 @@ let accumulatedVolume = 0; let accumulatedLargeTransactionHashes = []; // https://github.com/cryptocode/nano-websocket-sample-nodejs/blob/master/index.js -const ws = new ReconnectingWebSocket("wss://www.nanolooker.com/ws", [], { - WebSocket: WS, - connectionTimeout: 10000, - maxRetries: 100000, - maxReconnectionDelay: 2000, - minReconnectionDelay: 10, -}); - -ws.onopen = () => { +const ws = new WsReconnect({ reconnectDelay: 5000 }); +ws.open(`wss://www.nanolooker.com/ws:${process.env.WS_PORT}`); +ws.on("open", () => { console.log("WS OPENED"); const subscription = { action: "subscribe", @@ -38,22 +32,33 @@ ws.onopen = () => { ws.send(JSON.stringify(subscription)); updateDbInterval = setInterval(updateDb, UPDATE_CACHE_INTERVAL); -}; +}); -ws.onclose = () => { +ws.on("close", () => { console.log("WS close"); clearInterval(updateDbInterval); updateDb(); -}; +}); -ws.onerror = err => { +ws.on("error", err => { console.log("WS ERROR", err); clearInterval(updateDbInterval); updateDb(); -}; +}); ws.onmessage = msg => { + if (Buffer.isBuffer(msg)) { + const buffer = Buffer.from(msg, "hex"); + const jsonString = buffer.toString("utf-8"); + + msg = { + data: jsonString, + }; + + } + const { topic, message } = JSON.parse(msg.data); + const { amount, block: { subtype }, @@ -61,7 +66,6 @@ ws.onmessage = msg => { if (topic === "confirmation") { accumulatedConfirmations = accumulatedConfirmations + 1; - // 10,000 NANO if (subtype === "send" && amount.length >= 35) { diff --git a/src/api/hooks/use-nanoticker.tsx b/src/api/hooks/use-nanoticker.tsx index 78939a8f..bae77717 100644 --- a/src/api/hooks/use-nanoticker.tsx +++ b/src/api/hooks/use-nanoticker.tsx @@ -11,14 +11,14 @@ const useNanoTicker = (): UseUptimeReturn => { const getConfirmationsPerSecond = async () => { clearTimeout(confirmationsPerSecondTimeout); - try { + // try { const res = await fetch("/api/nanoticker"); const { cps } = await res.json(); setConfirmationsPerSecond(cps); - } catch (err) { - setConfirmationsPerSecond(undefined); - } + // } catch (err) { + // setConfirmationsPerSecond(undefined); + // } confirmationsPerSecondTimeout = window.setTimeout(() => { getConfirmationsPerSecond(); diff --git a/src/pages/NanoBrowserQuest/Guide/index.tsx b/src/pages/NanoBrowserQuest/Guide/index.tsx index ab0140f2..80c26db8 100644 --- a/src/pages/NanoBrowserQuest/Guide/index.tsx +++ b/src/pages/NanoBrowserQuest/Guide/index.tsx @@ -28,7 +28,7 @@ const NanoBrowserQuestGuidePage: React.FC = () => { text = text.replace(/:rune([a-z]+):/gi, (match, capturedLetters: string) => { //@ts-ignore const rune = runeKind[capturedLetters]; - console.log("~~~~rune", rune); + const replacement = `![{"name": "${capturedLetters.toUpperCase()} Rune #${ rune.rank }", "itemClass": "${getItemClassFromBaseLevel(rune.requirement)}", "requirement": "${ @@ -89,10 +89,7 @@ const Image: React.FC = ({ src, alt: rawAttributes }) => { if (rawAttributes?.startsWith("{")) { try { title = getItemAttributes(JSON.parse(rawAttributes)); - // console.log("`~~~rawAttributes", rawAttributes); } catch (err) { - // console.log("`~~~rawAttributes", JSON.parse(rawAttributes)); - console.log("`~~~ERR", err); } return ( diff --git a/users.acl b/users.acl new file mode 100644 index 00000000..30b48371 --- /dev/null +++ b/users.acl @@ -0,0 +1,4 @@ + +#user default on>password ~* &* +@all +user default on nopass ~* &* +@all +user default +@all ~jobs:* on >nopass