@hive-p2p/browser 1.0.94 → 1.0.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -44,8 +44,10 @@ export class CryptoCodex {
44
44
  /** @param {boolean} asPublicNode @param {Uint8Array} [seed] The privateKey. DON'T USE IN SIMULATION */
45
45
  async generate(asPublicNode, seed) { // Generate Ed25519 keypair cross-platform | set id only for simulator
46
46
  if (this.nodeId) return;
47
- await this.#generateAntiSybilIdentity(seed, asPublicNode);
48
- this.AVOID_CRYPTO = false; // enable crypto operations
47
+
48
+ const s = seed || await CryptoCodex.generateNewSybilIdentity(asPublicNode, this.verbose > 0);
49
+ await this.#generateAntiSybilIdentity(s, asPublicNode);
50
+ this.AVOID_CRYPTO = false; // force enable crypto operations
49
51
  if (!this.id) throw new Error('Failed to generate identity');
50
52
  }
51
53
  /** Check if the pubKey meets the difficulty using Argon2 derivation @param {Uint8Array} publicKey */
@@ -61,20 +63,27 @@ export class CryptoCodex {
61
63
  }
62
64
  /** @param {Uint8Array} seed The privateKey. @param {boolean} asPublicNode */
63
65
  async #generateAntiSybilIdentity(seed, asPublicNode) {
64
- const maxIterations = (2 ** IDENTITY.DIFFICULTY) * 100; // avoid infinite loop
65
- for (let i = 0; i < maxIterations; i++) { // avoid infinite loop
66
- const { secretKey, publicKey } = ed25519.keygen(seed);
67
- const id = this.#idFromPublicKey(publicKey);
68
- if (asPublicNode && !this.isPublicNode(id)) continue; // Check prefix
69
- if (!asPublicNode && this.isPublicNode(id)) continue; // Check prefix
70
- if (!await this.pubkeyDifficultyCheck(publicKey)) continue; // Check difficulty
66
+ const { secretKey, publicKey } = ed25519.keygen(seed);
67
+ const id = this.#idFromPublicKey(publicKey);
68
+ if (asPublicNode && !this.isPublicNode(id)) throw new Error('Seed does not produce a public node identity.');
69
+ if (!asPublicNode && this.isPublicNode(id)) throw new Error('Seed does not produce a private node identity.');
70
+ if (!await this.pubkeyDifficultyCheck(publicKey)) throw new Error('Seed does not meet difficulty requirements.');
71
+ this.id = id;
72
+ this.privateKey = secretKey; this.publicKey = publicKey;
73
+ }
74
+ /** @param {boolean} asPublicNode */
75
+ static async generateNewSybilIdentity(asPublicNode, log = true) {
76
+ const cryptoCodex = new CryptoCodex();
77
+ const maxIterations = (2 ** IDENTITY.DIFFICULTY) * 128;
78
+ for (let i = 0; i < maxIterations; i++) {
79
+ const seed = randomBytes(32);
80
+ try { await cryptoCodex.#generateAntiSybilIdentity(seed, asPublicNode); }
81
+ catch { continue; }
71
82
 
72
- this.id = id;
73
- this.privateKey = secretKey; this.publicKey = publicKey;
74
- if (this.verbose > 2) console.log(`%cNode generated id: ${this.id} (isPublic: ${asPublicNode}, difficulty: ${IDENTITY.DIFFICULTY}) after ${((i + 1) / 2).toFixed(1)} iterations`, LOG_CSS.CRYPTO_CODEX);
75
- return;
83
+ if (log) console.log(`Generated new ${asPublicNode ? 'public' : 'private'} identity after ${i + 1} iterations.`);
84
+ return seed;
76
85
  }
77
- if (this.verbose > 0) console.log(`%cFAILED to generate id after ${maxIterations} iterations. Try lowering the difficulty.`, LOG_CSS.CRYPTO_CODEX);
86
+ throw new Error(`Failed to generate identity after ${maxIterations} iterations. Try lowering the difficulty.`);
78
87
  }
79
88
 
80
89
  // PRIVACY
@@ -50,10 +50,10 @@ export class NodeServices {
50
50
  }
51
51
  #startWebSocketServer(domain = 'localhost', port = SERVICE.PORT) {
52
52
  this.wsServer = new TRANSPORTS.WS_SERVER({ port, host: domain });
53
- this.wsServer.on('error', (error) => console.error(`WebSocket error on Node #${this.id}:`, error));
53
+ this.wsServer.on('error', (error) => console.warn(`WebSocket error on Node #${this.id}:`, error));
54
54
  this.wsServer.on('connection', (ws) => {
55
55
  ws.on('close', () => { if (remoteId) for (const cb of this.peerStore.callbacks.disconnect) cb(remoteId, 'in'); });
56
- ws.on('error', (error) => console.error(`WebSocket error on Node #${this.id} with peer ${remoteId}:`, error.stack));
56
+ ws.on('error', (error) => console.warn(`WebSocket error on Node #${this.id} with peer ${remoteId}:`, error.stack));
57
57
 
58
58
  let remoteId;
59
59
  ws.on('message', (data) => { // When peer proves his id, we can handle data normally
@@ -170,7 +170,7 @@ export class Topologist {
170
170
  #connectToPublicNode(publicUrl = 'localhost:8080') {
171
171
  let remoteId = null;
172
172
  const ws = new TRANSPORTS.WS_CLIENT(this.#getFullWsUrl(publicUrl)); ws.binaryType = 'arraybuffer';
173
- ws.onerror = (error) => console.error(`WebSocket error:`, error.stack);
173
+ ws.onerror = (error) => console.warn(`WebSocket error:`, error.stack);
174
174
  ws.onopen = () => {
175
175
  this.bootstrapsConnectionState.set(publicUrl, true);
176
176
  ws.onclose = () => {