@leofcoin/chain 1.9.13 → 1.9.15

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.
@@ -1,3 +1,3 @@
1
- export { N as default } from './node-browser-Oq89xLSU.js';
2
- import './identity-B8_RBemH-Dq17MYzU.js';
1
+ export { N as default } from './node-browser-y2adT6_R.js';
2
+ import 'crypto';
3
3
  import './constants-V2VjIc2r.js';
package/exports/chain.js CHANGED
@@ -2339,22 +2339,22 @@ class Chain extends VersionControl {
2339
2339
  #sleep(ms) {
2340
2340
  return new Promise((resolve) => setTimeout(resolve, ms));
2341
2341
  }
2342
- async #recordPeerFailure(peerId2, reason) {
2343
- if (!this.#peerReputations.has(peerId2)) {
2344
- this.#peerReputations.set(peerId2, { score: 0, failures: [] });
2342
+ async #recordPeerFailure(peerId, reason) {
2343
+ if (!this.#peerReputations.has(peerId)) {
2344
+ this.#peerReputations.set(peerId, { score: 0, failures: [] });
2345
2345
  }
2346
- const rep = this.#peerReputations.get(peerId2);
2346
+ const rep = this.#peerReputations.get(peerId);
2347
2347
  rep.score -= 1;
2348
2348
  rep.failures.push(`${Date.now()}: ${reason}`);
2349
2349
  if (rep.failures.length > this.#maxPeerFailures) {
2350
2350
  rep.failures.shift();
2351
2351
  }
2352
2352
  if (rep.score < this.#minPeerScore) {
2353
- console.warn(`[peer-ban] Peer ${peerId2} banned after ${rep.failures.length} failures`);
2353
+ console.warn(`[peer-ban] Peer ${peerId} banned after ${rep.failures.length} failures`);
2354
2354
  try {
2355
- await globalThis.peernet.disconnect(peerId2);
2355
+ await globalThis.peernet.disconnect(peerId);
2356
2356
  } catch (e) {
2357
- debug(`Failed to disconnect peer ${peerId2}`);
2357
+ debug(`Failed to disconnect peer ${peerId}`);
2358
2358
  }
2359
2359
  }
2360
2360
  }
@@ -2474,8 +2474,8 @@ class Chain extends VersionControl {
2474
2474
  const start = Date.now();
2475
2475
  try {
2476
2476
  await this.#createBlock();
2477
- } catch (error2) {
2478
- console.error(error2);
2477
+ } catch (error) {
2478
+ console.error(error);
2479
2479
  }
2480
2480
  const end = Date.now();
2481
2481
  console.log((end - start) / 1e3 + " s");
@@ -2525,6 +2525,36 @@ class Chain extends VersionControl {
2525
2525
  console.log("init");
2526
2526
  await super.init();
2527
2527
  console.log("super init done");
2528
+ const peernetAny = globalThis.peernet;
2529
+ if (typeof peernetAny.removePeer === "function" && !peernetAny.__chainRemovePeerGuardInstalled) {
2530
+ const originalRemovePeer = peernetAny.removePeer.bind(peernetAny);
2531
+ peernetAny.removePeer = async (peer) => {
2532
+ if (!peer || typeof peer !== "object") {
2533
+ debug("removePeer called with invalid peer (ignored)");
2534
+ return;
2535
+ }
2536
+ const peerId = peer?.id || peer?.peerId;
2537
+ if (!peerId || typeof peerId !== "string") {
2538
+ debug("removePeer called with peer missing id (ignored)");
2539
+ return;
2540
+ }
2541
+ const trackedPeers = Object.values(peernetAny.connections || {});
2542
+ const isStillTracked = trackedPeers.some((trackedPeer) => {
2543
+ const trackedId = trackedPeer?.id || trackedPeer?.peerId;
2544
+ return trackedPeer === peer || trackedId === peerId;
2545
+ });
2546
+ if (!isStillTracked) {
2547
+ debug(`removePeer called for unknown peer ${peerId} (ignored)`);
2548
+ return;
2549
+ }
2550
+ try {
2551
+ return await originalRemovePeer(peer);
2552
+ } catch (error) {
2553
+ debug("removePeer failed (ignored):", error?.message ?? error);
2554
+ }
2555
+ };
2556
+ peernetAny.__chainRemovePeerGuardInstalled = true;
2557
+ }
2528
2558
  this.#connectionMonitor.start(this.version);
2529
2559
  await globalThis.peernet.addRequestHandler("bw-request-message", () => {
2530
2560
  const bw = globalThis.peernet.client?.bw || { up: 0, down: 0 };
@@ -2532,9 +2562,11 @@ class Chain extends VersionControl {
2532
2562
  });
2533
2563
  await globalThis.peernet.addRequestHandler("transactionPool", this.#transactionPoolHandler.bind(this));
2534
2564
  await globalThis.peernet.addRequestHandler("version", this.#versionHandler.bind(this));
2535
- await globalThis.peernet.addRequestHandler("stateInfo", () => {
2565
+ await globalThis.peernet.addRequestHandler("stateInfo", async () => {
2566
+ const lastblock = await this.lastBlock || { index: 0, hash: "0x0", previousHash: "0x0" };
2567
+ const values = this.machine?.states?.info || {};
2536
2568
  return new globalThis.peernet.protos["peernet-response"]({
2537
- response: new StateMessage(this.machine.states.info).encoded
2569
+ response: new StateMessage({ lastblock, values }).encoded
2538
2570
  });
2539
2571
  });
2540
2572
  globalThis.peernet.subscribe("add-block", this.#addBlock.bind(this));
@@ -2590,10 +2622,10 @@ class Chain extends VersionControl {
2590
2622
  console.warn(`Deprecated: ${response.decoded.response} is not an Uint8Array`);
2591
2623
  }
2592
2624
  return response.decoded.response;
2593
- } catch (error2) {
2594
- const peerId2 = peer?.peerId || peer?.id || peer?.address || "unknown";
2595
- debug(`peernet request failed: ${request} -> ${peerId2}:`, error2?.message ?? error2);
2596
- throw error2;
2625
+ } catch (error) {
2626
+ const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
2627
+ debug(`peernet request failed: ${request} -> ${peerId}:`, error?.message ?? error);
2628
+ throw error;
2597
2629
  }
2598
2630
  }
2599
2631
  async #decodeKnownBlocksResponse(response) {
@@ -2657,8 +2689,8 @@ class Chain extends VersionControl {
2657
2689
  let txData;
2658
2690
  try {
2659
2691
  txData = await globalThis.peernet.get(key, "transaction");
2660
- } catch (error2) {
2661
- debug(`Failed to get transaction ${key}:`, error2?.message ?? error2);
2692
+ } catch (error) {
2693
+ debug(`Failed to get transaction ${key}:`, error?.message ?? error);
2662
2694
  }
2663
2695
  if (txData !== void 0) {
2664
2696
  transactionsToGet.push(transactionPoolStore.put(key, txData));
@@ -2667,13 +2699,23 @@ class Chain extends VersionControl {
2667
2699
  }
2668
2700
  return Promise.all(transactionsToGet);
2669
2701
  }
2670
- async #peerConnected(peerId2) {
2671
- debug(`peer connected: ${peerId2}`);
2672
- const peer = peernet.getConnection(peerId2);
2702
+ async #peerConnected(peerId) {
2703
+ debug(`peer connected: ${peerId}`);
2704
+ const peer = peernet.getConnection(peerId);
2673
2705
  if (!peer) {
2674
- debug(`peer not found: ${peerId2}`);
2706
+ debug(`peer not found: ${peerId}`);
2675
2707
  return;
2676
2708
  }
2709
+ const peerAny = peer;
2710
+ if (typeof peerAny.on === "function" && !peerAny.__chainErrorListenerInstalled) {
2711
+ peerAny.on("error", async (error) => {
2712
+ const reason = error?.message ?? String(error);
2713
+ const peerName = peerAny?.peerId || peerAny?.id || peerAny?.address || peerId || "unknown";
2714
+ debug(`peer error: ${peerName}:`, reason);
2715
+ await this.#recordPeerFailure(peerId, `peer error: ${reason}`);
2716
+ });
2717
+ peerAny.__chainErrorListenerInstalled = true;
2718
+ }
2677
2719
  if (!peer.version) {
2678
2720
  try {
2679
2721
  let versionResponse = await this.#makeRequest(peer, "version");
@@ -2686,13 +2728,13 @@ class Chain extends VersionControl {
2686
2728
  peer.version = versionResponse.version;
2687
2729
  }
2688
2730
  if (!peer.version || typeof peer.version !== "string") {
2689
- const reason = `invalid version response from peer ${peerId2}`;
2731
+ const reason = `invalid version response from peer ${peerId}`;
2690
2732
  debug(reason);
2691
- await this.#recordPeerFailure(peerId2, reason);
2733
+ await this.#recordPeerFailure(peerId, reason);
2692
2734
  return;
2693
2735
  }
2694
- } catch (error2) {
2695
- debug(`failed to request version from peer ${peerId2}:`, error2?.message ?? error2);
2736
+ } catch (error) {
2737
+ debug(`failed to request version from peer ${peerId}:`, error?.message ?? error);
2696
2738
  return;
2697
2739
  }
2698
2740
  }
@@ -2700,7 +2742,7 @@ class Chain extends VersionControl {
2700
2742
  if (!this.isVersionCompatible(peer.version)) {
2701
2743
  const mismatchReason = `incompatible peer version ${peer.version} (local: ${this.version})`;
2702
2744
  console.error(`[chain] ${mismatchReason}`);
2703
- await this.#recordPeerFailure(peerId2, mismatchReason);
2745
+ await this.#recordPeerFailure(peerId, mismatchReason);
2704
2746
  return;
2705
2747
  }
2706
2748
  let lastBlock;
@@ -2710,22 +2752,22 @@ class Chain extends VersionControl {
2710
2752
  const lastBlockRaw = await this.#makeRequest(peer, "lastBlock");
2711
2753
  console.log(new LastBlockMessage(lastBlockRaw));
2712
2754
  lastBlock = new LastBlockMessage(lastBlockRaw).decoded;
2713
- } catch (error2) {
2714
- const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
2715
- debug(`lastBlock request failed: ${peerName2}:`, error2?.message ?? error2);
2716
- await this.#recordPeerFailure(peerId2, `lastBlock request failed: ${error2?.message ?? error2}`);
2755
+ } catch (error) {
2756
+ const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2757
+ debug(`lastBlock request failed: ${peerName}:`, error?.message ?? error);
2758
+ await this.#recordPeerFailure(peerId, `lastBlock request failed: ${error?.message ?? error}`);
2717
2759
  return;
2718
2760
  }
2719
2761
  const localBlock = await this.lastBlock;
2720
2762
  const MAX_SYNC_AHEAD = 1e5;
2721
2763
  if (lastBlock?.index > BigInt(localBlock?.index ?? 0) + BigInt(MAX_SYNC_AHEAD)) {
2722
- const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
2723
- debug(`Peer ${peerName2} claims unreasonable block height ${lastBlock.index} (local: ${localBlock?.index ?? 0})`);
2724
- await this.#recordPeerFailure(peerId2, `unreasonable lastBlock index: ${lastBlock.index}`);
2764
+ const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2765
+ debug(`Peer ${peerName} claims unreasonable block height ${lastBlock.index} (local: ${localBlock?.index ?? 0})`);
2766
+ await this.#recordPeerFailure(peerId, `unreasonable lastBlock index: ${lastBlock.index}`);
2725
2767
  return;
2726
2768
  }
2727
2769
  if (!lastBlock || !lastBlock.hash || lastBlock.hash === "0x0") {
2728
- debug(`peer has no lastBlock: ${peerId2}`);
2770
+ debug(`peer has no lastBlock: ${peerId}`);
2729
2771
  return;
2730
2772
  }
2731
2773
  const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
@@ -2736,7 +2778,7 @@ class Chain extends VersionControl {
2736
2778
  const knownBlocksResponse = await this.#decodeKnownBlocksResponse(knownBlocksRaw);
2737
2779
  if (!knownBlocksResponse) {
2738
2780
  debug(
2739
- `knownBlocks decode failed for peer ${peerId2} (non-fatal), continuing sync without prefilled wantList`
2781
+ `knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`
2740
2782
  );
2741
2783
  } else {
2742
2784
  const MAX_WANTLIST_SIZE = 1e3;
@@ -2747,11 +2789,11 @@ class Chain extends VersionControl {
2747
2789
  }
2748
2790
  }
2749
2791
  }
2750
- } catch (error2) {
2751
- const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
2792
+ } catch (error) {
2793
+ const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2752
2794
  debug(
2753
- `knownBlocks request failed: ${peerName2} (non-fatal), continuing sync without prefilled wantList:`,
2754
- error2?.message ?? error2
2795
+ `knownBlocks request failed: ${peerName} (non-fatal), continuing sync without prefilled wantList:`,
2796
+ error?.message ?? error
2755
2797
  );
2756
2798
  }
2757
2799
  }
@@ -2768,28 +2810,29 @@ class Chain extends VersionControl {
2768
2810
  try {
2769
2811
  const peerTransactionPool = higherThenCurrentLocal && await this.getPeerTransactionPool(peer) || [];
2770
2812
  if (this.#participating && peerTransactionPool.length > 0) return this.#runEpoch();
2771
- } catch (error2) {
2772
- const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
2773
- debug(`transactionPool request failed: ${peerName2}:`, error2?.message ?? error2);
2813
+ } catch (error) {
2814
+ const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2815
+ debug(`transactionPool request failed: ${peerName}:`, error?.message ?? error);
2774
2816
  }
2775
2817
  }, 3e3);
2776
2818
  try {
2777
2819
  let stateInfo = await this.#makeRequest(peer, "stateInfo");
2778
2820
  if (stateInfo instanceof Uint8Array) {
2779
- stateInfo = new StateMessage(stateInfo).decoded;
2821
+ const decodedStateInfo = new StateMessage(stateInfo).decoded;
2822
+ stateInfo = decodedStateInfo?.values ?? decodedStateInfo;
2780
2823
  }
2781
2824
  debug(
2782
- `sync start with peer ${peerId2}: local=${localBlock?.index ?? -1} remote=${lastBlock?.index ?? -1} hash=${lastBlock?.hash}`
2825
+ `sync start with peer ${peerId}: local=${localBlock?.index ?? -1} remote=${lastBlock?.index ?? -1} hash=${lastBlock?.hash}`
2783
2826
  );
2784
2827
  await this.syncChain(lastBlock);
2785
2828
  debug(
2786
- `sync finished with peer ${peerId2}: state=${this.syncState} localNow=${(await this.lastBlock)?.index ?? -1}`
2829
+ `sync finished with peer ${peerId}: state=${this.syncState} localNow=${(await this.lastBlock)?.index ?? -1}`
2787
2830
  );
2788
2831
  this.machine.states.info = stateInfo;
2789
- } catch (error2) {
2790
- const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
2791
- debug(`stateInfo/syncChain failed: ${peerName2}:`, error2?.message ?? error2);
2792
- await this.#recordPeerFailure(peerId2, `stateInfo/syncChain failed: ${error2?.message ?? error2}`);
2832
+ } catch (error) {
2833
+ const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2834
+ debug(`stateInfo/syncChain failed: ${peerName}:`, error?.message ?? error);
2835
+ await this.#recordPeerFailure(peerId, `stateInfo/syncChain failed: ${error?.message ?? error}`);
2793
2836
  return;
2794
2837
  }
2795
2838
  }
@@ -2805,19 +2848,16 @@ class Chain extends VersionControl {
2805
2848
  try {
2806
2849
  let result = await this.machine.execute(to, method, params);
2807
2850
  globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fulfilled", hash });
2808
- debug(
2809
- `lastBlock request failed: ${peerName} (non-fatal), continuing sync without prefilled wantList:`,
2810
- error?.message ?? error
2811
- );
2812
- } catch (error2) {
2851
+ return result || "no state change";
2852
+ } catch (error) {
2813
2853
  await transactionPoolStore.delete(hash);
2814
2854
  try {
2815
2855
  globalThis.peernet.publish("invalid-transaction", hash);
2816
2856
  } catch (publishError) {
2817
2857
  debug("peernet publish failed: invalid-transaction", publishError?.message ?? publishError);
2818
2858
  }
2819
- globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error: error2 });
2820
- throw { error: error2, hash, from, to, params, nonce };
2859
+ globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error });
2860
+ throw { error, hash, from, to, params, nonce };
2821
2861
  }
2822
2862
  }
2823
2863
  async #addBlock(block) {
@@ -2828,7 +2868,6 @@ class Chain extends VersionControl {
2828
2868
  const existingBlockAtHeight = this.#blocks[blockIndex];
2829
2869
  if (existingBlockAtHeight) {
2830
2870
  if (existingBlockAtHeight.hash !== hash) {
2831
- debug(`knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`);
2832
2871
  console.error(` Local: ${existingBlockAtHeight.hash}`);
2833
2872
  console.error(` Remote: ${hash}`);
2834
2873
  throw new Error(`Block conflict detected at index ${blockIndex}`);
@@ -2936,10 +2975,10 @@ class Chain extends VersionControl {
2936
2975
  await this.updateState(blockMessage);
2937
2976
  }
2938
2977
  globalThis.pubsub.publish("block-processed", blockMessage.decoded);
2939
- } catch (error2) {
2940
- console.log(error2.hash);
2978
+ } catch (error) {
2979
+ console.log(error.hash);
2941
2980
  console.log("errrrr");
2942
- await transactionPoolStore.delete(error2.hash);
2981
+ await transactionPoolStore.delete(error.hash);
2943
2982
  }
2944
2983
  }
2945
2984
  async participate(address) {
@@ -2957,12 +2996,12 @@ class Chain extends VersionControl {
2957
2996
  const transaction = await signTransaction(rawTransaction, globalThis.peernet.identity);
2958
2997
  try {
2959
2998
  await this.sendTransaction(transaction);
2960
- } catch (error2) {
2961
- console.error(error2);
2999
+ } catch (error) {
3000
+ console.error(error);
2962
3001
  }
2963
3002
  }
2964
- } catch (error2) {
2965
- debug("Error in participate:", error2.message);
3003
+ } catch (error) {
3004
+ debug("Error in participate:", error.message);
2966
3005
  }
2967
3006
  if (await this.hasTransactionToHandle() && !this.#runningEpoch && this.#participating) await this.#runEpoch();
2968
3007
  }
@@ -3059,9 +3098,9 @@ class Chain extends VersionControl {
3059
3098
  address: validator,
3060
3099
  bw: bw.up + bw.down
3061
3100
  };
3062
- } catch (error2) {
3063
- const peerId2 = peer?.peerId || peer?.id || peer?.address || "unknown";
3064
- debug(`bw request failed: ${peerId2}:`, error2?.message ?? error2);
3101
+ } catch (error) {
3102
+ const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
3103
+ debug(`bw request failed: ${peerId}:`, error?.message ?? error);
3065
3104
  return null;
3066
3105
  }
3067
3106
  } else if (globalThis.peernet.selectedAccount === validator) {
@@ -3079,8 +3118,8 @@ class Chain extends VersionControl {
3079
3118
  }
3080
3119
  }
3081
3120
  };
3082
- finalizeBWAndBroadcast().catch((error2) => {
3083
- debug(`background BW finalization failed:`, error2?.message ?? error2);
3121
+ finalizeBWAndBroadcast().catch((error) => {
3122
+ debug(`background BW finalization failed:`, error?.message ?? error);
3084
3123
  });
3085
3124
  block.validators = block.validators.map((validator) => {
3086
3125
  validator.reward = block.fees;
@@ -3145,8 +3184,8 @@ class Chain extends VersionControl {
3145
3184
  debug("peernet publish failed: consensus:propose", publishError?.message ?? publishError);
3146
3185
  }
3147
3186
  await this.#castVote("prevote", hash, block.index, this.#consensusRound);
3148
- } catch (error2) {
3149
- console.log(error2);
3187
+ } catch (error) {
3188
+ console.log(error);
3150
3189
  throw new Error(`invalid block ${block}`);
3151
3190
  }
3152
3191
  }
@@ -3277,8 +3316,8 @@ class Chain extends VersionControl {
3277
3316
  if (globalThis.peernet && globalThis.peernet.start) {
3278
3317
  await globalThis.peernet.start();
3279
3318
  }
3280
- } catch (error2) {
3281
- console.warn("Failed to reconnect to peers:", error2.message);
3319
+ } catch (error) {
3320
+ console.warn("Failed to reconnect to peers:", error.message);
3282
3321
  }
3283
3322
  }
3284
3323
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/chain",
3
- "version": "1.9.13",
3
+ "version": "1.9.15",
4
4
  "description": "Official javascript implementation",
5
5
  "private": false,
6
6
  "exports": {
@@ -49,7 +49,7 @@
49
49
  "author": "",
50
50
  "license": "MIT",
51
51
  "devDependencies": {
52
- "@rollup/plugin-commonjs": "^29.0.2",
52
+ "@rollup/plugin-commonjs": "^29.0.3",
53
53
  "@rollup/plugin-json": "^6.1.0",
54
54
  "@rollup/plugin-node-resolve": "^16.0.3",
55
55
  "@rollup/plugin-typescript": "^12.3.0",
@@ -69,9 +69,9 @@
69
69
  "@leofcoin/errors": "^1.0.28",
70
70
  "@leofcoin/lib": "^1.2.77",
71
71
  "@leofcoin/messages": "^1.5.2",
72
- "@leofcoin/multi-wallet": "^3.1.8",
72
+ "@leofcoin/multi-wallet": "^3.1.9",
73
73
  "@leofcoin/networks": "^1.1.28",
74
- "@leofcoin/peernet": "^1.2.20",
74
+ "@leofcoin/peernet": "^1.2.21",
75
75
  "@leofcoin/storage": "^3.5.38",
76
76
  "@leofcoin/utils": "^1.1.42",
77
77
  "@leofcoin/workers": "^1.5.30",