@leofcoin/chain 1.9.11 → 1.9.12

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.
@@ -6116,22 +6116,22 @@ class Chain extends VersionControl {
6116
6116
  #sleep(ms) {
6117
6117
  return new Promise((resolve) => setTimeout(resolve, ms));
6118
6118
  }
6119
- async #recordPeerFailure(peerId, reason) {
6120
- if (!this.#peerReputations.has(peerId)) {
6121
- this.#peerReputations.set(peerId, { score: 0, failures: [] });
6119
+ async #recordPeerFailure(peerId2, reason) {
6120
+ if (!this.#peerReputations.has(peerId2)) {
6121
+ this.#peerReputations.set(peerId2, { score: 0, failures: [] });
6122
6122
  }
6123
- const rep = this.#peerReputations.get(peerId);
6123
+ const rep = this.#peerReputations.get(peerId2);
6124
6124
  rep.score -= 1;
6125
6125
  rep.failures.push(`${Date.now()}: ${reason}`);
6126
6126
  if (rep.failures.length > this.#maxPeerFailures) {
6127
6127
  rep.failures.shift();
6128
6128
  }
6129
6129
  if (rep.score < this.#minPeerScore) {
6130
- console.warn(`[peer-ban] Peer ${peerId} banned after ${rep.failures.length} failures`);
6130
+ console.warn(`[peer-ban] Peer ${peerId2} banned after ${rep.failures.length} failures`);
6131
6131
  try {
6132
- await globalThis.peernet.disconnect(peerId);
6132
+ await globalThis.peernet.disconnect(peerId2);
6133
6133
  } catch (e) {
6134
- debug(`Failed to disconnect peer ${peerId}`);
6134
+ debug(`Failed to disconnect peer ${peerId2}`);
6135
6135
  }
6136
6136
  }
6137
6137
  }
@@ -6251,8 +6251,8 @@ class Chain extends VersionControl {
6251
6251
  const start = Date.now();
6252
6252
  try {
6253
6253
  await this.#createBlock();
6254
- } catch (error) {
6255
- console.error(error);
6254
+ } catch (error2) {
6255
+ console.error(error2);
6256
6256
  }
6257
6257
  const end = Date.now();
6258
6258
  console.log((end - start) / 1e3 + " s");
@@ -6367,30 +6367,57 @@ class Chain extends VersionControl {
6367
6367
  console.warn(`Deprecated: ${response.decoded.response} is not an Uint8Array`);
6368
6368
  }
6369
6369
  return response.decoded.response;
6370
- } catch (error) {
6371
- const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
6372
- debug(`peernet request failed: ${request} -> ${peerId}:`, error?.message ?? error);
6373
- throw error;
6370
+ } catch (error2) {
6371
+ const peerId2 = peer?.peerId || peer?.id || peer?.address || "unknown";
6372
+ debug(`peernet request failed: ${request} -> ${peerId2}:`, error2?.message ?? error2);
6373
+ throw error2;
6374
6374
  }
6375
6375
  }
6376
6376
  async #decodeKnownBlocksResponse(response) {
6377
6377
  if (!response) return null;
6378
+ if (Array.isArray(response)) {
6379
+ return { blocks: response };
6380
+ }
6378
6381
  if (Array.isArray(response.blocks)) {
6379
6382
  return { blocks: response.blocks };
6380
6383
  }
6384
+ if (response.response && Array.isArray(response.response.blocks)) {
6385
+ return { blocks: response.response.blocks };
6386
+ }
6387
+ if (typeof response === "string") {
6388
+ try {
6389
+ const parsed = JSON.parse(response);
6390
+ if (Array.isArray(parsed)) return { blocks: parsed };
6391
+ if (parsed && Array.isArray(parsed.blocks)) return { blocks: parsed.blocks };
6392
+ if (parsed?.response && Array.isArray(parsed.response.blocks)) return { blocks: parsed.response.blocks };
6393
+ } catch {
6394
+ return null;
6395
+ }
6396
+ return null;
6397
+ }
6381
6398
  if (!(response instanceof Uint8Array)) return null;
6382
6399
  let payload = response;
6383
- for (let i = 0; i < 2; i++) {
6400
+ for (let i = 0; i < 3; i++) {
6384
6401
  if (!(payload instanceof Uint8Array)) break;
6385
6402
  try {
6386
6403
  const nestedResponse = await new globalThis.peernet.protos["peernet-response"](payload);
6387
6404
  payload = nestedResponse?.decoded?.response;
6388
6405
  } catch {
6389
- return null;
6406
+ break;
6390
6407
  }
6391
6408
  }
6392
6409
  if (Array.isArray(payload)) return { blocks: payload };
6393
6410
  if (payload && Array.isArray(payload.blocks)) return { blocks: payload.blocks };
6411
+ if (payload?.response && Array.isArray(payload.response.blocks)) return { blocks: payload.response.blocks };
6412
+ try {
6413
+ const decoded = new TextDecoder().decode(response);
6414
+ const parsed = JSON.parse(decoded);
6415
+ if (Array.isArray(parsed)) return { blocks: parsed };
6416
+ if (parsed && Array.isArray(parsed.blocks)) return { blocks: parsed.blocks };
6417
+ if (parsed?.response && Array.isArray(parsed.response.blocks)) return { blocks: parsed.response.blocks };
6418
+ } catch {
6419
+ return null;
6420
+ }
6394
6421
  return null;
6395
6422
  }
6396
6423
  async getPeerTransactionPool(peer) {
@@ -6407,8 +6434,8 @@ class Chain extends VersionControl {
6407
6434
  let txData;
6408
6435
  try {
6409
6436
  txData = await globalThis.peernet.get(key, "transaction");
6410
- } catch (error) {
6411
- debug(`Failed to get transaction ${key}:`, error?.message ?? error);
6437
+ } catch (error2) {
6438
+ debug(`Failed to get transaction ${key}:`, error2?.message ?? error2);
6412
6439
  }
6413
6440
  if (txData !== void 0) {
6414
6441
  transactionsToGet.push(transactionPoolStore.put(key, txData));
@@ -6417,11 +6444,11 @@ class Chain extends VersionControl {
6417
6444
  }
6418
6445
  return Promise.all(transactionsToGet);
6419
6446
  }
6420
- async #peerConnected(peerId) {
6421
- debug(`peer connected: ${peerId}`);
6422
- const peer = peernet.getConnection(peerId);
6447
+ async #peerConnected(peerId2) {
6448
+ debug(`peer connected: ${peerId2}`);
6449
+ const peer = peernet.getConnection(peerId2);
6423
6450
  if (!peer) {
6424
- debug(`peer not found: ${peerId}`);
6451
+ debug(`peer not found: ${peerId2}`);
6425
6452
  return;
6426
6453
  }
6427
6454
  if (!peer.version) {
@@ -6436,13 +6463,13 @@ class Chain extends VersionControl {
6436
6463
  peer.version = versionResponse.version;
6437
6464
  }
6438
6465
  if (!peer.version || typeof peer.version !== "string") {
6439
- const reason = `invalid version response from peer ${peerId}`;
6466
+ const reason = `invalid version response from peer ${peerId2}`;
6440
6467
  debug(reason);
6441
- await this.#recordPeerFailure(peerId, reason);
6468
+ await this.#recordPeerFailure(peerId2, reason);
6442
6469
  return;
6443
6470
  }
6444
- } catch (error) {
6445
- debug(`failed to request version from peer ${peerId}:`, error?.message ?? error);
6471
+ } catch (error2) {
6472
+ debug(`failed to request version from peer ${peerId2}:`, error2?.message ?? error2);
6446
6473
  return;
6447
6474
  }
6448
6475
  }
@@ -6450,31 +6477,32 @@ class Chain extends VersionControl {
6450
6477
  if (!this.isVersionCompatible(peer.version)) {
6451
6478
  const mismatchReason = `incompatible peer version ${peer.version} (local: ${this.version})`;
6452
6479
  console.error(`[chain] ${mismatchReason}`);
6453
- await this.#recordPeerFailure(peerId, mismatchReason);
6480
+ await this.#recordPeerFailure(peerId2, mismatchReason);
6454
6481
  return;
6455
6482
  }
6456
6483
  let lastBlock;
6457
6484
  try {
6458
6485
  console.log("requesting last block from peer...");
6459
6486
  console.log(await this.lastBlock);
6460
- console.log(new LastBlockMessage(await this.#makeRequest(peer, "lastBlock")));
6461
- lastBlock = new LastBlockMessage(await this.#makeRequest(peer, "lastBlock")).decoded;
6462
- } catch (error) {
6463
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
6464
- debug(`lastBlock request failed: ${peerName}:`, error?.message ?? error);
6465
- await this.#recordPeerFailure(peerId, `lastBlock request failed: ${error?.message ?? error}`);
6487
+ const lastBlockRaw = await this.#makeRequest(peer, "lastBlock");
6488
+ console.log(new LastBlockMessage(lastBlockRaw));
6489
+ lastBlock = new LastBlockMessage(lastBlockRaw).decoded;
6490
+ } catch (error2) {
6491
+ const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
6492
+ debug(`lastBlock request failed: ${peerName2}:`, error2?.message ?? error2);
6493
+ await this.#recordPeerFailure(peerId2, `lastBlock request failed: ${error2?.message ?? error2}`);
6466
6494
  return;
6467
6495
  }
6468
6496
  const localBlock = await this.lastBlock;
6469
6497
  const MAX_SYNC_AHEAD = 1e5;
6470
6498
  if (lastBlock?.index > BigInt(localBlock?.index ?? 0) + BigInt(MAX_SYNC_AHEAD)) {
6471
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
6472
- debug(`Peer ${peerName} claims unreasonable block height ${lastBlock.index} (local: ${localBlock?.index ?? 0})`);
6473
- await this.#recordPeerFailure(peerId, `unreasonable lastBlock index: ${lastBlock.index}`);
6499
+ const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
6500
+ debug(`Peer ${peerName2} claims unreasonable block height ${lastBlock.index} (local: ${localBlock?.index ?? 0})`);
6501
+ await this.#recordPeerFailure(peerId2, `unreasonable lastBlock index: ${lastBlock.index}`);
6474
6502
  return;
6475
6503
  }
6476
6504
  if (!lastBlock || !lastBlock.hash || lastBlock.hash === "0x0") {
6477
- debug(`peer has no lastBlock: ${peerId}`);
6505
+ debug(`peer has no lastBlock: ${peerId2}`);
6478
6506
  return;
6479
6507
  }
6480
6508
  const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
@@ -6484,23 +6512,24 @@ class Chain extends VersionControl {
6484
6512
  const knownBlocksRaw = await this.#makeRequest(peer, "knownBlocks");
6485
6513
  const knownBlocksResponse = await this.#decodeKnownBlocksResponse(knownBlocksRaw);
6486
6514
  if (!knownBlocksResponse) {
6487
- const reason = `knownBlocks decode failed for peer ${peerId}`;
6488
- debug(reason);
6489
- await this.#recordPeerFailure(peerId, reason);
6490
- return;
6491
- }
6492
- const MAX_WANTLIST_SIZE = 1e3;
6493
- const remaining = MAX_WANTLIST_SIZE - this.wantList.length;
6494
- if (remaining > 0) {
6495
- for (const hash of knownBlocksResponse.blocks.slice(0, remaining)) {
6496
- this.wantList.push(hash);
6515
+ debug(
6516
+ `knownBlocks decode failed for peer ${peerId2} (non-fatal), continuing sync without prefilled wantList`
6517
+ );
6518
+ } else {
6519
+ const MAX_WANTLIST_SIZE = 1e3;
6520
+ const remaining = MAX_WANTLIST_SIZE - this.wantList.length;
6521
+ if (remaining > 0) {
6522
+ for (const hash of knownBlocksResponse.blocks.slice(0, remaining)) {
6523
+ this.wantList.push(hash);
6524
+ }
6497
6525
  }
6498
6526
  }
6499
- } catch (error) {
6500
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
6501
- debug(`knownBlocks request failed: ${peerName}:`, error?.message ?? error);
6502
- await this.#recordPeerFailure(peerId, `knownBlocks request failed: ${error?.message ?? error}`);
6503
- return;
6527
+ } catch (error2) {
6528
+ const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
6529
+ debug(
6530
+ `knownBlocks request failed: ${peerName2} (non-fatal), continuing sync without prefilled wantList:`,
6531
+ error2?.message ?? error2
6532
+ );
6504
6533
  }
6505
6534
  }
6506
6535
  }
@@ -6516,9 +6545,9 @@ class Chain extends VersionControl {
6516
6545
  try {
6517
6546
  const peerTransactionPool = higherThenCurrentLocal && await this.getPeerTransactionPool(peer) || [];
6518
6547
  if (this.#participating && peerTransactionPool.length > 0) return this.#runEpoch();
6519
- } catch (error) {
6520
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
6521
- debug(`transactionPool request failed: ${peerName}:`, error?.message ?? error);
6548
+ } catch (error2) {
6549
+ const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
6550
+ debug(`transactionPool request failed: ${peerName2}:`, error2?.message ?? error2);
6522
6551
  }
6523
6552
  }, 3e3);
6524
6553
  try {
@@ -6526,12 +6555,18 @@ class Chain extends VersionControl {
6526
6555
  if (stateInfo instanceof Uint8Array) {
6527
6556
  stateInfo = new StateMessage(stateInfo).decoded;
6528
6557
  }
6558
+ debug(
6559
+ `sync start with peer ${peerId2}: local=${localBlock?.index ?? -1} remote=${lastBlock?.index ?? -1} hash=${lastBlock?.hash}`
6560
+ );
6529
6561
  await this.syncChain(lastBlock);
6562
+ debug(
6563
+ `sync finished with peer ${peerId2}: state=${this.syncState} localNow=${(await this.lastBlock)?.index ?? -1}`
6564
+ );
6530
6565
  this.machine.states.info = stateInfo;
6531
- } catch (error) {
6532
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
6533
- debug(`stateInfo/syncChain failed: ${peerName}:`, error?.message ?? error);
6534
- await this.#recordPeerFailure(peerId, `stateInfo/syncChain failed: ${error?.message ?? error}`);
6566
+ } catch (error2) {
6567
+ const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
6568
+ debug(`stateInfo/syncChain failed: ${peerName2}:`, error2?.message ?? error2);
6569
+ await this.#recordPeerFailure(peerId2, `stateInfo/syncChain failed: ${error2?.message ?? error2}`);
6535
6570
  return;
6536
6571
  }
6537
6572
  }
@@ -6547,16 +6582,19 @@ class Chain extends VersionControl {
6547
6582
  try {
6548
6583
  let result = await this.machine.execute(to, method, params);
6549
6584
  globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fulfilled", hash });
6550
- return result || "no state change";
6551
- } catch (error) {
6585
+ debug(
6586
+ `lastBlock request failed: ${peerName} (non-fatal), continuing sync without prefilled wantList:`,
6587
+ error?.message ?? error
6588
+ );
6589
+ } catch (error2) {
6552
6590
  await transactionPoolStore.delete(hash);
6553
6591
  try {
6554
6592
  globalThis.peernet.publish("invalid-transaction", hash);
6555
6593
  } catch (publishError) {
6556
6594
  debug("peernet publish failed: invalid-transaction", publishError?.message ?? publishError);
6557
6595
  }
6558
- globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error });
6559
- throw { error, hash, from, to, params, nonce };
6596
+ globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error: error2 });
6597
+ throw { error: error2, hash, from, to, params, nonce };
6560
6598
  }
6561
6599
  }
6562
6600
  async #addBlock(block) {
@@ -6567,7 +6605,7 @@ class Chain extends VersionControl {
6567
6605
  const existingBlockAtHeight = this.#blocks[blockIndex];
6568
6606
  if (existingBlockAtHeight) {
6569
6607
  if (existingBlockAtHeight.hash !== hash) {
6570
- console.error(`[CONSENSUS ALERT] Conflicting blocks at height ${blockIndex}:`);
6608
+ debug(`knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`);
6571
6609
  console.error(` Local: ${existingBlockAtHeight.hash}`);
6572
6610
  console.error(` Remote: ${hash}`);
6573
6611
  throw new Error(`Block conflict detected at index ${blockIndex}`);
@@ -6675,10 +6713,10 @@ class Chain extends VersionControl {
6675
6713
  await this.updateState(blockMessage);
6676
6714
  }
6677
6715
  globalThis.pubsub.publish("block-processed", blockMessage.decoded);
6678
- } catch (error) {
6679
- console.log(error.hash);
6716
+ } catch (error2) {
6717
+ console.log(error2.hash);
6680
6718
  console.log("errrrr");
6681
- await transactionPoolStore.delete(error.hash);
6719
+ await transactionPoolStore.delete(error2.hash);
6682
6720
  }
6683
6721
  }
6684
6722
  async participate(address) {
@@ -6696,12 +6734,12 @@ class Chain extends VersionControl {
6696
6734
  const transaction = await signTransaction(rawTransaction, globalThis.peernet.identity);
6697
6735
  try {
6698
6736
  await this.sendTransaction(transaction);
6699
- } catch (error) {
6700
- console.error(error);
6737
+ } catch (error2) {
6738
+ console.error(error2);
6701
6739
  }
6702
6740
  }
6703
- } catch (error) {
6704
- debug("Error in participate:", error.message);
6741
+ } catch (error2) {
6742
+ debug("Error in participate:", error2.message);
6705
6743
  }
6706
6744
  if (await this.hasTransactionToHandle() && !this.#runningEpoch && this.#participating) await this.#runEpoch();
6707
6745
  }
@@ -6798,9 +6836,9 @@ class Chain extends VersionControl {
6798
6836
  address: validator,
6799
6837
  bw: bw.up + bw.down
6800
6838
  };
6801
- } catch (error) {
6802
- const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
6803
- debug(`bw request failed: ${peerId}:`, error?.message ?? error);
6839
+ } catch (error2) {
6840
+ const peerId2 = peer?.peerId || peer?.id || peer?.address || "unknown";
6841
+ debug(`bw request failed: ${peerId2}:`, error2?.message ?? error2);
6804
6842
  return null;
6805
6843
  }
6806
6844
  } else if (globalThis.peernet.selectedAccount === validator) {
@@ -6818,8 +6856,8 @@ class Chain extends VersionControl {
6818
6856
  }
6819
6857
  }
6820
6858
  };
6821
- finalizeBWAndBroadcast().catch((error) => {
6822
- debug(`background BW finalization failed:`, error?.message ?? error);
6859
+ finalizeBWAndBroadcast().catch((error2) => {
6860
+ debug(`background BW finalization failed:`, error2?.message ?? error2);
6823
6861
  });
6824
6862
  block.validators = block.validators.map((validator) => {
6825
6863
  validator.reward = block.fees;
@@ -6884,8 +6922,8 @@ class Chain extends VersionControl {
6884
6922
  debug("peernet publish failed: consensus:propose", publishError?.message ?? publishError);
6885
6923
  }
6886
6924
  await this.#castVote("prevote", hash, block.index, this.#consensusRound);
6887
- } catch (error) {
6888
- console.log(error);
6925
+ } catch (error2) {
6926
+ console.log(error2);
6889
6927
  throw new Error(`invalid block ${block}`);
6890
6928
  }
6891
6929
  }
@@ -7016,8 +7054,8 @@ class Chain extends VersionControl {
7016
7054
  if (globalThis.peernet && globalThis.peernet.start) {
7017
7055
  await globalThis.peernet.start();
7018
7056
  }
7019
- } catch (error) {
7020
- console.warn("Failed to reconnect to peers:", error.message);
7057
+ } catch (error2) {
7058
+ console.warn("Failed to reconnect to peers:", error2.message);
7021
7059
  }
7022
7060
  }
7023
7061
  }
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(peerId, reason) {
2343
- if (!this.#peerReputations.has(peerId)) {
2344
- this.#peerReputations.set(peerId, { score: 0, failures: [] });
2342
+ async #recordPeerFailure(peerId2, reason) {
2343
+ if (!this.#peerReputations.has(peerId2)) {
2344
+ this.#peerReputations.set(peerId2, { score: 0, failures: [] });
2345
2345
  }
2346
- const rep = this.#peerReputations.get(peerId);
2346
+ const rep = this.#peerReputations.get(peerId2);
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 ${peerId} banned after ${rep.failures.length} failures`);
2353
+ console.warn(`[peer-ban] Peer ${peerId2} banned after ${rep.failures.length} failures`);
2354
2354
  try {
2355
- await globalThis.peernet.disconnect(peerId);
2355
+ await globalThis.peernet.disconnect(peerId2);
2356
2356
  } catch (e) {
2357
- debug(`Failed to disconnect peer ${peerId}`);
2357
+ debug(`Failed to disconnect peer ${peerId2}`);
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 (error) {
2478
- console.error(error);
2477
+ } catch (error2) {
2478
+ console.error(error2);
2479
2479
  }
2480
2480
  const end = Date.now();
2481
2481
  console.log((end - start) / 1e3 + " s");
@@ -2590,30 +2590,57 @@ class Chain extends VersionControl {
2590
2590
  console.warn(`Deprecated: ${response.decoded.response} is not an Uint8Array`);
2591
2591
  }
2592
2592
  return response.decoded.response;
2593
- } catch (error) {
2594
- const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
2595
- debug(`peernet request failed: ${request} -> ${peerId}:`, error?.message ?? error);
2596
- throw error;
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;
2597
2597
  }
2598
2598
  }
2599
2599
  async #decodeKnownBlocksResponse(response) {
2600
2600
  if (!response) return null;
2601
+ if (Array.isArray(response)) {
2602
+ return { blocks: response };
2603
+ }
2601
2604
  if (Array.isArray(response.blocks)) {
2602
2605
  return { blocks: response.blocks };
2603
2606
  }
2607
+ if (response.response && Array.isArray(response.response.blocks)) {
2608
+ return { blocks: response.response.blocks };
2609
+ }
2610
+ if (typeof response === "string") {
2611
+ try {
2612
+ const parsed = JSON.parse(response);
2613
+ if (Array.isArray(parsed)) return { blocks: parsed };
2614
+ if (parsed && Array.isArray(parsed.blocks)) return { blocks: parsed.blocks };
2615
+ if (parsed?.response && Array.isArray(parsed.response.blocks)) return { blocks: parsed.response.blocks };
2616
+ } catch {
2617
+ return null;
2618
+ }
2619
+ return null;
2620
+ }
2604
2621
  if (!(response instanceof Uint8Array)) return null;
2605
2622
  let payload = response;
2606
- for (let i = 0; i < 2; i++) {
2623
+ for (let i = 0; i < 3; i++) {
2607
2624
  if (!(payload instanceof Uint8Array)) break;
2608
2625
  try {
2609
2626
  const nestedResponse = await new globalThis.peernet.protos["peernet-response"](payload);
2610
2627
  payload = nestedResponse?.decoded?.response;
2611
2628
  } catch {
2612
- return null;
2629
+ break;
2613
2630
  }
2614
2631
  }
2615
2632
  if (Array.isArray(payload)) return { blocks: payload };
2616
2633
  if (payload && Array.isArray(payload.blocks)) return { blocks: payload.blocks };
2634
+ if (payload?.response && Array.isArray(payload.response.blocks)) return { blocks: payload.response.blocks };
2635
+ try {
2636
+ const decoded = new TextDecoder().decode(response);
2637
+ const parsed = JSON.parse(decoded);
2638
+ if (Array.isArray(parsed)) return { blocks: parsed };
2639
+ if (parsed && Array.isArray(parsed.blocks)) return { blocks: parsed.blocks };
2640
+ if (parsed?.response && Array.isArray(parsed.response.blocks)) return { blocks: parsed.response.blocks };
2641
+ } catch {
2642
+ return null;
2643
+ }
2617
2644
  return null;
2618
2645
  }
2619
2646
  async getPeerTransactionPool(peer) {
@@ -2630,8 +2657,8 @@ class Chain extends VersionControl {
2630
2657
  let txData;
2631
2658
  try {
2632
2659
  txData = await globalThis.peernet.get(key, "transaction");
2633
- } catch (error) {
2634
- debug(`Failed to get transaction ${key}:`, error?.message ?? error);
2660
+ } catch (error2) {
2661
+ debug(`Failed to get transaction ${key}:`, error2?.message ?? error2);
2635
2662
  }
2636
2663
  if (txData !== void 0) {
2637
2664
  transactionsToGet.push(transactionPoolStore.put(key, txData));
@@ -2640,11 +2667,11 @@ class Chain extends VersionControl {
2640
2667
  }
2641
2668
  return Promise.all(transactionsToGet);
2642
2669
  }
2643
- async #peerConnected(peerId) {
2644
- debug(`peer connected: ${peerId}`);
2645
- const peer = peernet.getConnection(peerId);
2670
+ async #peerConnected(peerId2) {
2671
+ debug(`peer connected: ${peerId2}`);
2672
+ const peer = peernet.getConnection(peerId2);
2646
2673
  if (!peer) {
2647
- debug(`peer not found: ${peerId}`);
2674
+ debug(`peer not found: ${peerId2}`);
2648
2675
  return;
2649
2676
  }
2650
2677
  if (!peer.version) {
@@ -2659,13 +2686,13 @@ class Chain extends VersionControl {
2659
2686
  peer.version = versionResponse.version;
2660
2687
  }
2661
2688
  if (!peer.version || typeof peer.version !== "string") {
2662
- const reason = `invalid version response from peer ${peerId}`;
2689
+ const reason = `invalid version response from peer ${peerId2}`;
2663
2690
  debug(reason);
2664
- await this.#recordPeerFailure(peerId, reason);
2691
+ await this.#recordPeerFailure(peerId2, reason);
2665
2692
  return;
2666
2693
  }
2667
- } catch (error) {
2668
- debug(`failed to request version from peer ${peerId}:`, error?.message ?? error);
2694
+ } catch (error2) {
2695
+ debug(`failed to request version from peer ${peerId2}:`, error2?.message ?? error2);
2669
2696
  return;
2670
2697
  }
2671
2698
  }
@@ -2673,31 +2700,32 @@ class Chain extends VersionControl {
2673
2700
  if (!this.isVersionCompatible(peer.version)) {
2674
2701
  const mismatchReason = `incompatible peer version ${peer.version} (local: ${this.version})`;
2675
2702
  console.error(`[chain] ${mismatchReason}`);
2676
- await this.#recordPeerFailure(peerId, mismatchReason);
2703
+ await this.#recordPeerFailure(peerId2, mismatchReason);
2677
2704
  return;
2678
2705
  }
2679
2706
  let lastBlock;
2680
2707
  try {
2681
2708
  console.log("requesting last block from peer...");
2682
2709
  console.log(await this.lastBlock);
2683
- console.log(new LastBlockMessage(await this.#makeRequest(peer, "lastBlock")));
2684
- lastBlock = new LastBlockMessage(await this.#makeRequest(peer, "lastBlock")).decoded;
2685
- } catch (error) {
2686
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2687
- debug(`lastBlock request failed: ${peerName}:`, error?.message ?? error);
2688
- await this.#recordPeerFailure(peerId, `lastBlock request failed: ${error?.message ?? error}`);
2710
+ const lastBlockRaw = await this.#makeRequest(peer, "lastBlock");
2711
+ console.log(new LastBlockMessage(lastBlockRaw));
2712
+ 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}`);
2689
2717
  return;
2690
2718
  }
2691
2719
  const localBlock = await this.lastBlock;
2692
2720
  const MAX_SYNC_AHEAD = 1e5;
2693
2721
  if (lastBlock?.index > BigInt(localBlock?.index ?? 0) + BigInt(MAX_SYNC_AHEAD)) {
2694
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2695
- debug(`Peer ${peerName} claims unreasonable block height ${lastBlock.index} (local: ${localBlock?.index ?? 0})`);
2696
- await this.#recordPeerFailure(peerId, `unreasonable lastBlock index: ${lastBlock.index}`);
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}`);
2697
2725
  return;
2698
2726
  }
2699
2727
  if (!lastBlock || !lastBlock.hash || lastBlock.hash === "0x0") {
2700
- debug(`peer has no lastBlock: ${peerId}`);
2728
+ debug(`peer has no lastBlock: ${peerId2}`);
2701
2729
  return;
2702
2730
  }
2703
2731
  const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
@@ -2707,23 +2735,24 @@ class Chain extends VersionControl {
2707
2735
  const knownBlocksRaw = await this.#makeRequest(peer, "knownBlocks");
2708
2736
  const knownBlocksResponse = await this.#decodeKnownBlocksResponse(knownBlocksRaw);
2709
2737
  if (!knownBlocksResponse) {
2710
- const reason = `knownBlocks decode failed for peer ${peerId}`;
2711
- debug(reason);
2712
- await this.#recordPeerFailure(peerId, reason);
2713
- return;
2714
- }
2715
- const MAX_WANTLIST_SIZE = 1e3;
2716
- const remaining = MAX_WANTLIST_SIZE - this.wantList.length;
2717
- if (remaining > 0) {
2718
- for (const hash of knownBlocksResponse.blocks.slice(0, remaining)) {
2719
- this.wantList.push(hash);
2738
+ debug(
2739
+ `knownBlocks decode failed for peer ${peerId2} (non-fatal), continuing sync without prefilled wantList`
2740
+ );
2741
+ } else {
2742
+ const MAX_WANTLIST_SIZE = 1e3;
2743
+ const remaining = MAX_WANTLIST_SIZE - this.wantList.length;
2744
+ if (remaining > 0) {
2745
+ for (const hash of knownBlocksResponse.blocks.slice(0, remaining)) {
2746
+ this.wantList.push(hash);
2747
+ }
2720
2748
  }
2721
2749
  }
2722
- } catch (error) {
2723
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2724
- debug(`knownBlocks request failed: ${peerName}:`, error?.message ?? error);
2725
- await this.#recordPeerFailure(peerId, `knownBlocks request failed: ${error?.message ?? error}`);
2726
- return;
2750
+ } catch (error2) {
2751
+ const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
2752
+ debug(
2753
+ `knownBlocks request failed: ${peerName2} (non-fatal), continuing sync without prefilled wantList:`,
2754
+ error2?.message ?? error2
2755
+ );
2727
2756
  }
2728
2757
  }
2729
2758
  }
@@ -2739,9 +2768,9 @@ class Chain extends VersionControl {
2739
2768
  try {
2740
2769
  const peerTransactionPool = higherThenCurrentLocal && await this.getPeerTransactionPool(peer) || [];
2741
2770
  if (this.#participating && peerTransactionPool.length > 0) return this.#runEpoch();
2742
- } catch (error) {
2743
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2744
- debug(`transactionPool request failed: ${peerName}:`, error?.message ?? error);
2771
+ } catch (error2) {
2772
+ const peerName2 = peer?.peerId || peer?.id || peer?.address || peerId2 || "unknown";
2773
+ debug(`transactionPool request failed: ${peerName2}:`, error2?.message ?? error2);
2745
2774
  }
2746
2775
  }, 3e3);
2747
2776
  try {
@@ -2749,12 +2778,18 @@ class Chain extends VersionControl {
2749
2778
  if (stateInfo instanceof Uint8Array) {
2750
2779
  stateInfo = new StateMessage(stateInfo).decoded;
2751
2780
  }
2781
+ debug(
2782
+ `sync start with peer ${peerId2}: local=${localBlock?.index ?? -1} remote=${lastBlock?.index ?? -1} hash=${lastBlock?.hash}`
2783
+ );
2752
2784
  await this.syncChain(lastBlock);
2785
+ debug(
2786
+ `sync finished with peer ${peerId2}: state=${this.syncState} localNow=${(await this.lastBlock)?.index ?? -1}`
2787
+ );
2753
2788
  this.machine.states.info = stateInfo;
2754
- } catch (error) {
2755
- const peerName = peer?.peerId || peer?.id || peer?.address || peerId || "unknown";
2756
- debug(`stateInfo/syncChain failed: ${peerName}:`, error?.message ?? error);
2757
- await this.#recordPeerFailure(peerId, `stateInfo/syncChain failed: ${error?.message ?? error}`);
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}`);
2758
2793
  return;
2759
2794
  }
2760
2795
  }
@@ -2770,16 +2805,19 @@ class Chain extends VersionControl {
2770
2805
  try {
2771
2806
  let result = await this.machine.execute(to, method, params);
2772
2807
  globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fulfilled", hash });
2773
- return result || "no state change";
2774
- } catch (error) {
2808
+ debug(
2809
+ `lastBlock request failed: ${peerName} (non-fatal), continuing sync without prefilled wantList:`,
2810
+ error?.message ?? error
2811
+ );
2812
+ } catch (error2) {
2775
2813
  await transactionPoolStore.delete(hash);
2776
2814
  try {
2777
2815
  globalThis.peernet.publish("invalid-transaction", hash);
2778
2816
  } catch (publishError) {
2779
2817
  debug("peernet publish failed: invalid-transaction", publishError?.message ?? publishError);
2780
2818
  }
2781
- globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error });
2782
- throw { error, hash, from, to, params, nonce };
2819
+ globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: "fail", hash, error: error2 });
2820
+ throw { error: error2, hash, from, to, params, nonce };
2783
2821
  }
2784
2822
  }
2785
2823
  async #addBlock(block) {
@@ -2790,7 +2828,7 @@ class Chain extends VersionControl {
2790
2828
  const existingBlockAtHeight = this.#blocks[blockIndex];
2791
2829
  if (existingBlockAtHeight) {
2792
2830
  if (existingBlockAtHeight.hash !== hash) {
2793
- console.error(`[CONSENSUS ALERT] Conflicting blocks at height ${blockIndex}:`);
2831
+ debug(`knownBlocks decode failed for peer ${peerId} (non-fatal), continuing sync without prefilled wantList`);
2794
2832
  console.error(` Local: ${existingBlockAtHeight.hash}`);
2795
2833
  console.error(` Remote: ${hash}`);
2796
2834
  throw new Error(`Block conflict detected at index ${blockIndex}`);
@@ -2898,10 +2936,10 @@ class Chain extends VersionControl {
2898
2936
  await this.updateState(blockMessage);
2899
2937
  }
2900
2938
  globalThis.pubsub.publish("block-processed", blockMessage.decoded);
2901
- } catch (error) {
2902
- console.log(error.hash);
2939
+ } catch (error2) {
2940
+ console.log(error2.hash);
2903
2941
  console.log("errrrr");
2904
- await transactionPoolStore.delete(error.hash);
2942
+ await transactionPoolStore.delete(error2.hash);
2905
2943
  }
2906
2944
  }
2907
2945
  async participate(address) {
@@ -2919,12 +2957,12 @@ class Chain extends VersionControl {
2919
2957
  const transaction = await signTransaction(rawTransaction, globalThis.peernet.identity);
2920
2958
  try {
2921
2959
  await this.sendTransaction(transaction);
2922
- } catch (error) {
2923
- console.error(error);
2960
+ } catch (error2) {
2961
+ console.error(error2);
2924
2962
  }
2925
2963
  }
2926
- } catch (error) {
2927
- debug("Error in participate:", error.message);
2964
+ } catch (error2) {
2965
+ debug("Error in participate:", error2.message);
2928
2966
  }
2929
2967
  if (await this.hasTransactionToHandle() && !this.#runningEpoch && this.#participating) await this.#runEpoch();
2930
2968
  }
@@ -3021,9 +3059,9 @@ class Chain extends VersionControl {
3021
3059
  address: validator,
3022
3060
  bw: bw.up + bw.down
3023
3061
  };
3024
- } catch (error) {
3025
- const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
3026
- debug(`bw request failed: ${peerId}:`, error?.message ?? error);
3062
+ } catch (error2) {
3063
+ const peerId2 = peer?.peerId || peer?.id || peer?.address || "unknown";
3064
+ debug(`bw request failed: ${peerId2}:`, error2?.message ?? error2);
3027
3065
  return null;
3028
3066
  }
3029
3067
  } else if (globalThis.peernet.selectedAccount === validator) {
@@ -3041,8 +3079,8 @@ class Chain extends VersionControl {
3041
3079
  }
3042
3080
  }
3043
3081
  };
3044
- finalizeBWAndBroadcast().catch((error) => {
3045
- debug(`background BW finalization failed:`, error?.message ?? error);
3082
+ finalizeBWAndBroadcast().catch((error2) => {
3083
+ debug(`background BW finalization failed:`, error2?.message ?? error2);
3046
3084
  });
3047
3085
  block.validators = block.validators.map((validator) => {
3048
3086
  validator.reward = block.fees;
@@ -3107,8 +3145,8 @@ class Chain extends VersionControl {
3107
3145
  debug("peernet publish failed: consensus:propose", publishError?.message ?? publishError);
3108
3146
  }
3109
3147
  await this.#castVote("prevote", hash, block.index, this.#consensusRound);
3110
- } catch (error) {
3111
- console.log(error);
3148
+ } catch (error2) {
3149
+ console.log(error2);
3112
3150
  throw new Error(`invalid block ${block}`);
3113
3151
  }
3114
3152
  }
@@ -3239,8 +3277,8 @@ class Chain extends VersionControl {
3239
3277
  if (globalThis.peernet && globalThis.peernet.start) {
3240
3278
  await globalThis.peernet.start();
3241
3279
  }
3242
- } catch (error) {
3243
- console.warn("Failed to reconnect to peers:", error.message);
3280
+ } catch (error2) {
3281
+ console.warn("Failed to reconnect to peers:", error2.message);
3244
3282
  }
3245
3283
  }
3246
3284
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/chain",
3
- "version": "1.9.11",
3
+ "version": "1.9.12",
4
4
  "description": "Official javascript implementation",
5
5
  "private": false,
6
6
  "exports": {