From 4f0f66cf19fea8ab25c2b8bcadf5cabd261acd5f Mon Sep 17 00:00:00 2001 From: sergeych Date: Thu, 30 Jul 2026 23:02:12 +0400 Subject: [PATCH] Reduce sample to network smoke test --- README.md | 16 +++------ package.json | 7 ++-- src/index.js | 98 ++++++++-------------------------------------------- 3 files changed, 20 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index 202da6c..8a3b261 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # u-js-sample -A small Node.js command-line example using `universa-core2@2.0.0-alpha.1`. +A minimal network smoke test using `universa-core2@2.0.0-alpha.1`. ## Initialize and test @@ -9,14 +9,6 @@ npm ci scripts/test-network.sh ``` -The test loads `src/universa.json` through `Topology`, connects with `Network`, -authenticates to every available node, and verifies `sping=spong`. The alpha -package intentionally has no bundled default topology, so applications must -provide one explicitly. - -## Examples - -```sh -npm start -- --generate-key -npm start -- --test-network -``` +The test loads `src/universa.json`, initializes `Network`, connects to the +available topology, and asserts that the network returns `sping=spong`. The +alpha package intentionally has no bundled default topology. diff --git a/package.json b/package.json index 6fb04f3..faaeebf 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,14 @@ { "name": "u-js-sample", "version": "0.1.0", - "description": "A small universa-core2 Node.js sample.", + "description": "A minimal universa-core2 network smoke test.", "type": "module", "private": true, - "bin": { - "u-js-sample": "./src/index.js" - }, "scripts": { "start": "node src/index.js", "test:network": "bash scripts/test-network.sh", "check": "node --check src/index.js", - "test": "npm run check && npm run test:network" + "test": "npm run test:network" }, "engines": { "node": ">=20" diff --git a/src/index.js b/src/index.js index fae08ee..0962f25 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ #!/usr/bin/env node +import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -13,91 +14,20 @@ import { const sourceDirectory = dirname(fileURLToPath(import.meta.url)); const topologyFile = resolve(sourceDirectory, 'universa.json'); -async function withTimeout(promise, milliseconds, message) { - let timeoutId; - const timeout = new Promise((_, reject) => { - timeoutId = setTimeout(() => reject(new Error(message)), milliseconds); - }); +await unicryptoReady; - try { - return await Promise.race([promise, timeout]); - } finally { - clearTimeout(timeoutId); - } -} +const topologyData = JSON.parse(await readFile(topologyFile, 'utf8')); +const topology = await Topology.load(topologyData); +const privateKey = await PrivateKey.generate({ strength: 2048 }); +const network = new Network(privateKey, { + topology, + directConnection: true +}); -async function loadTopology() { - const packed = JSON.parse(await readFile(topologyFile, 'utf8')); - return Topology.load(packed); -} +console.log(`Connecting to ${topology.size()} Universa nodes from ${topologyFile}`); +await network.connect(); -async function testNetwork(privateKey) { - const topology = await loadTopology(); - const network = new Network(privateKey, { - topology, - directConnection: true - }); +const response = await network.command('sping'); +assert.equal(response?.sping, 'spong', 'unexpected network state response'); - console.log(`Testing ${topology.size()} Universa nodes from ${topologyFile}`); - await withTimeout(network.connect(), 15_000, 'Network connection timed out'); - - const nodes = Object.entries(network.topology.nodes); - const results = await Promise.all(nodes.map(async ([id, node]) => { - try { - const connection = await withTimeout( - network.nodeConnection(id), - 10_000, - `${node.name} connection timed out` - ); - const response = await connection.command('sping', {}, { timeout: 5_000 }); - if (response?.sping !== 'spong') throw new Error('unexpected sping response'); - console.log(`PASS ${node.name}: authenticated, sping=spong`); - return true; - } catch (error) { - console.error(`FAIL ${node.name}: ${error instanceof Error ? error.message : error}`); - return false; - } - })); - - const passed = results.filter(Boolean).length; - const quorum = Math.max(1, Math.ceil(nodes.length * 0.4)); - if (passed < quorum) { - throw new Error(`Network quorum failed: ${passed}/${nodes.length} nodes passed; ${quorum} required`); - } - - console.log(`Universa network is functioning: ${passed}/${nodes.length} nodes passed`); -} - -function printHelp() { - console.log(`Usage: u-js-sample [options] - -Options: - --generate-key Generate a private key and print its short address - --test-network Test every node in src/universa.json - --help Show this help`); -} - -async function main() { - const options = new Set(process.argv.slice(2)); - if (options.size === 0 || options.has('--help')) return printHelp(); - - const unknown = [...options].find((option) => ( - option !== '--generate-key' && option !== '--test-network' - )); - if (unknown) throw new Error(`Unknown option: ${unknown}`); - - if (options.has('--generate-key') || options.has('--test-network')) { - await unicryptoReady; - const privateKey = await PrivateKey.generate({ strength: 2048 }); - console.log(`Universa short address: ${privateKey.publicKey.shortAddress58}`); - - if (options.has('--test-network')) await testNetwork(privateKey); - } -} - -try { - await main(); -} catch (error) { - console.error(error instanceof Error ? error.message : error); - process.exitCode = 1; -} +console.log(`Universa network is functioning: ${network.size()} nodes, sping=spong`);